mlpcardgame/src/views/Settings.vue

189 lines
4.5 KiB
Vue

<template>
<section class="settings">
<TopNav class="top" />
<section class="settings-box download">
<header>
<h1>Storage settings</h1>
</header>
<div class="rows">
<article>
<div class="name">
Card image source
</div>
<div class="value">
{{ imageSource }}
</div>
<div class="actions">
<b-button
class="is-primary"
@click="downloadImages"
:disabled="cardImageSource == 'local'"
>Download images</b-button
>
</div>
</article>
</div>
</section>
<b-modal :active.sync="isDownloading" :can-cancel="false">
<div class="modal-card" style="width: auto">
<header class="modal-card-head">
<p class="modal-card-title">
{{ downloadStatus }}
</p>
</header>
<section class="modal-card-body">
<b-progress
size="is-large"
type="is-danger"
v-if="downloadProgress"
:max="downloadProgress.total"
:value="downloadProgress.progress"
show-value
>
{{ downloadProgressString }}
</b-progress>
</section>
</div>
</b-modal>
</section>
</template>
<style lang="scss" scoped>
@import "@/assets/scss/_variables.scss";
.settings {
display: grid;
}
.top {
grid-column: 1 / end;
}
.settings-box {
margin: 20px;
padding: 20px;
background: rgba($white, 0.1);
border-radius: 6px;
header {
h1 {
font-family: $fantasy;
font-size: 17pt;
}
}
.rows {
display: flex;
flex-direction: column;
article {
margin: 10px 0;
font-size: 12pt;
display: flex;
align-items: center;
& > div {
margin: 5px;
}
.value {
border: 1px solid rgba($black, 0.4);
border-radius: 3px;
padding: 5px 10px;
}
}
}
}
</style>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import TopNav from "@/components/Navigation/TopNav.vue";
import { TaskRunner } from "@/workers";
import { cardImageSource, refreshCardSource } from "@/mlpccg";
@Component({
components: { TopNav }
})
export default class SettingsView extends Vue {
private cardImageSource!: "local" | "remote";
private downloadState!: "starting" | "download" | "extract" | null;
private downloadProgress!: { progress: number; total: number } | null;
private downloadImages() {
this.downloadState = "starting";
const worker = new TaskRunner("downloadCardImages");
worker.on("dl-progress", progress => {
if (this.downloadState != "download") {
this.downloadState = "download";
}
this.downloadProgress = progress;
});
worker.on("ex-progress", progress => {
if (this.downloadState != "extract") {
this.downloadState = "extract";
}
this.downloadProgress = progress;
});
worker.on("finish", async _ => {
this.downloadState = null;
await refreshCardSource();
});
}
private data() {
return {
cardImageSource: cardImageSource(),
downloadState: null,
downloadProgress: null
};
}
private get imageSource() {
switch (this.cardImageSource) {
case "local":
return "Local saved copy";
case "remote":
return "Remote server";
}
return "Unknown";
}
private get isDownloading(): boolean {
return this.downloadState !== null;
}
private get downloadStatus(): string {
switch (this.downloadState) {
case "starting":
return "Starting download...";
case "download":
return `Downloading image archive (${Math.round(
this.downloadProgress!.total / 10485.76
) / 100} MB)`;
case "extract":
return `Extracting images`;
}
return "";
}
private get downloadProgressString(): string {
if (!this.downloadProgress) {
return "";
}
let current = "";
let total = "";
if (this.downloadState == "extract") {
current = `${(this.downloadProgress.progress / 2) | 0}`;
total = `${(this.downloadProgress.total / 2) | 0}`;
} else {
current = `${Math.round(this.downloadProgress.progress / 10485.76) /
100}`;
total = `${Math.round(this.downloadProgress.total / 10485.76) / 100} MB`;
}
const percent = Math.round(
(this.downloadProgress.progress / this.downloadProgress.total) * 100
);
return `${percent}% (${current}/${total})`;
}
}
</script>