diff --git a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java index 0d796893..6a0a5f36 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricRegistry.java @@ -24,6 +24,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import pub.doric.plugin.AnimatePlugin; +import pub.doric.plugin.CoordinatorPlugin; import pub.doric.plugin.DoricJavaPlugin; import pub.doric.plugin.ModalPlugin; import pub.doric.plugin.NavBarPlugin; @@ -91,6 +92,7 @@ public class DoricRegistry { this.registerNativePlugin(AnimatePlugin.class); this.registerNativePlugin(NotificationPlugin.class); this.registerNativePlugin(StatusBarPlugin.class); + this.registerNativePlugin(CoordinatorPlugin.class); this.registerViewNode(RootNode.class); this.registerViewNode(TextNode.class); diff --git a/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java b/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java new file mode 100644 index 00000000..8d1cc5c1 --- /dev/null +++ b/doric-android/doric/src/main/java/pub/doric/plugin/CoordinatorPlugin.java @@ -0,0 +1,186 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pub.doric.plugin; + +import android.graphics.Color; +import android.view.View; + +import com.github.pengfeizhou.jscore.JSObject; +import com.github.pengfeizhou.jscore.JSValue; + +import java.util.concurrent.Callable; + +import pub.doric.DoricContext; +import pub.doric.DoricScrollChangeListener; +import pub.doric.IDoricScrollable; +import pub.doric.async.AsyncResult; +import pub.doric.extension.bridge.DoricMethod; +import pub.doric.extension.bridge.DoricPlugin; +import pub.doric.extension.bridge.DoricPromise; +import pub.doric.shader.SuperNode; +import pub.doric.shader.ViewNode; +import pub.doric.utils.DoricUtils; +import pub.doric.utils.ThreadMode; + +/** + * @Description: pub.doric.plugin + * @Author: pengfei.zhou + * @CreateDate: 2020-02-13 + */ +@DoricPlugin(name = "coordinator") +public class CoordinatorPlugin extends DoricJavaPlugin { + public CoordinatorPlugin(DoricContext doricContext) { + super(doricContext); + } + + @DoricMethod + public void ready(final DoricPromise doricPromise) { + getDoricContext().getDriver().asyncCall(new Callable() { + @Override + public Object call() { + getDoricContext().getDriver().asyncCall(new Callable() { + @Override + public Object call() { + doricPromise.resolve(); + return null; + } + }, ThreadMode.UI); + return null; + } + }, ThreadMode.UI); + } + + + @DoricMethod + public void verticalScrolling(final JSObject argument, final DoricPromise doricPromise) { + getDoricContext().getDriver().asyncCall(new Callable() { + @Override + public Object call() throws Exception { + JSValue[] scrollableIds = argument.getProperty("scrollable").asArray().toArray(); + ViewNode scrollNode = null; + for (JSValue value : scrollableIds) { + if (scrollNode == null) { + scrollNode = getDoricContext().targetViewNode(value.asString().value()); + } else { + if (value.isString() && scrollNode instanceof SuperNode) { + String viewId = value.asString().value(); + scrollNode = ((SuperNode) scrollNode).getSubNodeById(viewId); + } + } + } + if (scrollNode == null) { + throw new Exception("Cannot find scrollable view"); + } + JSObject scrollRange = argument.getProperty("scrollRange").asObject(); + final int startAnchor = DoricUtils.dp2px(scrollRange.getProperty("start").asNumber().toFloat()); + final int endAnchor = DoricUtils.dp2px(scrollRange.getProperty("end").asNumber().toFloat()); + + JSValue target = argument.getProperty("target"); + boolean isNavBar = false; + ViewNode targetNode = null; + if (target.isString() && "NavBar".equals(target.asString().value())) { + isNavBar = true; + } else if (target.isArray()) { + JSValue[] targetIds = target.asArray().toArray(); + for (JSValue value : targetIds) { + if (targetNode == null) { + targetNode = getDoricContext().targetViewNode(value.asString().value()); + } else { + if (value.isString() && targetNode instanceof SuperNode) { + String viewId = value.asString().value(); + targetNode = ((SuperNode) targetNode).getSubNodeById(viewId); + } + } + } + } else { + throw new Exception("Target type error"); + } + JSObject changing = argument.getProperty("changing").asObject(); + final String name = changing.getProperty("name").asString().value(); + final float changingStart = changing.getProperty("start").asNumber().toFloat(); + final float changingEnd = changing.getProperty("end").asNumber().toFloat(); + + + final ViewNode finalScrollNode = scrollNode; + final ViewNode finalTargetNode = targetNode; + final boolean finalIsNavBar = isNavBar; + + if (finalScrollNode instanceof IDoricScrollable) { + + ((IDoricScrollable) finalScrollNode).setScrollChangeListener(new DoricScrollChangeListener() { + @Override + public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { + if (scrollY <= startAnchor) { + setValue(finalTargetNode, finalIsNavBar, name, changingStart); + } else if (scrollY >= endAnchor) { + setValue(finalTargetNode, finalIsNavBar, name, changingEnd); + } else { + float range = Math.max(1, endAnchor - startAnchor); + float offset = scrollY - startAnchor; + float rate = offset / range; + float value; + if ("backgroundColor".equals(name)) { + int startColor = (int) changingStart; + int endColor = (int) changingEnd; + value = Color.argb((int) (Color.alpha(startColor) + (Color.alpha(endColor) - Color.alpha(startColor)) * rate), + (int) (Color.red(startColor) + (Color.red(endColor) - Color.red(startColor)) * rate), + (int) (Color.green(startColor) + (Color.green(endColor) - Color.green(startColor)) * rate), + (int) (Color.blue(startColor) + (Color.blue(endColor) - Color.blue(startColor)) * rate)); + } else { + value = changingStart + (changingEnd - changingStart) * rate; + } + setValue(finalTargetNode, finalIsNavBar, name, value); + } + } + }); + return null; + } else { + throw new Exception("Scroller type error"); + } + } + }, ThreadMode.UI).setCallback(new AsyncResult.Callback() { + @Override + public void onResult(Object result) { + doricPromise.resolve(); + } + + @Override + public void onError(Throwable t) { + doricPromise.reject(); + } + + @Override + public void onFinish() { + + } + }); + } + + private void setValue(ViewNode viewNode, boolean isNavBar, String name, float value) { + if ("backgroundColor".equals(name)) { + if (isNavBar) { + getDoricContext().getDoricNavBar().setBackgroundColor((int) value); + } else { + viewNode.setBackgroundColor((int) value); + } + } else if ("width".equals(name)) { + viewNode.setWidth(value); + } else if ("height".equals(name)) { + viewNode.setHeight(value); + } + + } +} diff --git a/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java b/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java index 955a5378..b5fa9c95 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/ViewNode.java @@ -519,7 +519,7 @@ public abstract class ViewNode extends DoricContextHolder { } @DoricMethod - protected void setWidth(float width) { + public void setWidth(float width) { if (mLayoutParams.width >= 0) { mLayoutParams.width = DoricUtils.dp2px(width); if (mView.getLayoutParams() != mLayoutParams) { @@ -530,7 +530,7 @@ public abstract class ViewNode extends DoricContextHolder { } @DoricMethod - protected void setHeight(float height) { + public void setHeight(float height) { if (mLayoutParams.height >= 0) { mLayoutParams.height = DoricUtils.dp2px(height); if (mView.getLayoutParams() != mLayoutParams) { @@ -541,7 +541,7 @@ public abstract class ViewNode extends DoricContextHolder { } @DoricMethod - protected void setX(float x) { + public void setX(float x) { if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { ((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin = DoricUtils.dp2px(x); getNodeView().requestLayout(); @@ -549,7 +549,7 @@ public abstract class ViewNode extends DoricContextHolder { } @DoricMethod - protected void setY(float y) { + public void setY(float y) { if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { ((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin = DoricUtils.dp2px(y); getNodeView().requestLayout(); diff --git a/doric-js/bundle/doric-lib.es5.js b/doric-js/bundle/doric-lib.es5.js index e3e615d8..46ae1595 100644 --- a/doric-js/bundle/doric-lib.es5.js +++ b/doric-js/bundle/doric-lib.es5.js @@ -2843,6 +2843,77 @@ function statusbar(context) { }; } +var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator$1 = (undefined && undefined.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) { throw t[1]; } return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) { throw new TypeError("Generator is already executing."); } + while (_) { try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) { return t; } + if (y = 0, t) { op = [op[0] & 2, t.value]; } + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) { _.ops.pop(); } + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } } + if (op[0] & 5) { throw op[1]; } return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +function viewIdChains(view) { + var viewIds = []; + var thisView = view; + while (thisView != undefined) { + viewIds.push(thisView.viewId); + thisView = thisView.superview; + } + return viewIds.reverse(); +} +function coordinator(context) { + var _this = this; + return { + verticalScrolling: function (argument) { return __awaiter$1(_this, void 0, void 0, function () { + return __generator$1(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, context.callNative("coordinator", "ready")]; + case 1: + _a.sent(); + argument.scrollable = viewIdChains(argument.scrollable); + if (argument.target instanceof View) { + argument.target = viewIdChains(argument.target); + } + if (argument.changing.start instanceof Color) { + argument.changing.start = argument.changing.start.toModel(); + } + if (argument.changing.end instanceof Color) { + argument.changing.end = argument.changing.end.toModel(); + } + return [2 /*return*/, context.callNative("coordinator", "verticalScrolling", argument)]; + } + }); + }); } + }; +} + var __values$5 = (undefined && undefined.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) { return m.call(o); } @@ -3015,6 +3086,7 @@ exports.View = View; exports.ViewHolder = ViewHolder; exports.ViewModel = ViewModel; exports.animate = animate; +exports.coordinator = coordinator; exports.draggable = draggable; exports.flowItem = flowItem; exports.flowlayout = flowlayout; diff --git a/doric-js/bundle/doric-lib.js b/doric-js/bundle/doric-lib.js index 8394c036..01929ef9 100644 --- a/doric-js/bundle/doric-lib.js +++ b/doric-js/bundle/doric-lib.js @@ -2150,6 +2150,43 @@ function statusbar(context) { }; } +var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function viewIdChains(view) { + const viewIds = []; + let thisView = view; + while (thisView != undefined) { + viewIds.push(thisView.viewId); + thisView = thisView.superview; + } + return viewIds.reverse(); +} +function coordinator(context) { + return { + verticalScrolling: (argument) => __awaiter$1(this, void 0, void 0, function* () { + yield context.callNative("coordinator", "ready"); + argument.scrollable = viewIdChains(argument.scrollable); + if (argument.target instanceof View) { + argument.target = viewIdChains(argument.target); + } + if (argument.changing.start instanceof Color) { + argument.changing.start = argument.changing.start.toModel(); + } + if (argument.changing.end instanceof Color) { + argument.changing.end = argument.changing.end.toModel(); + } + return context.callNative("coordinator", "verticalScrolling", argument); + }) + }; +} + class Observable { constructor(provider, clz) { this.observers = new Set; @@ -2276,6 +2313,7 @@ exports.View = View; exports.ViewHolder = ViewHolder; exports.ViewModel = ViewModel; exports.animate = animate; +exports.coordinator = coordinator; exports.draggable = draggable; exports.flowItem = flowItem; exports.flowlayout = flowlayout; diff --git a/doric-js/bundle/doric-vm.js b/doric-js/bundle/doric-vm.js index 2f448f09..2245660b 100644 --- a/doric-js/bundle/doric-vm.js +++ b/doric-js/bundle/doric-vm.js @@ -3609,6 +3609,43 @@ function statusbar(context) { }; } +var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +function viewIdChains(view) { + const viewIds = []; + let thisView = view; + while (thisView != undefined) { + viewIds.push(thisView.viewId); + thisView = thisView.superview; + } + return viewIds.reverse(); +} +function coordinator(context) { + return { + verticalScrolling: (argument) => __awaiter$1(this, void 0, void 0, function* () { + yield context.callNative("coordinator", "ready"); + argument.scrollable = viewIdChains(argument.scrollable); + if (argument.target instanceof View) { + argument.target = viewIdChains(argument.target); + } + if (argument.changing.start instanceof Color) { + argument.changing.start = argument.changing.start.toModel(); + } + if (argument.changing.end instanceof Color) { + argument.changing.end = argument.changing.end.toModel(); + } + return context.callNative("coordinator", "verticalScrolling", argument); + }) + }; +} + class Observable { constructor(provider, clz) { this.observers = new Set; @@ -3841,6 +3878,7 @@ exports.View = View; exports.ViewHolder = ViewHolder; exports.ViewModel = ViewModel; exports.animate = animate; +exports.coordinator = coordinator; exports.draggable = draggable; exports.flowItem = flowItem; exports.flowlayout = flowlayout; diff --git a/doric-js/index.d.ts b/doric-js/index.d.ts index 8c0dc949..5e8c47d3 100644 --- a/doric-js/index.d.ts +++ b/doric-js/index.d.ts @@ -90,6 +90,7 @@ declare module 'doric/lib/src/native/index.native' { export * from 'doric/lib/src/native/animate'; export * from 'doric/lib/src/native/notification'; export * from 'doric/lib/src/native/statusbar'; + export * from 'doric/lib/src/native/coordinator'; } declare module 'doric/lib/src/util/index.util' { @@ -856,6 +857,30 @@ declare module 'doric/lib/src/native/statusbar' { }; } +declare module 'doric/lib/src/native/coordinator' { + import { BridgeContext } from "doric/lib/src/runtime/global"; + import { Scroller } from "doric/lib/src/widget/scroller"; + import { List } from "doric/lib/src/widget/list"; + import { FlowLayout } from "doric/lib/src/widget/flowlayout"; + import { View } from "doric/lib/src/ui/view"; + import { Color } from "doric/lib/src/util/color"; + export function coordinator(context: BridgeContext): { + verticalScrolling: (argument: { + scrollable: List | Scroller | FlowLayout; + scrollRange: { + start: number; + end: number; + }; + target: View | "NavBar"; + changing: { + name: "width" | "height" | "x" | "y" | "backgroundColor"; + start: number | Color; + end: number | Color; + }; + }) => Promise; + }; +} + declare module 'doric/lib/src/util/color' { import { Modeling } from "doric/lib/src/util/types"; /** diff --git a/doric-js/lib/src/native/coordinator.d.ts b/doric-js/lib/src/native/coordinator.d.ts new file mode 100644 index 00000000..2940efa2 --- /dev/null +++ b/doric-js/lib/src/native/coordinator.d.ts @@ -0,0 +1,21 @@ +import { BridgeContext } from "../runtime/global"; +import { Scroller } from "../widget/scroller"; +import { List } from "../widget/list"; +import { FlowLayout } from "../widget/flowlayout"; +import { View } from "../ui/view"; +import { Color } from "../util/color"; +export declare function coordinator(context: BridgeContext): { + verticalScrolling: (argument: { + scrollable: List | Scroller | FlowLayout; + scrollRange: { + start: number; + end: number; + }; + target: View | "NavBar"; + changing: { + name: "width" | "height" | "x" | "y" | "backgroundColor"; + start: number | Color; + end: number | Color; + }; + }) => Promise; +}; diff --git a/doric-js/lib/src/native/coordinator.js b/doric-js/lib/src/native/coordinator.js new file mode 100644 index 00000000..bcf1177f --- /dev/null +++ b/doric-js/lib/src/native/coordinator.js @@ -0,0 +1,38 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { View } from "../ui/view"; +import { Color } from "../util/color"; +function viewIdChains(view) { + const viewIds = []; + let thisView = view; + while (thisView != undefined) { + viewIds.push(thisView.viewId); + thisView = thisView.superview; + } + return viewIds.reverse(); +} +export function coordinator(context) { + return { + verticalScrolling: (argument) => __awaiter(this, void 0, void 0, function* () { + yield context.callNative("coordinator", "ready"); + argument.scrollable = viewIdChains(argument.scrollable); + if (argument.target instanceof View) { + argument.target = viewIdChains(argument.target); + } + if (argument.changing.start instanceof Color) { + argument.changing.start = argument.changing.start.toModel(); + } + if (argument.changing.end instanceof Color) { + argument.changing.end = argument.changing.end.toModel(); + } + return context.callNative("coordinator", "verticalScrolling", argument); + }) + }; +} diff --git a/doric-js/lib/src/native/index.native.d.ts b/doric-js/lib/src/native/index.native.d.ts index 581d2e5a..e35a83c9 100644 --- a/doric-js/lib/src/native/index.native.d.ts +++ b/doric-js/lib/src/native/index.native.d.ts @@ -7,3 +7,4 @@ export * from './popover'; export * from './animate'; export * from './notification'; export * from './statusbar'; +export * from './coordinator'; diff --git a/doric-js/lib/src/native/index.native.js b/doric-js/lib/src/native/index.native.js index 8feef678..91058c1a 100644 --- a/doric-js/lib/src/native/index.native.js +++ b/doric-js/lib/src/native/index.native.js @@ -22,3 +22,4 @@ export * from './popover'; export * from './animate'; export * from './notification'; export * from './statusbar'; +export * from './coordinator'; diff --git a/doric-js/src/native/coordinator.ts b/doric-js/src/native/coordinator.ts new file mode 100644 index 00000000..b7fd3ce3 --- /dev/null +++ b/doric-js/src/native/coordinator.ts @@ -0,0 +1,63 @@ +/* + * Copyright [2019] [Doric.Pub] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { BridgeContext } from "../runtime/global" +import { Scroller } from "../widget/scroller" +import { List } from "../widget/list" +import { FlowLayout } from "../widget/flowlayout" +import { View } from "../ui/view" +import { Color } from "../util/color" + +function viewIdChains(view: View) { + const viewIds = [] + let thisView: View | undefined = view + while (thisView != undefined) { + viewIds.push(thisView.viewId) + thisView = thisView.superview + } + return viewIds.reverse() +} + +export function coordinator(context: BridgeContext) { + return { + verticalScrolling: async ( + argument: { + scrollable: Scroller | List | FlowLayout, + scrollRange: { + start: number, + end: number, + }, + target: View | "NavBar", + changing: { + name: "backgroundColor" | "width" | "height" | "x" | "y", + start: number | Color + end: number | Color + }, + }) => { + await context.callNative("coordinator", "ready"); + (argument as any).scrollable = viewIdChains(argument.scrollable) + if (argument.target instanceof View) { + (argument as any).target = viewIdChains(argument.target) + } + if (argument.changing.start instanceof Color) { + argument.changing.start = argument.changing.start.toModel() + } + if (argument.changing.end instanceof Color) { + argument.changing.end = argument.changing.end.toModel() + } + return context.callNative("coordinator", "verticalScrolling", argument) + } + } +} \ No newline at end of file diff --git a/doric-js/src/native/index.native.ts b/doric-js/src/native/index.native.ts index fe3e9235..1eb3af99 100644 --- a/doric-js/src/native/index.native.ts +++ b/doric-js/src/native/index.native.ts @@ -22,3 +22,4 @@ export * from './popover' export * from './animate' export * from './notification' export * from './statusbar' +export * from './coordinator'