mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
Merge branch 'master' of https://github.com/Azgaar/Fantasy-Map-Generator
This commit is contained in:
commit
efbab14d11
5 changed files with 139 additions and 4 deletions
87
modules/ui/ai-generator.js
Normal file
87
modules/ui/ai-generator.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"use strict";
|
||||
|
||||
const GPT_MODELS = ["gpt-4o-mini", "chatgpt-4o-latest", "gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"];
|
||||
const SYSTEM_MESSAGE = "I'm working on my fantasy map.";
|
||||
|
||||
function geneateWithAi(defaultPrompt, onApply) {
|
||||
updateValues();
|
||||
|
||||
$("#aiGenerator").dialog({
|
||||
title: "AI Text Generator",
|
||||
position: {my: "center", at: "center", of: "svg"},
|
||||
resizable: false,
|
||||
buttons: {
|
||||
Generate: function (e) {
|
||||
generate(e.target);
|
||||
},
|
||||
Apply: function () {
|
||||
const result = byId("aiGeneratorResult").value;
|
||||
if (!result) return tip("No result to apply", true, "error", 4000);
|
||||
onApply(result);
|
||||
$(this).dialog("close");
|
||||
},
|
||||
Close: function () {
|
||||
$(this).dialog("close");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (modules.geneateWithAi) return;
|
||||
modules.geneateWithAi = true;
|
||||
|
||||
function updateValues() {
|
||||
byId("aiGeneratorResult").value = "";
|
||||
byId("aiGeneratorPrompt").value = defaultPrompt;
|
||||
byId("aiGeneratorKey").value = localStorage.getItem("fmg-ai-kl") || "";
|
||||
|
||||
const select = byId("aiGeneratorModel");
|
||||
select.options.length = 0;
|
||||
GPT_MODELS.forEach(model => select.options.add(new Option(model, model)));
|
||||
select.value = localStorage.getItem("fmg-ai-model") || GPT_MODELS[0];
|
||||
}
|
||||
|
||||
async function generate(button) {
|
||||
const key = byId("aiGeneratorKey").value;
|
||||
if (!key) return tip("Please enter an OpenAI API key", true, "error", 4000);
|
||||
localStorage.setItem("fmg-ai-kl", key);
|
||||
|
||||
const model = byId("aiGeneratorModel").value;
|
||||
if (!model) return tip("Please select a model", true, "error", 4000);
|
||||
localStorage.setItem("fmg-ai-model", model);
|
||||
|
||||
const prompt = byId("aiGeneratorPrompt").value;
|
||||
if (!prompt) return tip("Please enter a prompt", true, "error", 4000);
|
||||
|
||||
try {
|
||||
button.disabled = true;
|
||||
byId("aiGeneratorResult").disabled = true;
|
||||
|
||||
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json", Authorization: `Bearer ${key}`},
|
||||
body: JSON.stringify({
|
||||
model,
|
||||
messages: [
|
||||
{role: "system", content: SYSTEM_MESSAGE},
|
||||
{role: "user", content: prompt}
|
||||
],
|
||||
temperature: 1.2
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
throw new Error(json?.error?.message || "Failed to generate");
|
||||
}
|
||||
|
||||
const {choices} = await response.json();
|
||||
const result = choices[0].message.content;
|
||||
byId("aiGeneratorResult").value = result;
|
||||
} catch (error) {
|
||||
return tip(error.message, true, "error", 4000);
|
||||
} finally {
|
||||
button.disabled = false;
|
||||
byId("aiGeneratorResult").disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -55,6 +55,7 @@ function editNotes(id, name) {
|
|||
byId("notesLegend").addEventListener("blur", updateLegend);
|
||||
byId("notesPin").addEventListener("click", toggleNotesPin);
|
||||
byId("notesFocus").addEventListener("click", validateHighlightElement);
|
||||
byId("notesGenerateWithAi").addEventListener("click", openAiGenerator);
|
||||
byId("notesDownload").addEventListener("click", downloadLegends);
|
||||
byId("notesUpload").addEventListener("click", () => legendsToLoad.click());
|
||||
byId("legendsToLoad").addEventListener("change", function () {
|
||||
|
|
@ -143,6 +144,25 @@ function editNotes(id, name) {
|
|||
});
|
||||
}
|
||||
|
||||
function openAiGenerator() {
|
||||
const note = notes.find(note => note.id === notesSelect.value);
|
||||
|
||||
let prompt = `Respond with description. Use simple dry language. Invent facts, names and details. Split to paragraphs and format to HTML. Remove h tags, remove markdown.`;
|
||||
if (note?.name) prompt += ` Name: ${note.name}.`;
|
||||
if (note?.legend) prompt += ` Data: ${note.legend}`;
|
||||
|
||||
const onApply = result => {
|
||||
notesLegend.innerHTML = result;
|
||||
if (note) {
|
||||
note.legend = result;
|
||||
updateNotesBox(note);
|
||||
if (window.tinymce) tinymce.activeEditor.setContent(note.legend);
|
||||
}
|
||||
};
|
||||
|
||||
geneateWithAi(prompt, onApply);
|
||||
}
|
||||
|
||||
function downloadLegends() {
|
||||
const notesData = JSON.stringify(notes);
|
||||
const name = getFileName("Notes") + ".txt";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue