/**
* history.js - プロンプト生成履歴の管理
*
* 主な機能:
* - 履歴の保存と読み込み
* - 履歴の検索
* - 履歴項目の編集と削除
* - ストレージ使用量の表示
*
* 重要な関数:
* - saveToHistory(): 新しい履歴項目を保存
* - updateHistoryList(): 履歴リストを更新
* - filterHistory(): 履歴の検索機能
* - loadHistoryItem(): 履歴項目を読み込み
*
* 注意事項:
* - 履歴の最大サイズは3MB
* - 容量超過時は古い履歴から自動削除
*/
function saveToHistory(title) {
if(!title) {
title = document.getElementById('query').value.slice(0, 10);
}
const historyItem = {
query: document.getElementById('query').value,
promptEn: document.getElementById('promptEn').value,
promptMyLanguage: document.getElementById('promptMyLanguage').value,
danbooruTags: document.getElementById('danbooruTags').value,
timestamp: new Date().toISOString(),
title: title
};
let history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
history.unshift(historyItem);
// 履歴の合計サイズが3MB以下になるまで古い項目を削除
while (JSON.stringify(history).length > 3 * 1024 * 1024) {
history.pop();
}
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
updateHistoryList();
}
function updateHistoryList() {
const historyList = document.getElementById('historyList');
const noHistoryMessage = document.getElementById('noHistoryMessage');
historyList.innerHTML = '';
const history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
if (history.length === 0) {
noHistoryMessage.classList.remove('d-none');
historyList.classList.add('d-none');
} else {
noHistoryMessage.classList.add('d-none');
historyList.classList.remove('d-none');
// 容量プログレスバーを追加
const storageUsage = JSON.stringify(history).length;
const storageLimit = 3 * 1024 * 1024; // 3MB
const usagePercentage = (storageUsage / storageLimit) * 100;
const progressBarContainer = document.createElement('div');
progressBarContainer.className = 'mb-3';
progressBarContainer.innerHTML = `
${(storageUsage / 1024 / 1024).toFixed(2)}MB / ${storageLimit / 1024 / 1024}MB
`;
historyList.appendChild(progressBarContainer);
// 検索フォームを追加
const searchForm = document.createElement('div');
searchForm.className = 'mb-3';
searchForm.innerHTML = `
`;
historyList.appendChild(searchForm);
history.forEach((item, index) => {
const li = document.createElement('li');
li.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-start';
li.dataset.item = JSON.stringify(item);
const contentDiv = document.createElement('div');
contentDiv.className = 'ms-2 me-auto';
contentDiv.style.cursor = 'pointer';
contentDiv.onclick = () => loadHistoryItem(index);
const titleDiv = document.createElement('div');
titleDiv.className = 'fw-bold text-truncate';
titleDiv.textContent = item.title || item.query.slice(0, 10);
const dateDiv = document.createElement('div');
dateDiv.className = 'small text-muted';
dateDiv.textContent = new Date(item.timestamp).toLocaleString();
contentDiv.appendChild(titleDiv);
contentDiv.appendChild(dateDiv);
const buttonsContainer = document.createElement('div');
buttonsContainer.className = 'd-flex';
const editButton = document.createElement('button');
editButton.className = 'btn btn-secondary btn-sm me-2';
editButton.innerHTML = '';
editButton.onclick = (e) => {
e.stopPropagation();
editHistoryItemTitle(index, titleDiv);
};
const deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-danger btn-sm';
deleteButton.innerHTML = '';
deleteButton.onclick = (e) => {
e.stopPropagation();
deleteHistoryItem(index);
};
buttonsContainer.appendChild(editButton);
buttonsContainer.appendChild(deleteButton);
li.appendChild(contentDiv);
li.appendChild(buttonsContainer);
historyList.appendChild(li);
contentDiv.style.width = `calc(100% - ${buttonsContainer.offsetWidth}px)`;
});
// 検索機能を追加
const searchInput = document.getElementById('historySearchInput');
searchInput.addEventListener('input', filterHistory);
}
}
function deleteHistoryItem(index) {
if (confirm('Are you sure you want to delete this history item?')) {
let history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
history.splice(index, 1);
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
updateHistoryList();
}
}
function loadHistoryItem(index) {
const history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
const item = history[index];
document.getElementById('query').value = item.query;
document.getElementById('promptEn').value = item.promptEn;
document.getElementById('promptMyLanguage').value = item.promptMyLanguage;
document.getElementById('danbooruTags').value = item.danbooruTags;
saveToUserStorage(true);
}
function clearHistory() {
if (confirm('Are you sure you want to delete all history items?')) {
localStorage.removeItem('gemini_prompt_history');
updateHistoryList();
}
}
function createHistoryItem(item, index) {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center';
const titleSpan = document.createElement('span');
titleSpan.textContent = item.title || item.query.slice(0, 10);
titleSpan.className = 'me-2';
li.appendChild(titleSpan);
const buttonsContainer = document.createElement('div');
const editButton = document.createElement('button');
editButton.className = 'btn btn-sm btn-secondary me-2';
editButton.innerHTML = '';
editButton.onclick = () => editHistoryItemTitle(index, titleSpan);
const useButton = document.createElement('button');
useButton.className = 'btn btn-sm btn-primary me-2';
useButton.innerHTML = '';
useButton.onclick = () => useHistoryItem(index);
const deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-sm btn-danger';
deleteButton.innerHTML = '';
deleteButton.onclick = () => {
if (confirm('Are you sure you want to delete this history item?')) {
deleteHistoryItem(index);
}
};
buttonsContainer.appendChild(editButton);
buttonsContainer.appendChild(useButton);
buttonsContainer.appendChild(deleteButton);
li.appendChild(buttonsContainer);
return li;
}
function editHistoryItemTitle(index, titleDiv) {
const history = JSON.parse(localStorage.getItem('gemini_prompt_history') || '[]');
const item = history[index];
const currentTitle = item.title || item.query.slice(0, 10);
const newTitle = prompt('New title:', currentTitle);
if (newTitle !== null && newTitle.trim() !== '') {
item.title = newTitle.trim();
history[index] = item;
localStorage.setItem('gemini_prompt_history', JSON.stringify(history));
titleDiv.textContent = newTitle.trim();
}
}
function filterHistory() {
const searchInput = document.getElementById('historySearchInput');
const searchTerm = searchInput.value.toLowerCase();
const historyItems = document.querySelectorAll('#historyList li[data-item]');
historyItems.forEach(item => {
const itemData = JSON.parse(item.dataset.item);
const searchableText = `${itemData.title} ${itemData.query} ${itemData.promptEn} ${itemData.promptMyLanguage} ${itemData.danbooruTags}`.toLowerCase();
if (searchableText.includes(searchTerm)) {
item.classList.remove('d-none');
} else {
item.classList.add('d-none');
}
});
}