Merge pull request #319 from AlphaX-Projects/master
Fix gif not display before 100% loaded
This commit is contained in:
commit
c828df6775
230
plugins/plugins/core/components/ChatImageGif.js
Normal file
230
plugins/plugins/core/components/ChatImageGif.js
Normal file
@ -0,0 +1,230 @@
|
||||
import { html, LitElement } from 'lit'
|
||||
import { Epml } from '../../../epml'
|
||||
import { RequestQueueWithPromise } from '../../utils/classes'
|
||||
import { chatImageStyles } from './plugins-css'
|
||||
import axios from 'axios'
|
||||
|
||||
// Multi language support
|
||||
import { get, translate } from '../../../../core/translate'
|
||||
|
||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
||||
|
||||
const requestQueue = new RequestQueueWithPromise(5)
|
||||
|
||||
export class ChatImageGif extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
resource: { type: Object },
|
||||
isReady: { type: Boolean },
|
||||
status: { type: Object },
|
||||
setOpenDialogGif: { attribute: false }
|
||||
}
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [chatImageStyles]
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.resource = {
|
||||
identifier: '',
|
||||
name: '',
|
||||
service: ''
|
||||
}
|
||||
this.status = {
|
||||
status: ''
|
||||
}
|
||||
this.url = ''
|
||||
this.isReady = false
|
||||
this.nodeUrl = this.getNodeUrl()
|
||||
this.myNode = this.getMyNode()
|
||||
this.hasCalledWhenDownloaded = false
|
||||
this.isFetching = false
|
||||
this.observer = new IntersectionObserver(entries => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting && this.status.status !== 'READY') {
|
||||
this.fetchGif()
|
||||
this.observer.unobserve(this)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return html`
|
||||
<div class=${[`image-container`, this.status.status !== 'READY' ? 'defaultSize' : '', this.status.status !== 'READY' ? 'hideImg' : '',].join(' ')}>
|
||||
${this.status.status !== 'READY' ?
|
||||
html`
|
||||
<div style="display: flex; flex-direction: column; width:100%; height: 100%; justify-content: center; align-items: center; position: absolute;">
|
||||
<div class=${`smallLoading`}></div>
|
||||
<p style="color: var(--black)">${`${Math.round(this.status.percentLoaded || 0).toFixed(0)}% `}${translate('chatpage.cchange94')}</p>
|
||||
</div>
|
||||
`
|
||||
: ''
|
||||
}
|
||||
${this.status.status === 'READY' ?
|
||||
html`
|
||||
${this.createGif(this.url)}
|
||||
`
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.observer.observe(this)
|
||||
}
|
||||
|
||||
createGif(gif) {
|
||||
const gifHTMLRes = new Image()
|
||||
gifHTMLRes.src = gif
|
||||
gifHTMLRes.style = 'max-width:45vh; max-height:40vh; border-radius: 5px; cursor: pointer;'
|
||||
gifHTMLRes.onclick = () => {this.setOpenDialogGif(true);}
|
||||
gifHTMLRes.onload = () => {this.isGifLoaded = true;}
|
||||
gifHTMLRes.onerror = () => {
|
||||
if (this.gifFetches < 4) {
|
||||
setTimeout(() => {
|
||||
this.gifFetches = this.gifFetches + 1
|
||||
gifHTMLRes.src = gif
|
||||
}, 10000)
|
||||
} else {
|
||||
gifHTMLRes.src = '/img/chain.png'
|
||||
gifHTMLRes.style = 'max-width:45vh; max-height:20vh; border-radius: 5px; filter: opacity(0.5);'
|
||||
gifHTMLRes.onclick = () => {}
|
||||
this.isGifLoaded = true
|
||||
}
|
||||
}
|
||||
return gifHTMLRes
|
||||
}
|
||||
|
||||
getNodeUrl() {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||
return nodeUrl
|
||||
}
|
||||
|
||||
getMyNode() {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
return myNode
|
||||
}
|
||||
|
||||
async fetchResource() {
|
||||
try {
|
||||
if (this.isFetching) return
|
||||
this.isFetching = true
|
||||
await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}`)
|
||||
this.isFetching = false
|
||||
} catch (error) {
|
||||
this.isFetching = false
|
||||
}
|
||||
}
|
||||
|
||||
async fetchGifUrl() {
|
||||
this.fetchResource()
|
||||
this.url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?async=true`
|
||||
}
|
||||
|
||||
async fetchStatus() {
|
||||
let isCalling = false
|
||||
let percentLoaded = 0
|
||||
let timer = 24
|
||||
|
||||
const response = await axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}`)
|
||||
|
||||
if (response && response.data && response.data.status === 'READY') {
|
||||
this.status = response.data
|
||||
return
|
||||
}
|
||||
|
||||
const intervalId = setInterval(async () => {
|
||||
if (isCalling) return
|
||||
|
||||
isCalling = true
|
||||
|
||||
const data = await requestQueue.enqueue(() => {
|
||||
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}`)
|
||||
})
|
||||
|
||||
const res = data.data
|
||||
|
||||
isCalling = false
|
||||
|
||||
if (res.localChunkCount) {
|
||||
if (res.percentLoaded) {
|
||||
if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) {
|
||||
timer = timer - 5
|
||||
} else {
|
||||
timer = 24
|
||||
}
|
||||
|
||||
if (timer < 0) {
|
||||
timer = 24
|
||||
|
||||
isCalling = true
|
||||
|
||||
this.status = {
|
||||
...res,
|
||||
status: 'REFETCHING'
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
isCalling = false
|
||||
this.fetchResource()
|
||||
}, 25000)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
percentLoaded = res.percentLoaded
|
||||
}
|
||||
|
||||
this.status = res
|
||||
|
||||
if (this.status.status === 'DOWNLOADED') {
|
||||
this.fetchResource()
|
||||
}
|
||||
}
|
||||
|
||||
// check if progress is 100% and clear interval if true
|
||||
if (res.status === 'READY') {
|
||||
clearInterval(intervalId)
|
||||
this.status = res
|
||||
this.isReady = true
|
||||
}
|
||||
}, 5000) // 5 second interval
|
||||
}
|
||||
|
||||
async fetchGif() {
|
||||
try {
|
||||
this.fetchGifUrl({name: this.resource.name, service: this.resource.service, identifier: this.resource.identifier})
|
||||
this.fetchStatus()
|
||||
} catch (error) { /* empty */ }
|
||||
}
|
||||
|
||||
shouldUpdate(changedProperties) {
|
||||
if (changedProperties.has('setOpenDialogGif') && changedProperties.size === 1) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Standard functions
|
||||
getApiKey() {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
return myNode.apiKey
|
||||
}
|
||||
|
||||
isEmptyArray(arr) {
|
||||
if (!arr) { return true }
|
||||
return arr.length === 0
|
||||
}
|
||||
|
||||
round(number) {
|
||||
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('chat-image-gif', ChatImageGif)
|
@ -18,6 +18,7 @@ import './NameMenu'
|
||||
import './UserInfo'
|
||||
import './WrapperModal'
|
||||
import './ChatImage'
|
||||
import './ChatImageGif'
|
||||
import '@material/mwc-button'
|
||||
import '@material/mwc-dialog'
|
||||
import '@material/mwc-icon'
|
||||
@ -1118,15 +1119,6 @@ class MessageTemplate extends LitElement {
|
||||
|
||||
levelFounder = html`<level-founder checkleveladdress="${this.messageObj.sender}"></level-founder>`
|
||||
|
||||
if (this.messageObj.senderName) {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||
const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.messageObj.senderName}/qortal_avatar?async=true`
|
||||
avatarImg = html`<img src="${avatarUrl}" style="max-width:100%; max-height:100%;" onerror="this.onerror=null; this.src='/img/incognito.png';" />`
|
||||
} else {
|
||||
avatarImg = html`<img src="/img/incognito.png" style="max-width:100%; max-height:100%;" onerror="this.onerror=null;" />`
|
||||
}
|
||||
|
||||
const createGif = (gif) => {
|
||||
const gifHTMLRes = new Image()
|
||||
gifHTMLRes.src = gif
|
||||
@ -1149,6 +1141,15 @@ class MessageTemplate extends LitElement {
|
||||
return gifHTMLRes
|
||||
}
|
||||
|
||||
if (this.messageObj.senderName) {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||
const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.messageObj.senderName}/qortal_avatar?async=true`
|
||||
avatarImg = html`<img src="${avatarUrl}" style="max-width:100%; max-height:100%;" onerror="this.onerror=null; this.src='/img/incognito.png';" />`
|
||||
} else {
|
||||
avatarImg = html`<img src="/img/incognito.png" style="max-width:100%; max-height:100%;" onerror="this.onerror=null;" />`
|
||||
}
|
||||
|
||||
if (image) {
|
||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||
@ -1157,7 +1158,7 @@ class MessageTemplate extends LitElement {
|
||||
imageHTML = html`
|
||||
<chat-image
|
||||
.resource=${{name: image.name, service: image.service, identifier: image.identifier}}
|
||||
.setOpenDialogImage=${(val)=> this.setOpenDialogImage(val)}
|
||||
.setOpenDialogImage=${(val) => this.setOpenDialogImage(val)}
|
||||
>
|
||||
</chat-image>
|
||||
`
|
||||
@ -1169,7 +1170,13 @@ class MessageTemplate extends LitElement {
|
||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||
gifUrl = `${nodeUrl}/arbitrary/${gif.service}/${gif.name}/${gif.identifier}?async=true`
|
||||
if (this.viewImage || this.myAddress === this.messageObj.sender) {
|
||||
gifHTML = createGif(gifUrl)
|
||||
gifHTML = html`
|
||||
<chat-image-gif
|
||||
.resource=${{name: gif.name, service: gif.service, identifier: gif.identifier}}
|
||||
.setOpenDialogGif=${(val) => this.setOpenDialogGif(val)}
|
||||
>
|
||||
</chat-image-gif>
|
||||
`
|
||||
gifHTMLDialog = createGif(gifUrl)
|
||||
gifHTMLDialog.style = 'height: auto; max-height: 80vh; width: auto; max-width: 80vw; object-fit: contain; border-radius: 5px;'
|
||||
}
|
||||
@ -1612,7 +1619,7 @@ class MessageTemplate extends LitElement {
|
||||
<mwc-dialog id="showDialogPublicKey" ?open=${this.openDialogImage} @closed=${() => {this.openDialogImage = false;}}>
|
||||
<div class="dialog-header"></div>
|
||||
<div class="dialog-container imageContainer">
|
||||
${this.openDialogImage ? html`<img src=${imageUrl} style="height: auto; max-height: 80vh; width: auto; max-width: 80vw; object-fit: contain; border-radius: 5px;"/>` : ''}
|
||||
${this.openDialogImage ? html`<img src=${imageUrl} style="height: auto; max-height: 80vh; width: auto; max-width: 80vw; object-fit: contain; border-radius: 5px;">` : ''}
|
||||
</div>
|
||||
<mwc-button slot="primaryAction" dialogAction="cancel" class="red" @click=${() => {this.openDialogImage = false;}}>
|
||||
${translate('general.close')}
|
||||
@ -1875,6 +1882,10 @@ class MessageTemplate extends LitElement {
|
||||
this.openDialogImage = val
|
||||
}
|
||||
|
||||
setOpenDialogGif(val) {
|
||||
this.openDialogGif = val
|
||||
}
|
||||
|
||||
shouldUpdate(changedProperties) {
|
||||
if (changedProperties.has('messageObj')) {
|
||||
return true
|
||||
|
Loading…
x
Reference in New Issue
Block a user