TASK: #115114 - 小组件基类添加生命周期
This commit is contained in:
parent
e5b420c4d3
commit
bb5032f2ed
|
@ -35,6 +35,15 @@ class BatteryWidget extends GaiaWidget {
|
|||
this.charge = this._battery.charging
|
||||
this._battery.addEventListener('levelchange', this)
|
||||
this._battery.addEventListener('chargingchange', this)
|
||||
this.lifeCycle = 'initialized'
|
||||
}
|
||||
|
||||
run = async () => {
|
||||
if (this.lifeCycle == 'initializing') {
|
||||
await this.init()
|
||||
}
|
||||
this.percent = this._battery.level * 100
|
||||
this.charge = this._battery.charging
|
||||
}
|
||||
|
||||
handleEvent(event: Event): void {
|
||||
|
|
|
@ -40,14 +40,20 @@ class ClockWidget extends GaiaWidget {
|
|||
})
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
clock!: StarClock
|
||||
connectedCallback() {
|
||||
this.clock = this.shadowRoot!.querySelector('star-clock')!
|
||||
}
|
||||
|
||||
run = () => {
|
||||
if (!this.clock) this.clock = this.shadowRoot!.querySelector('star-clock')!
|
||||
this.clock.date = new Date()
|
||||
}
|
||||
|
||||
openActivity = (_: any): any => {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.clock.date = new Date()
|
||||
}
|
||||
|
|
|
@ -45,6 +45,15 @@ export default class GaiaWidget extends StarBaseElement {
|
|||
createTime: number = new Date().getTime()
|
||||
container!: HTMLElement
|
||||
activityRequestTimer: number | undefined
|
||||
lifeCycle!:
|
||||
| 'initializing'
|
||||
| 'initializition-failed'
|
||||
| 'initialized'
|
||||
| 'preparing'
|
||||
| 'running'
|
||||
| 'preparation-failed'
|
||||
// TODO: 补充activity失败原因
|
||||
status!: 'requesting' | 'idle' | 'activity-shut-down' | 'err'
|
||||
constructor({
|
||||
url,
|
||||
size,
|
||||
|
@ -70,35 +79,64 @@ export default class GaiaWidget extends StarBaseElement {
|
|||
this.attachShadow({mode: 'open'})
|
||||
this.shadowRoot!.innerHTML = this.template
|
||||
|
||||
this.lifeCycle = 'initializing'
|
||||
this.init()
|
||||
this.dispatchReady()
|
||||
}
|
||||
|
||||
init() {
|
||||
// 补全小组件入口地址
|
||||
if (!/^http(s)?:\/\//.test(this.url)) {
|
||||
if (/^\//.test(this.url)) {
|
||||
this.url = this.origin + this.url
|
||||
return new Promise((res, rej) => {
|
||||
if (this.lifeCycle == 'initializing') {
|
||||
// 补全小组件入口地址
|
||||
if (!/^http(s)?:\/\//.test(this.url)) {
|
||||
if (/^\//.test(this.url)) {
|
||||
this.url = this.origin + this.url
|
||||
} else {
|
||||
this.url = this.origin + '/' + this.url
|
||||
}
|
||||
}
|
||||
if (this.url.endsWith('html')) {
|
||||
this.container = this.shadowRoot!.querySelector(
|
||||
'#gaia-widget-container-' + this.createTime
|
||||
)!
|
||||
this.container.addEventListener('touchstart', this)
|
||||
this.container.addEventListener('touchmove', this)
|
||||
this.container.addEventListener('touchend', this)
|
||||
this.container.addEventListener('click', this)
|
||||
|
||||
// 需要在构造函数中被调用,在connectedCallback中调用会导致移动元素时刷新的问题
|
||||
this.querySources(this.url)
|
||||
.then(this.parseHTML)
|
||||
.then(() => {
|
||||
this.lifeCycle = 'initialized'
|
||||
res(undefined)
|
||||
})
|
||||
.catch((err) => {
|
||||
this.lifeCycle = 'initializition-failed'
|
||||
console.error(err)
|
||||
rej(err)
|
||||
})
|
||||
} else {
|
||||
this.lifeCycle = 'initialized'
|
||||
res(undefined)
|
||||
}
|
||||
} else {
|
||||
this.url = this.origin + '/' + this.url
|
||||
res(undefined)
|
||||
}
|
||||
}
|
||||
this.container = this.shadowRoot!.querySelector(
|
||||
'#gaia-widget-container-' + this.createTime
|
||||
)!
|
||||
this.container.addEventListener('touchstart', this)
|
||||
this.container.addEventListener('touchmove', this)
|
||||
this.container.addEventListener('touchend', this)
|
||||
this.container.addEventListener('click', this)
|
||||
})
|
||||
}
|
||||
|
||||
dispatchReady = () => {
|
||||
// 需要在构造函数中被调用,在connectedCallback中调用会导致移动元素时刷新的问题
|
||||
run = () => {
|
||||
this.lifeCycle = 'preparing'
|
||||
// 防止安装、更新应用时,首次 Activity 请求因注册方 Service Worker 未完成安装而丢失
|
||||
let n = 0
|
||||
this.activityRequestTimer = window.setInterval(() => {
|
||||
if (n++ > 4) clearInterval(this.activityRequestTimer)
|
||||
this.openActivity({data: {type: 'ready'}})
|
||||
if (n++ > 4) {
|
||||
clearInterval(this.activityRequestTimer)
|
||||
this.lifeCycle = 'preparation-failed'
|
||||
}
|
||||
this.openActivity({data: {type: 'ready'}}).then(
|
||||
() => (this.lifeCycle = 'running')
|
||||
)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
|
@ -164,23 +202,35 @@ export default class GaiaWidget extends StarBaseElement {
|
|||
}
|
||||
|
||||
openActivity = ({data}: any) => {
|
||||
data.widgetTitle = this.widgetTitle
|
||||
data.manifestName = this.manifestWidgetName
|
||||
data.viewName = this.viewName
|
||||
// TODO: 添加任务队列
|
||||
this.status = 'requesting'
|
||||
return new Promise((res, rej) => {
|
||||
data.widgetTitle = this.widgetTitle
|
||||
data.manifestName = this.manifestWidgetName
|
||||
data.viewName = this.viewName
|
||||
|
||||
// @ts-ignore
|
||||
const activity = new WebActivity(
|
||||
`${this.appName}_${this.manifestWidgetName}`,
|
||||
{data, type: ['widget']}
|
||||
)
|
||||
// @ts-ignore
|
||||
const activity = new WebActivity(
|
||||
`${this.appName}_${this.manifestWidgetName}`,
|
||||
{data, type: ['widget']}
|
||||
)
|
||||
|
||||
activity
|
||||
.start()
|
||||
.then((result: any) => {
|
||||
if (this.activityRequestTimer) clearInterval(this.activityRequestTimer)
|
||||
this.handleActivity(result)
|
||||
})
|
||||
.catch((err: any) => console.log(err))
|
||||
activity
|
||||
.start()
|
||||
.then((result: any) => {
|
||||
if (this.activityRequestTimer) {
|
||||
clearInterval(this.activityRequestTimer)
|
||||
}
|
||||
this.handleActivity(result)
|
||||
this.status = 'idle'
|
||||
res(result)
|
||||
})
|
||||
.catch((err: any) => {
|
||||
console.log(err)
|
||||
this.status = 'err'
|
||||
rej(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
wrapEvent = (event: any) => {
|
||||
|
@ -206,7 +256,7 @@ export default class GaiaWidget extends StarBaseElement {
|
|||
/**
|
||||
* 请求组件资源
|
||||
*/
|
||||
querySources(url: string) {
|
||||
querySources(url: string): Promise<string> {
|
||||
return new Promise((res, rej) => {
|
||||
// @ts-ignore
|
||||
const xhr = new XMLHttpRequest({mozSystem: true})
|
||||
|
@ -240,21 +290,24 @@ export default class GaiaWidget extends StarBaseElement {
|
|||
* @param {DOMString} html 文档字符串
|
||||
* @returns
|
||||
*/
|
||||
parseHTML = (html: string) => {
|
||||
html = this.handleSource(this.filterDom(html))
|
||||
parseHTML = (html?: string) => {
|
||||
return new Promise((res, rej) => {
|
||||
if (!html) return rej()
|
||||
html = this.handleSource(this.filterDom(html))
|
||||
|
||||
const parse = new DOMParser()
|
||||
const htmlDocument = parse.parseFromString(html, 'text/html')
|
||||
const {head, body} = htmlDocument
|
||||
// @ts-ignore
|
||||
this.widgetTitle = head?.querySelector('title').innerHTML
|
||||
if (this.widgetTitle === void 0) {
|
||||
throw new Error('There is not a widget name yet!')
|
||||
}
|
||||
const parse = new DOMParser()
|
||||
const htmlDocument = parse.parseFromString(html, 'text/html')
|
||||
const {head, body} = htmlDocument
|
||||
// @ts-ignore
|
||||
this.widgetTitle = head?.querySelector('title').innerHTML
|
||||
if (this.widgetTitle === void 0) {
|
||||
throw rej(new Error('There is not a widget name yet!'))
|
||||
}
|
||||
|
||||
this.appendStyle(htmlDocument)
|
||||
this.container.innerHTML = body.innerHTML
|
||||
return Promise.resolve()
|
||||
this.appendStyle(htmlDocument)
|
||||
this.container.innerHTML = body.innerHTML
|
||||
res(undefined)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue