2019-12-04 14:15:05 +08:00
|
|
|
import { Superview, View, Property, IView } from "../ui/view";
|
|
|
|
import { Stack } from "./layouts";
|
|
|
|
import { layoutConfig } from "../util/layoutconfig";
|
2019-12-06 15:45:53 +08:00
|
|
|
import { BridgeContext } from "../runtime/global";
|
2019-12-04 14:15:05 +08:00
|
|
|
|
|
|
|
export class SlideItem extends Stack {
|
|
|
|
/**
|
|
|
|
* Set to reuse native view
|
|
|
|
*/
|
|
|
|
@Property
|
|
|
|
identifier?: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface ISlider extends IView {
|
|
|
|
renderPage: (index: number) => SlideItem
|
|
|
|
itemCount: number
|
|
|
|
batchCount?: number
|
2019-12-06 15:45:53 +08:00
|
|
|
onPageSlided?: (index: number) => void
|
2019-12-04 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Slider extends Superview implements ISlider {
|
|
|
|
private cachedViews: Map<string, SlideItem> = new Map
|
|
|
|
|
|
|
|
private ignoreDirtyCallOnce = false
|
|
|
|
|
|
|
|
allSubviews() {
|
|
|
|
return this.cachedViews.values()
|
|
|
|
}
|
|
|
|
@Property
|
|
|
|
itemCount = 0
|
|
|
|
|
|
|
|
@Property
|
|
|
|
renderPage!: (index: number) => SlideItem
|
|
|
|
|
|
|
|
@Property
|
|
|
|
batchCount = 3
|
|
|
|
|
2019-12-06 15:45:53 +08:00
|
|
|
@Property
|
|
|
|
onPageSlided?: (index: number) => void
|
2019-12-04 14:15:05 +08:00
|
|
|
|
|
|
|
private getItem(itemIdx: number) {
|
|
|
|
let view = this.cachedViews.get(`${itemIdx}`)
|
|
|
|
if (view === undefined) {
|
|
|
|
view = this.renderPage(itemIdx)
|
|
|
|
view.superview = this
|
|
|
|
this.cachedViews.set(`${itemIdx}`, view)
|
|
|
|
}
|
|
|
|
return view
|
|
|
|
}
|
|
|
|
|
|
|
|
isDirty() {
|
|
|
|
if (this.ignoreDirtyCallOnce) {
|
|
|
|
this.ignoreDirtyCallOnce = false
|
|
|
|
//Ignore the dirty call once.
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return super.isDirty()
|
|
|
|
}
|
|
|
|
|
|
|
|
private renderBunchedItems(start: number, length: number) {
|
|
|
|
this.ignoreDirtyCallOnce = true;
|
|
|
|
return new Array(Math.min(length, this.itemCount - start)).fill(0).map((_, idx) => {
|
|
|
|
const slideItem = this.getItem(start + idx)
|
|
|
|
return slideItem.toModel()
|
|
|
|
})
|
|
|
|
}
|
2019-12-06 15:45:53 +08:00
|
|
|
|
|
|
|
slidePage(context: BridgeContext, page: number, smooth = false) {
|
2019-12-06 15:53:31 +08:00
|
|
|
return this.nativeChannel(context, "slidePage")({ page, smooth })
|
2019-12-06 15:45:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getSlidedPage(context: BridgeContext) {
|
2019-12-06 15:53:31 +08:00
|
|
|
return this.nativeChannel(context, "getSlidedPage")() as Promise<number>
|
2019-12-06 15:45:53 +08:00
|
|
|
}
|
|
|
|
|
2019-12-04 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export function slideItem(item: View) {
|
|
|
|
return (new SlideItem).also((it) => {
|
|
|
|
it.layoutConfig = layoutConfig().wrap()
|
|
|
|
it.addChild(item)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export function slider(config: ISlider) {
|
|
|
|
const ret = new Slider
|
|
|
|
for (let key in config) {
|
|
|
|
Reflect.set(ret, key, Reflect.get(config, key, config), ret)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|