feature: add snackbar for display the downloading gcode file and option to cancel it
Signed-off-by: Stefan Dej <meteyou@gmail.com>
This commit is contained in:
parent
1c1ce285bd
commit
2c38aad7fd
@ -88,13 +88,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<v-progress-linear class="mt-2" :value="loadingPercent"></v-progress-linear>
|
<v-progress-linear class="mt-2" :value="loadingPercent"></v-progress-linear>
|
||||||
<template v-slot:action="{ attrs }">
|
<template v-slot:action="{ attrs }">
|
||||||
<v-btn
|
<v-btn color="red" text v-bind="attrs" style="min-width: auto;" @click="cancelRendering()">
|
||||||
color="red"
|
<v-icon class="0">mdi-close</v-icon>
|
||||||
text
|
</v-btn>
|
||||||
v-bind="attrs"
|
</template>
|
||||||
style="min-width: auto;"
|
</v-snackbar>
|
||||||
@click="cancelRendering()"
|
<v-snackbar v-model="downloadSnackbar.status" :timeout="-1" :value="true" fixed right bottom dark>
|
||||||
>
|
<div>
|
||||||
|
{{ $t('GCodeViewer.Downloading') }} - {{ Math.round(downloadSnackbar.percent) }} % @ {{ formatFilesize(Math.round(downloadSnackbar.speed)) }}/s<br />
|
||||||
|
<strong>{{ downloadSnackbar.filename }}</strong>
|
||||||
|
</div>
|
||||||
|
<v-progress-linear class="mt-2" :value="downloadSnackbar.percent"></v-progress-linear>
|
||||||
|
<template v-slot:action="{ attrs }">
|
||||||
|
<v-btn color="red" text v-bind="attrs" @click="cancelDownload" style="min-width: auto;" >
|
||||||
<v-icon class="0">mdi-close</v-icon>
|
<v-icon class="0">mdi-close</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
@ -108,11 +114,27 @@ import BaseMixin from '../mixins/base'
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import GCodeViewer from '@sindarius/gcodeviewer'
|
import GCodeViewer from '@sindarius/gcodeviewer'
|
||||||
import {Debounce} from 'vue-debounce-decorator'
|
import {Debounce} from 'vue-debounce-decorator'
|
||||||
|
import axios from 'axios'
|
||||||
|
import {formatFilesize} from '@/plugins/helpers'
|
||||||
|
|
||||||
|
interface downloadSnackbar {
|
||||||
|
status: boolean
|
||||||
|
filename: string
|
||||||
|
percent: number
|
||||||
|
speed: number
|
||||||
|
total: number
|
||||||
|
cancelTokenSource: any
|
||||||
|
lastProgress: {
|
||||||
|
time: number
|
||||||
|
loaded: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let viewer: any = null
|
let viewer: any = null
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class Viewer extends Mixins(BaseMixin) {
|
export default class Viewer extends Mixins(BaseMixin) {
|
||||||
|
formatFilesize = formatFilesize
|
||||||
private isBusy = false
|
private isBusy = false
|
||||||
private loading = false
|
private loading = false
|
||||||
private loadingPercent = 0
|
private loadingPercent = 0
|
||||||
@ -127,6 +149,19 @@ export default class Viewer extends Mixins(BaseMixin) {
|
|||||||
private zSlicerHeight = 100
|
private zSlicerHeight = 100
|
||||||
private renderQuality = this.renderQualities[2]
|
private renderQuality = this.renderQualities[2]
|
||||||
|
|
||||||
|
private downloadSnackbar: downloadSnackbar = {
|
||||||
|
status: false,
|
||||||
|
filename: '',
|
||||||
|
percent: 0,
|
||||||
|
speed: 0,
|
||||||
|
total: 0,
|
||||||
|
cancelTokenSource: {},
|
||||||
|
lastProgress: {
|
||||||
|
time: 0,
|
||||||
|
loaded: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Prop({type: String, default: '', required: false}) filename!: string
|
@Prop({type: String, default: '', required: false}) filename!: string
|
||||||
@Ref('fileInput') fileInput!: HTMLInputElement
|
@Ref('fileInput') fileInput!: HTMLInputElement
|
||||||
//@Ref('viewerCanvasContainer') viewerCanvasContainer!: HTMLElement
|
//@Ref('viewerCanvasContainer') viewerCanvasContainer!: HTMLElement
|
||||||
@ -194,7 +229,7 @@ export default class Viewer extends Mixins(BaseMixin) {
|
|||||||
|
|
||||||
if (this.$route.query?.filename && this.loadedFile !== this.$route.query?.filename?.toString()) {
|
if (this.$route.query?.filename && this.loadedFile !== this.$route.query?.filename?.toString()) {
|
||||||
//TODO: test without sleep
|
//TODO: test without sleep
|
||||||
await this.sleep(2000) //Give the store a chance to initializ before loading the file.
|
await this.sleep(1000) //Give the store a chance to initializ before loading the file.
|
||||||
await this.loadFile(this.$route.query.filename.toString())
|
await this.loadFile(this.$route.query.filename.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,14 +319,45 @@ export default class Viewer extends Mixins(BaseMixin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadFile(filename: string) {
|
async loadFile(filename: string) {
|
||||||
let response = await fetch(this.apiUrl + '/server/files/' + encodeURI(filename))
|
this.downloadSnackbar.status = true
|
||||||
let text = await response.text()
|
this.downloadSnackbar.speed = 0
|
||||||
|
this.downloadSnackbar.lastProgress.time = 0
|
||||||
|
this.downloadSnackbar.filename = filename.startsWith('gcodes/') ? filename.slice(7) : filename
|
||||||
|
const CancelToken = axios.CancelToken
|
||||||
|
this.downloadSnackbar.cancelTokenSource = CancelToken.source()
|
||||||
|
const text = await axios.get(this.apiUrl + '/server/files/' + encodeURI(filename), {
|
||||||
|
cancelToken: this.downloadSnackbar.cancelTokenSource.token,
|
||||||
|
responseType: 'blob',
|
||||||
|
onDownloadProgress: (progressEvent) => {
|
||||||
|
this.downloadSnackbar.percent = (progressEvent.loaded * 100) / progressEvent.total
|
||||||
|
if (this.downloadSnackbar.lastProgress.time) {
|
||||||
|
const time = progressEvent.timeStamp - this.downloadSnackbar.lastProgress.time
|
||||||
|
const data = progressEvent.loaded - this.downloadSnackbar.lastProgress.loaded
|
||||||
|
|
||||||
|
if (time > 1000 || this.downloadSnackbar.speed === 0) {
|
||||||
|
this.downloadSnackbar.speed = data / (time / 1000)
|
||||||
|
this.downloadSnackbar.lastProgress.time = progressEvent.timeStamp
|
||||||
|
this.downloadSnackbar.lastProgress.loaded = progressEvent.loaded
|
||||||
|
}
|
||||||
|
} else this.downloadSnackbar.lastProgress.time = progressEvent.timeStamp
|
||||||
|
|
||||||
|
this.downloadSnackbar.total = progressEvent.total
|
||||||
|
}
|
||||||
|
}).then(res => res.data.text()).catch((e) => {
|
||||||
|
window.console.error(e.message)
|
||||||
|
})
|
||||||
|
this.downloadSnackbar.status = false
|
||||||
|
|
||||||
viewer.updateRenderQuality(this.renderQuality.value)
|
viewer.updateRenderQuality(this.renderQuality.value)
|
||||||
await viewer.processFile(text)
|
await viewer.processFile(text)
|
||||||
this.loadingPercent = 100
|
this.loadingPercent = 100
|
||||||
this.finishLoad()
|
this.finishLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelDownload() {
|
||||||
|
this.downloadSnackbar.cancelTokenSource.cancel('User canceled download gcode file')
|
||||||
|
}
|
||||||
|
|
||||||
async sleep(ms: number) {
|
async sleep(ms: number) {
|
||||||
await new Promise((resolve) => setTimeout(resolve, ms))
|
await new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
}
|
}
|
||||||
|
@ -614,6 +614,7 @@
|
|||||||
"ReloadRequired" : "Reload required",
|
"ReloadRequired" : "Reload required",
|
||||||
"TrackPrint": "Track Print",
|
"TrackPrint": "Track Print",
|
||||||
"ZClip" : "Z Clipping",
|
"ZClip" : "Z Clipping",
|
||||||
"Rendering" : "Rendering"
|
"Rendering" : "Rendering",
|
||||||
|
"Downloading" : "Downloading"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user