feat(mobile): implement language-based preset feeds for onboarding (#3109)
* feat(mobile): implement language-based preset feeds for onboarding * fix: enhance useIsNewUser hook to accept enabled parameter * refactor(mobile): streamline subscription handling in StepInterests component * fix(mobile): correct feedId values in English feeds JSON
This commit is contained in:
parent
ca897ebf2c
commit
9f07a3b0fd
|
|
@ -0,0 +1,263 @@
|
|||
[
|
||||
{
|
||||
"feedId": "43255084704601095",
|
||||
"title": "a16z Podcast",
|
||||
"url": "https://feeds.simplecast.com/JGE3yC0V",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "83007794771225600",
|
||||
"title": "Andrew Huberman - YouTube",
|
||||
"url": "rsshub://youtube/user/@hubermanlab",
|
||||
"language": "English",
|
||||
"view": 3
|
||||
},
|
||||
{
|
||||
"feedId": "62128288597853189",
|
||||
"title": "Cal Newport",
|
||||
"url": "https://calnewport.com/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "43881675446885376",
|
||||
"title": "Collab Fund",
|
||||
"url": "http://feeds.feedburner.com/collabfund",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41359648684677175",
|
||||
"title": "Derek Sivers blog",
|
||||
"url": "https://sive.rs/en.atom",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "52325519371718656",
|
||||
"title": "Hacker News",
|
||||
"url": "rsshub://hackernews",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41381007770949636",
|
||||
"title": "IGN Articles",
|
||||
"url": "https://www.ign.com/rss/articles/feed?tags=games",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "59461847827447808",
|
||||
"title": "International homepage",
|
||||
"url": "https://www.ft.com/rss/home",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "52333046926856207",
|
||||
"title": "Kotaku",
|
||||
"url": "https://kotaku.com/rss",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41768239731545104",
|
||||
"title": "LessWrong",
|
||||
"url": "https://www.lesswrong.com/feed.xml?view=curated-rss",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41375850878492672",
|
||||
"title": "Lex Fridman - YouTube",
|
||||
"url": "rsshub://youtube/user/%40lexfridman",
|
||||
"language": "English",
|
||||
"view": 3
|
||||
},
|
||||
{
|
||||
"feedId": "55258726035912721",
|
||||
"title": "Marginal REVOLUTION",
|
||||
"url": "https://marginalrevolution.com/feed",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "42109057149046784",
|
||||
"title": "Marques Brownlee - YouTube",
|
||||
"url": "rsshub://youtube/user/@mkbhd",
|
||||
"language": "English",
|
||||
"view": 3
|
||||
},
|
||||
{
|
||||
"feedId": "41768239731545089",
|
||||
"title": "MIT Technology Review",
|
||||
"url": "https://www.technologyreview.com/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "42127302309630072",
|
||||
"title": "Mr. Money Mustache",
|
||||
"url": "https://feeds.feedburner.com/mrmoneymustache",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41356263889737728",
|
||||
"title": "NASA Astronomy Picture of the Day",
|
||||
"url": "rsshub://nasa/apod",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "55130722692595739",
|
||||
"title": "Nassim Taleb",
|
||||
"url": "https://nassimtaleb.org/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41699925856588800",
|
||||
"title": "Nat Geo Photo of the Day",
|
||||
"url": "rsshub://natgeo/dailyphoto",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "42127302309630013",
|
||||
"title": "Nautilus",
|
||||
"url": "https://nautil.us/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41147805276726370",
|
||||
"title": "Obsidian Changelog",
|
||||
"url": "https://obsidian.md/changelog.xml",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41468521403732992",
|
||||
"title": "Paul Graham - Essays",
|
||||
"url": "rsshub://paulgraham/articles",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "55130722692595736",
|
||||
"title": "Peter Attia",
|
||||
"url": "https://peterattiamd.com/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41382261184290816",
|
||||
"title": "Product Hunt — The best new products, every day",
|
||||
"url": "https://www.producthunt.com/feed",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "43254816999905282",
|
||||
"title": "Research & Insights",
|
||||
"url": "https://www.bridgewater.com/research-and-insights.rss",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41147805276726402",
|
||||
"title": "RSSHub has new routes",
|
||||
"url": "rsshub://rsshub/routes",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "66860831563739166",
|
||||
"title": "Sabine Hossenfelder",
|
||||
"url": "https://www.youtube.com/feeds/videos.xml?channel_id=UC1yNl2E66ZzKApQdRuTQ4tw",
|
||||
"language": "English",
|
||||
"view": 3
|
||||
},
|
||||
{
|
||||
"feedId": "49470377330653207",
|
||||
"title": "Seth's Blog",
|
||||
"url": "https://seths.blog/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41795937311945747",
|
||||
"title": "Stratechery by Ben Thompson",
|
||||
"url": "https://stratechery.com/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "59299066394742784",
|
||||
"title": "TechCrunch",
|
||||
"url": "https://techcrunch.com/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "49470377330653193",
|
||||
"title": "The Blog of Author Tim Ferriss",
|
||||
"url": "https://tim.blog/feed/",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "57993144602143744",
|
||||
"title": "The Memo by Howard Marks",
|
||||
"url": "https://rss.art19.com/the-memo-by-howard-marks",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "100080366298125312",
|
||||
"title": "The Verge",
|
||||
"url": "https://www.theverge.com/rss/index.xml",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41572238278099968",
|
||||
"title": "The world in brief | The Economist",
|
||||
"url": "rsshub://economist/espresso",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41368476124603392",
|
||||
"title": "Trending repositories on GitHub this week · GitHub",
|
||||
"url": "rsshub://github/trending/weekly/any",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41461870197170196",
|
||||
"title": "Trending repositories on GitHub today · GitHub",
|
||||
"url": "rsshub://github/trending/daily/any",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "87076619508029440",
|
||||
"title": "Twitter @Balaji",
|
||||
"url": "rsshub://twitter/user/balajis",
|
||||
"language": "English",
|
||||
"view": 1
|
||||
},
|
||||
{
|
||||
"feedId": "59795737540541440",
|
||||
"title": "Twitter @David Sinclair",
|
||||
"url": "rsshub://twitter/user/davidasinclair",
|
||||
"language": "English",
|
||||
"view": 1
|
||||
},
|
||||
{
|
||||
"feedId": "100411504863520768",
|
||||
"title": "Twitter @Elon Musk",
|
||||
"url": "rsshub://twitter/user/elonmusk",
|
||||
"language": "English",
|
||||
"view": 1
|
||||
},
|
||||
{
|
||||
"feedId": "41215396143077382",
|
||||
"title": "Twitter @Follow",
|
||||
"url": "rsshub://twitter/user/follow_app_",
|
||||
"language": "English",
|
||||
"view": 1
|
||||
},
|
||||
{
|
||||
"feedId": "55866936513101824",
|
||||
"title": "Twitter @James Clear",
|
||||
"url": "rsshub://twitter/user/JamesClear",
|
||||
"language": "English",
|
||||
"view": 1
|
||||
},
|
||||
{
|
||||
"feedId": "41342818712721408",
|
||||
"title": "Wait But Why",
|
||||
"url": "https://waitbutwhy.com/feed?code=c6f56c4214621ab98b86acbcae6b4405",
|
||||
"language": "English"
|
||||
},
|
||||
{
|
||||
"feedId": "41965184796582014",
|
||||
"title": "WIRED",
|
||||
"url": "https://www.wired.com/feed/rss",
|
||||
"language": "English"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,8 @@
|
|||
import { FeedViewType } from "@follow/constants"
|
||||
import { getLocales } from "expo-localization"
|
||||
|
||||
import feeds from "./feeds.json"
|
||||
import englishFeeds from "./feeds-english.json"
|
||||
|
||||
export type PresetFeedConfig = {
|
||||
title: string
|
||||
|
|
@ -7,116 +11,21 @@ export type PresetFeedConfig = {
|
|||
view: FeedViewType
|
||||
}
|
||||
|
||||
export const presetFeeds: PresetFeedConfig[] = [
|
||||
{
|
||||
feedId: "41358761177015296",
|
||||
title: "知乎热榜 - 全站",
|
||||
url: "rsshub://zhihu/hot/total",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "100020530265058357",
|
||||
title: "阮一峰的网络日志",
|
||||
url: "https://feeds.feedburner.com/ruanyifeng",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
export const englishPresetFeeds: PresetFeedConfig[] = englishFeeds.map((feed) => ({
|
||||
view: FeedViewType.Articles,
|
||||
...feed,
|
||||
}))
|
||||
|
||||
{
|
||||
feedId: "41358830592746496",
|
||||
title: "微博热搜榜",
|
||||
url: "rsshub://weibo/search/hot",
|
||||
view: FeedViewType.SocialMedia,
|
||||
},
|
||||
{
|
||||
feedId: "100411504863520768",
|
||||
title: "Twitter @Elon Musk",
|
||||
url: "rsshub://twitter/user/elonmusk",
|
||||
view: FeedViewType.SocialMedia,
|
||||
},
|
||||
{
|
||||
feedId: "41324816676184077",
|
||||
title: "Twitter @DIŸgöd ☀️",
|
||||
url: "rsshub://twitter/user/DIYgod",
|
||||
view: FeedViewType.SocialMedia,
|
||||
},
|
||||
export const otherPresetFeeds: PresetFeedConfig[] = feeds
|
||||
// .filter((feed) => feed.language === "Chinese")
|
||||
.map((feed) => ({
|
||||
view: FeedViewType.Articles,
|
||||
...feed,
|
||||
}))
|
||||
|
||||
{
|
||||
feedId: "78806242632741888",
|
||||
title: "bilibili 排行榜-全站",
|
||||
url: "rsshub://bilibili/ranking/0",
|
||||
view: FeedViewType.Videos,
|
||||
},
|
||||
const locales = getLocales()
|
||||
// `getLocales` guaranteed to contain at least 1 element.
|
||||
const languageTag = locales[0]?.languageTag || "en-US"
|
||||
const isEnglishUser = languageTag.startsWith("en")
|
||||
|
||||
{
|
||||
feedId: "60338304723722240",
|
||||
title: "实时财经快讯 - FastBull",
|
||||
url: "rsshub://fastbull/express-news",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "55611390687386624",
|
||||
title: "格隆汇快讯-7x24小时市场快讯-财经市场热点",
|
||||
url: "rsshub://gelonghui/live",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "49375919416104960",
|
||||
title: "深潮TechFlow - 快讯",
|
||||
url: "rsshub://techflowpost/express",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "55982073122828305",
|
||||
title: "TED Talks Daily",
|
||||
url: "https://feeds.acast.com/public/shows/67587e77c705e441797aff96",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "72541715399995392",
|
||||
title: "TheBlockBeats - 快讯",
|
||||
url: "rsshub://theblockbeats/newsflash/0",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "100184911354754055",
|
||||
title: "小Lin说",
|
||||
url: "https://www.youtube.com/feeds/videos.xml?channel_id=UCilwQlk62k1z7aUEZPOB6yw",
|
||||
view: FeedViewType.Videos,
|
||||
},
|
||||
{
|
||||
feedId: "100185810923910148",
|
||||
title: "张小珺Jùn|商业访谈录",
|
||||
url: "https://feed.xyzfm.space/dk4yh3pkpjp3",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "56584656988676096",
|
||||
title: "迷因电波",
|
||||
url: "rsshub://xiaoyuzhou/podcast/61d52b3bee197a3aac3dac44",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "76051724651752448",
|
||||
title: "极致音乐汇 的 bilibili 空间",
|
||||
url: "rsshub://bilibili/user/video/1691501735",
|
||||
view: FeedViewType.Videos,
|
||||
},
|
||||
{
|
||||
feedId: "66701376672681984",
|
||||
title: "AP Top News - AP News",
|
||||
url: "rsshub://apnews/api/apf-topnews",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "44366244616936448",
|
||||
title: "金十数据",
|
||||
url: "rsshub://jin10",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
{
|
||||
feedId: "52325519371718656",
|
||||
title: "Hacker News",
|
||||
url: "rsshub://hackernews",
|
||||
view: FeedViewType.Articles,
|
||||
},
|
||||
]
|
||||
export const presetFeeds = isEnglishUser ? englishPresetFeeds : otherPresetFeeds
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import Animated, { FadeIn, FadeOut } from "react-native-reanimated"
|
|||
|
||||
import { Search3CuteReIcon } from "@/src/icons/search_3_cute_re"
|
||||
import { Shuffle2CuteReIcon } from "@/src/icons/shuffle_2_cute_re"
|
||||
import { toast } from "@/src/lib/toast"
|
||||
import { useSubscription } from "@/src/store/subscription/hooks"
|
||||
import { subscriptionSyncService } from "@/src/store/subscription/store"
|
||||
import { accentColor } from "@/src/theme/colors"
|
||||
|
|
@ -13,28 +12,6 @@ import { accentColor } from "@/src/theme/colors"
|
|||
import type { PresetFeedConfig } from "./preset"
|
||||
import { presetFeeds } from "./preset"
|
||||
|
||||
const subscribeFeed = async (config: PresetFeedConfig) => {
|
||||
await subscriptionSyncService.subscribe({
|
||||
feedId: config.feedId,
|
||||
title: config.title,
|
||||
url: config.url,
|
||||
view: config.view,
|
||||
category: "",
|
||||
isPrivate: false,
|
||||
})
|
||||
|
||||
toast.success(`Subscribed to ${config.title}`, {
|
||||
position: "bottom",
|
||||
})
|
||||
}
|
||||
|
||||
const unsubscribeFeed = async (feedId: string) => {
|
||||
await subscriptionSyncService.unsubscribe(feedId)
|
||||
toast.success(`Unsubscribed from feed`, {
|
||||
position: "bottom",
|
||||
})
|
||||
}
|
||||
|
||||
export const StepInterests = () => {
|
||||
const [displayFeeds, setDisplayFeeds] = useState<PresetFeedConfig[]>(presetFeeds.slice(0, 7))
|
||||
|
||||
|
|
@ -66,7 +43,7 @@ export const StepInterests = () => {
|
|||
|
||||
<View className="flex-row flex-wrap justify-center gap-2 px-4">
|
||||
{displayFeeds.map((feed) => (
|
||||
<FeedChip key={feed.feedId} {...feed} />
|
||||
<FeedChip key={feed.feedId} feed={feed} />
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
|
@ -74,18 +51,43 @@ export const StepInterests = () => {
|
|||
)
|
||||
}
|
||||
|
||||
const FeedChip = (feed: PresetFeedConfig) => {
|
||||
const isSubscribed = useSubscription(feed.feedId)
|
||||
const FeedChip = ({ feed }: { feed: PresetFeedConfig }) => {
|
||||
const subscription = useSubscription(feed.feedId)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [isSubscribed, setIsSubscribed] = useState(!!subscription)
|
||||
|
||||
const handleSubscribe = useCallback(
|
||||
async (feed: PresetFeedConfig) => {
|
||||
if (loading) return
|
||||
setLoading(true)
|
||||
if (isSubscribed) {
|
||||
await unsubscribeFeed(feed.feedId)
|
||||
try {
|
||||
setIsSubscribed(false)
|
||||
await subscriptionSyncService.unsubscribe(feed.feedId)
|
||||
} catch {
|
||||
setIsSubscribed(true)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
return
|
||||
}
|
||||
await subscribeFeed(feed)
|
||||
try {
|
||||
setIsSubscribed(true)
|
||||
await subscriptionSyncService.subscribe({
|
||||
feedId: feed.feedId,
|
||||
title: feed.title,
|
||||
url: feed.url,
|
||||
view: feed.view,
|
||||
category: "",
|
||||
isPrivate: false,
|
||||
})
|
||||
} catch {
|
||||
setIsSubscribed(false)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
},
|
||||
[isSubscribed],
|
||||
[isSubscribed, loading],
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ export const useUser = (userId?: string) => {
|
|||
return useUserStore((state) => (userId ? state.users[userId] : undefined))
|
||||
}
|
||||
|
||||
export function useIsNewUser() {
|
||||
export function useIsNewUser(enabled = true) {
|
||||
const { data } = useQuery({
|
||||
enabled,
|
||||
queryKey: isNewUserQueryKey,
|
||||
queryFn: async () => {
|
||||
const isOnboardingFinished = await kv.get(isOnboardingFinishedStorageKey)
|
||||
|
|
@ -42,7 +43,8 @@ export function useIsNewUser() {
|
|||
}
|
||||
|
||||
export function useOnboarding() {
|
||||
const isNewUser = useIsNewUser()
|
||||
const whoami = useWhoami()
|
||||
const isNewUser = useIsNewUser(!!whoami)
|
||||
useEffect(() => {
|
||||
if (isNewUser) {
|
||||
router.push("/onboarding")
|
||||
|
|
|
|||
Loading…
Reference in New Issue