diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-05-01 08:59:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-01 08:59:40 +0100 |
commit | 81ae7e425dc52846c5d4c282a0422a3875d84e2f (patch) | |
tree | fd268c721913a2d6548b299f4e3193bdb5cd5883 | |
parent | 181e61bedb21003921fa21f6e8b86baf918d62bf (diff) | |
download | voidsky-81ae7e425dc52846c5d4c282a0422a3875d84e2f.tar.zst |
Add kawaii mode (#3773)
-rw-r--r-- | .github/workflows/golang-test-lint.yml | 8 | ||||
-rw-r--r-- | Dockerfile.embedr | 1 | ||||
-rw-r--r-- | assets/kawaii.png | bin | 0 -> 118701 bytes | |||
-rw-r--r-- | assets/kawaii_smol.png | bin | 0 -> 6715 bytes | |||
-rw-r--r-- | bskyweb/.gitignore | 2 | ||||
-rw-r--r-- | bskyweb/cmd/bskyweb/server.go | 2 | ||||
-rw-r--r-- | bskyweb/static/media/.gitkeep | 0 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/state/persisted/index.ts | 8 | ||||
-rw-r--r-- | src/state/persisted/schema.ts | 2 | ||||
-rw-r--r-- | src/state/preferences/index.tsx | 5 | ||||
-rw-r--r-- | src/state/preferences/kawaii.tsx | 50 | ||||
-rw-r--r-- | src/view/com/auth/SplashScreen.web.tsx | 13 | ||||
-rw-r--r-- | src/view/com/home/HomeHeaderLayout.web.tsx | 14 | ||||
-rw-r--r-- | src/view/icons/Logo.tsx | 25 | ||||
-rw-r--r-- | src/view/shell/Drawer.tsx | 13 | ||||
-rw-r--r-- | src/view/shell/desktop/RightNav.tsx | 33 |
17 files changed, 150 insertions, 28 deletions
diff --git a/.github/workflows/golang-test-lint.yml b/.github/workflows/golang-test-lint.yml index 2576c3479..a87e7f144 100644 --- a/.github/workflows/golang-test-lint.yml +++ b/.github/workflows/golang-test-lint.yml @@ -20,8 +20,8 @@ jobs: uses: actions/setup-go@v3 with: go-version: '1.21' - - name: Dummy JS File - run: touch bskyweb/static/js/blah.js + - name: Dummy Static Files + run: touch bskyweb/static/js/blah.js && touch bskyweb/static/media/blah.txt - name: Check run: cd bskyweb/ && make check - name: Build (binary) @@ -37,7 +37,7 @@ jobs: uses: actions/setup-go@v3 with: go-version: '1.21' - - name: Dummy JS File - run: touch bskyweb/static/js/blah.js + - name: Dummy Static Files + run: touch bskyweb/static/js/blah.js && touch bskyweb/static/media/blah.txt - name: Lint run: cd bskyweb/ && make lint diff --git a/Dockerfile.embedr b/Dockerfile.embedr index c70251658..63f060980 100644 --- a/Dockerfile.embedr +++ b/Dockerfile.embedr @@ -40,6 +40,7 @@ RUN find ./bskyweb/embedr-static && find ./bskyweb/embedr-templates && find ./bs # hack around issue with empty directory and go:embed RUN touch bskyweb/static/js/empty.txt +RUN touch bskyweb/static/media/empty.txt # # Generate the embedr Go binary. diff --git a/assets/kawaii.png b/assets/kawaii.png new file mode 100644 index 000000000..79cab8e52 --- /dev/null +++ b/assets/kawaii.png Binary files differdiff --git a/assets/kawaii_smol.png b/assets/kawaii_smol.png new file mode 100644 index 000000000..4bed56208 --- /dev/null +++ b/assets/kawaii_smol.png Binary files differdiff --git a/bskyweb/.gitignore b/bskyweb/.gitignore index fad122a28..05b3ad7ab 100644 --- a/bskyweb/.gitignore +++ b/bskyweb/.gitignore @@ -10,6 +10,8 @@ static/js/*.js static/js/*.map static/js/*.js.LICENSE.txt static/js/empty.txt +static/media/*.png +static/media/empty.txt templates/scripts.html templates/*-embed.html static/embed/*.html diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index 54580d643..e1b009646 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -158,7 +158,7 @@ func serve(cctx *cli.Context) error { // Cache javascript and images files for 1 week, which works because // they're always versioned (e.g. /static/js/main.64c14927.js) - if strings.HasPrefix(path, "/static/js/") || strings.HasPrefix(path, "/static/images/") { + if strings.HasPrefix(path, "/static/js/") || strings.HasPrefix(path, "/static/images/") || strings.HasPrefix(path, "/static/media/") { maxAge = 7 * (60 * 60 * 24) // 1 week } diff --git a/bskyweb/static/media/.gitkeep b/bskyweb/static/media/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/bskyweb/static/media/.gitkeep diff --git a/package.json b/package.json index acb9007b4..874a55c16 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "web": "expo start --web", "use-build-number": "./scripts/useBuildNumberEnv.sh", "use-build-number-with-bump": "./scripts/useBuildNumberEnvWithBump.sh", - "build-web": "expo export:web && node ./scripts/post-web-build.js && cp -v ./web-build/static/js/*.* ./bskyweb/static/js/", + "build-web": "expo export:web && node ./scripts/post-web-build.js && cp -v ./web-build/static/js/*.* ./bskyweb/static/js/ && cp -v ./web-build/static/media/*.png ./bskyweb/static/media/", "build-all": "yarn intl:build && yarn use-build-number-with-bump eas build --platform all", "build-ios": "yarn use-build-number-with-bump eas build -p ios", "build-android": "yarn use-build-number-with-bump eas build -p android", diff --git a/src/state/persisted/index.ts b/src/state/persisted/index.ts index f57172d2f..5fe0f9bd0 100644 --- a/src/state/persisted/index.ts +++ b/src/state/persisted/index.ts @@ -1,11 +1,11 @@ import EventEmitter from 'eventemitter3' + +import BroadcastChannel from '#/lib/broadcast' import {logger} from '#/logger' -import {defaults, Schema} from '#/state/persisted/schema' import {migrate} from '#/state/persisted/legacy' +import {defaults, Schema} from '#/state/persisted/schema' import * as store from '#/state/persisted/store' -import BroadcastChannel from '#/lib/broadcast' - -export type {Schema, PersistedAccount} from '#/state/persisted/schema' +export type {PersistedAccount, Schema} from '#/state/persisted/schema' export {defaults} from '#/state/persisted/schema' const broadcast = new BroadcastChannel('BSKY_BROADCAST_CHANNEL') diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts index 43f08e12e..77a79b78e 100644 --- a/src/state/persisted/schema.ts +++ b/src/state/persisted/schema.ts @@ -80,6 +80,7 @@ export const schema = z.object({ pdsAddressHistory: z.array(z.string()).optional(), disableHaptics: z.boolean().optional(), disableAutoplay: z.boolean().optional(), + kawaii: z.boolean().optional(), }) export type Schema = z.infer<typeof schema> @@ -117,4 +118,5 @@ export const defaults: Schema = { pdsAddressHistory: [], disableHaptics: false, disableAutoplay: prefersReducedMotion, + kawaii: false, } diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx index 820358518..5bca35452 100644 --- a/src/state/preferences/index.tsx +++ b/src/state/preferences/index.tsx @@ -7,6 +7,7 @@ import {Provider as DisableHapticsProvider} from './disable-haptics' import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs' import {Provider as HiddenPostsProvider} from './hidden-posts' import {Provider as InAppBrowserProvider} from './in-app-browser' +import {Provider as KawaiiProvider} from './kawaii' import {Provider as LanguagesProvider} from './languages' export { @@ -32,7 +33,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { <InAppBrowserProvider> <DisableHapticsProvider> <AutoplayProvider> - <DmServiceUrlProvider>{children}</DmServiceUrlProvider> + <DmServiceUrlProvider> + <KawaiiProvider>{children}</KawaiiProvider> + </DmServiceUrlProvider> </AutoplayProvider> </DisableHapticsProvider> </InAppBrowserProvider> diff --git a/src/state/preferences/kawaii.tsx b/src/state/preferences/kawaii.tsx new file mode 100644 index 000000000..4aa95ef8b --- /dev/null +++ b/src/state/preferences/kawaii.tsx @@ -0,0 +1,50 @@ +import React from 'react' + +import {isWeb} from '#/platform/detection' +import * as persisted from '#/state/persisted' + +type StateContext = persisted.Schema['kawaii'] + +const stateContext = React.createContext<StateContext>( + persisted.defaults.kawaii, +) + +export function Provider({children}: React.PropsWithChildren<{}>) { + const [state, setState] = React.useState(persisted.get('kawaii')) + + const setStateWrapped = React.useCallback( + (kawaii: persisted.Schema['kawaii']) => { + setState(kawaii) + persisted.write('kawaii', kawaii) + }, + [setState], + ) + + React.useEffect(() => { + return persisted.onUpdate(() => { + setState(persisted.get('kawaii')) + }) + }, [setStateWrapped]) + + React.useEffect(() => { + // dumb and stupid but it's web only so just refresh the page if you want to change it + + if (isWeb) { + const kawaii = new URLSearchParams(window.location.search).get('kawaii') + switch (kawaii) { + case 'true': + setStateWrapped(true) + break + case 'false': + setStateWrapped(false) + break + } + } + }, [setStateWrapped]) + + return <stateContext.Provider value={state}>{children}</stateContext.Provider> +} + +export function useKawaiiMode() { + return React.useContext(stateContext) +} diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx index f905e1e8d..6df4e439a 100644 --- a/src/view/com/auth/SplashScreen.web.tsx +++ b/src/view/com/auth/SplashScreen.web.tsx @@ -4,6 +4,7 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' +import {useKawaiiMode} from '#/state/preferences/kawaii' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {Logo} from '#/view/icons/Logo' import {Logotype} from '#/view/icons/Logotype' @@ -28,6 +29,8 @@ export const SplashScreen = ({ const t = useTheme() const {isTabletOrMobile: isMobileWeb} = useWebMediaQueries() + const kawaii = useKawaiiMode() + return ( <> {onDismiss && ( @@ -66,11 +69,13 @@ export const SplashScreen = ({ ]}> <ErrorBoundary> <View style={[a.justify_center, a.align_center]}> - <Logo width={92} fill="sky" /> + <Logo width={kawaii ? 300 : 92} fill="sky" /> - <View style={[a.pb_sm, a.pt_5xl]}> - <Logotype width={161} fill={t.atoms.text.color} /> - </View> + {!kawaii && ( + <View style={[a.pb_sm, a.pt_5xl]}> + <Logotype width={161} fill={t.atoms.text.color} /> + </View> + )} <Text style={[ diff --git a/src/view/com/home/HomeHeaderLayout.web.tsx b/src/view/com/home/HomeHeaderLayout.web.tsx index 644d4cab6..f00a15b3f 100644 --- a/src/view/com/home/HomeHeaderLayout.web.tsx +++ b/src/view/com/home/HomeHeaderLayout.web.tsx @@ -15,6 +15,7 @@ import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {Logo} from '#/view/icons/Logo' +import {useKawaiiMode} from '../../../state/preferences/kawaii' import {Link} from '../util/Link' import {HomeHeaderLayoutMobile} from './HomeHeaderLayoutMobile' @@ -43,10 +44,19 @@ function HomeHeaderLayoutDesktopAndTablet({ const {hasSession} = useSession() const {_} = useLingui() + const kawaii = useKawaiiMode() + return ( <> {hasSession && ( - <View style={[pal.view, pal.border, styles.bar, styles.topBar]}> + <View + style={[ + pal.view, + pal.border, + styles.bar, + styles.topBar, + kawaii && {paddingTop: 4, paddingBottom: 0}, + ]}> <Link href="/settings/following-feed" hitSlop={10} @@ -58,7 +68,7 @@ function HomeHeaderLayoutDesktopAndTablet({ style={pal.textLight as FontAwesomeIconStyle} /> </Link> - <Logo width={28} /> + <Logo width={kawaii ? 60 : 28} /> <Link href="/settings/saved-feeds" hitSlop={10} diff --git a/src/view/icons/Logo.tsx b/src/view/icons/Logo.tsx index 9212381a9..4de7c1613 100644 --- a/src/view/icons/Logo.tsx +++ b/src/view/icons/Logo.tsx @@ -1,15 +1,17 @@ import React from 'react' import {StyleSheet, TextProps} from 'react-native' import Svg, { - Path, Defs, LinearGradient, + Path, + PathProps, Stop, SvgProps, - PathProps, } from 'react-native-svg' +import {Image} from 'expo-image' import {colors} from '#/lib/styles' +import {useKawaiiMode} from '#/state/preferences/kawaii' const ratio = 57 / 64 @@ -25,6 +27,25 @@ export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { const _fill = gradient ? 'url(#sky)' : fill || styles?.color || colors.blue3 // @ts-ignore it's fiiiiine const size = parseInt(rest.width || 32) + + const isKawaii = useKawaiiMode() + + if (isKawaii) { + return ( + <Image + source={ + size > 100 + ? require('../../../assets/kawaii.png') + : require('../../../assets/kawaii_smol.png') + } + accessibilityLabel="Bluesky" + accessibilityHint="" + accessibilityIgnoresInvertColors + style={[{height: size, aspectRatio: 1.4}]} + /> + ) + } + return ( <Svg fill="none" diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx index 8145fa408..d8e604ec3 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx @@ -18,6 +18,7 @@ import {useLingui} from '@lingui/react' import {StackActions, useNavigation} from '@react-navigation/native' 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 {SessionAccount, useSession} from '#/state/session' @@ -117,6 +118,7 @@ let DrawerContent = ({}: {}): React.ReactNode => { const {isAtHome, isAtSearch, isAtFeeds, isAtNotifications, isAtMyProfile} = useNavigationTabState() const {hasSession, currentAccount} = useSession() + const kawaii = useKawaiiMode() // events // = @@ -262,6 +264,17 @@ let DrawerContent = ({}: {}): React.ReactNode => { href="https://bsky.social/about/support/privacy-policy" text={_(msg`Privacy Policy`)} /> + {kawaii && ( + <Text type="md" style={pal.textLight}> + Logo by{' '} + <TextLink + type="md" + href="/profile/sawaratsuki.bsky.social" + text="@sawaratsuki.bsky.social" + style={pal.link} + /> + </Text> + )} </View> <View style={styles.smallSpacer} /> diff --git a/src/view/shell/desktop/RightNav.tsx b/src/view/shell/desktop/RightNav.tsx index c1f498724..f0cd4f59a 100644 --- a/src/view/shell/desktop/RightNav.tsx +++ b/src/view/shell/desktop/RightNav.tsx @@ -1,22 +1,26 @@ import React from 'react' import {StyleSheet, View} from 'react-native' -import {usePalette} from 'lib/hooks/usePalette' -import {DesktopSearch} from './Search' -import {DesktopFeeds} from './Feeds' -import {Text} from 'view/com/util/text/Text' -import {TextLink} from 'view/com/util/Link' -import {FEEDBACK_FORM_URL, HELP_DESK_URL} from 'lib/constants' -import {s} from 'lib/styles' -import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' -import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useKawaiiMode} from '#/state/preferences/kawaii' import {useSession} from '#/state/session' +import {FEEDBACK_FORM_URL, HELP_DESK_URL} from 'lib/constants' +import {usePalette} from 'lib/hooks/usePalette' +import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' +import {s} from 'lib/styles' +import {TextLink} from 'view/com/util/Link' +import {Text} from 'view/com/util/text/Text' +import {DesktopFeeds} from './Feeds' +import {DesktopSearch} from './Search' export function DesktopRightNav({routeName}: {routeName: string}) { const pal = usePalette('default') const {_} = useLingui() const {hasSession, currentAccount} = useSession() + const kawaii = useKawaiiMode() + const {isTablet} = useWebMediaQueries() if (isTablet) { return null @@ -90,6 +94,17 @@ export function DesktopRightNav({routeName}: {routeName: string}) { text={_(msg`Help`)} /> </View> + {kawaii && ( + <Text type="md" style={[pal.textLight, {marginTop: 12}]}> + Logo by{' '} + <TextLink + type="md" + href="/profile/sawaratsuki.bsky.social" + text="@sawaratsuki.bsky.social" + style={pal.link} + /> + </Text> + )} </View> </View> </View> |