From 0b3e3b353416231618baeb1db5d8d5d720b6209d Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Thu, 21 Jan 2021 16:34:04 -0300 Subject: [PATCH] feat: reusable views --- apps/ui/src/issues/issue-7469-page.css | 15 ++ apps/ui/src/issues/issue-7469-page.ts | 158 +++++++++++++++++++++ apps/ui/src/issues/issue-7469-page.xml | 37 +++++ apps/ui/src/issues/main-page.ts | 1 + packages/core/ui/core/view-base/index.d.ts | 13 ++ packages/core/ui/core/view-base/index.ts | 105 ++++++++------ 6 files changed, 289 insertions(+), 40 deletions(-) create mode 100644 apps/ui/src/issues/issue-7469-page.css create mode 100644 apps/ui/src/issues/issue-7469-page.ts create mode 100644 apps/ui/src/issues/issue-7469-page.xml diff --git a/apps/ui/src/issues/issue-7469-page.css b/apps/ui/src/issues/issue-7469-page.css new file mode 100644 index 0000000000..dd2685f0d8 --- /dev/null +++ b/apps/ui/src/issues/issue-7469-page.css @@ -0,0 +1,15 @@ +.test-label { + padding: 10; + background-color: black; + color: white; + } + + .stack1 { + background-color: green; + color: white; + } + + .stack2 { + background-color: blue; + color: red; + } \ No newline at end of file diff --git a/apps/ui/src/issues/issue-7469-page.ts b/apps/ui/src/issues/issue-7469-page.ts new file mode 100644 index 0000000000..eca14bb6a4 --- /dev/null +++ b/apps/ui/src/issues/issue-7469-page.ts @@ -0,0 +1,158 @@ +import { EventData, Label, StackLayout } from '@nativescript/core'; +import { addCallback, removeCallback, start, stop } from '@nativescript/core/fps-meter'; + +let callbackId; +let fpsLabel: any; +export function startFPSMeter() { + callbackId = addCallback((fps: number, minFps: number) => { + // console.log(`Frames per seconds: ${fps.toFixed(2)}`); + // console.log(minFps.toFixed(2)); + if (fpsLabel) { + fpsLabel.text = `${fps}`; + } + }); + start(); +} + +export function stopFPSMeter() { + removeCallback(callbackId); + stop(); +} + +let timeouts = []; +let intervals = []; + +let reusableItem; +let vcToggle; +let loaded = false; +let isIn1 = false; + +function updateVcToggleText() { + vcToggle.text = `Container is${reusableItem.reusable ? ' ' : ' NOT '}Reusable` +} + +export function pageLoaded(args) { + startFPSMeter(); + if (loaded) { + fpsLabel = null; + // stopFPSMeter(); + timeouts.forEach((v) => clearTimeout(v)); + intervals.forEach((v) => clearInterval(v)); + reusableItem._tearDownUI(true); + } + loaded = true; + reusableItem = args.object.getViewById('reusableItem'); + vcToggle = args.object.getViewById('vcToggle'); + updateVcToggleText(); + fpsLabel = args.object.getViewById('fpslabel'); + const stack1: StackLayout = args.object.getViewById('stack1'); + const stack2: StackLayout = args.object.getViewById('stack2'); + setTimeout(() => { + // label.android.setTextColor(new Color("red").android); + // label.android.setBackgroundColor(new Color("red").android); + startFPSMeter(); + console.log('setRed'); + }, 1000); + // console.log(label._context); + // isIn1 = false; + // timeouts.push(setTimeout(() => { + // intervals.push(setInterval(() => { + // label.parent.removeChild(label); + // // console.log(label.nativeView); + // if(isIn1) { + // isIn1 = false; + // stack2.addChild(label); + // } else { + // isIn1 = true; + // stack1.addChild(label); + // } + // }, 10)); + // }, 1001)); +} + +export function pageUnloaded(args) { + // +} + +export function makeReusable(args: EventData) { + console.log('loaded:', args.object); + // console.log("making reusable"); + if ((args.object as any).___reusableRan) { + return; + } + (args.object as any).___reusableRan = true; + (args.object as any).reusable = true; + if(args.object === reusableItem) { + updateVcToggleText(); + } +} + +export function onReusableUnloaded(args: EventData) { + console.log('unloaded:', args.object); +} +var testLabel: Label; + +export function test(args: any) { + const page = args.object.page; + reusableItem = page.getViewById('reusableItem'); + const stack1: StackLayout = page.getViewById('stack1'); + const stack2: StackLayout = page.getViewById('stack2'); + if (!testLabel) { + testLabel = new Label(); + testLabel.text = 'This label is not reusable and is dynamic'; + testLabel.on('loaded', () => { + console.log('LODADED testLabel'); + }); + testLabel.on('unloaded', () => { + console.log('UNLODADED testLabel'); + }); + } + reusableItem.parent.removeChild(reusableItem); + if (!reusableItem._suspendNativeUpdatesCount) { + console.log('reusableItem SHOULD BE UNLOADED'); + } + if (!testLabel._suspendNativeUpdatesCount) { + console.log('testLabel SHOULD BE UNLOADED'); + } + if (!testLabel.parent) { + reusableItem.addChild(testLabel); + } + if (!testLabel.nativeView) { + console.log('testLabel NATIVE VIEW SHOULD BE CREATED'); + } + if (!testLabel._suspendNativeUpdatesCount) { + console.log('testLabel SHOULD BE UNLOADED'); + } + if (isIn1) { + isIn1 = false; + stack2.addChild(reusableItem); + } else { + isIn1 = true; + stack1.addChild(reusableItem); + } + if (reusableItem._suspendNativeUpdatesCount) { + console.log('reusableItem SHOULD BE LOADED AND RECEIVING UPDATES'); + } + if (testLabel._suspendNativeUpdatesCount) { + console.log('testLabel SHOULD BE LOADED AND RECEIVING UPDATES'); + } + // console.log("onTap"); + // alert("onTap"); +} +let ignoreInput = false; + +export function toggleReusable(args: EventData) { + if (ignoreInput) { + return; + } + ignoreInput = true; + setTimeout(() => (ignoreInput = false), 0); // hack to avoid gesture collision + const target: any = args.object; + target.reusable = !target.reusable; + console.log(`${target} is now ${target.reusable ? '' : 'NOT '}reusable`); +} + +export function toggleVCReusable() { + reusableItem.reusable = !reusableItem.reusable; + updateVcToggleText(); +} diff --git a/apps/ui/src/issues/issue-7469-page.xml b/apps/ui/src/issues/issue-7469-page.xml new file mode 100644 index 0000000000..ed1797c682 --- /dev/null +++ b/apps/ui/src/issues/issue-7469-page.xml @@ -0,0 +1,37 @@ + + +