fix(control): uploaded files never finished animation

This commit is contained in:
E44
2026-01-12 19:56:51 +01:00
parent 9be8a70452
commit ea2f063991
2 changed files with 77 additions and 37 deletions
@@ -199,19 +199,10 @@ function generate_valid_file_name(original_file_name: string, used_file_names: s
async function upload(task: FileTransferTask): Promise<void> {
const task_data = task.data;
if (task_data.type !== 'upload' || !task_data.file) return console.warn('Task cancelled: wrong task type:', task);
if (task_data.type !== 'upload' || !task_data.file)
return console.warn('Task cancelled: wrong task type:', task);
await upload_file_via_xhr(task, task.display, task_data.file);
// Generate Thumbnail if not done already
setTimeout(async () => {
const inode_element: Inode | undefined = await db.files.get(
JSON.parse(task.file_primary_key) as [string, string, number, string]
);
if (!!inode_element && inode_element.thumbnail === null) {
await generate_thumbnail(task.display.ip, task.path, inode_element);
}
}, 10);
}
export async function sync(task: FileTransferTask) {
@@ -271,7 +262,8 @@ export async function download_file(selected_file_id: string, selected_display_i
selected_file_id,
selected_display_ids
);
if (!file_data || file_data.file.type === 'inode/directory') return console.warn('Download cancelled: is folder');
if (!file_data || file_data.file.type === 'inode/directory')
return console.warn('Download cancelled: is folder');
try {
const url = `http://${file_data.short_display_with_file.ip}:1323/api${get_sanitized_file_url(file_data.file.path + file_data.file.name)}`;
@@ -305,8 +297,7 @@ async function start_task_loop() {
const current_task = tasks[0];
if (current_task.data.type === 'upload') {
await upload(current_task);
}
else if (current_task.data.type === 'sync') {
} else if (current_task.data.type === 'sync') {
await sync(current_task);
}
tasks.shift(); // Remove current_task from tasks
@@ -314,8 +305,13 @@ async function start_task_loop() {
is_processing = false;
}
async function upload_file_via_xhr(task: FileTransferTask, current_short_display: ShortDisplay, current_file: File) {
async function upload_file_via_xhr(
task: FileTransferTask,
current_short_display: ShortDisplay,
current_file: File
) {
const start_time = new Date();
const loading_type = task.data.type === 'upload' ? 'upload' : 'sync_upload';
return new Promise<void>((resolve) => {
const xhr = new XMLHttpRequest();
@@ -328,7 +324,13 @@ async function upload_file_via_xhr(task: FileTransferTask, current_short_display
xhr.upload.onprogress = (e) => {
const apply = async () => {
await update_current_loading_data(task.data.type === 'upload' ? 'upload' : 'sync_upload', task, e.loaded, start_time, current_short_display.id);
await update_current_loading_data(
loading_type,
task,
e.loaded,
start_time,
current_short_display.id
);
};
apply();
};
@@ -341,9 +343,20 @@ async function upload_file_via_xhr(task: FileTransferTask, current_short_display
xhr.onreadystatechange = async () => {
if (xhr.readyState === 4) {
if (xhr.status == 200) {
await db.files_on_display.update([current_short_display.ip, task.file_primary_key], {
// set loading_data to 100%
await db.files_on_display.update([current_short_display.id, task.file_primary_key], {
date_created: new Date(),
loading_data: null
}); // TODO: Stattdessen update machen und gucken, ob die Datei wirklich da ist
});
// Generate Thumbnail if not done already
setTimeout(async () => {
const inode_element: Inode | undefined = await db.files.get(
JSON.parse(task.file_primary_key) as [string, string, number, string]
);
if (!!inode_element && inode_element.thumbnail === null) {
await generate_thumbnail(task.display.ip, task.path, inode_element);
}
}, 10);
} else {
await show_error(task, `HTTP ${xhr.status}`);
}
@@ -352,21 +365,33 @@ async function upload_file_via_xhr(task: FileTransferTask, current_short_display
};
xhr.send(current_file);
})
});
}
async function update_current_loading_data(type: FileLoadingData['type'], task: FileTransferTask, current_bytes: number, start_time: Date, other_display_id: string | null = null) {
const current_percentage = task.bytes_total > 0 ? Math.round((current_bytes / task.bytes_total) * 100) : 1;
async function update_current_loading_data(
type: FileLoadingData['type'],
task: FileTransferTask,
current_bytes: number,
start_time: Date,
other_display_id: string | null = null
) {
const current_percentage = Math.min(
task.bytes_total > 0 ? Math.round((current_bytes / task.bytes_total) * 100) : 1,
99
); // calculate percantage, but maximum value is 99%
const prognosed_data = get_prognosed_data(start_time, current_bytes, task.bytes_total);
await db.files_on_display.update([other_display_id ? other_display_id : task.display.id, task.file_primary_key], {
await db.files_on_display.update(
[other_display_id ? other_display_id : task.display.id, task.file_primary_key],
{
loading_data: {
type,
percentage: current_percentage,
bytes_per_second: prognosed_data.bytes_per_second,
seconds_until_finish: prognosed_data.seconds_until_finish
}
});
}
);
}
function get_prognosed_data(
+23 -8
View File
@@ -211,17 +211,30 @@ export async function update_folder_elements_recursively(
const new_folder_elements = await get_file_data(display.ip, file_path);
if (!new_folder_elements) return;
const existing_file_keys_on_display_in_path: [string, string, number, string][] = (
await db.files_on_display.where('display_id').equals(display.id).toArray()
).map((e) => JSON.parse(e.file_primary_key) as [string, string, number, string]);
const existing_files_on_display_in_path: Inode[] = await db.files
const existing_files_on_display_in_path: FileOnDisplay[] = await db.files_on_display
.where('display_id')
.equals(display.id)
.toArray();
const existing_file_keys_on_display_in_path: [string, string, number, string][] =
existing_files_on_display_in_path.map(
(e) => JSON.parse(e.file_primary_key) as [string, string, number, string]
);
const existing_files: Inode[] = await db.files
.where('[path+name+size+type]')
.anyOf(existing_file_keys_on_display_in_path)
.filter((e) => e.path === file_path)
.toArray();
const existing_files_with_loading_state: { folder_element: Inode; is_loading: boolean }[] =
existing_files.map((folder_element) => ({
folder_element,
is_loading: !!existing_files_on_display_in_path.find(
(e) => e.file_primary_key === get_file_primary_key(folder_element)
)?.loading_data
}));
const diff = get_folder_elements_difference(
existing_files_on_display_in_path,
existing_files_with_loading_state,
new_folder_elements
);
@@ -262,13 +275,15 @@ export async function update_folder_elements_recursively(
}
function get_folder_elements_difference(
old_elements: Inode[],
old_elements: { folder_element: Inode; is_loading: boolean }[],
new_elements: { folder_element: Inode; date_created: Date }[]
): { deleted: Inode[]; new: { folder_element: Inode; date_created: Date }[] } {
const old_keys = new Set(old_elements.map((e) => get_file_primary_key(e)));
const old_keys = new Set(old_elements.map((e) => get_file_primary_key(e.folder_element)));
const new_keys = new Set(new_elements.map((e) => get_file_primary_key(e.folder_element)));
const only_in_old = old_elements.filter((e) => !new_keys.has(get_file_primary_key(e)));
const only_in_old = old_elements
.filter((e) => !new_keys.has(get_file_primary_key(e.folder_element)) && !e.is_loading)
.map((e) => e.folder_element);
const only_in_new = new_elements.filter(
(e) => !old_keys.has(get_file_primary_key(e.folder_element))
);