Newer
Older
medialib-manager / static / js / components / global-transcoding-tasks.js
const globalTasks = {};
const mediaInfoCenter = {};

function createEmptyTaskView(taskId) {
	const li = document.createElement('li');
	li.classList.add("list-group-item");
	li.classList.add("task");
	li.dataset.taskId = taskId;

	let html = `
		<div class="file">
      <div class="circle-progress-bar" data-value="0" data-bar-color="#666666" data-bar-stroke="4" data-bar-size="30"></div>
      <a href="/single?path=" class="link-primary"></a>
      <span class="progress-percent" style="opacity: .7">- 99%</span>
    </div>
    <div class="control">
      <button class="btn btn-danger cancel" data-task-id="${ taskId }"><i class="bi bi-stop-fill"></i> Stop</button>
      <div class="spinner-border text-secondary" role="status" style="display: none">
			  <span class="visually-hidden">Loading...</span>
			</div>
    </div>
	`;

	li.innerHTML = html;
	initSingleCircleProgressBar(li.querySelector(".circle-progress-bar"));
	return initTaskView(li);
}

function getTotalActiveTasks() {
	return Object.keys(globalTasks).length;
}

function initTaskView(view) {
	view.querySelector(".control .cancel").addEventListener("click", e => {
		const taskId = e.currentTarget.dataset.taskId;
		$(e.currentTarget).hide();
		$(e.currentTarget).parent().find(".spinner-border").show();

		$.getJSON(`/stop-transcoding?task_id=${taskId}`, function(resp) {
      if(resp.status == "stoped" && resp.task_id == taskId) {
      	if(typeof globalTasks[resp.task_id] != "undefined") {
      		// delete globalTasks[resp.task_id];
      	}
      } else {
      	// TODO: show error
      }
    });
	});

	return view;
}

function updateExistsView(data, view) {
	const taskContainer = $(view);
	const fileLink = taskContainer.find(".file a");
	fileLink.text(data.task.file.split("/").at(-1));
	fileLink.attr("href", `/single?path=${ data.task.file }`);

	let time = getTimeFromTranscodingProgressMessage(data.message);
	const mInf = getMediaInfo(data.task.file);
	
	if(!mInf) {
		return;
	}

	const progressPercent = calcTranscodingProgress(time, mInf.info.container.duration);

	taskContainer.find(".file .progress-percent").text(`- ${ progressPercent }%`);
	taskContainer.find(".file .circle-progress-bar")[0].dataset.value = progressPercent;
}

function globalTranscodingTasksInit() {
	const tasksContainer = $(".transcoding-tasks-container > ul");

	socket.on("progress", data => {
		if(typeof data.task.id == "undefined") {
			return;
		}

		if(typeof globalTasks[data.task.id] == "undefined") {
			// create new view
			const view = createEmptyTaskView(data.task.id);
			tasksContainer.append(view);
			globalTasks[data.task.id] = {
				"data": data,
				"view": view
			}
		}

		// update exists view
		updateExistsView(data, globalTasks[data.task.id].view);

		$(".total-tasks").text(getTotalActiveTasks());
	});

	socket.on("completed", data => {
		if(typeof globalTasks[data.task.id] != "undefined") {
			// remove task view
			$(globalTasks[data.task.id].view).remove();
			delete globalTasks[data.task.id];

			$(".total-tasks").text(getTotalActiveTasks());
		}
	});

	socket.on("canceled", data => {
		if(typeof globalTasks[data.task.id] != "undefined") {
			// remove task view
			$(globalTasks[data.task.id].view).remove();
			delete globalTasks[data.task.id];
			$(".total-tasks").text(getTotalActiveTasks());
		}
	});

	socket.on("error", data => {
		// show error		
	});
}

function getMediaInfo(path) {
	if(typeof mediaInfoCenter[path] == "undefined") {
		getSingleMediaFileInfo(path, resp => {
			console.log(resp);
			mediaInfoCenter[resp.path] = resp;
		});

		return false;
	}

	return mediaInfoCenter[path];
}

$(document).ready(function() {
	if(typeof mediaInfo != "undefined") {
		mediaInfoCenter[mediaInfo.path] = mediaInfo;
	}

	globalTranscodingTasksInit();
});