Add Japan-gated custom logo (#11161)

This commit is contained in:
Samuel Newman
2026-07-16 14:26:05 +03:00
committed by GitHub
parent 4037392105
commit 406fb5425c
21 changed files with 80 additions and 34 deletions
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" viewBox="0 0 1000 500"><defs><clipPath id="cp1" clipPathUnits="userSpaceOnUse"><path d="M626.36 100.49c-5.11 3.07-10.03 6.4-14.6 9.83-16.71 12.55-33.83 29.35-50.01 47.72-20.77 23.59-39.97 49.76-54.68 72.84-8.59 13.48-15.65 25.91-20.6 36.14-17.68-36.56-62.26-101-107.36-141.8-5.99-5.42-11.99-10.44-17.94-14.9-26.96-20.24-66.21-37.06-85.02-17.49-6.73 6.99-10.87 18.59-10.87 36.4 0 13.51 7.75 113.48 12.29 129.72 12.82 45.8 53.13 63.9 95.24 64.44l1.72 4.1c-66.07 20.14-79.15 64.89-35.52 109.66 40.27 41.32 70.75 42.51 93.25 28.05 29.66-19.06 45.43-65.32 51.38-82.78q.71-2.11 1.24-3.62c1.07-3.02 1.58-4.08 1.59-2.4.01-2.24.91.39 2.83 6.02 9.24 27.14 42.23 123.92 114.26 79.79 9.44-5.78 19.55-13.95 30.36-25.06 15.25-15.63 23.56-31.27 25.13-45.86 1.64-15.29-4.17-29.4-17.18-41.17l-12.59-30.19c29.25-6.89 54.25-24.56 64.85-56.99.43-1.32.85-2.63 1.24-3.99 4.54-16.24 12.28-116.21 12.28-129.72 0-59.2-45.42-50.3-81.29-28.74"/></clipPath></defs><style>.s0{fill:#7bb244}.s1{fill:#008442}.s3{fill:#008cd2}.s4{fill:#e7451e}.s5{fill:#f6a700}.s6{fill:#fff}.s7{mix-blend-mode:multiply;fill:#e7451e}.s8{fill:#4b9754}</style><g id="デザイン"><g id="&lt;Group&gt;"><path id="&lt;Path&gt;" d="M362.1 110.32c-26.96-20.24-66.21-37.06-85.03-17.49l96.66 230.56c9.77.13 19.64-.69 29.28-2.33-10.04 1.71-19.2 3.88-27.56 6.43l57.74 137.71c29.66-19.06 45.43-65.32 51.38-82.78q.71-2.11 1.24-3.62L380.04 125.22c-5.99-5.42-11.99-10.44-17.94-14.9" class="s0"/><path d="M266.21 129.23c0 13.51 7.75 113.48 12.29 129.72 12.81 45.8 53.13 63.9 95.23 64.44L277.07 92.83c-6.72 6.99-10.86 18.59-10.86 36.4m73.73 307.93c40.26 41.31 70.75 42.5 93.25 28.04l-57.74-137.71c-66.06 20.14-79.14 64.89-35.51 109.67" class="s1"/><path d="M696.29 258.95c4.55-16.24 12.29-116.21 12.29-129.72 0-59.2-45.42-50.31-81.29-28.74l67.76 162.45q.66-1.96 1.24-3.99" class="s0"/><path d="m642.8 350.12 17.17 41.17c1.64-15.28-4.16-29.4-17.17-41.17m52.25-87.18-67.76-162.45c-5.11 3.07-10.03 6.4-14.6 9.83-16.71 12.55-33.84 29.35-50.01 47.72l67.53 161.89c29.25-6.89 54.25-24.56 64.84-56.99m-207.65 4.08c-17.69-36.57-62.27-101-107.36-141.8L485.81 378.8c1.07-3.02 1.58-4.09 1.59-2.4.01-2.24.91.39 2.82 6.02 9.25 27.14 42.24 123.92 114.27 79.79L508 230.88c-8.59 13.48-15.65 25.91-20.6 36.14" class="s1"/><path d="M571.78 321.06c19.44 3.31 39.79 3.27 58.43-1.13l-67.53-161.89c-20.78 23.59-39.97 49.76-54.68 72.84l96.49 231.33c9.44-5.78 19.54-13.95 30.36-25.05 15.24-15.64 23.56-31.28 25.12-45.87l-17.17-41.17c-14.63-13.24-38.36-23.5-71.02-29.06" class="s0"/><path d="m537.4 4-17.72 143.35 88.33-113.64z" style="fill:#f4ae1a"/><path d="m895.69 371.73-230.18-31.9 148.57 101.66z" class="s3"/><path d="m90.72 95.32 159.34 126.77L0 162.43z" class="s4"/><path d="m148.73 361.28 250.64-7.29-290.74 141.27z" class="s5"/><g id="&lt;Clip Group&gt;" clip-path="url(#cp1)"><path id="&lt;Compound Path&gt;" fill-rule="evenodd" d="m569.43 371.9 51.37 123.15-4.45 1.85-51.37-123.16c-10.11 3.92-21.06 6.16-32.54 6.16-49.82 0-90.36-40.54-90.36-90.36 0-36.66 21.97-68.22 53.41-82.38l-33.88-81.21 4.45-1.86 33.88 81.23c10.11-3.92 21.04-6.15 32.5-6.15 49.83 0 90.37 40.54 90.37 90.37 0 36.64-21.96 68.19-53.38 82.36M501.8 209.77l65.77 157.68c29.68-13.44 50.42-43.27 50.42-77.91 0-47.17-38.38-85.55-85.55-85.55-10.81 0-21.11 2.1-30.64 5.78m61.32 159.52-65.77-157.68c-29.7 13.43-50.45 43.27-50.45 77.93 0 47.16 38.37 85.54 85.54 85.54 10.82 0 21.14-2.1 30.68-5.79" class="s6"/></g><path d="m763.79 80.37-201.27 208 304.16 14z" class="s4"/><path d="M970.03 253.88c-48.46 57.07-138.53 68.27-201.19 25.02-62.65-43.24-74.16-124.56-25.7-181.63 48.46-57.06 138.53-68.26 201.18-25.02 62.66 43.25 74.17 124.57 25.71 181.63" class="s6"/><path d="M914.45 112.85s-47.72-9.42-60.98-3.44c0 0-20.85 41.71-19.79 49.19 0 0 42.36 33.2 51.62 34.93 0 0 41.25-18.78 47.5-27.04 0 0-6.8-44.96-18.35-53.64" class="s5"/><path d="M745.71 149.33s8.94 18.59 30.66 28.61c0 0-8.04 41.65-6.08 52.61 0 0-29.32 1.2-36.92-.32 0 0-13.68-21.28-15.2-48.63 0 0 11.16-22.62 27.54-32.27" class="s7"/><path d="M882.41 248.11s19.49 18.58 36.64 21.56c0 0-10.87 18.86-27.62 28.95 0 0-46.24 8.07-56.83.06 0 0-12.6-21.27-11.02-30.65 0 0 47.78-9.62 58.83-19.92" class="s8"/><path d="M996.29 160.32s-11.03 24.46-22.17 27.94c0 0 1.59 34.85-6.18 48.82l10.12.75s24.82-41.68 18.23-77.51" class="s7"/><path d="m908.15 55.46-6.72 1.39s22.77 2.58 34.07 29c0 0 29.75 6.27 39.52 19.76 0 0-11.63-20.9-27.55-31.65-15.91-10.75-39.32-18.5-39.32-18.5" class="s8"/><path d="m829.78 51.19 9.62 1.95s-22.02 16.72-20.32 25.78c0 0-32.01 5-52.33 20.56l-7.5-13.26s16.01-15.28 34.08-24.48c18.08-9.21 36.45-10.55 36.45-10.55" class="s3"/></g></g></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

+1
View File
@@ -18,6 +18,7 @@ export enum Features {
PostGalleryEmbedEnable = 'post_gallery_embed:enable',
PostThreadKnownLikersEnable = 'post_thread:known_likers:enable',
PostThreadKnownLikersFetchEnable = 'post_thread:known_likers:fetch:enable',
CustomLogoJapanEnable = 'custom_logo:japan:enable',
AATest = 'aa-test',
}
+1 -1
View File
@@ -22,7 +22,7 @@ export function Badge() {
backgroundColor: t.palette.primary_25,
},
]}>
<Logo fill={t.palette.primary_600} width={14} />
<Logo allowVariants={false} fill={t.palette.primary_600} width={14} />
<Text
style={[
a.font_semi_bold,
+6 -2
View File
@@ -86,7 +86,7 @@ export function QrCode({
<Trans>
on
<View style={[a.flex_row, a.align_center, {gap: 6}]}>
<Logo width={25} fill="white" />
<Logo allowVariants={false} width={25} fill="white" />
<View style={[{marginTop: 3.5}]}>
<Logotype width={72} fill="white" />
</View>
@@ -129,7 +129,11 @@ export function QrCodeInner({link}: {link: string}) {
zIndex: 1,
padding: 4,
}}>
<Logo width={logoArea.width - 14} height={logoArea.height - 14} />
<Logo
allowVariants={false}
width={logoArea.width - 14}
height={logoArea.height - 14}
/>
</View>
)}
<QRCode
+1 -1
View File
@@ -107,7 +107,7 @@ export function WelcomeModal({control}: WelcomeModalProps) {
a.p_0,
]}>
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
<Logo width={26} />
<Logo allowVariants={false} width={26} />
<Text
style={[
a.text_2xl,
+1 -1
View File
@@ -55,7 +55,7 @@ function SigninDialogInner({}: {control: Dialog.DialogOuterProps['control']}) {
a.gap_sm,
a.pb_lg,
]}>
<Logo width={36} />
<Logo allowVariants={false} width={36} />
<View style={{paddingTop: 6}}>
<Logotype width={120} fill={t.atoms.text.color} />
</View>
@@ -177,7 +177,11 @@ export function ThemedQrCard({
/>
) : (
<View style={[a.flex_1, a.align_center, a.justify_center]}>
<Logo width={40} fill={variant.qrPrimary} />
<Logo
allowVariants={false}
width={40}
fill={variant.qrPrimary}
/>
</View>
)}
</View>
+1 -1
View File
@@ -109,7 +109,7 @@ export function Deactivated() {
<View
style={[a.w_full, {marginHorizontal: 'auto', maxWidth: COL_WIDTH}]}>
<View style={[a.w_full, a.justify_center, a.align_center, a.pb_5xl]}>
<Logo width={40} />
<Logo allowVariants={false} width={40} />
</View>
<View style={[a.gap_xs, a.pb_3xl]}>
+1 -1
View File
@@ -123,7 +123,7 @@ export function SignupQueued() {
<View style={[a.flex_1, {maxWidth: COL_WIDTH}]}>
<View
style={[a.w_full, a.justify_center, a.align_center, a.my_4xl]}>
<Logo width={120} />
<Logo allowVariants={false} width={120} />
</View>
<Text style={[a.text_4xl, a.font_bold, a.pb_sm]}>
@@ -179,7 +179,7 @@ function LandingScreenLoaded({
},
]}>
<View style={[a.flex_row, a.gap_md, a.pb_sm]}>
<Logo width={76} fill="white" />
<Logo allowVariants={false} width={76} fill="white" />
</View>
<Text
style={[
+1 -1
View File
@@ -132,7 +132,7 @@ export function Takendown() {
]}>
<View style={[a.flex_1, {maxWidth: COL_WIDTH, minHeight: COL_WIDTH}]}>
<View style={[a.pb_xl]}>
<Logo width={64} />
<Logo allowVariants={false} width={64} />
</View>
<Text style={[a.text_4xl, a.font_bold, a.pb_md]}>
+5 -3
View File
@@ -5,10 +5,10 @@ import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {Logo} from '#/view/icons/Logo'
import {Logotype} from '#/view/icons/Logotype'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {
AppClipOverlay,
postAppClipMessage,
@@ -46,7 +46,9 @@ export const SplashScreen = ({
}
}, [])
const kawaii = useKawaiiMode()
const logoVariant = useLogoVariant()
const kawaii = logoVariant === 'kawaii'
const japanLogo = logoVariant === 'japan'
return (
<>
@@ -81,7 +83,7 @@ export const SplashScreen = ({
]}>
<ErrorBoundary>
<View style={[a.justify_center, a.align_center]}>
<Logo width={kawaii ? 300 : 92} fill="sky" />
<Logo width={kawaii ? 300 : japanLogo ? 120 : 92} fill="sky" />
{!kawaii && (
<View style={[a.pb_sm, a.pt_5xl]}>
+11 -3
View File
@@ -4,11 +4,11 @@ import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {HITSLOP_10} from '#/lib/constants'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useSession} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {HomeHeaderLayoutMobile} from '#/view/com/home/HomeHeaderLayoutMobile'
import {Logo} from '#/view/icons/Logo'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {atoms as a, useBreakpoints, useGutters, useTheme} from '#/alf'
import {ButtonIcon} from '#/components/Button'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
@@ -40,7 +40,7 @@ function HomeHeaderLayoutDesktopAndTablet({
const {hasSession} = useSession()
const {_} = useLingui()
const ax = useAnalytics()
const kawaii = useKawaiiMode()
const logoVariant = useLogoVariant()
const gutters = useGutters([0, 'base'])
return (
@@ -51,7 +51,15 @@ function HomeHeaderLayoutDesktopAndTablet({
style={[a.flex_row, a.align_center, gutters, a.pt_md, t.atoms.bg]}>
<View style={{width: 34}} />
<View style={[a.flex_1, a.align_center, a.justify_center]}>
<Logo width={kawaii ? 60 : 28} />
<Logo
width={
logoVariant === 'kawaii'
? 60
: logoVariant === 'japan'
? 34
: 28
}
/>
</View>
<Link
to="/feeds"
+3 -1
View File
@@ -14,6 +14,7 @@ import {useSession} from '#/state/session'
import {useShellLayout} from '#/state/shell/shell-layout'
import {useHomeHeaderTransform} from '#/view/com/util/MainScrollProvider'
import {Logo} from '#/view/icons/Logo'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {atoms as a, useTheme} from '#/alf'
import {ButtonIcon} from '#/components/Button'
import {Hashtag_Stroke2_Corner0_Rounded as FeedsIcon} from '#/components/icons/Hashtag'
@@ -37,6 +38,7 @@ export function HomeHeaderLayoutMobile({
const {hasSession} = useSession()
const playHaptic = useHaptics()
const {navigate} = useNavigation<NavigationProp>()
const logoVariant = useLogoVariant()
return (
<Animated.View
@@ -71,7 +73,7 @@ export function HomeHeaderLayoutMobile({
emitSoftReset()
}
}}>
<Logo width={30} />
<Logo width={logoVariant === 'japan' ? 34 : 30} />
</PressableScale>
</View>
+12 -8
View File
@@ -10,19 +10,20 @@ import Svg, {
} from 'react-native-svg'
import {Image} from 'expo-image'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {flatten, useTheme} from '#/alf'
const ratio = 57 / 64
type Props = {
allowVariants?: boolean
fill?: PathProps['fill']
style?: TextProps['style']
} & Omit<SvgProps, 'style'>
export const Logo = forwardRef(function LogoImpl(props: Props, ref) {
const t = useTheme()
const {fill, ...rest} = props
const {allowVariants = true, fill, ...rest} = props
const gradient = fill === 'sky'
const styles = flatten(props.style)
const _fill = gradient
@@ -31,20 +32,23 @@ export const Logo = forwardRef(function LogoImpl(props: Props, ref) {
// @ts-ignore it's fiiiiine
const size = parseInt(rest.width || 32, 10)
const isKawaii = useKawaiiMode()
const logoVariant = useLogoVariant(allowVariants)
if (isKawaii) {
if (logoVariant !== 'default') {
const isJapanLogo = logoVariant === 'japan'
return (
<Image
source={
size > 100
? require('../../../assets/kawaii.png')
: require('../../../assets/kawaii_smol.png')
isJapanLogo
? require('../../../assets/icons/custom_logo_japan.svg')
: size > 100
? require('../../../assets/kawaii.png')
: require('../../../assets/kawaii_smol.png')
}
accessibilityLabel="Bluesky"
accessibilityHint=""
accessibilityIgnoresInvertColors
style={[{height: size, aspectRatio: 1.4}]}
style={[{height: size, aspectRatio: isJapanLogo ? 2 : 1.4}]}
/>
)
}
+20
View File
@@ -0,0 +1,20 @@
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useAnalytics} from '#/analytics'
import {useGeolocation} from '#/geolocation'
export type LogoVariant = 'default' | 'japan' | 'kawaii'
export function useLogoVariant(allowVariants = true): LogoVariant {
const ax = useAnalytics()
const geolocation = useGeolocation()
const kawaii = useKawaiiMode()
const japanLogoEnabled =
allowVariants &&
geolocation.countryCode === 'JP' &&
ax.features.enabled(ax.features.CustomLogoJapanEnable)
if (!allowVariants) return 'default'
if (japanLogoEnabled) return 'japan'
if (kawaii) return 'kawaii'
return 'default'
}
+3 -3
View File
@@ -21,13 +21,13 @@ import {type NavigationProp} from '#/lib/routes/types'
import {sanitizeHandle} from '#/lib/strings/handles'
import {colors} from '#/lib/styles'
import {emitSoftReset} from '#/state/events'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useUnreadNotifications} from '#/state/queries/notifications/unread'
import {useProfileQuery} from '#/state/queries/profile'
import {type SessionAccount, useSession} from '#/state/session'
import {useSetDrawerOpen} from '#/state/shell'
import {formatCount} from '#/view/com/util/numeric/format'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {NavSignupCard} from '#/view/shell/NavSignupCard'
import {atoms as a, tokens, useTheme, web} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
@@ -747,7 +747,7 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
function ExtraLinks() {
const {_} = useLingui()
const t = useTheme()
const kawaii = useKawaiiMode()
const logoVariant = useLogoVariant()
return (
<View style={[a.flex_col, a.gap_md, a.flex_wrap]}>
@@ -763,7 +763,7 @@ function ExtraLinks() {
label={_(msg`Privacy Policy`)}>
<Trans>Privacy Policy</Trans>
</InlineLinkText>
{kawaii && (
{logoVariant === 'kawaii' && (
<Text style={t.atoms.text_contrast_medium}>
<Trans>
Logo by{' '}
+1 -1
View File
@@ -32,7 +32,7 @@ let NavSignupCard = ({}: {}): React.ReactNode => {
return (
<View style={[{maxWidth: 245}]}>
<Link to="/" label="Bluesky - Home">
<Logo width={32} />
<Logo allowVariants={false} width={32} />
</Link>
<View style={[a.pt_lg]}>
+1 -1
View File
@@ -339,7 +339,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
}}>
<View
style={{flexDirection: 'row', alignItems: 'center', gap: 8}}>
<Logo width={28} />
<Logo allowVariants={false} width={28} />
<View style={{paddingTop: 4}}>
<Logotype width={80} fill={t.atoms.text.color} />
</View>
+1 -1
View File
@@ -228,7 +228,7 @@ export function BottomBarWeb() {
},
]}>
<View style={[a.flex_row, a.align_center, a.gap_md]}>
<Logo width={32} />
<Logo allowVariants={false} width={32} />
<View style={{paddingTop: 4}}>
<Logotype width={80} fill={t.atoms.text.color} />
</View>
+3 -3
View File
@@ -6,8 +6,8 @@ import {Trans} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants'
import {useKawaiiMode} from '#/state/preferences/kawaii'
import {useSession} from '#/state/session'
import {useLogoVariant} from '#/view/icons/useLogoVariant'
import {DesktopFeeds} from '#/view/shell/desktop/Feeds'
import {DesktopSearch} from '#/view/shell/desktop/Search'
import {SidebarTrendingTopics} from '#/view/shell/desktop/SidebarTrendingTopics'
@@ -46,7 +46,7 @@ export function DesktopRightNav({routeName}: {routeName: string}) {
const t = useTheme()
const {_} = useLingui()
const {hasSession, currentAccount} = useSession()
const kawaii = useKawaiiMode()
const logoVariant = useLogoVariant()
const gutters = useGutters(['base', 0, 'base', 'wide'])
const isSearchScreen = routeName === 'Search'
const isMessagesRelatedScreen = routeName.startsWith('Messages')
@@ -134,7 +134,7 @@ export function DesktopRightNav({routeName}: {routeName: string}) {
</InlineLinkText>
</Text>
{kawaii && (
{logoVariant === 'kawaii' && (
<Text style={[t.atoms.text_contrast_medium, {marginTop: 12}]}>
<Trans>
Logo by{' '}