Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix splash screen logo size jump on Samsung OneUI v4 #28644

Merged
merged 6 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __mocks__/react-native.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jest.doMock('react-native', () => {
BootSplash: {
getVisibilityStatus: jest.fn(),
hide: jest.fn(),
logoSizeRatio: 1,
navigationBarHeight: 0,
},
StartupTimer: {stop: jest.fn()},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.view.Window;
import android.view.WindowManager.LayoutParams;
import androidx.annotation.NonNull;
import com.expensify.chat.R;

public class BootSplashDialog extends Dialog {

Expand All @@ -26,6 +27,10 @@ protected void onCreate(Bundle savedInstanceState) {

if (window != null) {
window.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

if (BootSplashModule.isSamsungOneUI4()) {
window.setBackgroundDrawableResource(R.drawable.bootsplash_samsung_oneui_4);
}
}

super.onCreate(savedInstanceState);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.PixelUtil;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
Expand All @@ -47,6 +48,19 @@ public String getName() {
return NAME;
}

// From https://stackoverflow.com/a/61062773
public static boolean isSamsungOneUI4() {
String name = "SEM_PLATFORM_INT";

try {
Field field = Build.VERSION.class.getDeclaredField(name);
int version = (field.getInt(null) - 90000) / 10000;
return version == 4;
} catch (Exception ignored) {
return false;
}
}
Comment on lines +51 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand not wanting to bundle this in the library, but just curious if you thought about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will apply the same in react-native-bootsplash in a upcoming version.

This is not pretty, but it's extracted from a Samsung APK so it should be correct, and we unfortunately need it 😕

I have a similar method in react-native-localize for Xiaomi devices. I always rather use a workaround than let users reporting issues, as they don't know that it's their phone Android implementation fault.

I often wish Google enforce Android stock usage (without any modifications) to manufacturers, but it's a wild dream 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will apply the same in react-native-bootsplash in a upcoming version.

Okay, that's great. Can you let us know when this is ready so that we can update our code?

I often wish Google enforce Android stock usage

As an ex-native Android dev I 100% agree.

Copy link
Contributor Author

@zoontek zoontek Oct 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Julesssss Yes, I will. The module in Expensify is based on my initial work on v5, but has been merged way before I released the latest version (as I added support for brand image, dark mode, web, in this release)

Once bootsplash catch up on this, I will do a proposal to migrate Expensify back to it (and delete the custom module in your codebase). I know that light / dark mode support is planned on your side + you will be able to remove your web custom implementation.

Meanwhile, I'd rather be able to merge and check that this indeed fix the Samsung issue (as I don't have such test devices)


@Override
public Map<String, Object> getConstants() {
final HashMap<String, Object> constants = new HashMap<>();
Expand All @@ -61,6 +75,7 @@ public Map<String, Object> getConstants() {
? Math.round(PixelUtil.toDIPFromPixel(resources.getDimensionPixelSize(heightResId)))
: 0;

constants.put("logoSizeRatio", isSamsungOneUI4() ? 0.5 : 1);
constants.put("navigationBarHeight", height);
return constants;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:opacity="opaque">
<item android:gravity="fill">
<color android:color="?attr/windowSplashScreenBackground" />
</item>

<!-- There's an issue with logo size on Samsung OneUI v4
We need to render it 2 times smaller (288 / 2 = 144) -->
<item
tools:ignore="UnusedAttribute"
android:drawable="?windowSplashScreenAnimatedIcon"
android:gravity="center"
android:width="144dp"
android:height="144dp" />
</layer-list>
2 changes: 1 addition & 1 deletion android/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

<style name="BootTheme" parent="Theme.SplashScreen">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="windowSplashScreenAnimatedIcon">@mipmap/bootsplash_logo</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/bootsplash_logo</item>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the bootsplash logo from mipmap-* to drawable-* directories to align with react-native-bootsplash v5 and AndroidX core-splashscreen

<item name="windowSplashScreenBackground">@color/bootsplash_background</item>
</style>

Expand Down
37 changes: 9 additions & 28 deletions assets/images/new-expensify-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions src/components/SplashScreenHider/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const defaultProps = {
function SplashScreenHider(props) {
const {onHide} = props;

const logoSizeRatio = BootSplash.logoSizeRatio || 1;
const navigationBarHeight = BootSplash.navigationBarHeight || 0;

const opacity = useSharedValue(1);
const scale = useSharedValue(1);

Expand Down Expand Up @@ -64,15 +67,15 @@ function SplashScreenHider(props) {
opacityStyle,
{
// Apply negative margins to center the logo on window (instead of screen)
marginBottom: -(BootSplash.navigationBarHeight || 0),
marginBottom: -navigationBarHeight,
},
]}
>
<Reanimated.View style={scaleStyle}>
<Logo
viewBox="0 0 80 80"
width={100}
height={100}
width={100 * logoSizeRatio}
height={100 * logoSizeRatio}
/>
</Reanimated.View>
</Reanimated.View>
Expand Down
1 change: 1 addition & 0 deletions src/libs/BootSplash/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ function hide(): Promise<void> {
export default {
hide,
getVisibilityStatus: BootSplash.getVisibilityStatus,
logoSizeRatio: BootSplash.logoSizeRatio || 1,
navigationBarHeight: BootSplash.navigationBarHeight || 0,
};
1 change: 1 addition & 0 deletions src/libs/BootSplash/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ function getVisibilityStatus(): Promise<VisibilityStatus> {
export default {
hide,
getVisibilityStatus,
logoSizeRatio: 1,
navigationBarHeight: 0,
};
1 change: 1 addition & 0 deletions src/libs/BootSplash/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type VisibilityStatus = 'visible' | 'hidden';

type BootSplashModule = {
logoSizeRatio: number;
navigationBarHeight: number;
hide: () => Promise<void>;
getVisibilityStatus: () => Promise<VisibilityStatus>;
Expand Down