diff options
author | GeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com> | 2023-04-10 21:17:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-10 21:17:00 +0200 |
commit | 2be2ef6ce5232ea859ae814c401cd99e87f57af9 (patch) | |
tree | b364b9ddf492f02d02f1fdb02fd9191a57a39d27 /src-vue/src/components | |
parent | 6d58e6793d40df4fec518f37351868803a02a033 (diff) | |
download | FlightCore-2be2ef6ce5232ea859ae814c401cd99e87f57af9.tar.gz FlightCore-2be2ef6ce5232ea859ae814c401cd99e87f57af9.zip |
feat: Show download progress for installing Northstar (#200)
* chore: Bump libthermite to 0.5.3
This adds a change needed for making progressbar work on dowload
* wip: First attempt at showing download progress
Simply prints it to JavaScript console for now
* feat: Emit download progress at most every 250ms
If we spam emit too much we use a lot of extra resources, slowing down
the actual download
* feat: Initial messages for extracting
* feat: Add install state enum
* refactor: Change payload to current + total size
downloaded
* fix: Remove extra emit
* fix: Remove extra emit
* refactor: Rename struct
* refactor: Move struct to top of file
* feat: Add TypeScript bindings
* feat: Add console logs for printing state for now
* fix: Remove duplicate identifier
* feat: Initial progressbar in frontend
* fix: Remove event listener added for debugging
* feat: Display status and downloaded bytes
* feat: Set loading bar to indeterminate on extract
* fix: Phrasing in comment
* feat: Add i18n for progress state
* refactor: Adjust control flow
do not show downloaded size anymore during extraction
* fix: Manually specify progressbar size
* fix: Update download progress every 100ms
instead of 250ms
Gives impression of faster / more fluent download.
* feat: layout does not move when progress bar is hidden
* feat: fix progress bar width to 200px
* refactor: put services container in a flex container, for it not to overlap play button
* refactor: export progress bar to dedicated component file
* refactor: Update status first outside of branch
* fix: Proper typing of event payload
* fix: Do not assign to unused variable
---------
Co-authored-by: Rémy Raes <contact@remyraes.com>
Diffstat (limited to 'src-vue/src/components')
-rw-r--r-- | src-vue/src/components/InstallProgressBar.vue | 102 | ||||
-rw-r--r-- | src-vue/src/components/PlayButton.vue | 48 |
2 files changed, 126 insertions, 24 deletions
diff --git a/src-vue/src/components/InstallProgressBar.vue b/src-vue/src/components/InstallProgressBar.vue new file mode 100644 index 00000000..d0c2047c --- /dev/null +++ b/src-vue/src/components/InstallProgressBar.vue @@ -0,0 +1,102 @@ +<script lang="ts"> +import { defineComponent } from 'vue'; +import { appWindow } from '@tauri-apps/api/window'; +import { InstallProgress } from '../../../src-tauri/bindings/InstallProgress'; + +export default defineComponent({ + name: 'InstallProgressBar', + computed: { + progressBarStyle(): string { + return !this.install_or_update ? 'hide-progress' : ''; + } + }, + data() { + return { + percentage: 0, + color: '#409EFF', + install_or_update: false, + status: "unknown", + current_downloaded: -1, + total_size: -1, + }; + }, + methods: { + formatBytes(bytes: number, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + const k = 1000; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + }, + formatText() { + if (this.status == "DOWNLOADING") { + const current_downloaded_string = this.formatBytes(this.current_downloaded); + const total_size_string = this.formatBytes(this.total_size); + const status = this.$t("generic.downloading"); + return `${status}: ${current_downloaded_string}/${total_size_string}`; + } + if (this.status == "EXTRACTING") { + return this.$t("generic.extracting"); + } + return "Inactive"; // Needed to keep same size format when progress bar is hidden + } + }, + mounted() { + appWindow.listen<InstallProgress>( + 'northstar-install-download-progress', + ({ event, payload }) => { + this.install_or_update = true; + let progress = payload; + this.status = progress.state; + if (progress.state == "DOWNLOADING") { + this.percentage = ((Number(progress.current_downloaded) / Number(progress.total_size)) * 100); + this.color = '#409EFF'; + this.current_downloaded = Number(progress.current_downloaded); + this.total_size = Number(progress.total_size); + } + if (progress.state == "EXTRACTING") { + this.percentage = 100; + this.color = '#67C23A'; + } + if (progress.state == "DONE") { + // Clear state again + this.install_or_update = false + } + } + ); + } +}); +</script> + +<template> + <el-progress + :class="progressBarStyle" + :format="formatText" + :percentage="percentage" + :color="color" + :indeterminate="status === 'EXTRACTING'" + :duration="1" + > + </el-progress> +</template> + +<style scoped> +.el-progress { + margin-top: 10px; +} + +/* Set progress bar width */ +.el-progress:deep(.el-progress-bar) { + width: 200px; + flex-grow: initial; +} + +.el-progress:deep(.el-progress__text) { + line-height: 1.2; +} + +.hide-progress { + opacity: 0; +} +</style> diff --git a/src-vue/src/components/PlayButton.vue b/src-vue/src/components/PlayButton.vue index 3efcc9f5..208b4703 100644 --- a/src-vue/src/components/PlayButton.vue +++ b/src-vue/src/components/PlayButton.vue @@ -83,10 +83,10 @@ export default defineComponent({ return this.showReleaseSwitch ? 'border-radius: 2px 0 0 2px;' : 'border-radius: 2px'; - } + }, }, methods: { - launchGame() { + async launchGame() { this.$store.commit('launchGame'); } } @@ -94,30 +94,31 @@ export default defineComponent({ </script> <template> - <el-button :disabled="northstarIsRunning" - type="primary" size="large" @click="launchGame" - class="fc_launch__button" :style="buttonRadiusStyle"> - {{ playButtonLabel }} - </el-button> - <el-select v-if="showReleaseSwitch" :disabled="northstarIsRunning" - v-model="currentCanal" placeholder="Select"> - <el-option-group - v-for="group in selectOptions" - :key="group.label" - :label="group.label" - > - <el-option - v-for="item in group.options" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-option-group> - </el-select> + <nav> + <el-button :disabled="northstarIsRunning" + type="primary" size="large" @click="launchGame" + class="fc_launch__button" :style="buttonRadiusStyle"> + {{ playButtonLabel }} + </el-button> + <el-select v-if="showReleaseSwitch" :disabled="northstarIsRunning" + v-model="currentCanal" placeholder="Select"> + <el-option-group + v-for="group in selectOptions" + :key="group.label" + :label="group.label" + > + <el-option + v-for="item in group.options" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-option-group> + </el-select> + </nav> </template> <style scoped> - button { text-transform: uppercase; padding: 30px; @@ -130,7 +131,6 @@ button { } /* Release canal selector */ - .el-select { width: 0; margin-right: 50px; |