Skip to content

Commit

Permalink
Merge branch 'main' into @kkafar/shopify-not-truncated-title-with-hea…
Browse files Browse the repository at this point in the history
…derright-custom-shadownodes-2
  • Loading branch information
kkafar committed Oct 4, 2024
2 parents bf544c7 + e864aaf commit 7a7f324
Show file tree
Hide file tree
Showing 70 changed files with 1,065 additions and 271 deletions.
6 changes: 3 additions & 3 deletions Example/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,21 @@ GEM
netrc (0.11.0)
nkf (0.2.0)
public_suffix (4.0.7)
rexml (3.2.9)
rexml (3.3.6)
strscan
ruby-macho (2.5.1)
strscan (3.1.0)
typhoeus (1.4.1)
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.24.0)
xcodeproj (1.25.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
rexml (>= 3.3.2, < 4.0)

PLATFORMS
ruby
Expand Down
25 changes: 16 additions & 9 deletions Example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5505,6 +5505,13 @@ __metadata:
languageName: node
linkType: hard

"encodeurl@npm:~2.0.0":
version: 2.0.0
resolution: "encodeurl@npm:2.0.0"
checksum: 10c0/5d317306acb13e6590e28e27924c754163946a2480de11865c991a3a7eed4315cd3fba378b543ca145829569eefe9b899f3d84bb09870f675ae60bc924b01ceb
languageName: node
linkType: hard

"encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
Expand Down Expand Up @@ -10963,9 +10970,9 @@ __metadata:
languageName: node
linkType: hard

"send@npm:0.18.0":
version: 0.18.0
resolution: "send@npm:0.18.0"
"send@npm:0.19.0":
version: 0.19.0
resolution: "send@npm:0.19.0"
dependencies:
debug: "npm:2.6.9"
depd: "npm:2.0.0"
Expand All @@ -10980,7 +10987,7 @@ __metadata:
on-finished: "npm:2.4.1"
range-parser: "npm:~1.2.1"
statuses: "npm:2.0.1"
checksum: 10c0/0eb134d6a51fc13bbcb976a1f4214ea1e33f242fae046efc311e80aff66c7a43603e26a79d9d06670283a13000e51be6e0a2cb80ff0942eaf9f1cd30b7ae736a
checksum: 10c0/ea3f8a67a8f0be3d6bf9080f0baed6d2c51d11d4f7b4470de96a5029c598a7011c497511ccc28968b70ef05508675cebff27da9151dd2ceadd60be4e6cf845e3
languageName: node
linkType: hard

Expand All @@ -11001,14 +11008,14 @@ __metadata:
linkType: hard

"serve-static@npm:^1.13.1":
version: 1.15.0
resolution: "serve-static@npm:1.15.0"
version: 1.16.2
resolution: "serve-static@npm:1.16.2"
dependencies:
encodeurl: "npm:~1.0.2"
encodeurl: "npm:~2.0.0"
escape-html: "npm:~1.0.3"
parseurl: "npm:~1.3.3"
send: "npm:0.18.0"
checksum: 10c0/fa9f0e21a540a28f301258dfe1e57bb4f81cd460d28f0e973860477dd4acef946a1f41748b5bd41c73b621bea2029569c935faa38578fd34cd42a9b4947088ba
send: "npm:0.19.0"
checksum: 10c0/528fff6f5e12d0c5a391229ad893910709bc51b5705962b09404a1d813857578149b8815f35d3ee5752f44cd378d0f31669d4b1d7e2d11f41e08283d5134bd1f
languageName: node
linkType: hard

Expand Down
2 changes: 1 addition & 1 deletion FabricExample/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ GEM
netrc (0.11.0)
nkf (0.2.0)
public_suffix (4.0.7)
rexml (3.3.3)
rexml (3.3.6)
strscan
ruby-macho (2.5.1)
strscan (3.1.0)
Expand Down
20 changes: 5 additions & 15 deletions FabricExample/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3879,7 +3879,7 @@ __metadata:
languageName: node
linkType: hard

"braces@npm:^3.0.2, braces@npm:^3.0.3":
"braces@npm:^3.0.3":
version: 3.0.3
resolution: "braces@npm:3.0.3"
dependencies:
Expand Down Expand Up @@ -7550,23 +7550,13 @@ __metadata:
languageName: node
linkType: hard

"micromatch@npm:^4.0.2":
version: 4.0.7
resolution: "micromatch@npm:4.0.7"
"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4":
version: 4.0.8
resolution: "micromatch@npm:4.0.8"
dependencies:
braces: "npm:^3.0.3"
picomatch: "npm:^2.3.1"
checksum: 10c0/58fa99bc5265edec206e9163a1d2cec5fabc46a5b473c45f4a700adce88c2520456ae35f2b301e4410fb3afb27e9521fb2813f6fc96be0a48a89430e0916a772
languageName: node
linkType: hard

"micromatch@npm:^4.0.4":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"
dependencies:
braces: "npm:^3.0.2"
picomatch: "npm:^2.3.1"
checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff
checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8
languageName: node
linkType: hard

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ To take advantage of the native stack navigator primitive for React Navigation t

## `FullWindowOverlay`

Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/TestsExample/src/Test1096.tsx
Native `iOS` component for rendering views straight under the `Window`. Based on `RCTPerfMonitor`. You should treat it as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child `View`, being the root of its view hierarchy. For the example usage, see https://github.com/software-mansion/react-native-screens/blob/main/apps/src/tests/Test1096.tsx

## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation)

Expand Down
32 changes: 26 additions & 6 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ buildscript {
rnsDefaultKotlinVersion = '1.8.0'
}
ext.safeExtGet = {prop, fallback ->
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
def props = (prop instanceof String) ? [prop] : prop
def result = props.find { key ->
return rootProject.ext.has(key)
}
return result ? rootProject.ext.get(result) : fallback
}
repositories {
google()
Expand Down Expand Up @@ -77,8 +81,8 @@ android {
}

defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', rnsDefaultMinSdkVersion)
targetSdkVersion safeExtGet('targetSdkVersion', rnsDefaultTargetSdkVersion)
minSdkVersion safeExtGet(['minSdkVersion', 'minSdk'], rnsDefaultMinSdkVersion)
targetSdkVersion safeExtGet(['targetSdkVersion', 'targetSdk'], rnsDefaultTargetSdkVersion)
versionCode 1
versionName "1.0"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", IS_NEW_ARCHITECTURE_ENABLED.toString()
Expand Down Expand Up @@ -136,7 +140,7 @@ android {
}
}
res {
if (safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) >= 33) {
if (safeExtGet(['compileSdkVersion', 'compileSdk'], rnsDefaultCompileSdkVersion) >= 33) {
srcDirs = ["${androidResDir}/base", "${androidResDir}/v33"]
} else {
srcDirs = ["${androidResDir}/base"]
Expand All @@ -148,10 +152,26 @@ android {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
// Matches the RN Hello World template

// First look for the standard location of react-native, as in RN Hello World template
// https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/local-cli/templates/HelloWorld/android/build.gradle#L21
url "$projectDir/../node_modules/react-native/android"
// TODO(kkafar): Note, that in latest template app https://github.com/react-native-community/template/blob/0f4745b7a9d84232aeedec2def8d75ab9b050d11/template/android/build.gradle
// this is not specified at all.
File standardRnAndroidDirLocation = file("$rootDir/../node_modules/react-native/android")
if (standardRnAndroidDirLocation.exists()) {
url standardRnAndroidDirLocation
} else {
// We're in non standard setup - try to use node resolver to locate the react-native package.
File reactNativePackage = file(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim())
def rnAndroidDirLocation = "$reactNativePackage.parentFile/android"
if (reactNativePackage.exists()) {
url rnAndroidDirLocation
} else {
println "[RNScreens] Failed to resolve react-native directory. Attempted locations: ${standardRnAndroidDirLocation}, ${rnAndroidDirLocation}"
}
}
}

mavenCentral()
mavenLocal()
google()
Expand Down
47 changes: 46 additions & 1 deletion android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,60 @@ package com.swmansion.rnscreens

import android.annotation.SuppressLint
import android.content.Context
import android.os.Build
import androidx.appcompat.widget.Toolbar
import com.facebook.react.modules.core.ChoreographerCompat
import com.facebook.react.modules.core.ReactChoreographer

// This class is used to store config closer to search bar
@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
open class CustomToolbar(
context: Context,
val config: ScreenStackHeaderConfig,
) : Toolbar(context) {
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
private var isLayoutEnqueued = false
private val layoutCallback: ChoreographerCompat.FrameCallback =
object : ChoreographerCompat.FrameCallback() {
override fun doFrame(frameTimeNanos: Long) {
isLayoutEnqueued = false
measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
)
layout(left, top, right, bottom)
}
}

override fun requestLayout() {
super.requestLayout()
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
// Below Android API 29, layout is not being requested when subviews are being added to the layout,
// leading to having their subviews in position 0,0 of the toolbar (as Android don't calculate
// the position of each subview, even if Yoga has correctly set their width and height).
// This is mostly the issue, when windowSoftInputMode is set to adjustPan in AndroidManifest.
// Thus, we're manually calling the layout **after** the current layout.
@Suppress("SENSELESS_COMPARISON") // mLayoutCallback can be null here since this method can be called in init
if (!isLayoutEnqueued && layoutCallback != null) {
isLayoutEnqueued = true
// we use NATIVE_ANIMATED_MODULE choreographer queue because it allows us to catch the current
// looper loop instead of enqueueing the update in the next loop causing a one frame delay.
ReactChoreographer
.getInstance()
.postFrameCallback(
ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE,
layoutCallback,
)
}
}
}

override fun onLayout(
changed: Boolean,
l: Int,
t: Int,
r: Int,
b: Int,
) {
super.onLayout(changed, l, t, r, b)

// our children are already laid out
Expand Down
44 changes: 40 additions & 4 deletions android/src/main/java/com/swmansion/rnscreens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.webkit.WebView
import android.widget.ImageView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.children
import androidx.fragment.app.Fragment
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.facebook.react.bridge.GuardedRunnable
import com.facebook.react.bridge.ReactContext
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.scroll.ReactScrollView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.shape.CornerFamily
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
import com.swmansion.rnscreens.events.SheetDetentChangedEvent

Expand Down Expand Up @@ -52,10 +58,16 @@ class Screen(

// Props for controlling modal presentation
var isSheetGrabberVisible: Boolean = false

// corner radius must be updated after all props prop updates from a single transaction
// have been applied, because it depends on the presentation type.
private var shouldUpdateSheetCornerRadius = false
var sheetCornerRadius: Float = 0F
set(value) {
field = value
(fragment as? ScreenStackFragment)?.onSheetCornerRadiusChange()
if (field != value) {
field = value
shouldUpdateSheetCornerRadius = true
}
}
var sheetExpandsWhenScrolledToEdge: Boolean = true

Expand Down Expand Up @@ -363,7 +375,7 @@ class Screen(
parent?.let {
for (i in 0 until it.childCount) {
val child = it.getChildAt(i)
if (child.javaClass.simpleName.equals("CircleImageView")) {
if (parent is SwipeRefreshLayout && child is ImageView) {
// SwipeRefreshLayout class which has CircleImageView as a child,
// does not handle `startViewTransition` properly.
// It has a custom `getChildDrawingOrder` method which returns
Expand Down Expand Up @@ -418,6 +430,29 @@ class Screen(
)
}

internal fun onFinalizePropsUpdate() {
if (shouldUpdateSheetCornerRadius) {
shouldUpdateSheetCornerRadius = false
onSheetCornerRadiusChange()
}
}

internal fun onSheetCornerRadiusChange() {
if (stackPresentation !== StackPresentation.FORM_SHEET || background == null) {
return
}
(background as MaterialShapeDrawable?)?.let {
val resolvedCornerRadius = PixelUtil.toDIPFromPixel(sheetCornerRadius)
it.shapeAppearanceModel =
ShapeAppearanceModel
.Builder()
.apply {
setTopLeftCorner(CornerFamily.ROUNDED, resolvedCornerRadius)
setTopRightCorner(CornerFamily.ROUNDED, resolvedCornerRadius)
}.build()
}
}

enum class StackPresentation {
PUSH,
MODAL,
Expand All @@ -433,7 +468,8 @@ class Screen(
SLIDE_FROM_RIGHT,
SLIDE_FROM_LEFT,
FADE_FROM_BOTTOM,
IOS,
IOS_FROM_RIGHT,
IOS_FROM_LEFT,
}

enum class ReplaceAnimation {
Expand Down
9 changes: 6 additions & 3 deletions android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ class ScreenStack(
R.anim.rns_no_animation_medium,
)
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_slide_in_from_right_ios, R.anim.rns_slide_out_to_left_ios)
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_foreground_open, R.anim.rns_ios_from_right_background_open)
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_foreground_open, R.anim.rns_ios_from_left_background_open)
}
} else {
when (stackAnimation) {
Expand Down Expand Up @@ -220,7 +221,8 @@ class ScreenStack(
R.anim.rns_slide_out_to_bottom,
)
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_slide_in_from_left_ios, R.anim.rns_slide_out_to_right_ios)
StackAnimation.IOS_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_ios_from_right_background_close, R.anim.rns_ios_from_right_foreground_close)
StackAnimation.IOS_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_ios_from_left_background_close, R.anim.rns_ios_from_left_foreground_close)
}
}
}
Expand Down Expand Up @@ -413,6 +415,7 @@ class ScreenStack(
Build.VERSION.SDK_INT >= 33 ||
fragmentWrapper.screen.stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM ||
fragmentWrapper.screen.stackAnimation === StackAnimation.FADE_FROM_BOTTOM ||
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_RIGHT ||
fragmentWrapper.screen.stackAnimation === StackAnimation.IOS_FROM_LEFT
}
}
Loading

0 comments on commit 7a7f324

Please sign in to comment.