修复了重新翻译时没有释放资源的问题
This commit is contained in:
@@ -39,7 +39,6 @@
|
|||||||
transition: all 0.3s ease-in-out;
|
transition: all 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === 修改点: 为等待ID的状态添加样式 === */
|
|
||||||
.task-id-placeholder {
|
.task-id-placeholder {
|
||||||
color: var(--bs-secondary-color);
|
color: var(--bs-secondary-color);
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
@@ -122,7 +121,6 @@
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MODIFIED: Redefined gutter styles for both directions */
|
|
||||||
.gutter {
|
.gutter {
|
||||||
background-color: var(--bs-tertiary-bg);
|
background-color: var(--bs-tertiary-bg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@@ -163,39 +161,32 @@
|
|||||||
z-index: 1050;
|
z-index: 1050;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* === MODIFIED: Added Responsive Styles === */
|
|
||||||
|
|
||||||
/* Make the main layout responsive for mobile (stacks below lg breakpoint) */
|
|
||||||
@media (max-width: 991.98px) {
|
@media (max-width: 991.98px) {
|
||||||
.main-container {
|
.main-container {
|
||||||
height: auto; /* Allow natural page height */
|
height: auto;
|
||||||
padding-bottom: 6rem; /* Add padding at the bottom for floating theme switch */
|
padding-bottom: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-panel, .task-area {
|
.settings-panel, .task-area {
|
||||||
height: auto; /* Remove fixed height to allow natural flow */
|
height: auto;
|
||||||
overflow-y: visible;
|
overflow-y: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settings-panel {
|
.settings-panel {
|
||||||
padding-right: 0; /* No scrollbar space needed */
|
padding-right: 0;
|
||||||
margin-bottom: 2rem; /* Add space when panels stack */
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjustments for smaller screens (tablets and phones) */
|
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
/* Add space between file area and log area when they stack on mobile */
|
|
||||||
.task-card .col-md-7 {
|
.task-card .col-md-7 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make preview offcanvas full width on mobile */
|
|
||||||
#previewOffcanvas {
|
#previewOffcanvas {
|
||||||
--bs-offcanvas-width: 100vw;
|
--bs-offcanvas-width: 100vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -432,7 +423,6 @@
|
|||||||
<template id="taskCardTemplate">
|
<template id="taskCardTemplate">
|
||||||
<div class="card mb-3 task-card">
|
<div class="card mb-3 task-card">
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
<!-- === 修改点: 初始显示占位符,而不是ID === -->
|
|
||||||
<span class="fw-bold">任务 ID: <code class="task-id-display"><span class="task-id-placeholder">等待提交...</span></code></span>
|
<span class="fw-bold">任务 ID: <code class="task-id-display"><span class="task-id-placeholder">等待提交...</span></code></span>
|
||||||
<button type="button" class="btn-close remove-task-btn" aria-label="Close"></button>
|
<button type="button" class="btn-close remove-task-btn" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
@@ -741,7 +731,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (restoreState && backendTaskId) {
|
if (restoreState && backendTaskId) {
|
||||||
elements.taskIdDisplay.textContent = backendTaskId;
|
elements.taskIdDisplay.innerHTML = `<code>${backendTaskId}</code>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks[cardId] = {
|
tasks[cardId] = {
|
||||||
@@ -770,6 +760,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the backend to release a task's resources.
|
||||||
|
* @param {string} backendTaskId - The ID of the task to release.
|
||||||
|
*/
|
||||||
|
async function releaseTask(backendTaskId) {
|
||||||
|
try {
|
||||||
|
fetch(`/service/release/${backendTaskId}`, { method: 'POST' });
|
||||||
|
console.log(`[${backendTaskId}] Release request sent to backend.`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[${backendTaskId}] Failed to send release request:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a task card from the UI and releases its backend resources.
|
||||||
|
* @param {string} cardId - The local ID of the card to remove.
|
||||||
|
*/
|
||||||
async function removeTask(cardId) {
|
async function removeTask(cardId) {
|
||||||
const task = tasks[cardId];
|
const task = tasks[cardId];
|
||||||
if (!task) return;
|
if (!task) return;
|
||||||
@@ -777,11 +784,12 @@
|
|||||||
const backendTaskId = task.state.backendTaskId;
|
const backendTaskId = task.state.backendTaskId;
|
||||||
if (backendTaskId) {
|
if (backendTaskId) {
|
||||||
stopPolling(backendTaskId);
|
stopPolling(backendTaskId);
|
||||||
await fetch(`/service/release/${backendTaskId}`,{method: 'POST'});
|
await releaseTask(backendTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
task.elements.card.remove();
|
task.elements.card.remove();
|
||||||
delete tasks[cardId];
|
delete tasks[cardId];
|
||||||
|
|
||||||
saveTaskIds();
|
saveTaskIds();
|
||||||
updateTaskPlaceholderVisibility();
|
updateTaskPlaceholderVisibility();
|
||||||
}
|
}
|
||||||
@@ -863,6 +871,17 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ======================== FIX: RELEASE OLD TASK ON RETRY ========================
|
||||||
|
// If a previous backend task exists for this card, release it before starting a new one.
|
||||||
|
const oldBackendTaskId = state.backendTaskId;
|
||||||
|
if (oldBackendTaskId) {
|
||||||
|
console.log(`[${oldBackendTaskId}] Re-translating. Releasing resources for the old task.`);
|
||||||
|
await releaseTask(oldBackendTaskId);
|
||||||
|
// Immediately reset the backend ID in the state.
|
||||||
|
state.backendTaskId = null;
|
||||||
|
}
|
||||||
|
// ==============================================================================
|
||||||
|
|
||||||
state.isTranslating = true;
|
state.isTranslating = true;
|
||||||
elements.startBtn.disabled = true;
|
elements.startBtn.disabled = true;
|
||||||
elements.startBtn.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 初始化...`;
|
elements.startBtn.innerHTML = `<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 初始化...`;
|
||||||
@@ -901,9 +920,9 @@
|
|||||||
|
|
||||||
if (response.ok && result.task_started) {
|
if (response.ok && result.task_started) {
|
||||||
const backendTaskId = result.task_id;
|
const backendTaskId = result.task_id;
|
||||||
state.backendTaskId = backendTaskId;
|
state.backendTaskId = backendTaskId; // Store the NEW task ID
|
||||||
state.isSubmitted = true;
|
state.isSubmitted = true;
|
||||||
elements.taskIdDisplay.textContent = backendTaskId;
|
elements.taskIdDisplay.innerHTML = `<code>${backendTaskId}</code>`;
|
||||||
elements.taskIdDisplay.classList.remove('task-id-placeholder');
|
elements.taskIdDisplay.classList.remove('task-id-placeholder');
|
||||||
|
|
||||||
saveTaskIds();
|
saveTaskIds();
|
||||||
@@ -1012,12 +1031,13 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { elements, state } = card;
|
const { elements, state } = card;
|
||||||
const cardId = card.elements.card.dataset.cardId;
|
const cardId = elements.card.dataset.cardId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/service/status/${backendTaskId}`);
|
const response = await fetch(`/service/status/${backendTaskId}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 404 && isRestore) {
|
if (response.status === 404 && isRestore) {
|
||||||
|
console.warn(`Task ${backendTaskId} not found on server (404). Removing from UI.`);
|
||||||
await removeTask(cardId);
|
await removeTask(cardId);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -1166,19 +1186,14 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// MODIFIED: This function now handles responsive layout for the preview panes.
|
|
||||||
function setPreviewDisplayMode(mode) {
|
function setPreviewDisplayMode(mode) {
|
||||||
if (previewSplitInstance) {
|
if (previewSplitInstance) {
|
||||||
previewSplitInstance.destroy();
|
previewSplitInstance.destroy();
|
||||||
previewSplitInstance = null;
|
previewSplitInstance = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check screen size to determine layout (true for mobile, false for desktop)
|
const isMobileView = window.innerWidth < 992;
|
||||||
const isMobileView = window.innerWidth < 992; // Using Bootstrap's 'lg' breakpoint
|
|
||||||
|
|
||||||
const splitContainer = document.querySelector('.preview-split-container');
|
const splitContainer = document.querySelector('.preview-split-container');
|
||||||
|
|
||||||
// Reset element styles
|
|
||||||
originalPreviewContainer.style.display = 'flex';
|
originalPreviewContainer.style.display = 'flex';
|
||||||
translatedPreviewContainer.style.display = 'flex';
|
translatedPreviewContainer.style.display = 'flex';
|
||||||
[originalPreviewContainer, translatedPreviewContainer].forEach(el => {
|
[originalPreviewContainer, translatedPreviewContainer].forEach(el => {
|
||||||
@@ -1191,22 +1206,12 @@
|
|||||||
previewOffcanvasLabel.textContent = '双语预览';
|
previewOffcanvasLabel.textContent = '双语预览';
|
||||||
|
|
||||||
if (isMobileView) {
|
if (isMobileView) {
|
||||||
// Mobile: Vertical Split
|
|
||||||
previewSplitInstance = Split(['#originalPreviewContainer', '#translatedPreviewContainer'], {
|
previewSplitInstance = Split(['#originalPreviewContainer', '#translatedPreviewContainer'], {
|
||||||
direction: 'vertical',
|
direction: 'vertical', sizes: [50, 50], minSize: 150, gutterSize: 10, cursor: 'row-resize',
|
||||||
sizes: [50, 50],
|
|
||||||
minSize: 150, // Smaller min-size for vertical layout
|
|
||||||
gutterSize: 10,
|
|
||||||
cursor: 'row-resize',
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Desktop: Horizontal Split
|
|
||||||
previewSplitInstance = Split(['#originalPreviewContainer', '#translatedPreviewContainer'], {
|
previewSplitInstance = Split(['#originalPreviewContainer', '#translatedPreviewContainer'], {
|
||||||
direction: 'horizontal',
|
direction: 'horizontal', sizes: [50, 50], minSize: 200, gutterSize: 10, cursor: 'col-resize',
|
||||||
sizes: [50, 50],
|
|
||||||
minSize: 200,
|
|
||||||
gutterSize: 10,
|
|
||||||
cursor: 'col-resize',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user