Skip to content

Commit 6499e96

Browse files
committed
TMP
1 parent eb9bd16 commit 6499e96

5 files changed

Lines changed: 33 additions & 96 deletions

File tree

client/src/components/files/operations/UploadStatus.vue

Lines changed: 12 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
<template>
44
<div class="upload-status">
5-
<template v-if="status && status.totalBytes === 0">
5+
<template v-if="status.totalBytes > 0">
6+
<div>
7+
{{ $msTranslate({ key: 'FoldersPage.ImportFile.syncing.filesLeft', count: status.totalFiles }) }}
8+
{{ $msTranslate(formatETA(rateCalculator.getEta(status.totalBytes))) }}
9+
</div>
10+
</template>
11+
<template v-else>
612
<ion-icon
713
:icon="checkmarkCircle"
814
class="upload-status__icon checkmark-icon"
@@ -14,89 +20,24 @@
1420
@click="$emit('close')"
1521
/>
1622
</template>
17-
<template v-else-if="status && status.totalBytes > 0">
18-
<transition
19-
name="step-fade"
20-
mode="out-in"
21-
>
22-
<div
23-
class="upload-status-step"
24-
:key="stepIndex"
25-
>
26-
<ion-icon
27-
:icon="currentStep.icon"
28-
class="upload-status-step__icon step-icon"
29-
/>
30-
<ion-text class="title-h5 upload-status-step__text">{{ $msTranslate(currentStep.label) }}</ion-text>
31-
</div>
32-
</transition>
33-
</template>
3423
</div>
3524
</template>
3625

3726
<script setup lang="ts">
3827
import { TransferRateCalculator } from '@/common/transferRate';
3928
import { UploadProgress } from '@/parsec';
29+
import { formatETA } from '@/services/translation';
4030
import { IonIcon, IonText } from '@ionic/vue';
41-
import { checkmarkCircle, close, cloudUpload, lockClosed, reader, shieldCheckmark } from 'ionicons/icons';
42-
import { computed, onUnmounted, ref, watch } from 'vue';
43-
44-
const UPLOAD_STEP_DURATION = 4000;
45-
const UPLOAD_STEPS = [
46-
{ icon: reader, label: 'FoldersPage.ImportFile.syncing.step1' },
47-
{ icon: lockClosed, label: 'FoldersPage.ImportFile.syncing.step2' },
48-
{ icon: shieldCheckmark, label: 'FoldersPage.ImportFile.syncing.step3' },
49-
{ icon: cloudUpload, label: 'FoldersPage.ImportFile.syncing.step4' },
50-
];
51-
52-
const stepIndex = ref(0);
53-
let stepIntervalId: ReturnType<typeof setInterval> | null = null;
54-
55-
const currentStep = computed(() => UPLOAD_STEPS[stepIndex.value]);
31+
import { checkmarkCircle, close } from 'ionicons/icons';
5632
57-
function startStepCycle(): void {
58-
stepIndex.value = 0;
59-
stepIntervalId = setInterval(() => {
60-
if (stepIndex.value === UPLOAD_STEPS.length - 1) {
61-
stepIndex.value = 0;
62-
} else {
63-
stepIndex.value += 1;
64-
}
65-
}, UPLOAD_STEP_DURATION);
66-
}
67-
68-
function stopStepCycle(): void {
69-
if (stepIntervalId !== null) {
70-
clearInterval(stepIntervalId);
71-
stepIntervalId = null;
72-
}
73-
}
74-
75-
const props = defineProps<{
76-
status?: UploadProgress;
33+
defineProps<{
34+
status: UploadProgress;
7735
rateCalculator: TransferRateCalculator;
7836
}>();
7937
8038
defineEmits<{
81-
(e: 'close'): boolean;
39+
(e: 'close'): void;
8240
}>();
83-
84-
watch(
85-
() => props.status,
86-
(newValue) => {
87-
if (newValue && newValue.totalBytes > 0) {
88-
if (!stepIntervalId) {
89-
startStepCycle();
90-
}
91-
} else {
92-
stopStepCycle();
93-
}
94-
},
95-
);
96-
97-
onUnmounted(() => {
98-
stopStepCycle();
99-
});
10041
</script>
10142

10243
<style scoped lang="scss">
@@ -161,14 +102,4 @@ onUnmounted(() => {
161102
margin-left: auto;
162103
}
163104
}
164-
165-
.step-fade-enter-active,
166-
.step-fade-leave-active {
167-
transition: opacity 0.3s ease;
168-
}
169-
170-
.step-fade-enter-from,
171-
.step-fade-leave-to {
172-
opacity: 0;
173-
}
174105
</style>

client/src/locales/en-US.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,10 +1114,7 @@
11141114
},
11151115
"synced": "All files synchronized and secured",
11161116
"syncing": {
1117-
"step1": "Analyzing and verifying",
1118-
"step2": "Splitting and encrypting",
1119-
"step3": "Securing all files and metadata",
1120-
"step4": "Synchronizing with the cloud"
1117+
"filesLeft": "One file left|{count} files left"
11211118
},
11221119
"noTasks": "No tasks",
11231120
"noCurrentTasks": "No tasks in this category",

