Spaces:
Running
Running
Upload 6 files
Browse files- control.js +12 -0
- history.js +56 -11
- index.html +27 -27
- prompt.js +10 -3
- translation.js +37 -8
control.js
CHANGED
|
@@ -20,3 +20,15 @@ document.getElementById('sidebarToggle').addEventListener('click', function () {
|
|
| 20 |
document.getElementById('sidebar').classList.toggle('active');
|
| 21 |
document.getElementById('content').classList.toggle('active');
|
| 22 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
document.getElementById('sidebar').classList.toggle('active');
|
| 21 |
document.getElementById('content').classList.toggle('active');
|
| 22 |
});
|
| 23 |
+
|
| 24 |
+
function resizeQueryTextarea() {
|
| 25 |
+
const queryTextarea = document.getElementById('query');
|
| 26 |
+
const cardBody = queryTextarea.closest('.card-body');
|
| 27 |
+
queryTextarea.style.minHeight = cardBody.offsetHeight + 'px';
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
document.addEventListener('DOMContentLoaded', function () {
|
| 31 |
+
resizeQueryTextarea();
|
| 32 |
+
});
|
| 33 |
+
|
| 34 |
+
window.addEventListener('resize', resizeQueryTextarea);
|
history.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
| 1 |
-
function saveToHistory() {
|
|
|
|
|
|
|
|
|
|
| 2 |
const historyItem = {
|
| 3 |
query: document.getElementById('query').value,
|
| 4 |
promptEn: document.getElementById('promptEn').value,
|
| 5 |
promptMyLanguage: document.getElementById('promptMyLanguage').value,
|
| 6 |
danbooruTags: document.getElementById('danbooruTags').value,
|
| 7 |
-
timestamp: new Date().toISOString()
|
|
|
|
| 8 |
};
|
| 9 |
|
| 10 |
let history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
|
| 11 |
history.unshift(historyItem);
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
| 13 |
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
|
| 14 |
|
| 15 |
updateHistoryList();
|
|
@@ -34,21 +41,31 @@ function updateHistoryList() {
|
|
| 34 |
|
| 35 |
const contentDiv = document.createElement('div');
|
| 36 |
contentDiv.className = 'ms-2 me-auto';
|
| 37 |
-
contentDiv.style.width = 'calc(100% - 40px)';
|
| 38 |
contentDiv.style.cursor = 'pointer';
|
| 39 |
contentDiv.onclick = () => loadHistoryItem(index);
|
| 40 |
|
| 41 |
-
const
|
| 42 |
-
|
| 43 |
-
|
| 44 |
|
| 45 |
const dateDiv = document.createElement('div');
|
| 46 |
dateDiv.className = 'small text-muted';
|
| 47 |
dateDiv.textContent = new Date(item.timestamp).toLocaleString();
|
| 48 |
|
| 49 |
-
contentDiv.appendChild(
|
| 50 |
contentDiv.appendChild(dateDiv);
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
const deleteButton = document.createElement('button');
|
| 53 |
deleteButton.className = 'btn btn-danger btn-sm';
|
| 54 |
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
|
|
@@ -57,9 +74,14 @@ function updateHistoryList() {
|
|
| 57 |
deleteHistoryItem(index);
|
| 58 |
};
|
| 59 |
|
|
|
|
|
|
|
|
|
|
| 60 |
li.appendChild(contentDiv);
|
| 61 |
-
li.appendChild(
|
| 62 |
historyList.appendChild(li);
|
|
|
|
|
|
|
| 63 |
});
|
| 64 |
}
|
| 65 |
}
|
|
@@ -93,10 +115,19 @@ function clearHistory() {
|
|
| 93 |
function createHistoryItem(item, index) {
|
| 94 |
const li = document.createElement('li');
|
| 95 |
li.className = 'list-group-item d-flex justify-content-between align-items-center';
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
const buttonsContainer = document.createElement('div');
|
| 99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
const useButton = document.createElement('button');
|
| 101 |
useButton.className = 'btn btn-sm btn-primary me-2';
|
| 102 |
useButton.innerHTML = '<i class="fas fa-redo"></i>';
|
|
@@ -106,15 +137,29 @@ function createHistoryItem(item, index) {
|
|
| 106 |
deleteButton.className = 'btn btn-sm btn-danger';
|
| 107 |
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
|
| 108 |
deleteButton.onclick = () => {
|
| 109 |
-
// 個別の履歴項目削除時にも確認ポップアップを表示
|
| 110 |
if (confirm('この履歴項目を削除してもよろしいですか?')) {
|
| 111 |
deleteHistoryItem(index);
|
| 112 |
}
|
| 113 |
};
|
| 114 |
|
|
|
|
| 115 |
buttonsContainer.appendChild(useButton);
|
| 116 |
buttonsContainer.appendChild(deleteButton);
|
| 117 |
li.appendChild(buttonsContainer);
|
| 118 |
|
| 119 |
return li;
|
| 120 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
function saveToHistory(title) {
|
| 2 |
+
if(!title) {
|
| 3 |
+
title = document.getElementById('query').value.slice(0, 10);
|
| 4 |
+
}
|
| 5 |
const historyItem = {
|
| 6 |
query: document.getElementById('query').value,
|
| 7 |
promptEn: document.getElementById('promptEn').value,
|
| 8 |
promptMyLanguage: document.getElementById('promptMyLanguage').value,
|
| 9 |
danbooruTags: document.getElementById('danbooruTags').value,
|
| 10 |
+
timestamp: new Date().toISOString(),
|
| 11 |
+
title: title
|
| 12 |
};
|
| 13 |
|
| 14 |
let history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
|
| 15 |
history.unshift(historyItem);
|
| 16 |
+
// 履歴の合計サイズが3MB以下になるまで古い項目を削除
|
| 17 |
+
while (JSON.stringify(history).length > 3 * 1024 * 1024) {
|
| 18 |
+
history.pop();
|
| 19 |
+
}
|
| 20 |
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
|
| 21 |
|
| 22 |
updateHistoryList();
|
|
|
|
| 41 |
|
| 42 |
const contentDiv = document.createElement('div');
|
| 43 |
contentDiv.className = 'ms-2 me-auto';
|
|
|
|
| 44 |
contentDiv.style.cursor = 'pointer';
|
| 45 |
contentDiv.onclick = () => loadHistoryItem(index);
|
| 46 |
|
| 47 |
+
const titleDiv = document.createElement('div');
|
| 48 |
+
titleDiv.className = 'fw-bold text-truncate';
|
| 49 |
+
titleDiv.textContent = item.title || item.query.slice(0, 10);
|
| 50 |
|
| 51 |
const dateDiv = document.createElement('div');
|
| 52 |
dateDiv.className = 'small text-muted';
|
| 53 |
dateDiv.textContent = new Date(item.timestamp).toLocaleString();
|
| 54 |
|
| 55 |
+
contentDiv.appendChild(titleDiv);
|
| 56 |
contentDiv.appendChild(dateDiv);
|
| 57 |
|
| 58 |
+
const buttonsContainer = document.createElement('div');
|
| 59 |
+
buttonsContainer.className = 'd-flex';
|
| 60 |
+
|
| 61 |
+
const editButton = document.createElement('button');
|
| 62 |
+
editButton.className = 'btn btn-secondary btn-sm me-2';
|
| 63 |
+
editButton.innerHTML = '<i class="fas fa-pencil-alt"></i>';
|
| 64 |
+
editButton.onclick = (e) => {
|
| 65 |
+
e.stopPropagation();
|
| 66 |
+
editHistoryItemTitle(index, titleDiv);
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
const deleteButton = document.createElement('button');
|
| 70 |
deleteButton.className = 'btn btn-danger btn-sm';
|
| 71 |
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
|
|
|
|
| 74 |
deleteHistoryItem(index);
|
| 75 |
};
|
| 76 |
|
| 77 |
+
buttonsContainer.appendChild(editButton);
|
| 78 |
+
buttonsContainer.appendChild(deleteButton);
|
| 79 |
+
|
| 80 |
li.appendChild(contentDiv);
|
| 81 |
+
li.appendChild(buttonsContainer);
|
| 82 |
historyList.appendChild(li);
|
| 83 |
+
|
| 84 |
+
contentDiv.style.width = `calc(100% - ${buttonsContainer.offsetWidth}px)`;
|
| 85 |
});
|
| 86 |
}
|
| 87 |
}
|
|
|
|
| 115 |
function createHistoryItem(item, index) {
|
| 116 |
const li = document.createElement('li');
|
| 117 |
li.className = 'list-group-item d-flex justify-content-between align-items-center';
|
| 118 |
+
|
| 119 |
+
const titleSpan = document.createElement('span');
|
| 120 |
+
titleSpan.textContent = item.title || item.query.slice(0, 10);
|
| 121 |
+
titleSpan.className = 'me-2';
|
| 122 |
+
li.appendChild(titleSpan);
|
| 123 |
|
| 124 |
const buttonsContainer = document.createElement('div');
|
| 125 |
|
| 126 |
+
const editButton = document.createElement('button');
|
| 127 |
+
editButton.className = 'btn btn-sm btn-secondary me-2';
|
| 128 |
+
editButton.innerHTML = '<i class="fas fa-pencil-alt"></i>';
|
| 129 |
+
editButton.onclick = () => editHistoryItemTitle(index, titleSpan);
|
| 130 |
+
|
| 131 |
const useButton = document.createElement('button');
|
| 132 |
useButton.className = 'btn btn-sm btn-primary me-2';
|
| 133 |
useButton.innerHTML = '<i class="fas fa-redo"></i>';
|
|
|
|
| 137 |
deleteButton.className = 'btn btn-sm btn-danger';
|
| 138 |
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
|
| 139 |
deleteButton.onclick = () => {
|
|
|
|
| 140 |
if (confirm('この履歴項目を削除してもよろしいですか?')) {
|
| 141 |
deleteHistoryItem(index);
|
| 142 |
}
|
| 143 |
};
|
| 144 |
|
| 145 |
+
buttonsContainer.appendChild(editButton);
|
| 146 |
buttonsContainer.appendChild(useButton);
|
| 147 |
buttonsContainer.appendChild(deleteButton);
|
| 148 |
li.appendChild(buttonsContainer);
|
| 149 |
|
| 150 |
return li;
|
| 151 |
}
|
| 152 |
+
|
| 153 |
+
function editHistoryItemTitle(index, titleDiv) {
|
| 154 |
+
const history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
|
| 155 |
+
const item = history[index];
|
| 156 |
+
const currentTitle = item.title || item.query.slice(0, 10);
|
| 157 |
+
|
| 158 |
+
const newTitle = prompt('新しいタイトルを入力してください:', currentTitle);
|
| 159 |
+
if (newTitle !== null && newTitle.trim() !== '') {
|
| 160 |
+
item.title = newTitle.trim();
|
| 161 |
+
history[index] = item;
|
| 162 |
+
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
|
| 163 |
+
titleDiv.textContent = newTitle.trim();
|
| 164 |
+
}
|
| 165 |
+
}
|
index.html
CHANGED
|
@@ -9,20 +9,14 @@
|
|
| 9 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
|
| 10 |
crossorigin="anonymous">
|
| 11 |
<style>
|
| 12 |
-
|
| 13 |
-
min-height:
|
| 14 |
}
|
| 15 |
-
|
| 16 |
-
#promptEn,
|
| 17 |
-
#promptMyLanguage {
|
| 18 |
-
min-height: 20vh;
|
| 19 |
-
}
|
| 20 |
-
|
| 21 |
#sidebar {
|
| 22 |
position: fixed;
|
| 23 |
top: 0;
|
| 24 |
-
left: -
|
| 25 |
-
width:
|
| 26 |
height: 100%;
|
| 27 |
background-color: #343a40;
|
| 28 |
transition: 0.3s;
|
|
@@ -35,12 +29,18 @@
|
|
| 35 |
|
| 36 |
#content {
|
| 37 |
transition: margin-left 0.3s;
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
#content.active {
|
| 41 |
margin-left: 250px;
|
| 42 |
}
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
#historyContainer::-webkit-scrollbar {
|
| 45 |
width: 5px;
|
| 46 |
}
|
|
@@ -81,6 +81,10 @@
|
|
| 81 |
width: 100%;
|
| 82 |
height: auto;
|
| 83 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
}
|
| 85 |
|
| 86 |
@keyframes comic-frame-switch {
|
|
@@ -104,7 +108,6 @@
|
|
| 104 |
<h3 id="settingsTitle" class="text-white">設定</h3>
|
| 105 |
<div class="form-group mb-3">
|
| 106 |
<label for="apiKey" class="form-label" id="apiKeyLabel">
|
| 107 |
-
|
| 108 |
<a href="https://aistudio.google.com/app/apikey?hl=ja" target="_blank">APIキー</a>
|
| 109 |
</label>
|
| 110 |
<input type="text" class="form-control" id="apiKey" placeholder="APIキーを入力してください">
|
|
@@ -134,13 +137,12 @@
|
|
| 134 |
<option value="gemini-1.5-flash-exp-0827">gemini-1.5-flash-exp-0827</option>
|
| 135 |
<option value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option>
|
| 136 |
<option value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option>
|
| 137 |
-
|
| 138 |
</select>
|
| 139 |
</div>
|
| 140 |
|
| 141 |
<h3 class="text-white mt-4">履歴</h3>
|
| 142 |
-
<div id="historyContainer"
|
| 143 |
-
<ul id="historyList" class="list-group">
|
| 144 |
<!-- 履歴項目がここに動的に追加されます -->
|
| 145 |
</ul>
|
| 146 |
<p id="noHistoryMessage" class="text-white mt-2 d-none">履歴がありません。</p>
|
|
@@ -149,7 +151,7 @@
|
|
| 149 |
<!-- デバッグ用のモーダル表示ボタンを追加 -->
|
| 150 |
<div class="mt-4">
|
| 151 |
<button id="showLoadingModalButton" class="btn btn-secondary w-100">
|
| 152 |
-
|
| 153 |
</button>
|
| 154 |
</div>
|
| 155 |
</div>
|
|
@@ -157,7 +159,7 @@
|
|
| 157 |
|
| 158 |
<div id="content">
|
| 159 |
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
| 160 |
-
<div class="container
|
| 161 |
<button id="sidebarToggle" class="btn btn-outline-light me-2">
|
| 162 |
<i class="fas fa-bars"></i>
|
| 163 |
</button>
|
|
@@ -167,8 +169,8 @@
|
|
| 167 |
|
| 168 |
<div class="container mt-3">
|
| 169 |
<div class="row">
|
| 170 |
-
<div id="inputQuery" class="col-md-
|
| 171 |
-
<div class="card">
|
| 172 |
<div class="card-header bg-primary text-white">
|
| 173 |
<h5 class="mb-0" id="inputQueryTitle">入力クエリ</h5>
|
| 174 |
</div>
|
|
@@ -192,26 +194,25 @@
|
|
| 192 |
</div>
|
| 193 |
</div>
|
| 194 |
</div>
|
| 195 |
-
<div id="outputPrompt" class="col-md-
|
| 196 |
-
<div class="card">
|
| 197 |
<div class="card-header bg-success text-white">
|
| 198 |
<h5 class="mb-0" id="outputPromptTitle">生成されたプロンプト</h5>
|
| 199 |
</div>
|
| 200 |
<div class="card-body">
|
| 201 |
<div class="form-group">
|
| 202 |
-
<
|
| 203 |
-
|
| 204 |
</div>
|
| 205 |
<div class="form-group mt-3">
|
| 206 |
-
<
|
| 207 |
-
|
| 208 |
</div>
|
| 209 |
<div class="form-group mt-3">
|
| 210 |
<label for="danbooruTags" class="form-label" id="danbooruTagsLabel">
|
| 211 |
danbooru tags
|
| 212 |
</label>
|
| 213 |
-
<input type="text" class="form-control" id="danbooruTags" placeholder="danbooru tags"
|
| 214 |
-
readonly>
|
| 215 |
</div>
|
| 216 |
</div>
|
| 217 |
</div>
|
|
@@ -251,7 +252,6 @@
|
|
| 251 |
|
| 252 |
<script>
|
| 253 |
document.getElementById('showLoadingModalButton').addEventListener('click', function () {
|
| 254 |
-
|
| 255 |
var loadingModal = new bootstrap.Modal(document.getElementById('loadingModal'));
|
| 256 |
loadingModal.show();
|
| 257 |
});
|
|
|
|
| 9 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
|
| 10 |
crossorigin="anonymous">
|
| 11 |
<style>
|
| 12 |
+
textarea.form-control {
|
| 13 |
+
min-height: 15vh;
|
| 14 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
#sidebar {
|
| 16 |
position: fixed;
|
| 17 |
top: 0;
|
| 18 |
+
left: -16em;
|
| 19 |
+
width: 16rem;
|
| 20 |
height: 100%;
|
| 21 |
background-color: #343a40;
|
| 22 |
transition: 0.3s;
|
|
|
|
| 29 |
|
| 30 |
#content {
|
| 31 |
transition: margin-left 0.3s;
|
| 32 |
+
min-height: 100vh;
|
| 33 |
}
|
| 34 |
|
| 35 |
#content.active {
|
| 36 |
margin-left: 250px;
|
| 37 |
}
|
| 38 |
|
| 39 |
+
#historyContainer {
|
| 40 |
+
max-height: 300px;
|
| 41 |
+
overflow-y: auto;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
#historyContainer::-webkit-scrollbar {
|
| 45 |
width: 5px;
|
| 46 |
}
|
|
|
|
| 81 |
width: 100%;
|
| 82 |
height: auto;
|
| 83 |
}
|
| 84 |
+
.form-group {
|
| 85 |
+
padding-left: 1rem;
|
| 86 |
+
padding-right: 1rem;
|
| 87 |
+
}
|
| 88 |
}
|
| 89 |
|
| 90 |
@keyframes comic-frame-switch {
|
|
|
|
| 108 |
<h3 id="settingsTitle" class="text-white">設定</h3>
|
| 109 |
<div class="form-group mb-3">
|
| 110 |
<label for="apiKey" class="form-label" id="apiKeyLabel">
|
|
|
|
| 111 |
<a href="https://aistudio.google.com/app/apikey?hl=ja" target="_blank">APIキー</a>
|
| 112 |
</label>
|
| 113 |
<input type="text" class="form-control" id="apiKey" placeholder="APIキーを入力してください">
|
|
|
|
| 137 |
<option value="gemini-1.5-flash-exp-0827">gemini-1.5-flash-exp-0827</option>
|
| 138 |
<option value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option>
|
| 139 |
<option value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option>
|
|
|
|
| 140 |
</select>
|
| 141 |
</div>
|
| 142 |
|
| 143 |
<h3 class="text-white mt-4">履歴</h3>
|
| 144 |
+
<div id="historyContainer">
|
| 145 |
+
<ul id="historyList" class="list-group small">
|
| 146 |
<!-- 履歴項目がここに動的に追加されます -->
|
| 147 |
</ul>
|
| 148 |
<p id="noHistoryMessage" class="text-white mt-2 d-none">履歴がありません。</p>
|
|
|
|
| 151 |
<!-- デバッグ用のモーダル表示ボタンを追加 -->
|
| 152 |
<div class="mt-4">
|
| 153 |
<button id="showLoadingModalButton" class="btn btn-secondary w-100">
|
| 154 |
+
Show Modal
|
| 155 |
</button>
|
| 156 |
</div>
|
| 157 |
</div>
|
|
|
|
| 159 |
|
| 160 |
<div id="content">
|
| 161 |
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
| 162 |
+
<div class="container">
|
| 163 |
<button id="sidebarToggle" class="btn btn-outline-light me-2">
|
| 164 |
<i class="fas fa-bars"></i>
|
| 165 |
</button>
|
|
|
|
| 169 |
|
| 170 |
<div class="container mt-3">
|
| 171 |
<div class="row">
|
| 172 |
+
<div id="inputQuery" class="col-lg-4 col-md-12 mb-4">
|
| 173 |
+
<div class="card h-100">
|
| 174 |
<div class="card-header bg-primary text-white">
|
| 175 |
<h5 class="mb-0" id="inputQueryTitle">入力クエリ</h5>
|
| 176 |
</div>
|
|
|
|
| 194 |
</div>
|
| 195 |
</div>
|
| 196 |
</div>
|
| 197 |
+
<div id="outputPrompt" class="col-lg-8 col-md-12 mb-4">
|
| 198 |
+
<div class="card h-100">
|
| 199 |
<div class="card-header bg-success text-white">
|
| 200 |
<h5 class="mb-0" id="outputPromptTitle">生成されたプロンプト</h5>
|
| 201 |
</div>
|
| 202 |
<div class="card-body">
|
| 203 |
<div class="form-group">
|
| 204 |
+
<label for="promptEn" class="form-label" id="promptEnLabel">English Prompt</label>
|
| 205 |
+
<textarea class="form-control" id="promptEn" placeholder="English Prompt"></textarea>
|
| 206 |
</div>
|
| 207 |
<div class="form-group mt-3">
|
| 208 |
+
<label for="promptMyLanguage" class="form-label" id="promptMyLanguageLabel">Your Language Translation</label>
|
| 209 |
+
<textarea class="form-control" id="promptMyLanguage" disabled></textarea>
|
| 210 |
</div>
|
| 211 |
<div class="form-group mt-3">
|
| 212 |
<label for="danbooruTags" class="form-label" id="danbooruTagsLabel">
|
| 213 |
danbooru tags
|
| 214 |
</label>
|
| 215 |
+
<input type="text" class="form-control" id="danbooruTags" placeholder="danbooru tags" readonly>
|
|
|
|
| 216 |
</div>
|
| 217 |
</div>
|
| 218 |
</div>
|
|
|
|
| 252 |
|
| 253 |
<script>
|
| 254 |
document.getElementById('showLoadingModalButton').addEventListener('click', function () {
|
|
|
|
| 255 |
var loadingModal = new bootstrap.Modal(document.getElementById('loadingModal'));
|
| 256 |
loadingModal.show();
|
| 257 |
});
|
prompt.js
CHANGED
|
@@ -17,7 +17,8 @@ function generatePrompt() {
|
|
| 17 |
anotherLanguage = `,
|
| 18 |
{
|
| 19 |
"language": "${i18next.language}",
|
| 20 |
-
"text": ${textFormat}
|
|
|
|
| 21 |
}`;
|
| 22 |
}
|
| 23 |
|
|
@@ -34,6 +35,7 @@ function generatePrompt() {
|
|
| 34 |
{
|
| 35 |
"language": "en",
|
| 36 |
"text": ${textFormat} # ${document.getElementById('characterCount').value}文字程度,
|
|
|
|
| 37 |
},
|
| 38 |
{
|
| 39 |
"language": "danbooru",
|
|
@@ -41,7 +43,8 @@ function generatePrompt() {
|
|
| 41 |
},
|
| 42 |
{
|
| 43 |
"language": "ja",
|
| 44 |
-
"text": ${textFormat}
|
|
|
|
| 45 |
}${anotherLanguage}
|
| 46 |
]
|
| 47 |
}
|
|
@@ -123,14 +126,17 @@ function generatePrompt() {
|
|
| 123 |
document.getElementById('danbooruTags').value = danbooruTags.join(", ");
|
| 124 |
}
|
| 125 |
|
|
|
|
| 126 |
|
| 127 |
// ローディングアイコンを非表示
|
| 128 |
document.getElementById('loading').classList.add('d-none');
|
| 129 |
document.getElementById('generatePromptButton').disabled = false;
|
| 130 |
document.getElementById('generatePromptButton').classList.remove('btn-secondary');
|
| 131 |
document.getElementById('generatePromptButton').classList.add('btn-primary');
|
|
|
|
|
|
|
| 132 |
saveToUserStorage(true);
|
| 133 |
-
saveToHistory(); // 履歴に保存
|
| 134 |
})
|
| 135 |
.catch(error => {
|
| 136 |
console.error(error);
|
|
@@ -139,6 +145,7 @@ function generatePrompt() {
|
|
| 139 |
document.getElementById('generatePromptButton').classList.add('btn-danger');
|
| 140 |
})
|
| 141 |
.finally(() => {
|
|
|
|
| 142 |
// ローディングアイコンを非表示
|
| 143 |
document.getElementById('loading').classList.add('d-none');
|
| 144 |
document.getElementById('generatePromptButton').disabled = false;
|
|
|
|
| 17 |
anotherLanguage = `,
|
| 18 |
{
|
| 19 |
"language": "${i18next.language}",
|
| 20 |
+
"text": ${textFormat},
|
| 21 |
+
"title": str
|
| 22 |
}`;
|
| 23 |
}
|
| 24 |
|
|
|
|
| 35 |
{
|
| 36 |
"language": "en",
|
| 37 |
"text": ${textFormat} # ${document.getElementById('characterCount').value}文字程度,
|
| 38 |
+
"title": str
|
| 39 |
},
|
| 40 |
{
|
| 41 |
"language": "danbooru",
|
|
|
|
| 43 |
},
|
| 44 |
{
|
| 45 |
"language": "ja",
|
| 46 |
+
"text": ${textFormat},
|
| 47 |
+
"title": str
|
| 48 |
}${anotherLanguage}
|
| 49 |
]
|
| 50 |
}
|
|
|
|
| 126 |
document.getElementById('danbooruTags').value = danbooruTags.join(", ");
|
| 127 |
}
|
| 128 |
|
| 129 |
+
const title = parsedData.results.find(x => x.language === i18next.language).title;
|
| 130 |
|
| 131 |
// ローディングアイコンを非表示
|
| 132 |
document.getElementById('loading').classList.add('d-none');
|
| 133 |
document.getElementById('generatePromptButton').disabled = false;
|
| 134 |
document.getElementById('generatePromptButton').classList.remove('btn-secondary');
|
| 135 |
document.getElementById('generatePromptButton').classList.add('btn-primary');
|
| 136 |
+
|
| 137 |
+
document.getElementById('query').value = query;
|
| 138 |
saveToUserStorage(true);
|
| 139 |
+
saveToHistory(title); // 履歴に保存
|
| 140 |
})
|
| 141 |
.catch(error => {
|
| 142 |
console.error(error);
|
|
|
|
| 145 |
document.getElementById('generatePromptButton').classList.add('btn-danger');
|
| 146 |
})
|
| 147 |
.finally(() => {
|
| 148 |
+
document.getElementById('query').value = query;
|
| 149 |
// ローディングアイコンを非表示
|
| 150 |
document.getElementById('loading').classList.add('d-none');
|
| 151 |
document.getElementById('generatePromptButton').disabled = false;
|
translation.js
CHANGED
|
@@ -11,7 +11,10 @@ const translations = {
|
|
| 11 |
promptEnPlaceholder: "英語のプロンプトがここに表示されます",
|
| 12 |
promptMyLanguagePlaceholder: "日本訳がここに表示されます",
|
| 13 |
apiKeyPlaceholder: "APIキーを入力してください",
|
| 14 |
-
characterCountPlaceholder: "生成するプロンプトの文字数を入力してください"
|
|
|
|
|
|
|
|
|
|
| 15 |
},
|
| 16 |
en: {
|
| 17 |
inputQueryTitle: "Input Query",
|
|
@@ -25,7 +28,10 @@ const translations = {
|
|
| 25 |
promptEnPlaceholder: "English prompt will be displayed here",
|
| 26 |
promptMyLanguagePlaceholder: "Translation will be displayed here",
|
| 27 |
apiKeyPlaceholder: "Enter your API key",
|
| 28 |
-
characterCountPlaceholder: "Enter the number of characters for the generated prompt"
|
|
|
|
|
|
|
|
|
|
| 29 |
},
|
| 30 |
zh: {
|
| 31 |
inputQueryTitle: "输入查询",
|
|
@@ -39,7 +45,10 @@ const translations = {
|
|
| 39 |
promptEnPlaceholder: "英文提示将显示在这里",
|
| 40 |
promptMyLanguagePlaceholder: "翻译将显示在这里",
|
| 41 |
apiKeyPlaceholder: "请输入您的API密钥",
|
| 42 |
-
characterCountPlaceholder: "请输入生成提示的字符数"
|
|
|
|
|
|
|
|
|
|
| 43 |
},
|
| 44 |
ko: {
|
| 45 |
inputQueryTitle: "입력 쿼리",
|
|
@@ -53,7 +62,10 @@ const translations = {
|
|
| 53 |
promptEnPlaceholder: "영어 프롬프트가 여기에 표시됩니다",
|
| 54 |
promptMyLanguagePlaceholder: "번역이 여기에 표시됩니다",
|
| 55 |
apiKeyPlaceholder: "API 키를 입력하세요",
|
| 56 |
-
characterCountPlaceholder: "생성할 프롬프트의 문자 수를 입력하세요"
|
|
|
|
|
|
|
|
|
|
| 57 |
},
|
| 58 |
fr: {
|
| 59 |
inputQueryTitle: "Requête d'entrée",
|
|
@@ -67,7 +79,10 @@ const translations = {
|
|
| 67 |
promptEnPlaceholder: "Le prompt en anglais s'affichera ici",
|
| 68 |
promptMyLanguagePlaceholder: "La traduction s'affichera ici",
|
| 69 |
apiKeyPlaceholder: "Entrez votre clé API",
|
| 70 |
-
characterCountPlaceholder: "Entrez le nombre de caractères pour le prompt généré"
|
|
|
|
|
|
|
|
|
|
| 71 |
},
|
| 72 |
es: {
|
| 73 |
inputQueryTitle: "Consulta de entrada",
|
|
@@ -81,7 +96,10 @@ const translations = {
|
|
| 81 |
promptEnPlaceholder: "El prompt en inglés se mostrará aquí",
|
| 82 |
promptMyLanguagePlaceholder: "La traducción se mostrará aquí",
|
| 83 |
apiKeyPlaceholder: "Ingrese su clave API",
|
| 84 |
-
characterCountPlaceholder: "Ingrese el número de caracteres para el prompt generado"
|
|
|
|
|
|
|
|
|
|
| 85 |
},
|
| 86 |
de: {
|
| 87 |
inputQueryTitle: "Eingabeabfrage",
|
|
@@ -95,7 +113,10 @@ const translations = {
|
|
| 95 |
promptEnPlaceholder: "Der englische Prompt wird hier angezeigt",
|
| 96 |
promptMyLanguagePlaceholder: "Die Übersetzung wird hier angezeigt",
|
| 97 |
apiKeyPlaceholder: "Geben Sie Ihren API-Schlüssel ein",
|
| 98 |
-
characterCountPlaceholder: "Geben Sie die Anzahl der Zeichen für den generierten Prompt ein"
|
|
|
|
|
|
|
|
|
|
| 99 |
},
|
| 100 |
it: {
|
| 101 |
inputQueryTitle: "Query di input",
|
|
@@ -109,7 +130,10 @@ const translations = {
|
|
| 109 |
promptEnPlaceholder: "Il prompt in inglese verrà visualizzato qui",
|
| 110 |
promptMyLanguagePlaceholder: "La traduzione verrà visualizzata qui",
|
| 111 |
apiKeyPlaceholder: "Inserisci la tua chiave API",
|
| 112 |
-
characterCountPlaceholder: "Inserisci il numero di caratteri per il prompt generato"
|
|
|
|
|
|
|
|
|
|
| 113 |
}
|
| 114 |
}
|
| 115 |
const resources = {
|
|
@@ -169,6 +193,11 @@ function updateContent() {
|
|
| 169 |
document.getElementById('promptMyLanguage').placeholder = i18next.t('promptMyLanguagePlaceholder');
|
| 170 |
document.getElementById('apiKey').placeholder = i18next.t('apiKeyPlaceholder');
|
| 171 |
document.getElementById('characterCount').placeholder = i18next.t('characterCountPlaceholder');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
}
|
| 173 |
|
| 174 |
// 言語切り替え関数
|
|
|
|
| 11 |
promptEnPlaceholder: "英語のプロンプトがここに表示されます",
|
| 12 |
promptMyLanguagePlaceholder: "日本訳がここに表示されます",
|
| 13 |
apiKeyPlaceholder: "APIキーを入力してください",
|
| 14 |
+
characterCountPlaceholder: "生成するプロンプトの文字数を入力してください",
|
| 15 |
+
endpointSelectLabel: "エンドポイント",
|
| 16 |
+
historyTitle: "履歴",
|
| 17 |
+
noHistoryMessage: "履歴がありません。"
|
| 18 |
},
|
| 19 |
en: {
|
| 20 |
inputQueryTitle: "Input Query",
|
|
|
|
| 28 |
promptEnPlaceholder: "English prompt will be displayed here",
|
| 29 |
promptMyLanguagePlaceholder: "Translation will be displayed here",
|
| 30 |
apiKeyPlaceholder: "Enter your API key",
|
| 31 |
+
characterCountPlaceholder: "Enter the number of characters for the generated prompt",
|
| 32 |
+
endpointSelectLabel: "Endpoint",
|
| 33 |
+
historyTitle: "History",
|
| 34 |
+
noHistoryMessage: "No history available."
|
| 35 |
},
|
| 36 |
zh: {
|
| 37 |
inputQueryTitle: "输入查询",
|
|
|
|
| 45 |
promptEnPlaceholder: "英文提示将显示在这里",
|
| 46 |
promptMyLanguagePlaceholder: "翻译将显示在这里",
|
| 47 |
apiKeyPlaceholder: "请输入您的API密钥",
|
| 48 |
+
characterCountPlaceholder: "请输入生成提示的字符数",
|
| 49 |
+
endpointSelectLabel: "端点",
|
| 50 |
+
historyTitle: "历史记录",
|
| 51 |
+
noHistoryMessage: "没有可用的历史记录。"
|
| 52 |
},
|
| 53 |
ko: {
|
| 54 |
inputQueryTitle: "입력 쿼리",
|
|
|
|
| 62 |
promptEnPlaceholder: "영어 프롬프트가 여기에 표시됩니다",
|
| 63 |
promptMyLanguagePlaceholder: "번역이 여기에 표시됩니다",
|
| 64 |
apiKeyPlaceholder: "API 키를 입력하세요",
|
| 65 |
+
characterCountPlaceholder: "생성할 프롬프트의 문자 수를 입력하세요",
|
| 66 |
+
endpointSelectLabel: "엔드포인트",
|
| 67 |
+
historyTitle: "기록",
|
| 68 |
+
noHistoryMessage: "사용 가능한 기록이 없습니다."
|
| 69 |
},
|
| 70 |
fr: {
|
| 71 |
inputQueryTitle: "Requête d'entrée",
|
|
|
|
| 79 |
promptEnPlaceholder: "Le prompt en anglais s'affichera ici",
|
| 80 |
promptMyLanguagePlaceholder: "La traduction s'affichera ici",
|
| 81 |
apiKeyPlaceholder: "Entrez votre clé API",
|
| 82 |
+
characterCountPlaceholder: "Entrez le nombre de caractères pour le prompt généré",
|
| 83 |
+
endpointSelectLabel: "Point de terminaison",
|
| 84 |
+
historyTitle: "Historique",
|
| 85 |
+
noHistoryMessage: "Aucun historique disponible."
|
| 86 |
},
|
| 87 |
es: {
|
| 88 |
inputQueryTitle: "Consulta de entrada",
|
|
|
|
| 96 |
promptEnPlaceholder: "El prompt en inglés se mostrará aquí",
|
| 97 |
promptMyLanguagePlaceholder: "La traducción se mostrará aquí",
|
| 98 |
apiKeyPlaceholder: "Ingrese su clave API",
|
| 99 |
+
characterCountPlaceholder: "Ingrese el número de caracteres para el prompt generado",
|
| 100 |
+
endpointSelectLabel: "Punto final",
|
| 101 |
+
historyTitle: "Historial",
|
| 102 |
+
noHistoryMessage: "No hay historial disponible."
|
| 103 |
},
|
| 104 |
de: {
|
| 105 |
inputQueryTitle: "Eingabeabfrage",
|
|
|
|
| 113 |
promptEnPlaceholder: "Der englische Prompt wird hier angezeigt",
|
| 114 |
promptMyLanguagePlaceholder: "Die Übersetzung wird hier angezeigt",
|
| 115 |
apiKeyPlaceholder: "Geben Sie Ihren API-Schlüssel ein",
|
| 116 |
+
characterCountPlaceholder: "Geben Sie die Anzahl der Zeichen für den generierten Prompt ein",
|
| 117 |
+
endpointSelectLabel: "Endpunkt",
|
| 118 |
+
historyTitle: "Verlauf",
|
| 119 |
+
noHistoryMessage: "Kein Verlauf verfügbar."
|
| 120 |
},
|
| 121 |
it: {
|
| 122 |
inputQueryTitle: "Query di input",
|
|
|
|
| 130 |
promptEnPlaceholder: "Il prompt in inglese verrà visualizzato qui",
|
| 131 |
promptMyLanguagePlaceholder: "La traduzione verrà visualizzata qui",
|
| 132 |
apiKeyPlaceholder: "Inserisci la tua chiave API",
|
| 133 |
+
characterCountPlaceholder: "Inserisci il numero di caratteri per il prompt generato",
|
| 134 |
+
endpointSelectLabel: "Endpoint",
|
| 135 |
+
historyTitle: "Cronologia",
|
| 136 |
+
noHistoryMessage: "Nessuna cronologia disponibile."
|
| 137 |
}
|
| 138 |
}
|
| 139 |
const resources = {
|
|
|
|
| 193 |
document.getElementById('promptMyLanguage').placeholder = i18next.t('promptMyLanguagePlaceholder');
|
| 194 |
document.getElementById('apiKey').placeholder = i18next.t('apiKeyPlaceholder');
|
| 195 |
document.getElementById('characterCount').placeholder = i18next.t('characterCountPlaceholder');
|
| 196 |
+
|
| 197 |
+
// エンドポイントと履歴のテキストを更新
|
| 198 |
+
document.getElementById('endpointSelectLabel').textContent = i18next.t('endpointSelectLabel');
|
| 199 |
+
document.querySelector('#sidebar h3:nth-of-type(2)').textContent = i18next.t('historyTitle');
|
| 200 |
+
document.getElementById('noHistoryMessage').textContent = i18next.t('noHistoryMessage');
|
| 201 |
}
|
| 202 |
|
| 203 |
// 言語切り替え関数
|