From 3c8b3b47823475b93a92dcf82a4cabbda625c323 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 10 Sep 2024 14:23:30 -0500 Subject: [PATCH] Progress on desktoip --- src/alf/index.tsx | 18 +- src/components/dialogs/nudges/TenMillion.tsx | 332 ++++++++++++++++--- src/view/icons/Logomark.tsx | 29 ++ 3 files changed, 332 insertions(+), 47 deletions(-) create mode 100644 src/view/icons/Logomark.tsx diff --git a/src/alf/index.tsx b/src/alf/index.tsx index 5fa7d3b1a1..d699de6a5b 100644 --- a/src/alf/index.tsx +++ b/src/alf/index.tsx @@ -18,9 +18,17 @@ export * from '#/alf/util/themeSelector' export const Context = React.createContext<{ themeName: ThemeName theme: Theme + themes: ReturnType }>({ themeName: 'light', theme: defaultTheme, + themes: createThemes({ + hues: { + primary: BLUE_HUE, + negative: RED_HUE, + positive: GREEN_HUE, + }, + }), }) export function ThemeProvider({ @@ -42,18 +50,22 @@ export function ThemeProvider({ ({ + themes, themeName: themeName, theme: theme, }), - [theme, themeName], + [theme, themeName, themes], )}> {children} ) } -export function useTheme() { - return React.useContext(Context).theme +export function useTheme(theme?: ThemeName) { + const ctx = React.useContext(Context) + return React.useMemo(() => { + return theme ? ctx.themes[theme] : ctx.theme + }, [theme, ctx]) } export function useBreakpoints() { diff --git a/src/components/dialogs/nudges/TenMillion.tsx b/src/components/dialogs/nudges/TenMillion.tsx index 9b5d5eae62..869056977b 100644 --- a/src/components/dialogs/nudges/TenMillion.tsx +++ b/src/components/dialogs/nudges/TenMillion.tsx @@ -1,25 +1,74 @@ import React from 'react' -import {useLingui} from '@lingui/react' -import {msg} from '@lingui/macro' import {View} from 'react-native' import ViewShot from 'react-native-view-shot' +import {moderateProfile} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' -import {atoms as a, useBreakpoints, tokens} from '#/alf' -import * as Dialog from '#/components/Dialog' -import {Text} from '#/components/Typography' -import {GradientFill} from '#/components/GradientFill' -import {Button, ButtonText} from '#/components/Button' +import {sanitizeDisplayName} from '#/lib/strings/display-names' +import {sanitizeHandle} from '#/lib/strings/handles' +import {isNative} from '#/platform/detection' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import {useProfileQuery} from '#/state/queries/profile' +import {useSession} from '#/state/session' import {useComposerControls} from 'state/shell' - +import {formatCount} from '#/view/com/util/numeric/format' +import {UserAvatar} from '#/view/com/util/UserAvatar' +import {Logomark} from '#/view/icons/Logomark' +import { + atoms as a, + ThemeProvider, + tokens, + useBreakpoints, + useTheme, +} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' import {useContext} from '#/components/dialogs/nudges' +import {Divider} from '#/components/Divider' +import {GradientFill} from '#/components/GradientFill' +import {ArrowOutOfBox_Stroke2_Corner0_Rounded as Share} from '#/components/icons/ArrowOutOfBox' +import {Image_Stroke2_Corner0_Rounded as ImageIcon} from '#/components/icons/Image' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' + +const RATIO = 8 / 10 +const WIDTH = 2000 +const HEIGHT = WIDTH * RATIO + +function getFontSize(count: number) { + const length = count.toString().length + if (length < 7) { + return 80 + } else if (length < 5) { + return 100 + } else { + return 70 + } +} export function TenMillion() { - const {_} = useLingui() + const t = useTheme() + const lightTheme = useTheme('light') + const {_, i18n} = useLingui() const {controls} = useContext() const {gtMobile} = useBreakpoints() const {openComposer} = useComposerControls() - const imageRef = React.useRef(null) + const {currentAccount} = useSession() + const {isLoading: isProfileLoading, data: profile} = useProfileQuery({ + did: currentAccount!.did, + }) // TODO PWI + const moderationOpts = useModerationOpts() + const moderation = React.useMemo(() => { + return profile && moderationOpts + ? moderateProfile(profile, moderationOpts) + : undefined + }, [profile, moderationOpts]) + + const isLoading = isProfileLoading || !moderation || !profile + + const userNumber = 56738 const share = () => { if (imageRef.current && imageRef.current.capture) { @@ -31,8 +80,8 @@ export function TenMillion() { imageUris: [ { uri, - width: 1000, - height: 1000, + width: WIDTH, + height: HEIGHT, }, ], }) @@ -48,52 +97,247 @@ export function TenMillion() { + style={[ + { + padding: 0, + }, + // gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full, + ]}> - + - + + + - 10 milly, babyyy + {isLoading ? ( + + ) : ( + + + + + + {/* Centered content */} + + + + Celebrating {formatCount(i18n, 10000000)} users + {' '} + 🎉 + + + + # + + {i18n.number(userNumber)} + + + {/* End centered content */} + + + + + + + {sanitizeDisplayName( + profile.displayName || + sanitizeHandle(profile.handle), + moderation.ui('displayName'), + )} + + + + {sanitizeHandle(profile.handle, '@')} + + + {profile.createdAt && ( + + {i18n.date(profile.createdAt, { + dateStyle: 'long', + })} + + )} + + + + + + )} + + - + + + + + You're part of the next wave of the internet. + + + + Online culture is too important to be controlled by a few + corporations.{' '} + + We’re dedicated to building an open foundation for the social + internet so that we can all shape its future. + + + + + + + + Brag a little ;) + + + + + + - + ) diff --git a/src/view/icons/Logomark.tsx b/src/view/icons/Logomark.tsx new file mode 100644 index 0000000000..5715a1a404 --- /dev/null +++ b/src/view/icons/Logomark.tsx @@ -0,0 +1,29 @@ +import React from 'react' +import Svg, {Path, PathProps, SvgProps} from 'react-native-svg' + +import {usePalette} from '#/lib/hooks/usePalette' + +const ratio = 54 / 61 + +export function Logomark({ + fill, + ...rest +}: {fill?: PathProps['fill']} & SvgProps) { + const pal = usePalette('default') + // @ts-ignore it's fiiiiine + const size = parseInt(rest.width || 32) + + return ( + + + + ) +}