function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type: contentType});
}
function uploadImageAI(blob) {
var formData = new FormData();
// 파일명은 임의로 지정 ("generated.png")
formData.append("file", blob, "generated.png");
// 기존에 숨겨진 input(#editor_nonce)이 있다면 사용하고,
// 없으면 전역 변수 ed_nonce를 사용합니다.
var nonceElem = document.getElementById('editor_nonce');
if (nonceElem && nonceElem.value) {
formData.append("editor_nonce", nonceElem.value);
} else if (ed_nonce) {
formData.append("editor_nonce", ed_nonce);
} else {
//console.warn("Nonce 값이 설정되어 있지 않습니다.");
}
return fetch(g5Config.g5_editor_url + '/php/rb.upload.php', {
method: 'POST',
body: formData
}).then(function(response) {
return response.json();
});
}
// 함수: 작업 유형에 따른 placeholder 변경
function updatePlaceholder() {
var taskType = document.querySelector('input[name="taskType"]:checked').value;
var promptInput = document.getElementById('prompt');
if (taskType === 'image') {
document.getElementById("prompt_ai_img").src = "./image/ai/Stability.svg";
promptInput.placeholder = "생성 하고자하는 주제를 영문(단어)로 입력하세요.";
} else {
document.getElementById("prompt_ai_img").src = "./image/ai/Gemini.svg";
promptInput.placeholder = "이전 대화를 기억하지 못합니다. 질의나 문장 생성용으로 사용하세요.";
}
}
// 엔터키 입력 시 바로 요청
document.getElementById('prompt').addEventListener('keydown', function (e) {
if (e.key === "Enter") {
e.preventDefault();
document.getElementById('generateBtn').click();
}
});
// 라디오 버튼 변경 시 플레이스홀더 업데이트
var radios = document.querySelectorAll('input[name="taskType"]');
radios.forEach(function (radio) {
radio.addEventListener('change', updatePlaceholder);
});
updatePlaceholder(); // 초기 로드시 설정
document.getElementById('generateBtn').addEventListener('click', function () {
var prompt = document.getElementById('prompt').value.trim();
var taskType = document.querySelector('input[name="taskType"]:checked').value; // 선택된 작업 유형
if (prompt === '') {
alert('생성하실 주제를 입력해 주세요.');
return;
}
var btn = document.getElementById('generateBtn');
btn.disabled = true;
btn.textContent = '생각 중..';
document.getElementById('result').innerHTML = '';
// 로딩 오버레이 표시
var overlay = document.querySelector(".loadingOverlay_ai");
overlay.style.display = "block";
// API 요청 데이터 설정
var formData = new URLSearchParams();
formData.append("prompt", prompt);
formData.append("taskType", taskType);
fetch(g5Config.g5_editor_url + '/plugin/ai/ajax.generate.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: formData.toString()
})
.then(response => response.json())
.then(data => {
var editor = document.getElementById("editor");
var accumulateCheckbox = document.getElementById('accumulateCheckbox');
if (taskType === 'text' && data.text) {
document.getElementById("prompt_ai_img").src = "./image/ai/Gemini.svg";
// 텍스트의 경우 누적 체크박스가 체크되지 않으면 에디터 초기화
if (!(accumulateCheckbox && accumulateCheckbox.checked)) {
editor.innerHTML = "";
}
var newText = document.createElement("div");
newText.innerHTML = data.text;
var emptyDiv = document.createElement("div");
emptyDiv.innerHTML = "
";
if (editor) {
editor.appendChild(newText);
editor.appendChild(emptyDiv); // 빈 줄 추가
} else {
//console.error("Error: #editor element not found.");
}
//document.getElementById('result').innerHTML = '
모델 : ' + data.model + '
'; // 텍스트 생성 후 입력창 비우기 document.getElementById('prompt').value = ""; } else if (taskType === 'image') { document.getElementById("prompt_ai_img").src = "./image/ai/Stability.svg"; if (data.image && data.image.length > 0) { // 이미지 생성 성공 시 if (!(accumulateCheckbox && accumulateCheckbox.checked)) { editor.innerHTML = ""; } // base64 데이터를 Blob으로 변환 (타입: image/png) var blob = b64toBlob(data.image, "image/png"); // 생성된 이미지를 업로드합니다. uploadImageAI(blob).then(function(uploadResponse) { if (uploadResponse.files && uploadResponse.files[0] && uploadResponse.files[0].url) { var fileUrl = uploadResponse.files[0].url; // ✅ .resizable_wrap 부모 div 생성 var resizableWrap = document.createElement("div"); resizableWrap.classList.add("resizable_wrap"); resizableWrap.style.position = "relative"; //resizableWrap.style.display = "inline-block"; // 부모 크기 유지 // ✅ AI 이미지용 wrapper 생성 (크기 및 리사이즈 핸들 포함) var newImage = document.createElement("div"); newImage.classList.add("resizable", "rb_ai_image"); newImage.style.width = "450px"; newImage.style.height = "300px"; newImage.style.position = "relative"; // 원본 크기와 비율을 data 속성에 추가 (원본 너비: 450, 원본 높이: 300) newImage.setAttribute("data-original-width", "450"); newImage.setAttribute("data-original-height", "300"); newImage.setAttribute("data-ratio", (300 / 450).toString()); newImage.innerHTML = `이미지 업로드 실패
'; } }).catch(function(err) { document.getElementById('result').innerHTML = '이미지 업로드 오류
'; }); } else { // 이미지 생성 실패 또는 에러 처리... if (data.error) { document.getElementById('result').innerHTML = '이미지 생성 실패
'; } else { document.getElementById('result').innerHTML = '잠시후 다시 생성해주세요.
'; } } } else if (data.error) { document.getElementById('result').innerHTML = '오류가 있습니다.
'; } overlay.style.display = "none"; btn.disabled = false; btn.textContent = '생성'; }) .catch(error => { document.getElementById('result').innerHTML = '오류가 있습니다.
'; document.querySelector(".loadingOverlay_ai").style.display = "none"; btn.disabled = false; btn.textContent = '생성'; }); });