This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/doric-web/src/shader/DoricRefreshableNode.ts

199 lines
7.1 KiB
TypeScript
Raw Normal View History

2021-04-15 11:35:58 +08:00
import { DoricSuperNode, DoricViewNode, DVModel } from "./DoricViewNode";
2019-12-28 14:25:03 +08:00
export class DoricRefreshableNode extends DoricSuperNode {
2021-04-15 11:35:58 +08:00
headerViewId = ""
headerNode?: DoricViewNode
2019-12-28 14:25:03 +08:00
2021-04-15 11:35:58 +08:00
contentViewId = ""
contentNode?: DoricViewNode
onRefreshCallback?: Function
headerContainer?: HTMLDivElement
contentContainer?: HTMLDivElement
2021-04-15 18:34:06 +08:00
refreshable = true
2019-12-28 14:25:03 +08:00
build() {
const ret = document.createElement('div')
2021-04-15 11:35:58 +08:00
ret.style.overflow = "hidden"
2021-04-14 17:46:58 +08:00
const header = document.createElement('div')
const content = document.createElement('div')
header.style.width = "100%"
2021-04-15 15:51:24 +08:00
header.style.height = "100%"
header.style.display = "flex"
header.style.alignItems = "flex-end"
header.style.justifyContent = "center"
2021-04-14 17:46:58 +08:00
content.style.width = "100%"
content.style.height = "100%"
ret.appendChild(header)
ret.appendChild(content)
2021-04-15 11:35:58 +08:00
let touchStart = 0
ret.ontouchstart = (ev) => {
2021-04-15 18:34:06 +08:00
if (!this.refreshable) {
return
}
2021-04-15 11:35:58 +08:00
touchStart = ev.touches[0].pageY
}
ret.ontouchmove = (ev) => {
2021-04-15 18:34:06 +08:00
if (!this.refreshable) {
return
}
2021-04-16 13:20:03 +08:00
const offset = (ev.touches[0].pageY - touchStart) * 0.68
ret.scrollTop = Math.max(0, header.offsetHeight - offset)
this.headerNode?.callJSResponse("setPullingDistance", offset)
2021-04-15 18:34:06 +08:00
}
const touchend = () => {
if (!this.refreshable) {
return
}
if (header.offsetHeight - ret.scrollTop >= (this.headerNode?.getWidth() || 0)) {
this.setRefreshing(true)
this.onRefreshCallback?.()
} else {
// To idel
ret.scrollTo({
top: header.offsetHeight,
behavior: "smooth"
})
}
2021-04-15 11:35:58 +08:00
}
ret.ontouchcancel = () => {
2021-04-15 18:34:06 +08:00
touchend()
2021-04-15 11:35:58 +08:00
}
ret.ontouchend = () => {
2021-04-15 18:34:06 +08:00
touchend()
2021-04-15 11:35:58 +08:00
}
window.requestAnimationFrame(() => {
ret.scrollTop = header.offsetHeight
2021-04-14 17:46:58 +08:00
})
2021-04-15 11:35:58 +08:00
this.headerContainer = header
this.contentContainer = content
2019-12-28 14:25:03 +08:00
return ret
}
2021-04-15 11:35:58 +08:00
blendProps(v: HTMLElement, propName: string, prop: any) {
if (propName === 'content') {
this.contentViewId = prop
} else if (propName === 'header') {
this.headerViewId = prop
} else if (propName === 'onRefresh') {
this.onRefreshCallback = () => {
this.callJSResponse(prop)
}
} else {
super.blendProps(v, propName, prop)
}
}
blendSubNode(model: DVModel) {
this.getSubNodeById(model.id)?.blend(model.props)
}
getSubNodeById(viewId: string) {
if (viewId === this.headerViewId) {
return this.headerNode
} else if (viewId === this.contentViewId) {
return this.contentNode
}
return undefined
}
onBlending() {
super.onBlending()
{
const headerModel = this.getSubModel(this.headerViewId)
if (headerModel) {
if (this.headerNode) {
if (this.headerNode.viewId !== this.headerViewId) {
if (this.reusable && this.headerNode.viewType === headerModel.type) {
this.headerNode.viewId = headerModel.id
this.headerNode.blend(headerModel.props)
} else {
this.headerContainer?.removeChild(this.headerNode.view)
const headerNode = DoricViewNode.create(this.context, headerModel.type)
if (headerNode) {
headerNode.viewId = headerModel.id
headerNode.init(this)
headerNode.blend(headerModel.props)
this.headerContainer?.appendChild(headerNode.view)
this.headerNode = headerNode
}
}
}
} else {
const headerNode = DoricViewNode.create(this.context, headerModel.type)
if (headerNode) {
headerNode.viewId = headerModel.id
headerNode.init(this)
headerNode.blend(headerModel.props)
this.headerContainer?.appendChild(headerNode.view)
this.headerNode = headerNode
}
}
}
}
{
const contentModel = this.getSubModel(this.contentViewId)
if (contentModel) {
if (this.contentNode) {
if (this.contentNode.viewId !== this.contentViewId) {
if (this.reusable && this.contentNode.viewType === contentModel.type) {
this.contentNode.viewId = contentModel.id
this.contentNode.blend(contentModel.props)
} else {
this.contentContainer?.removeChild(this.contentNode.view)
const contentNode = DoricViewNode.create(this.context, contentModel.type)
if (contentNode) {
contentNode.viewId = contentModel.id
contentNode.init(this)
contentNode.blend(contentModel.props)
this.contentContainer?.appendChild(contentNode.view)
this.contentNode = contentNode
}
}
}
} else {
const contentNode = DoricViewNode.create(this.context, contentModel.type)
if (contentNode) {
contentNode.viewId = contentModel.id
contentNode.init(this)
contentNode.blend(contentModel.props)
this.contentContainer?.appendChild(contentNode.view)
this.contentNode = contentNode
}
}
}
}
}
onBlended() {
super.onBlended()
}
2021-04-15 15:51:24 +08:00
setRefreshing(v: boolean) {
if (!this.headerContainer || !this.headerNode) {
return
}
if (v) {
this.view.scrollTo({
top: this.headerContainer.offsetHeight - this.headerNode.getHeight(),
behavior: "smooth"
})
2021-04-16 13:20:03 +08:00
this.headerNode.callJSResponse("startAnimation")
2021-04-15 15:51:24 +08:00
} else {
this.view.scrollTo({
top: this.headerContainer?.offsetHeight,
behavior: "smooth"
})
2021-04-16 13:20:03 +08:00
this.headerNode.callJSResponse("stopAnimation")
2021-04-15 15:51:24 +08:00
}
}
setRefreshable(v: boolean) {
2021-04-15 18:34:06 +08:00
this.refreshable = v
if (!v) {
this.setRefreshing(false)
}
2021-04-15 15:51:24 +08:00
}
2019-12-28 14:25:03 +08:00
}