-
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #149 from jpudysz/feature/insets
feat: add support for insets and status bar metadata
- Loading branch information
Showing
38 changed files
with
1,264 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include "helpers.h" | ||
#include "UnistylesRuntime.h" | ||
|
||
Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj) { | ||
jclass dimensionClass = env->FindClass("com/unistyles/Dimensions"); | ||
jfieldID widthFieldID = env->GetFieldID(dimensionClass, "width", "I"); | ||
jfieldID heightFieldID = env->GetFieldID(dimensionClass, "height", "I"); | ||
|
||
int width = env->GetIntField(dimensionObj, widthFieldID); | ||
int height = env->GetIntField(dimensionObj, heightFieldID); | ||
|
||
env->DeleteLocalRef(dimensionClass); | ||
|
||
return Dimensions{width, height}; | ||
} | ||
|
||
Insets jobjectToInsets(JNIEnv *env, jobject insetsObj) { | ||
jclass insetsClass = env->FindClass("com/unistyles/Insets"); | ||
jfieldID leftFieldID = env->GetFieldID(insetsClass, "left", "I"); | ||
jfieldID topFieldID = env->GetFieldID(insetsClass, "top", "I"); | ||
jfieldID rightFieldID = env->GetFieldID(insetsClass, "right", "I"); | ||
jfieldID bottomFieldID = env->GetFieldID(insetsClass, "bottom", "I"); | ||
|
||
int left = env->GetIntField(insetsObj, leftFieldID); | ||
int top = env->GetIntField(insetsObj, topFieldID); | ||
int right = env->GetIntField(insetsObj, rightFieldID); | ||
int bottom = env->GetIntField(insetsObj, bottomFieldID); | ||
|
||
env->DeleteLocalRef(insetsClass); | ||
|
||
return Insets{top, bottom, left, right}; | ||
} | ||
|
||
void throwKotlinException( | ||
JNIEnv *env, | ||
const char *message | ||
) { | ||
jclass runtimeExceptionClass = env->FindClass("java/lang/RuntimeException"); | ||
|
||
if (runtimeExceptionClass != nullptr) { | ||
env->ThrowNew(runtimeExceptionClass, message); | ||
env->DeleteLocalRef(runtimeExceptionClass); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include <jni.h> | ||
#include <string> | ||
#include <map> | ||
#include <UnistylesRuntime.h> | ||
|
||
Dimensions jobjectToDimensions(JNIEnv *env, jobject dimensionObj); | ||
Insets jobjectToInsets(JNIEnv *env, jobject insetsObj); | ||
|
||
void throwKotlinException(JNIEnv *env, const char *message); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package com.unistyles | ||
|
||
import android.annotation.SuppressLint | ||
import android.content.res.Configuration | ||
import com.facebook.react.bridge.ReactApplicationContext | ||
|
||
class UnistylesConfig(private val reactApplicationContext: ReactApplicationContext) { | ||
private val insets: UnistylesInsets = UnistylesInsets(reactApplicationContext) | ||
private val density: Float = reactApplicationContext.resources.displayMetrics.density | ||
private var lastConfig: Config = this.getAppConfig() | ||
private var lastLayoutConfig: LayoutConfig = this.getAppLayoutConfig() | ||
|
||
fun hasNewConfig(): Boolean { | ||
val newConfig = this.getAppConfig() | ||
val newContentSizeCategory = newConfig.contentSizeCategory != lastConfig.contentSizeCategory | ||
val newColorScheme = newConfig.colorScheme != lastConfig.colorScheme | ||
|
||
if (!newContentSizeCategory && !newColorScheme) { | ||
return false | ||
} | ||
|
||
lastConfig = newConfig | ||
lastConfig.hasNewContentSizeCategory = newContentSizeCategory | ||
lastConfig.hasNewColorScheme = newColorScheme | ||
|
||
return true | ||
} | ||
|
||
fun hasNewLayoutConfig(): Boolean { | ||
val newConfig = this.getAppLayoutConfig() | ||
|
||
if (newConfig.isEqual(lastLayoutConfig)) { | ||
return false | ||
} | ||
|
||
lastLayoutConfig = newConfig | ||
|
||
return true | ||
} | ||
|
||
fun getConfig(): Config { | ||
return this.lastConfig | ||
} | ||
|
||
fun getLayoutConfig(): LayoutConfig { | ||
return this.lastLayoutConfig | ||
} | ||
|
||
private fun getAppConfig(): Config { | ||
val fontScale = reactApplicationContext.resources.configuration.fontScale | ||
|
||
return Config( | ||
this.getColorScheme(), | ||
this.getContentSizeCategory(fontScale), | ||
) | ||
} | ||
|
||
private fun getAppLayoutConfig(): LayoutConfig { | ||
val displayMetrics = reactApplicationContext.resources.displayMetrics | ||
val screenWidth = (displayMetrics.widthPixels / density).toInt() | ||
val screenHeight = (displayMetrics.heightPixels / density).toInt() | ||
|
||
return LayoutConfig( | ||
Dimensions(screenWidth, screenHeight), | ||
this.insets.get(), | ||
Dimensions(screenWidth, getStatusBarHeight()), | ||
Dimensions(screenWidth, getNavigationBarHeight()) | ||
) | ||
} | ||
|
||
private fun getContentSizeCategory(fontScale: Float): String { | ||
val contentSizeCategory = when { | ||
fontScale <= 0.85f -> "Small" | ||
fontScale <= 1.0f -> "Default" | ||
fontScale <= 1.15f -> "Large" | ||
fontScale <= 1.3f -> "ExtraLarge" | ||
fontScale <= 1.5f -> "Huge" | ||
fontScale <= 1.8 -> "ExtraHuge" | ||
else -> "ExtraExtraHuge" | ||
} | ||
|
||
return contentSizeCategory | ||
} | ||
|
||
private fun getColorScheme(): String { | ||
val colorScheme = when (reactApplicationContext.resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) { | ||
Configuration.UI_MODE_NIGHT_YES -> "dark" | ||
Configuration.UI_MODE_NIGHT_NO -> "light" | ||
else -> "unspecified" | ||
} | ||
|
||
return colorScheme | ||
} | ||
|
||
@SuppressLint("InternalInsetResource", "DiscouragedApi") | ||
private fun getStatusBarHeight(): Int { | ||
val heightResId = reactApplicationContext.resources.getIdentifier("status_bar_height", "dimen", "android") | ||
|
||
if (heightResId > 0) { | ||
return (reactApplicationContext.resources.getDimensionPixelSize(heightResId) / density).toInt() | ||
} | ||
|
||
return 0 | ||
} | ||
|
||
@SuppressLint("InternalInsetResource", "DiscouragedApi") | ||
private fun getNavigationBarHeight(): Int { | ||
val heightResId = reactApplicationContext.resources.getIdentifier("navigation_bar_height", "dimen", "android") | ||
|
||
if (heightResId > 0) { | ||
return (reactApplicationContext.resources.getDimensionPixelSize(heightResId) / density).toInt() | ||
} | ||
|
||
return 0 | ||
} | ||
} |
Oops, something went wrong.