Skip to content

Commit

Permalink
Support for debugging of difference in cell dimension (#253)
Browse files Browse the repository at this point in the history
* [FINE] added support for debug config where clients can receive callback in case there is non-deterministic heights and there is a discrepancy in it.

* [FINE] made the debug handler pluggable.

* [FINE] made debugHandler container of other handlers.

* [FINE] not using I coding style for the interface.
  • Loading branch information
adnaan1703 authored and naqvitalha committed Oct 11, 2018
1 parent 9e62414 commit 84ab6d1
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 19 deletions.
1 change: 1 addition & 0 deletions scripts/clean.sh
@@ -1,3 +1,4 @@
#!/usr/bin/env bash
set -e

echo "Deleting old packages..."
Expand Down
49 changes: 32 additions & 17 deletions src/core/RecyclerListView.tsx
Expand Up @@ -35,12 +35,14 @@ import BaseScrollView, { ScrollEvent, ScrollViewDefaultProps } from "./scrollcom
import { TOnItemStatusChanged } from "./ViewabilityTracker";
import VirtualRenderer, { RenderStack, RenderStackItem, RenderStackParams } from "./VirtualRenderer";
import ItemAnimator, { BaseItemAnimator } from "./ItemAnimator";
import { DebugHandlers } from "..";

//#if [REACT-NATIVE]
import ScrollComponent from "../platform/reactnative/scrollcomponent/ScrollComponent";
import ViewRenderer from "../platform/reactnative/viewrenderer/ViewRenderer";
import { DefaultJSItemAnimator as DefaultItemAnimator } from "../platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";
import { Platform } from "react-native";

const IS_WEB = !Platform || Platform.OS === "web";
//#endif

Expand All @@ -51,7 +53,7 @@ const IS_WEB = !Platform || Platform.OS === "web";
//#if [WEB]
//import ScrollComponent from "../platform/web/scrollcomponent/ScrollComponent";
//import ViewRenderer from "../platform/web/viewrenderer/ViewRenderer";
//import { DefaultWebItemAnimator as DefaultItemAnimator} from "../platform/web/itemanimators/DefaultWebItemAnimator";
//import { DefaultWebItemAnimator as DefaultItemAnimator } from "../platform/web/itemanimators/DefaultWebItemAnimator";
//const IS_WEB = true;
//#endif

Expand All @@ -78,6 +80,7 @@ const refreshRequestDebouncer = debounce((executable: () => void) => {
export interface OnRecreateParams {
lastOffset?: number;
}

export interface RecyclerListViewProps {
layoutProvider: BaseLayoutProvider;
dataProvider: DataProvider;
Expand All @@ -104,11 +107,13 @@ export interface RecyclerListViewProps {
itemAnimator?: ItemAnimator;
optimizeForInsertDeleteAnimations?: boolean;
style?: object;
debugHandlers?: DebugHandlers;

//For all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread
//and passed down. For better typescript support.
scrollViewProps?: object;
}

export interface RecyclerListViewState {
renderStack: RenderStack;
}
Expand Down Expand Up @@ -481,29 +486,39 @@ export default class RecyclerListView<P extends RecyclerListViewProps, S extends
}
return (
<ViewRenderer key={key} data={data}
dataHasChanged={this._dataHasChanged}
x={itemRect.x}
y={itemRect.y}
layoutType={type}
index={dataIndex}
styleOverrides={styleOverrides}
layoutProvider={this.props.layoutProvider}
forceNonDeterministicRendering={this.props.forceNonDeterministicRendering}
isHorizontal={this.props.isHorizontal}
onSizeChanged={this._onViewContainerSizeChange}
childRenderer={this.props.rowRenderer}
height={itemRect.height}
width={itemRect.width}
itemAnimator={Default.value<ItemAnimator>(this.props.itemAnimator, this._defaultItemAnimator)}
extendedState={this.props.extendedState} />
dataHasChanged={this._dataHasChanged}
x={itemRect.x}
y={itemRect.y}
layoutType={type}
index={dataIndex}
styleOverrides={styleOverrides}
layoutProvider={this.props.layoutProvider}
forceNonDeterministicRendering={this.props.forceNonDeterministicRendering}
isHorizontal={this.props.isHorizontal}
onSizeChanged={this._onViewContainerSizeChange}
childRenderer={this.props.rowRenderer}
height={itemRect.height}
width={itemRect.width}
itemAnimator={Default.value<ItemAnimator>(this.props.itemAnimator, this._defaultItemAnimator)}
extendedState={this.props.extendedState}/>
);
}
return null;
}

private _onViewContainerSizeChange = (dim: Dimension, index: number): void => {
//Cannot be null here
(this._virtualRenderer.getLayoutManager() as LayoutManager).overrideLayout(index, dim);
const layoutManager: LayoutManager = this._virtualRenderer.getLayoutManager() as LayoutManager;

if (this.props.debugHandlers && this.props.debugHandlers.resizeDebugHandler) {
const itemRect = layoutManager.getLayouts()[index];
this.props.debugHandlers.resizeDebugHandler.resizeDebug({
width: itemRect.width,
height: itemRect.height,
}, dim, index);
}

layoutManager.overrideLayout(index, dim);
if (this._relayoutReqIndex === -1) {
this._relayoutReqIndex = index;
} else {
Expand Down
6 changes: 6 additions & 0 deletions src/core/devutils/debughandlers/DebugHandlers.ts
@@ -0,0 +1,6 @@
import ResizeDebugHandler from "./resize/ResizeDebugHandler";

// It is basically container of all debugHandlers.
export interface DebugHandlers {
resizeDebugHandler?: ResizeDebugHandler;
}
@@ -0,0 +1,29 @@
import { Dimension } from "../../../..";
import ResizeDebugHandler from "./ResizeDebugHandler";

export default class DefaultResizeDebugHandler implements ResizeDebugHandler {
private readonly relaxation: Dimension;
private readonly onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void;

// Relaxation is the Dimension object where it accepts the relaxation to allow for each dimension.
// Any of the dimension (height or width) whose value for relaxation is less than 0 would be ignored.
public constructor(relaxation: Dimension, onRelaxationViolation: (expectedDim: Dimension, actualDim: Dimension, index: number) => void) {
this.relaxation = relaxation;
this.onRelaxationViolation = onRelaxationViolation;
}

public resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void {
let isViolated: boolean = false;
if (this.relaxation.height >= 0 && Math.abs(newDim.height - oldDim.height) >= this.relaxation.height) {
isViolated = true;
}

if (!isViolated && this.relaxation.width >= 0 && Math.abs(newDim.width - oldDim.width) >= this.relaxation.width) {
isViolated = true;
}

if (isViolated) {
this.onRelaxationViolation(oldDim, newDim, index);
}
}
}
5 changes: 5 additions & 0 deletions src/core/devutils/debughandlers/resize/ResizeDebugHandler.ts
@@ -0,0 +1,5 @@
import { Dimension } from "../../../..";

export default interface ResizeDebugHandler {
resizeDebug(oldDim: Dimension, newDim: Dimension, index: number): void;
}
7 changes: 5 additions & 2 deletions src/index.ts
@@ -1,12 +1,14 @@
import ContextProvider from "./core/dependencies/ContextProvider";
import DataProvider from "./core/dependencies/DataProvider";
import { LayoutProvider, BaseLayoutProvider, Dimension } from "./core/dependencies/LayoutProvider";
import { BaseLayoutProvider, Dimension, LayoutProvider } from "./core/dependencies/LayoutProvider";
import RecyclerListView, { OnRecreateParams } from "./core/RecyclerListView";
import BaseScrollView from "./core/scrollcomponent/BaseScrollView";
import { BaseItemAnimator } from "./core/ItemAnimator";
import { AutoScroll } from "./utils/AutoScroll";
import { LayoutManager, WrapGridLayoutManager, Point, Layout } from "./core/layoutmanager/LayoutManager";
import { Layout, LayoutManager, Point, WrapGridLayoutManager } from "./core/layoutmanager/LayoutManager";
import ProgressiveListView from "./core/ProgressiveListView";
import { DebugHandlers } from "./core/devutils/debughandlers/DebugHandlers";

export {
ContextProvider,
DataProvider,
Expand All @@ -23,4 +25,5 @@ export {
Point,
Layout,
OnRecreateParams,
DebugHandlers,
};

0 comments on commit 84ab6d1

Please sign in to comment.