Telegram Web K with changes to work inside I2P
https://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
4.0 KiB
133 lines
4.0 KiB
/* |
|
* https://github.com/morethanwords/tweb |
|
* Copyright (C) 2019-2021 Eduard Kuzmenko |
|
* https://github.com/morethanwords/tweb/blob/master/LICENSE |
|
*/ |
|
|
|
import noop from '../helpers/noop'; |
|
import safeAssign from '../helpers/object/safeAssign'; |
|
import {LottieAssetName} from '../lib/rlottie/lottieLoader'; |
|
import RLottieIcon, {RLottieIconItemPartOptions, RLottieIconItemPart} from '../lib/rlottie/rlottieIcon'; |
|
import {RLottieColor} from '../lib/rlottie/rlottiePlayer'; |
|
|
|
export type SuperRLottieIconAddItemOptions = {name: LottieAssetName, parts: RLottieIconItemPartOptions}; |
|
export type SuperRLottieIconGetInfoResult = RLottieIconItemPart; |
|
export class SuperRLottieIcon<Options extends { |
|
PartState: any, |
|
ColorState?: any, |
|
Items?: { |
|
name: string |
|
}[] |
|
}> extends RLottieIcon { |
|
protected getPart: (state: Options['PartState'], prevState?: Options['PartState']) => SuperRLottieIconGetInfoResult; |
|
protected getColor?: (state: Options['ColorState'], prevState?: Options['ColorState']) => RLottieColor; |
|
|
|
protected partState: Options['PartState']; |
|
protected colorState: Options['ColorState']; |
|
protected loaded: boolean; |
|
|
|
constructor(options: { |
|
width: number, |
|
height: number, |
|
skipAnimation?: boolean, |
|
getPart: (state: Options['PartState'], prevState?: Options['PartState']) => SuperRLottieIconGetInfoResult, |
|
getColor?: (state: Options['ColorState'], prevState?: Options['ColorState']) => RLottieColor, |
|
}) { |
|
super({ |
|
width: options.width, |
|
height: options.height |
|
}); |
|
|
|
safeAssign(this, options); |
|
|
|
// hook the first call |
|
/* const originalFunction = this.setState.bind(this); |
|
this.setState = (partState, colorState) => { |
|
this.setState = originalFunction; |
|
this.load(partState, colorState); |
|
return originalFunction(partState, colorState); |
|
}; */ |
|
} |
|
|
|
public load(partState: Options['PartState'], colorState?: Options['ColorState']) { |
|
if(this.loaded) { |
|
return this.loadPromise; |
|
} |
|
|
|
this.loaded = true; |
|
this.partState = partState; |
|
this.colorState = colorState; |
|
|
|
const part = this.getPart(partState); |
|
const color = colorState !== undefined && this.getColor && this.getColor(colorState); |
|
|
|
const item = part.item; |
|
item.initFrame = part.endFrame; |
|
item.color = color; |
|
|
|
const promises = [...this.items.values()].map((item) => item.load()); |
|
return Promise.all(promises).then(noop); |
|
} |
|
|
|
/** |
|
* Will redirect setting color state to part callback to synchronize the rendering |
|
*/ |
|
public setState(partState: Options['PartState'], colorState?: Options['ColorState'], partCallback?: () => void) { |
|
if(!this.loaded) this.load(partState, colorState); |
|
|
|
let changedPartState = false, changedColorState = false; |
|
if(partState !== undefined) changedPartState = this.setPartState(partState, colorState, partCallback); |
|
else if(colorState !== undefined) changedColorState = this.setColorState(colorState); |
|
|
|
return changedPartState || changedColorState; |
|
} |
|
|
|
public setPartState(state: Options['PartState'], colorState?: Options['ColorState'], callback?: () => void) { |
|
const {partState: prevState} = this; |
|
if(prevState === state) { |
|
return colorState !== undefined ? this.setColorState(colorState) : false; |
|
} |
|
|
|
if(colorState !== undefined) { |
|
this.setColorState(colorState, false); |
|
} |
|
|
|
this.partState = state; |
|
|
|
const part = this.getPart(state, prevState); |
|
part.play(callback); |
|
|
|
return true; |
|
} |
|
|
|
public setColorState(state: Options['ColorState'], renderIfPaused = true) { |
|
const {colorState: prevState} = this; |
|
if(prevState === state || !this.getColor) { |
|
return false; |
|
} |
|
|
|
this.colorState = state; |
|
|
|
const item = this.getItem(); |
|
const color = this.getColor(state, prevState); |
|
const invoke = () => { |
|
item.player.setColor(color, renderIfPaused); |
|
}; |
|
|
|
if(item.player) { |
|
invoke(); |
|
} else { |
|
item.onLoadForColor = invoke; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public destroy() { |
|
this.items.forEach((item) => { |
|
item.loadPromise.then(() => { |
|
item.player.remove(); |
|
}); |
|
}); |
|
} |
|
}
|
|
|