Skip to content

Commit

Permalink
Squash commit of Shopify#931
Browse files Browse the repository at this point in the history
  • Loading branch information
Flewp committed Oct 11, 2023
1 parent 91d56d0 commit 0d5a18d
Show file tree
Hide file tree
Showing 119 changed files with 14,233 additions and 1,463 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-website-on-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
run: |
sudo gem install bundler
cd website
bundle install
sudo bundle install
- name: Publish website and docs
run: |
git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

- Added Fabric support for iOS and Android

## [1.6.1] - 2023-09-14

- Prevent an expired layout provider from being used again
- https://github.com/Shopify/flash-list/pull/915

## [1.6.0] - 2023-09-13

- Update types to match `react-native@0.72` view types.
- https://github.com/Shopify/flash-list/pull/890
- Add type definition for `ViewToken["item"]`
Expand Down
28 changes: 25 additions & 3 deletions RNFlashList.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,43 @@ require 'json'

package = JSON.parse(File.read(File.join(__dir__, 'package.json')))

folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'

Pod::Spec.new do |s|
s.name = 'RNFlashList'
s.version = package['version']
s.summary = package['description']
s.homepage = package['homepage']
s.license = package['license']
s.author = package['author']
s.platforms = { :ios => '11.0', :tvos => '12.0' }
s.source = { git: 'https://github.com/shopify/flash-list.git', tag: "v#{s.version}" }
s.source_files = 'ios/Sources/**/*'
s.requires_arc = true
s.swift_version = '5.0'
s.dependency "React-Core"

if fabric_enabled
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
'OTHER_SWIFT_FLAGS' => '-D RCT_NEW_ARCH_ENABLED',
}

# Dependencies
s.dependency 'React-Core'
s.dependency "React-RCTFabric"
s.dependency "React-Codegen"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
s.ios.deployment_target = "12.4"
s.platforms = { :ios => '12.4', :tvos => '12.0' }
else
# Settings for non-fabric builds
s.platforms = { :ios => '11.0', :tvos => '12.0' }
end

# Tests spec
s.test_spec 'Tests' do |test_spec|
Expand Down
19 changes: 17 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
apply plugin: 'com.android.library'
def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}

def _ext = rootProject.ext

def _reactNativeVersion = _ext.has('reactNative') ? _ext.reactNative : '+'
Expand Down Expand Up @@ -40,11 +47,19 @@ android {
debug.java.srcDirs += 'src/debug/kotlin'
test.java.srcDirs += 'src/test/kotlin'
androidTest.java.srcDirs += 'src/androidTest/kotlin'

if (isNewArchitectureEnabled()) {
main.java.srcDirs += ["${project.buildDir}/generated/source/codegen/java"]
main.java.srcDirs += ["src/fabric/java"]
} else {
main.java.srcDirs += ['src/paper/java']
}
}

