Skip to content

5.0.0

Compare
Choose a tag to compare
@zoontek zoontek released this 21 Aug 22:02
· 126 commits to master since this release
f90c5c9

What's new

Bye AndroidX 👋

v4 introduced the usage of the official Android SplashScreen API with androidx.core:core-splashscreen in order to support Android 12+. But this change came with a lot of issues (#381, #418, #440, #456, etc.), and those issues seem to be ignored on the Google issue tracker. The next version now uses its own polyfill, compatible with Android 5+ (without any degraded mode, compared to the AndroidX one).

Dark mode 🌚

The generator is now able to output a lot more files, including dark mode versions of all the splash screen assets (in all required pixel densities, but also config files, etc.)
The update is simple: run the generator, drag and drop the newly created Colors.xcassets in your Xcode project, done!

Brand image support 🏢

Dropping AndroidX was also necessary to add brand images support on Android 5+ as the feature wasn't polyfilled (and android:windowSplashScreenBrandingImage is only available on Android 12+).
You can finally tell your boss that the company logo will be visible at app opening 🧑‍💼

Web support 🌐

The generator will now look for a index.html file in you project (or the file you specify using the new --html option) and update it in place. All existing features are supported (brand image, dark mode, animation…).

An updated CLI 🧑‍💻

In order to support all these new features, I had to publish an updated CLI generator. By default, it will be as capable as the previous one (android, iOS and the assets directory). The only new emitted file is the manifest (for useHideAnimation usage). But in order to to use the --brand, --brand-width and --dark-* options, you must specify a --license-key 🔑

With it, the generator is able to output over 50 files (logo and brand images generated in all pixel densities, dark mode versions, etc.), saving you (and your company!) a massive amount of time not only at creation, but also at each adjustment.

Usage: react-native generate-bootsplash [options] <logo>

Generate a launch screen using a logo file path (PNG or SVG)

Options:
  --platforms <list>          Platforms to generate for, separated by a comma (default: "android,ios,web")
  --background <string>       Background color (in hexadecimal format) (default: "#fff")
  --logo-width <number>       Logo width at @1x (in dp - we recommend approximately ~100) (default: 100)
  --assets-output <string>    Assets output directory path
  --flavor <string>           Android flavor build variant (where your resource directory is) (default: "main")
  --html <string>             HTML template file path (your web app entry point) (default: "index.html")
  --license-key <string>      License key to enable brand and dark mode assets generation
  --brand <string>            Brand file path (PNG or SVG)
  --brand-width <number>      Brand width at @1x (in dp - we recommend approximately ~80) (default: 80)
  --dark-background <string>  [dark mode] Background color (in hexadecimal format)
  --dark-logo <string>        [dark mode] Logo file path (PNG or SVG)
  --dark-brand <string>       [dark mode] Brand file path (PNG or SVG)
  -h, --help                  display help for command

I know, free software is always better. But I think it's a good way to make the development of this library (and indirectly, react-native-permissions and react-native-localize) sustainable.
Monetizing open source is a hard task and I'm really glad a few individuals and companies are sponsoring my work, but unfortunately it's not systematic yet for companies to give a bit, even if their products are often built using free open source maintainers work.

❗️ Important: If you are currently sponsoring me, or sponsored me once in the past, contact me to get a free license key. It could have been any amount, even only 1$ for a coffee ☕️

Gumroad button

useHideAnimation 🫣

You always wanted a custom hide animation, similar to the one in the example project? useHideAnimation is a new hook that will help you creating one, in the easiest way possible.

How does it work? First, run the generator with the --assets-output option. Once the files are ready, create a custom splash screen:

const AnimatedBootSplash = ({ onAnimationEnd }: { onAnimationEnd: () => void }) => {
  const [opacity] = useState(() => new Animated.Value(1));
  const [translateY] = useState(() => new Animated.Value(0));

  // note that you can also animate the brand image (check the documentation)
  const { container, logo } = BootSplash.useHideAnimation({

    // the manifest file is generated when --assets-output is specified
    // it includes colors and computed sizes values
    manifest: require("../assets/bootsplash_manifest.json"),

    // the required generated assets
    logo: require("../assets/bootsplash_logo.png"),
    darkLogo: require("../assets/bootsplash_dark_logo.png"),

    // specify if you are using translucent status / navigation bars
    // in order to avoid a shift between the native and JS splash screen
    statusBarTranslucent: true,
    navigationBarTranslucent: false,

    // run animations. the call to hide() will be done automatically
    // you can use Animated, but also react-native-reanimated, etc.
    animate: () => {
      const { height } = Dimensions.get("window");

      Animated.stagger(250, [
        Animated.spring(translateY, {
          toValue: -50,
          useNativeDriver: true,
        }),
        Animated.spring(translateY, {
          toValue: height,
          useNativeDriver: true,
        }),
      ]).start();

      Animated.timing(opacity, {
        toValue: 0,
        duration: 150,
        delay: 350,
        useNativeDriver: true,
      }).start(() => {
        onAnimationEnd();
      });
    },
  });

  return (
    <Animated.View {...container} style={[container.style, { opacity }]}>
      <Animated.Image
        {...logo}
        style={[logo.style, { transform: [{ translateY }] }]}
      />
    </Animated.View>
  );
};

Then uses it:

const App = () => {
  const [visible, setVisible] = useState(true);

  return (
    <View style={{ flex: 1 }}>
      {/* content */}

      {visible && (
        <AnimatedBootSplash
          onAnimationEnd={() => {
            setVisible(false);
          }}
        />
      )}
    </View>
  );
};
useHideAnimation.usage.mp4

Other changes

  • Your Android theme status / navigation bar styles are not overwritten anymore. Guides for transparent status bar and edge-to-edge layouts have been added in the brand new FAQ.
  • Android generated assets has been migrated from mipmap-* directories to drawable-* ones.
  • To avoid conflicts, Android provided theme / properties has been renamed Theme.BootSplash / Theme.BootSplash.EdgeToEdge, bootSplashBackground, bootSplashLogo, bootSplashBrand and postBootSplashTheme.
  • The duration argument has been removed from fade() options.
  • getVisibilityStatus() has been replaced with isVisible() (which returns a Promise<boolean>). The transitioning status does not exists anymore (when the splash screen is fading, it stays visible until complete disappearance).
  • The CLI now output a bootsplash_manifest.json file to share image sizes + colors with the JS thread (used by useHideAnimation).
  • --assets-path CLI option has been renamed --assets-output.
  • React Native < 0.70 and iOS < 12.4 support has been dropped.
  • ReScript bindings has been removed as I don't know how to write them. Feels free to open a PR to add it back.

Migration

Follow the updated MIGRATION.md