aboutsummaryrefslogtreecommitdiff
path: root/src-vue/src
diff options
context:
space:
mode:
authorGeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com>2023-04-10 21:17:00 +0200
committerGitHub <noreply@github.com>2023-04-10 21:17:00 +0200
commit2be2ef6ce5232ea859ae814c401cd99e87f57af9 (patch)
treeb364b9ddf492f02d02f1fdb02fd9191a57a39d27 /src-vue/src
parent6d58e6793d40df4fec518f37351868803a02a033 (diff)
downloadFlightCore-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')
-rw-r--r--src-vue/src/components/InstallProgressBar.vue102
-rw-r--r--src-vue/src/components/PlayButton.vue48
-rw-r--r--src-vue/src/i18n/lang/en.json4
-rw-r--r--src-vue/src/views/PlayView.vue17
-rw-r--r--src-vue/src/views/RepairView.vue11
5 files changed, 149 insertions, 33 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;
diff --git a/src-vue/src/i18n/lang/en.json b/src-vue/src/i18n/lang/en.json
index 5e1974cc..3553d2a5 100644
--- a/src-vue/src/i18n/lang/en.json
+++ b/src-vue/src/i18n/lang/en.json
@@ -12,7 +12,9 @@
"no": "No",
"error": "Error",
"cancel": "Cancel",
- "informationShort": "Info"
+ "informationShort": "Info",
+ "downloading": "Downloading",
+ "extracting": "Extracting"
},
"play": {
diff --git a/src-vue/src/views/PlayView.vue b/src-vue/src/views/PlayView.vue
index 2f3562ef..76f4f328 100644
--- a/src-vue/src/views/PlayView.vue
+++ b/src-vue/src/views/PlayView.vue
@@ -2,10 +2,12 @@
import { Tabs } from "../utils/Tabs";
import PlayButton from '../components/PlayButton.vue';
import { defineComponent } from "vue";
+import InstallProgressBar from "../components/InstallProgressBar.vue";
export default defineComponent({
components: {
- PlayButton
+ PlayButton,
+ InstallProgressBar
},
computed: {
northstarIsRunning(): boolean {
@@ -45,7 +47,9 @@ export default defineComponent({
{{ $t('play.unable_to_load_playercount') }}
</div>
</div>
- <div>
+
+ <!-- Align play button and services state container -->
+ <div style="display: flex">
<PlayButton />
<div v-if="$store.state.developer_mode" id="fc_services__status">
<div>
@@ -58,12 +62,13 @@ export default defineComponent({
</div>
</div>
</div>
+ <InstallProgressBar />
</div>
</template>
<style scoped>
.fc_launch__container {
- margin: 50px;
+ margin: 50px 50px 30px 50px;
position: fixed;
bottom: 0;
}
@@ -101,13 +106,9 @@ export default defineComponent({
border-color: var(--el-color-primary);
}
-
#fc_services__status {
- display: inline-block;
- position: fixed;
- padding: 10px 20px;
color: #e8edef;
- bottom: 43px;
+ align-self: end;
}
.fc_version__line {
diff --git a/src-vue/src/views/RepairView.vue b/src-vue/src/views/RepairView.vue
index 9de9a7f3..3d449d70 100644
--- a/src-vue/src/views/RepairView.vue
+++ b/src-vue/src/views/RepairView.vue
@@ -33,6 +33,7 @@
<script lang="ts">
import { defineComponent } from "vue";
import { GameInstall } from "../utils/GameInstall";
+import { InstallProgress } from "../../../src-tauri/bindings/InstallProgress";
import { invoke } from "@tauri-apps/api";
import { ReleaseCanal } from "../utils/ReleaseCanal";
import { Store } from 'tauri-plugin-store-api';
@@ -76,6 +77,16 @@ export default defineComponent({
);
let install_northstar_result = invoke("install_northstar_caller", { gamePath: game_install.game_path, northstarPackageName: ReleaseCanal.RELEASE });
+
+ appWindow.listen<InstallProgress>(
+ 'northstar-install-download-progress',
+ ({ event, payload }) => {
+ let typed_payload = payload;
+ console.log("current_downloaded:", typed_payload.current_downloaded);
+ console.log("total_size: ", typed_payload.total_size);
+ console.log("state: ", typed_payload.state);
+ }
+ );
await install_northstar_result
.then((message) => {
// Send notification