defaultConfig {
minSdkVersion _minSdkVersion
targetSdkVersion _targetSdkVersion
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
versionCode 1
versionName "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand All @@ -61,7 +76,7 @@ android {

dependencies {
compileOnly "com.facebook.react:react-native:${_reactNativeVersion}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${_kotlinVersion}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${_kotlinVersion}"
testImplementation "junit:junit:${_junitVersion}"
testImplementation "org.mockito.kotlin:mockito-kotlin:${_mockitoVersion}"
testImplementation "org.mockito:mockito-inline:${_mockitoVersion}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.shopify.reactnative.flash_list

import com.facebook.react.bridge.ReactContext
import com.facebook.react.fabric.FabricUIManager
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.common.UIManagerType
import com.facebook.react.bridge.WritableMap

fun ReactContext.dispatchEvent(nativeTag: Int, eventName: String, event: WritableMap) {
val fabricUIManager = UIManagerHelper.getUIManager(this, UIManagerType.FABRIC) as FabricUIManager
fabricUIManager.receiveEvent(nativeTag, eventName, event)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ package com.shopify.reactnative.flash_list

import android.content.Context
import android.graphics.Canvas
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import android.widget.ScrollView
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.events.RCTEventEmitter
import com.facebook.react.views.view.ReactViewGroup


Expand Down Expand Up @@ -142,9 +139,8 @@ class AutoLayoutView(context: Context) : ReactViewGroup(context) {
val event: WritableMap = Arguments.createMap()
event.putDouble("offsetStart", alShadow.blankOffsetAtStart / pixelDensity)
event.putDouble("offsetEnd", alShadow.blankOffsetAtEnd / pixelDensity)

val reactContext = context as ReactContext
reactContext
.getJSModule(RCTEventEmitter::class.java)
.receiveEvent(id, "onBlankAreaEvent", event)
reactContext.dispatchEvent(id, "onBlankAreaEvent", event)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ package com.shopify.reactnative.flash_list
import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.ReactViewManager
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.viewmanagers.AutoLayoutViewManagerDelegate
import com.facebook.react.viewmanagers.AutoLayoutViewManagerInterface
import com.facebook.react.common.MapBuilder
import kotlin.math.roundToInt

/** ViewManager for AutoLayoutView - Container for all RecyclerListView children. Automatically removes all gaps and overlaps for GridLayouts with flexible spans.
* Note: This cannot work for masonry layouts i.e, pinterest like layout */
@ReactModule(name = AutoLayoutViewManager.REACT_CLASS)
class AutoLayoutViewManager: ReactViewManager() {
class AutoLayoutViewManager: ViewGroupManager<AutoLayoutView>(), AutoLayoutViewManagerInterface<AutoLayoutView> {
private val mDelegate: ViewManagerDelegate<AutoLayoutView>

init {
mDelegate = AutoLayoutViewManagerDelegate(this)
}

companion object {
const val REACT_CLASS = "AutoLayoutView"
Expand All @@ -21,45 +28,42 @@ class AutoLayoutViewManager: ReactViewManager() {
return REACT_CLASS
}

override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
override fun createViewInstance(context: ThemedReactContext): AutoLayoutView {
return AutoLayoutView(context).also { it.pixelDensity = context.resources.displayMetrics.density.toDouble() }
}

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
return MapBuilder.builder<String, Any>().put(
"onBlankAreaEvent",
MapBuilder.of(
"registrationName", "onBlankAreaEvent")
).build();
}
override fun getExportedCustomDirectEventTypeConstants() = mutableMapOf(
"onBlankAreaEvent" to mutableMapOf("registrationName" to "onBlankAreaEvent"),
"topOnBlankAreaEvent" to mutableMapOf("registrationName" to "onBlankAreaEvent"),
)

@ReactProp(name = "horizontal")
fun setHorizontal(view: AutoLayoutView, isHorizontal: Boolean) {
override fun setHorizontal(view: AutoLayoutView, isHorizontal: Boolean) {
view.alShadow.horizontal = isHorizontal
}

@ReactProp(name = "disableAutoLayout")
fun setDisableAutoLayout(view: AutoLayoutView, disableAutoLayout: Boolean) {
override fun setDisableAutoLayout(view: AutoLayoutView, disableAutoLayout: Boolean) {
view.disableAutoLayout = disableAutoLayout
}

@ReactProp(name = "scrollOffset")
fun setScrollOffset(view: AutoLayoutView, scrollOffset: Double) {
override fun setScrollOffset(view: AutoLayoutView, scrollOffset: Double) {
view.alShadow.scrollOffset = convertToPixelLayout(scrollOffset, view.pixelDensity)
}

@ReactProp(name = "windowSize")
fun setWindowSize(view: AutoLayoutView, windowSize: Double) {
override fun setWindowSize(view: AutoLayoutView, windowSize: Double) {
view.alShadow.windowSize = convertToPixelLayout(windowSize, view.pixelDensity)
}

@ReactProp(name = "renderAheadOffset")
fun setRenderAheadOffset(view: AutoLayoutView, renderOffset: Double) {
override fun setRenderAheadOffset(view: AutoLayoutView, renderOffset: Double) {
view.alShadow.renderOffset = convertToPixelLayout(renderOffset, view.pixelDensity)
}

@ReactProp(name = "enableInstrumentation")
fun setEnableInstrumentation(view: AutoLayoutView, enableInstrumentation: Boolean) {
override fun setEnableInstrumentation(view: AutoLayoutView, enableInstrumentation: Boolean) {
view.enableInstrumentation = enableInstrumentation
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ package com.shopify.reactnative.flash_list

import com.facebook.react.module.annotations.ReactModule
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.ViewManagerDelegate
import com.facebook.react.uimanager.annotations.ReactProp
import com.facebook.react.views.view.ReactViewGroup
import com.facebook.react.views.view.ReactViewManager
import com.facebook.react.viewmanagers.CellContainerManagerDelegate
import com.facebook.react.viewmanagers.CellContainerManagerInterface

@ReactModule(name = AutoLayoutViewManager.REACT_CLASS)
class CellContainerManager: ReactViewManager() {
class CellContainerManager: ViewGroupManager<CellContainerImpl>(), CellContainerManagerInterface<CellContainerImpl> {
private val mDelegate: ViewManagerDelegate<CellContainerImpl>

init {
mDelegate = CellContainerManagerDelegate(this);
}

companion object {
const val REACT_CLASS = "CellContainer"
}
Expand All @@ -16,12 +24,12 @@ class CellContainerManager: ReactViewManager() {
return REACT_CLASS
}

override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
override fun createViewInstance(context: ThemedReactContext): CellContainerImpl {
return CellContainerImpl(context)
}

@ReactProp(name = "index")
fun setIndex(view: CellContainerImpl, index: Int) {
override fun setIndex(view: CellContainerImpl, index: Int) {
view.index = index
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;

public class AutoLayoutViewManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & AutoLayoutViewManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public AutoLayoutViewManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case "horizontal":
mViewManager.setHorizontal(view, value == null ? false : (boolean) value);
break;
case "scrollOffset":
mViewManager.setScrollOffset(view, value == null ? 0f : ((Double) value).doubleValue());
break;
case "windowSize":
mViewManager.setWindowSize(view, value == null ? 0f : ((Double) value).doubleValue());
break;
case "renderAheadOffset":
mViewManager.setRenderAheadOffset(view, value == null ? 0f : ((Double) value).doubleValue());
break;
case "enableInstrumentation":
mViewManager.setEnableInstrumentation(view, value == null ? false : (boolean) value);
break;
case "disableAutoLayout":
mViewManager.setDisableAutoLayout(view, value == null ? false : (boolean) value);
break;
default:
super.setProperty(view, propName, value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;

public interface AutoLayoutViewManagerInterface<T extends View> {
void setHorizontal(T view, boolean value);
void setScrollOffset(T view, double value);
void setWindowSize(T view, double value);
void setRenderAheadOffset(T view, double value);
void setEnableInstrumentation(T view, boolean value);
void setDisableAutoLayout(T view, boolean value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;

public class CellContainerManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & CellContainerManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public CellContainerManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case "index":
mViewManager.setIndex(view, value == null ? 0 : ((Double) value).intValue());
break;
default:
super.setProperty(view, propName, value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/

package com.facebook.react.viewmanagers;

import android.view.View;

public interface CellContainerManagerInterface<T extends View> {
void setIndex(T view, int value);
}
Loading

0 comments on commit 0d5a18d

Please sign in to comment.