diff --git a/aiserver.py b/aiserver.py index b38bfd8e..7bba54c4 100644 --- a/aiserver.py +++ b/aiserver.py @@ -8779,6 +8779,32 @@ def UI_2_update_wi_keys(data): # Send to UI socketio.emit("world_info_entry", koboldai_vars.worldinfo_v2.world_info[uid], broadcast=True, room="UI_2") +@app.route("/set_wi_image/", methods=["POST"]) +@logger.catch +def UI_2_set_wi_image(uid): + if uid < 0: + socketio.emit("delete_new_world_info_entry", {}) + uid = koboldai_vars.worldinfo_v2.add_item( + "New World Info Entry", + [], + [], + None, + False, + "", + "", + ) + + koboldai_vars.worldinfo_v2.image_store[str(uid)] = request.get_data(as_text=True) + return ":)" + +@app.route("/get_wi_image/", methods=["GET"]) +@logger.catch +def UI_2_get_wi_image(uid): + try: + return koboldai_vars.worldinfo_v2.image_store[str(uid)] + except KeyError: + return ":( Couldn't find image", 404 + @socketio.on("scratchpad_prompt") @logger.catch def UI_2_scratchpad_prompt(data): diff --git a/koboldai_settings.py b/koboldai_settings.py index 4249c604..83ed345b 100644 --- a/koboldai_settings.py +++ b/koboldai_settings.py @@ -1650,6 +1650,7 @@ class KoboldWorldInfo(object): self.world_info = {} self.world_info_folder = OrderedDict() self.world_info_folder['root'] = [] + self.image_store = {} self.story_settings = story_settings def reset(self): @@ -1854,10 +1855,15 @@ class KoboldWorldInfo(object): def delete(self, uid): del self.world_info[uid] + + if uid in self.image_store: + del self.image_store[uid] + for folder in self.world_info_folder: if uid in self.world_info_folder[folder]: self.world_info_folder[folder].remove(uid) + self.story_settings.gamesaved = False self.sync_world_info_to_old_format() if self.socketio is not None: @@ -1909,15 +1915,24 @@ class KoboldWorldInfo(object): if folder is None: return { "folders": {x: self.world_info_folder[x] for x in self.world_info_folder}, - "entries": self.world_info + "entries": self.world_info, + "images": self.image_store } else: return { "folders": {x: self.world_info_folder[x] for x in self.world_info_folder if x == folder}, - "entries": {x: self.world_info[x] for x in self.world_info if self.world_info[x]['folder'] == folder} + "entries": {x: self.world_info[x] for x in self.world_info if self.world_info[x]['folder'] == folder}, + "images": self.image_store } def load_json(self, data, folder=None): + if "images" in data: + print("it's there alright") + self.image_store = data["images"] + print(self.image_store) + print("Yeeks!") + print(self.image_store.keys()) + if folder is None: self.world_info = {int(x): data['entries'][x] for x in data['entries']} self.world_info_folder = data['folders'] diff --git a/static/koboldai.css b/static/koboldai.css index 8c998957..d0c9fe03 100644 --- a/static/koboldai.css +++ b/static/koboldai.css @@ -1040,23 +1040,41 @@ td.server_vars { } .world_info_title_area { - display: grid; + display: flex; + justify-content: space-between; + align-items: center; + margin-left: 2px; - grid-template-areas: "title delete"; - grid-template-columns: auto 20px; user-select: text; } +.world_info_title_area > div { + display: flex; + align-items: center; +} + +.world_info_image_container { + min-width: 32px; + min-height: 32px; + + display: flex; + justify-content: center; + align-items: center; +} + +.world_info_image { + max-width: 70px; + max-height: 70px; +} + .world_info_title { - grid-area: title; user-select: text; -moz-user-select:text; } .world_info_delete { - grid-area: delete; cursor: pointer; - margin: 2px 0px 0px 4px; + margin-right: 9px; } .world_info_tag_area { diff --git a/static/koboldai.js b/static/koboldai.js index cdbe5baa..47f1e3e3 100644 --- a/static/koboldai.js +++ b/static/koboldai.js @@ -1852,6 +1852,51 @@ function world_info_entry(data) { } ); } + + const wiImgContainer = world_info_card.querySelector(".world_info_image_container"); + const wiImg = wiImgContainer.querySelector(".world_info_image"); + const wiImgPlaceholder = wiImgContainer.querySelector(".placeholder"); + const wiImgInput = $e("input", null, {type: "file"}); + + console.log(data.image) + + if (data.uid > -1) { + + fetch(`/get_wi_image/${data.uid}`, { + method: "GET", + }).then(async function(r) { + if (!r.ok) return; + wiImgPlaceholder.style.display = "none"; + wiImg.src = await r.text(); + }); + } + + wiImgContainer.addEventListener("click", function() { + wiImgInput.click(); + }); + + wiImgInput.addEventListener("change", function() { + const file = wiImgInput.files[0]; + if (file.type.split("/")[0] !== "image") { + reportError("Unable to upload WI image", `File type ${file.type} is not a compatible image type!`) + return; + } + let objectUrl = URL.createObjectURL(file); + wiImgPlaceholder.style.display = "none"; + wiImg.src = objectUrl; + + let reader = new FileReader(); + reader.addEventListener("loadend", async function() { + console.log(reader.result) + let r = await fetch(`/set_wi_image/${data.uid}`, { + method: "POST", + body: reader.result + }); + }); + reader.readAsDataURL(file); + console.log(file) + }); + tags = world_info_card.querySelector('.world_info_tag_primary_area'); tags.id = "world_info_tags_"+data.uid; //add tag content here @@ -4602,6 +4647,8 @@ function $e(tag, parent, attributes, insertionLocation=null) { } } + if (!parent) return element; + if (insertionLocation && Object.keys(insertionLocation).length) { let [placement, target] = Object.entries(insertionLocation)[0]; if (placement === "before") { diff --git a/templates/templates.html b/templates/templates.html index 5dcd56b7..bc663d50 100644 --- a/templates/templates.html +++ b/templates/templates.html @@ -1,8 +1,14 @@
-

+
+
+ add + +
+

+
X