diff --git a/assets/splash.png b/assets/splash.png new file mode 100644 index 0000000..5713ab9 Binary files /dev/null and b/assets/splash.png differ diff --git a/src/App.tsx b/src/App.tsx index 9696472..dedffa8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,6 +10,8 @@ import { ThemeProvider, useTheme } from './ui/useTheme'; import { VpnScreen } from './vpn/VpnScreen'; const appIcon = require('../assets/icon.png'); +// The splash keeps the fuller mesh scene the icon used to be, now that the icon is a reduction of it. +const splashArt = require('../assets/splash.png'); const wordmark = require('../assets/wordmark.png'); /** @@ -52,6 +54,7 @@ export const App = () => { setShowCredits(true)} /> {showSplash ? ( { onDone={() => setShowSplash(false)} /> ) : null} - {showCredits ? setShowCredits(false)} /> : null} + {showCredits ? ( + setShowCredits(false)} /> + ) : null} ); diff --git a/src/ui/AppSplash.tsx b/src/ui/AppSplash.tsx index ae95a70..8f79a5f 100644 --- a/src/ui/AppSplash.tsx +++ b/src/ui/AppSplash.tsx @@ -13,6 +13,16 @@ import type { ImageSourcePropType } from 'react-native'; export type AppSplashProps = { /** The app's branding icon (its `assets/icon.png` art). */ icon: ImageSourcePropType; + /** + * Artwork to show INSTEAD of the icon, when the two are not the same picture. + * + * They stopped being the same on 2026-08-15: the icon became a reduction that survives 40 points, + * while the splash keeps the fuller scene there is room for. Without this the splash silently + * inherited every icon change, which is how replacing the icon replaced the splash too. + * + * Drawn untiled and letterboxed rather than masked and cropped — it is a composition, not an icon. + */ + art?: ImageSourcePropType; /** App name shown under the icon (e.g. "OffTailscale"), and the accessibility label for `wordmark`. */ name: string; /** @@ -35,7 +45,7 @@ export type AppSplashProps = { */ export const WORDMARK_ASPECT = 1759 / 345; -export const AppSplash = ({ icon, name, wordmark, tagline, onDone, zIndex = 100, hold = false }: AppSplashProps) => { +export const AppSplash = ({ icon, art, name, wordmark, tagline, onDone, zIndex = 100, hold = false }: AppSplashProps) => { const { width, height } = useWindowDimensions(); // One native-driven 0→1 timing over the whole intro; opacity + icon scale are INTERPOLATED from it. const progress = useRef(new Animated.Value(0)).current; @@ -78,7 +88,11 @@ export const AppSplash = ({ icon, name, wordmark, tagline, onDone, zIndex = 100, ]} > - + {art ? ( + + ) : ( + + )} {wordmark ? (