Files
2025-02-11 09:03:15 +09:00

260 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- UI言語は英語で統一する。コメントは日本語可 -->
<title>ComfyUI Mobile Client</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
<style>
#inputList textarea {
min-height: 15vh;
}
#historyList img {
max-height: 15vh;
}
article .card-img-top {
object-fit: scale-down;
height: 200px;
width: 100%;
overflow: hidden;
transition: transform 0.2s;
}
article .card-img-top:hover {
transform: scale(1.02);
}
article .card {
overflow: hidden;
}
article .card-header small {
display: block;
max-height: 3em;
overflow: hidden;
text-overflow: ellipsis;
}
#imageModal .modal-body {
padding: 0;
background-color: rgba(0, 0, 0, 0.9);
}
#imageModal .modal-body img {
max-height: 90vh;
object-fit: contain;
}
#imageModal .btn-dark {
background-color: rgba(0, 0, 0, 0.5);
border: none;
padding: 1rem;
margin: 0 1rem;
}
#imageModal .btn-dark:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* スマートフォン向けのモーダルスタイル追加 */
@media (max-width: 767.98px) {
#promptEditModal .modal-dialog {
margin: 0;
max-width: 100%;
width: 100%;
height: 100%;
}
#promptEditModal .modal-content {
border: none;
border-radius: 0;
min-height: 100vh;
}
}
</style>
</head>
<body id="comfyui-mobile-client">
<header class="navbar navbar-expand-lg navbar-dark bg-dark sticky-top">
<div class="container-fluid">
<button class="btn btn-outline-light" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar"
aria-controls="sidebar">
<i class="fas fa-bars"></i>
</button>
<div class="navbar-brand mx-auto position-relative">
ComfyUI Mobile Client
<span id="queueRunningBadge" class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger d-none">
0
</span>
<span id="queuePendingBadge" class="position-absolute top-0 start-100 translate-middle ms-4 badge rounded-pill bg-success d-none">
0
</span>
</div>
</div>
</header>
<div class="offcanvas offcanvas-start" tabindex="-1" id="sidebar" aria-labelledby="sidebarLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="sidebarLabel">Settings</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<form id="settingsForm">
<!-- Server Connection -->
<div class="border-bottom pb-3 mb-4">
<div class="mb-3">
<label for="origin" class="form-label">Server Origin (Required)</label>
<input type="text" class="form-control" id="origin" required>
</div>
<div class="mb-3 d-none">
<label for="username" class="form-label">Username (Optional)</label>
<input type="text" class="form-control" id="username">
</div>
<div class="mb-3 d-none">
<label for="password" class="form-label">Password (Optional)</label>
<input type="password" class="form-control" id="password">
</div>
</div>
<!-- Prompt Generation Settings -->
<div class="border-bottom pb-3 mb-4">
<div class="mb-3">
<label for="seedKeyPatterns" class="form-label">Seed Key Patterns</label>
<input type="text" class="form-control" id="seedKeyPatterns"
placeholder="noise_seed, seed, etc... (comma-separated)">
<small class="form-text text-muted">Specify key patterns to identify seed values (comma-separated)</small>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="autoRandomizeSeed" checked>
<label class="form-check-label" for="autoRandomizeSeed">Auto Randomize Seeds</label>
</div>
</div>
<!-- Form Field Patterns -->
<div class="border-bottom pb-3 mb-4">
<div class="mb-3">
<label for="textareaKeyPatterns" class="form-label">Textarea Key Patterns</label>
<input type="text" class="form-control" id="textareaKeyPatterns"
placeholder="prompt, text, etc... (comma-separated)">
<small class="form-text text-muted">Specify key patterns to identify editable text fields (comma-separated)</small>
</div>
<div class="mb-3">
<label for="inputKeyPatterns" class="form-label">Input Key Patterns</label>
<input type="text" class="form-control" id="inputKeyPatterns"
placeholder="latent_name, image_name, etc... (comma-separated)">
<small class="form-text text-muted">Specify key patterns to identify single-line text fields (comma-separated)</small>
</div>
<div class="mb-3">
<label for="integerKeyPatterns" class="form-label">Integer Key Patterns</label>
<input type="text" class="form-control" id="integerKeyPatterns"
placeholder="steps, start_at_step, etc... (comma-separated)">
<small class="form-text text-muted">Specify key patterns to identify integer fields (comma-separated)</small>
</div>
<div class="mb-3">
<label for="floatKeyPatterns" class="form-label">Float Key Patterns</label>
<input type="text" class="form-control" id="floatKeyPatterns"
placeholder="cfg, etc... (comma-separated)">
<small class="form-text text-muted">Specify key patterns to identify decimal number fields (comma-separated)</small>
</div>
</div>
<!-- Queue Monitoring -->
<div class="border-bottom pb-3 mb-4">
<div class="mb-3">
<label for="retryInterval" class="form-label">Queue Status Check Interval (ms)</label>
<input type="number" class="form-control" id="retryInterval" value="1000" min="1000" step="100">
<small class="form-text text-muted">Interval for checking queue status. Setting too short may increase server load.</small>
</div>
<div class="mb-3 d-none">
<label class="form-label">Connection Test</label>
<div class="d-flex gap-2">
<button type="button" class="btn btn-secondary" id="testQueueStatus">Queue Status</button>
<button type="button" class="btn btn-secondary" id="testHistory">History</button>
</div>
</div>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">Save Settings</button>
<button type="button" class="btn btn-outline-danger" id="resetSettings">Reset to Default</button>
</div>
</form>
</div>
</div>
<!-- トースト通知 -->
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="loadingToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-body d-flex align-items-center">
<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
Loading gallery...
</div>
</div>
</div>
<!-- JSONアップロード領域 -->
<div class="container mt-2">
<h2 class="mb-3">Upload Workflow</h2>
<div class="card bg-dark border-secondary">
<div class="card-body py-2">
<input type="file" class="form-control form-control-sm" id="jsonFileInput" accept=".json">
</div>
</div>
</div>
<main id="gallery" class="container mt-4">
<article>
</article>
</main>
<!-- 画像表示用モーダル -->
<div class="modal fade" id="imageModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content bg-dark">
<div class="modal-header border-secondary">
<h5 class="modal-title text-light">Image View</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body d-flex align-items-center justify-content-center position-relative">
<button class="btn btn-dark position-absolute start-0 top-50 translate-middle-y" id="prevImage">
<i class="fas fa-chevron-left fa-2x"></i>
</button>
<img src="" class="img-fluid" id="modalImage" alt="Large Image">
<button class="btn btn-dark position-absolute end-0 top-50 translate-middle-y" id="nextImage">
<i class="fas fa-chevron-right fa-2x"></i>
</button>
</div>
</div>
</div>
</div>
<!-- プロンプト編集用モーダル -->
<div class="modal fade" id="promptEditModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header p-2">
<h5 class="modal-title">Edit Prompt</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="savePromptButton">Generate</button>
<hr>
<form id="promptEditForm"></form>
</div>
<div class="modal-footer d-none">
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="index.js"></script>
</body>
</html>