client/src/locales/fr-FR.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,10 +1115,7 @@
11151115
},
11161116
"synced": "Fichiers synchronisés et sécurisés",
11171117
"syncing": {
1118-
"step1": "Analyse et vérification",
1119-
"step2": "Découpage et chiffrement",
1120-
"step3": "Sécurisation des fichiers et de leurs métadonnées",
1121-
"step4": "Synchronisation avec le cloud"
1118+
"filesLeft": "Un fichier restant|{count} fichiers restant"
11221119
},
11231120
"noTasks": "Aucune tâche",
11241121
"noCurrentTasks": "Aucun tâche dans cette catégorie",

client/src/services/translation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ export function longLocaleCodeToShort(longCode: Locale): string {
8686
}
8787

8888
export function formatETA(seconds: number): Translatable {
89+
if (seconds === Infinity || seconds < 0) {
90+
return '';
91+
}
8992
const entries = Object.entries(Duration.fromObject({ seconds }).rescale().toObject())
9093
.filter(([k, v]) => v > 0 && k !== 'milliseconds')
9194
.slice(0, 2);

client/src/views/files/FileOperationMenu.vue

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
</div>
2626

2727
<upload-status
28+
v-if="showUploadStatus"
2829
class="upload-menu-status"
29-
v-if="uploadProgressStatus && showUploadStatus"
3030
:status="uploadProgressStatus"
3131
:rate-calculator="rateCalculator as TransferRateCalculator"
3232
@close="showUploadStatus = false"
@@ -163,12 +163,12 @@ const currentItems = computed(() => {
163163
});
164164
165165
let canceller!: FileEventRegistrationCanceller;
166-
let uploadProgressIntervalId: any = null;
166+
let uploadProgressTimeoutId: any = null;
167167
const isFileOperationManagerActive = ref(false);
168168
const uploadMenuList = ref();
169-
const uploadProgressStatus = ref<UploadProgress | undefined>(undefined);
169+
const uploadProgressStatus = ref<UploadProgress>({ totalBytes: 0, totalFiles: 0 });
170170
const rateCalculator = ref<TransferRateCalculator>(new TransferRateCalculator());
171-
const showUploadStatus = ref(true);
171+
const showUploadStatus = ref(false);
172172
173173
function toggleMenu(): void {
174174
if (menu.isMinimized()) {
@@ -210,19 +210,25 @@ async function updateProgress(): Promise<void> {
210210
showUploadStatus.value = true;
211211
}
212212
} else {
213-
uploadProgressStatus.value = undefined;
213+
uploadProgressStatus.value = { totalBytes: 0, totalFiles: 0 };
214214
rateCalculator.value.clear();
215215
}
216+
if (uploadProgressStatus.value.totalBytes > 0) {
217+
// If we're still uploading, we poll faster for a smooth display
218+
uploadProgressTimeoutId = setTimeout(updateProgress, 500);
219+
} else {
220+
// Otherwise we can stop the timeout, it will get reactivated on a new file operation
221+
uploadProgressTimeoutId = null;
222+
}
216223
}
217224
218225
onMounted(async () => {
219226
canceller = await fileOperationManager.value.registerCallback(onFileOperationEvent);
220-
uploadProgressIntervalId = setInterval(updateProgress, 400);
221227
});
222228
223229
onUnmounted(async () => {
224230
canceller.cancel();
225-
clearInterval(uploadProgressIntervalId);
231+
clearTimeout(uploadProgressTimeoutId);
226232
});
227233
228234
async function onFileOperationEvent(
@@ -231,6 +237,9 @@ async function onFileOperationEvent(
231237
eventData?: FileOperationEventData,
232238
): Promise<void> {
233239
isFileOperationManagerActive.value = true;
240+
if (!uploadProgressTimeoutId) {
241+
uploadProgressTimeoutId = setTimeout(updateProgress, 1000);
242+
}
234243
if (!operationData) {
235244
if (event !== FileOperationEvents.AllFinished) {
236245
window.electronAPI.log('warn', `Got event ${event} without operation data`);

0 commit comments

Comments
 (0)