mirror of
https://github.com/KoboldAI/KoboldAI-Client.git
synced 2025-02-02 18:46:48 +01:00
WI folders and WI drag-and-drop
This commit is contained in:
parent
9e3318c696
commit
b99ac92a52
167
aiserver.py
167
aiserver.py
@ -86,7 +86,9 @@ class vars:
|
||||
authornote = "" # Text submitted to Author's Note field
|
||||
andepth = 3 # How far back in history to append author's note
|
||||
actions = structures.KoboldStoryRegister() # Actions submitted by user and AI
|
||||
worldinfo = [] # Array of World Info key/value objects
|
||||
worldinfo = [] # List of World Info key/value objects
|
||||
wifolders_d = {} # Dictionary of World Info folder UID-info pairs
|
||||
wifolders_l = [] # List of World Info folder UIDs
|
||||
# badwords = [] # Array of str/chr values that should be removed from output
|
||||
badwordsids = [[13460], [6880], [50256], [42496], [4613], [17414], [22039], [16410], [27], [29], [38430], [37922], [15913], [24618], [28725], [58], [47175], [36937], [26700], [12878], [16471], [37981], [5218], [29795], [13412], [45160], [3693], [49778], [4211], [20598], [36475], [33409], [44167], [32406], [29847], [29342], [42669], [685], [25787], [7359], [3784], [5320], [33994], [33490], [34516], [43734], [17635], [24293], [9959], [23785], [21737], [28401], [18161], [26358], [32509], [1279], [38155], [18189], [26894], [6927], [14610], [23834], [11037], [14631], [26933], [46904], [22330], [25915], [47934], [38214], [1875], [14692], [41832], [13163], [25970], [29565], [44926], [19841], [37250], [49029], [9609], [44438], [16791], [17816], [30109], [41888], [47527], [42924], [23984], [49074], [33717], [31161], [49082], [30138], [31175], [12240], [14804], [7131], [26076], [33250], [3556], [38381], [36338], [32756], [46581], [17912], [49146]] # Tokenized array of badwords used to prevent AI artifacting
|
||||
deletewi = -1 # Temporary storage for index to delete
|
||||
@ -858,6 +860,8 @@ def download():
|
||||
"key": wi["key"],
|
||||
"keysecondary": wi["keysecondary"],
|
||||
"content": wi["content"],
|
||||
"comment": wi["comment"],
|
||||
"folder": wi["folder"],
|
||||
"selective": wi["selective"],
|
||||
"constant": wi["constant"]
|
||||
})
|
||||
@ -1055,17 +1059,49 @@ def get_message(msg):
|
||||
elif(msg['cmd'] == 'wiinit'):
|
||||
if(int(msg['data']) < len(vars.worldinfo)):
|
||||
vars.worldinfo[msg['data']]["init"] = True
|
||||
addwiitem()
|
||||
addwiitem(folder_uid=msg['folder'])
|
||||
elif(msg['cmd'] == 'wifolderinit'):
|
||||
addwifolder()
|
||||
elif(msg['cmd'] == 'wimoveitem'):
|
||||
movewiitem(msg['destination'], msg['data'])
|
||||
elif(msg['cmd'] == 'wimovefolder'):
|
||||
movewifolder(msg['destination'], msg['data'])
|
||||
elif(msg['cmd'] == 'widelete'):
|
||||
deletewi(msg['data'])
|
||||
elif(msg['cmd'] == 'wifolderdelete'):
|
||||
deletewifolder(msg['data'])
|
||||
elif(msg['cmd'] == 'wiexpand'):
|
||||
assert 0 <= int(msg['data']) < len(vars.worldinfo)
|
||||
emit('from_server', {'cmd': 'wiexpand', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiexpandfolder'):
|
||||
assert 0 <= int(msg['data']) < len(vars.worldinfo)
|
||||
emit('from_server', {'cmd': 'wiexpandfolder', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiupdate'):
|
||||
num = int(msg['num'])
|
||||
fields = ("key", "keysecondary", "content", "comment")
|
||||
for field in fields:
|
||||
if(field in msg['data'] and type(msg['data'][field]) is str):
|
||||
vars.worldinfo[num][field] = msg['data'][field]
|
||||
emit('from_server', {'cmd': 'wiupdate', 'num': msg['num'], 'data': {field: vars.worldinfo[num][field] for field in fields}}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wifolderupdate'):
|
||||
uid = int(msg['uid'])
|
||||
fields = ("name", "collapsed")
|
||||
for field in fields:
|
||||
if(field in msg['data'] and type(msg['data'][field]) is (str if field != "collapsed" else bool)):
|
||||
vars.wifolders_d[uid][field] = msg['data'][field]
|
||||
emit('from_server', {'cmd': 'wifolderupdate', 'uid': msg['uid'], 'data': {field: vars.wifolders_d[uid][field] for field in fields}}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiselon'):
|
||||
vars.worldinfo[msg['data']]["selective"] = True
|
||||
emit('from_server', {'cmd': 'wiselon', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiseloff'):
|
||||
vars.worldinfo[msg['data']]["selective"] = False
|
||||
emit('from_server', {'cmd': 'wiseloff', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiconstanton'):
|
||||
vars.worldinfo[msg['data']]["constant"] = True
|
||||
emit('from_server', {'cmd': 'wiconstanton', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'wiconstantoff'):
|
||||
vars.worldinfo[msg['data']]["constant"] = False
|
||||
emit('from_server', {'cmd': 'wiconstantoff', 'data': msg['data']}, broadcast=True)
|
||||
elif(msg['cmd'] == 'sendwilist'):
|
||||
commitwi(msg['data'])
|
||||
elif(msg['cmd'] == 'aidgimport'):
|
||||
@ -2104,32 +2140,76 @@ def togglewimode():
|
||||
#==================================================================#
|
||||
#
|
||||
#==================================================================#
|
||||
def addwiitem():
|
||||
ob = {"key": "", "keysecondary": "", "content": "", "num": len(vars.worldinfo), "init": False, "selective": False, "constant": False}
|
||||
vars.worldinfo.append(ob);
|
||||
def addwiitem(folder_uid=None):
|
||||
assert folder_uid is None or folder_uid in vars.wifolders_d
|
||||
ob = {"key": "", "keysecondary": "", "content": "", "comment": "", "folder": folder_uid, "num": len(vars.worldinfo), "init": False, "selective": False, "constant": False}
|
||||
vars.worldinfo.append(ob)
|
||||
emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True)
|
||||
|
||||
#==================================================================#
|
||||
# Creates a new WI folder with an unused cryptographically secure random UID
|
||||
#==================================================================#
|
||||
def addwifolder():
|
||||
while(True):
|
||||
uid = int.from_bytes(os.urandom(4), "little", signed=True)
|
||||
if(uid not in vars.wifolders_d):
|
||||
break
|
||||
ob = {"name": "", "collapsed": False}
|
||||
vars.wifolders_d[uid] = ob
|
||||
vars.wifolders_l.append(uid)
|
||||
emit('from_server', {'cmd': 'addwifolder', 'uid': uid, 'data': ob}, broadcast=True)
|
||||
addwiitem(folder_uid=uid)
|
||||
|
||||
#==================================================================#
|
||||
# Move the WI entry with number src so that it immediately precedes
|
||||
# the WI entry with number dst
|
||||
#==================================================================#
|
||||
def movewiitem(dst, src):
|
||||
vars.worldinfo[src]["folder"] = vars.worldinfo[dst]["folder"]
|
||||
vars.worldinfo.insert(dst - (dst >= src), vars.worldinfo.pop(src))
|
||||
sendwi()
|
||||
|
||||
#==================================================================#
|
||||
# Move the WI folder with UID src so that it immediately precedes
|
||||
# the WI folder with UID dst
|
||||
#==================================================================#
|
||||
def movewifolder(dst, src):
|
||||
vars.wifolders_l.remove(src)
|
||||
if(dst is None):
|
||||
# If dst is None, that means we should move src to be the last folder
|
||||
vars.wifolders_l.append(src)
|
||||
else:
|
||||
vars.wifolders_l.insert(vars.wifolders_l.index(dst), src)
|
||||
sendwi()
|
||||
|
||||
#==================================================================#
|
||||
#
|
||||
#==================================================================#
|
||||
def sendwi():
|
||||
# Cache len of WI
|
||||
ln = len(vars.worldinfo)
|
||||
|
||||
|
||||
# Clear contents of WI container
|
||||
emit('from_server', {'cmd': 'clearwi', 'data': ''}, broadcast=True)
|
||||
|
||||
emit('from_server', {'cmd': 'wistart', 'wifolders_d': vars.wifolders_d, 'wifolders_l': vars.wifolders_l, 'data': ''}, broadcast=True)
|
||||
|
||||
# Stable-sort WI entries in order of folder
|
||||
stablesortwi()
|
||||
|
||||
# If there are no WI entries, send an empty WI object
|
||||
if(ln == 0):
|
||||
addwiitem()
|
||||
else:
|
||||
# Send contents of WI array
|
||||
organizewi()
|
||||
last_folder = ...
|
||||
for wi in vars.worldinfo:
|
||||
if(wi["folder"] != last_folder):
|
||||
emit('from_server', {'cmd': 'addwifolder', 'uid': wi["folder"], 'data': vars.wifolders_d[wi["folder"]] if wi["folder"] is not None else None}, broadcast=True)
|
||||
last_folder = wi["folder"]
|
||||
ob = wi
|
||||
emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True)
|
||||
# Make sure last WI item is uninitialized
|
||||
if(vars.worldinfo[-1]["init"]):
|
||||
addwiitem()
|
||||
|
||||
emit('from_server', {'cmd': 'wifinish', 'data': ''}, broadcast=True)
|
||||
|
||||
#==================================================================#
|
||||
# Request current contents of all WI HTML elements
|
||||
@ -2140,6 +2220,25 @@ def requestwi():
|
||||
list.append(wi["num"])
|
||||
emit('from_server', {'cmd': 'requestwiitem', 'data': list})
|
||||
|
||||
#==================================================================#
|
||||
# Stable-sort WI items so that items in the same folder are adjacent,
|
||||
# and items in different folders are sorted based on the order of the folders
|
||||
#==================================================================#
|
||||
def stablesortwi():
|
||||
mapping = {uid: index for index, uid in enumerate(vars.wifolders_l)}
|
||||
vars.worldinfo.sort(key=lambda x: mapping[x["folder"]] if x["folder"] is not None else float("inf"))
|
||||
last_folder = ...
|
||||
last_wi = None
|
||||
for wi in vars.worldinfo:
|
||||
wi["init"] = True
|
||||
if(wi["folder"] != last_folder):
|
||||
if(last_wi is not None and last_folder is not ...):
|
||||
last_wi["init"] = False
|
||||
last_folder = wi["folder"]
|
||||
last_wi = wi
|
||||
if(last_wi) is not None:
|
||||
last_wi["init"] = False
|
||||
|
||||
#==================================================================#
|
||||
# Renumber WI items consecutively
|
||||
#==================================================================#
|
||||
@ -2159,12 +2258,13 @@ def commitwi(ar):
|
||||
vars.worldinfo[ob["num"]]["key"] = ob["key"]
|
||||
vars.worldinfo[ob["num"]]["keysecondary"] = ob["keysecondary"]
|
||||
vars.worldinfo[ob["num"]]["content"] = ob["content"]
|
||||
vars.worldinfo[ob["num"]]["comment"] = ob.get("comment", "")
|
||||
vars.worldinfo[ob["num"]]["folder"] = ob.get("folder", None)
|
||||
vars.worldinfo[ob["num"]]["selective"] = ob["selective"]
|
||||
vars.worldinfo[ob["num"]]["constant"] = ob.get("constant", False)
|
||||
# Was this a deletion request? If so, remove the requested index
|
||||
if(vars.deletewi >= 0):
|
||||
del vars.worldinfo[vars.deletewi]
|
||||
organizewi()
|
||||
# Send the new WI array structure
|
||||
sendwi()
|
||||
# And reset deletewi index
|
||||
@ -2180,6 +2280,23 @@ def deletewi(num):
|
||||
# Get contents of WI HTML inputs
|
||||
requestwi()
|
||||
|
||||
#==================================================================#
|
||||
#
|
||||
#==================================================================#
|
||||
def deletewifolder(uid):
|
||||
uid = int(uid)
|
||||
del vars.wifolders_d[uid]
|
||||
del vars.wifolders_l[vars.wifolders_l.index(uid)]
|
||||
# Delete uninitialized entries in the folder we're going to delete
|
||||
vars.worldinfo = [wi for wi in vars.worldinfo if wi["folder"] != uid or wi["init"]]
|
||||
# Move WI entries that are inside of the folder we're going to delete
|
||||
# so that they're outside of all folders
|
||||
for wi in vars.worldinfo:
|
||||
if(wi["folder"] == uid):
|
||||
wi["folder"] = None
|
||||
|
||||
sendwi()
|
||||
|
||||
#==================================================================#
|
||||
# Look for WI keys in text to generator
|
||||
#==================================================================#
|
||||
@ -2495,6 +2612,8 @@ def saveRequest(savpath):
|
||||
js["authorsnote"] = vars.authornote
|
||||
js["actions"] = tuple(vars.actions.values())
|
||||
js["worldinfo"] = []
|
||||
js["wifolders_d"] = vars.wifolders_d
|
||||
js["wifolders_l"] = vars.wifolders_l
|
||||
|
||||
# Extract only the important bits of WI
|
||||
for wi in vars.worldinfo:
|
||||
@ -2503,6 +2622,8 @@ def saveRequest(savpath):
|
||||
"key": wi["key"],
|
||||
"keysecondary": wi["keysecondary"],
|
||||
"content": wi["content"],
|
||||
"comment": wi["comment"],
|
||||
"folder": wi["folder"],
|
||||
"selective": wi["selective"],
|
||||
"constant": wi["constant"]
|
||||
})
|
||||
@ -2583,6 +2704,8 @@ def loadRequest(loadpath, filename=None):
|
||||
vars.prompt = js["prompt"]
|
||||
vars.memory = js["memory"]
|
||||
vars.worldinfo = []
|
||||
vars.wifolders_d = {int(k): v for k, v in js.get("wifolders_d", {}).items()}
|
||||
vars.wifolders_l = js.get("wifolders_l", [])
|
||||
vars.lastact = ""
|
||||
vars.lastctx = ""
|
||||
|
||||
@ -2615,13 +2738,19 @@ def loadRequest(loadpath, filename=None):
|
||||
"key": wi["key"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["content"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
"constant": wi.get("constant", False)
|
||||
})
|
||||
num += 1
|
||||
|
||||
|
||||
for uid in vars.wifolders_l + [None]:
|
||||
vars.worldinfo.append({"key": "", "keysecondary": "", "content": "", "comment": "", "folder": uid, "num": None, "init": False, "selective": False, "constant": False})
|
||||
stablesortwi()
|
||||
|
||||
# Save path for save button
|
||||
vars.savedir = loadpath
|
||||
|
||||
@ -2762,6 +2891,8 @@ def importgame():
|
||||
vars.authornote = ref["authorsNote"] if type(ref["authorsNote"]) is str else ""
|
||||
vars.actions = structures.KoboldStoryRegister()
|
||||
vars.worldinfo = []
|
||||
vars.wifolders_d = {}
|
||||
vars.wifolders_l = []
|
||||
vars.lastact = ""
|
||||
vars.lastctx = ""
|
||||
|
||||
@ -2784,6 +2915,8 @@ def importgame():
|
||||
"key": wi["keys"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["entry"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
@ -2826,6 +2959,8 @@ def importAidgRequest(id):
|
||||
vars.authornote = js["authorsNote"]
|
||||
vars.actions = structures.KoboldStoryRegister()
|
||||
vars.worldinfo = []
|
||||
vars.wifolders_d = {}
|
||||
vars.wifolders_l = []
|
||||
vars.lastact = ""
|
||||
vars.lastctx = ""
|
||||
|
||||
@ -2835,6 +2970,8 @@ def importAidgRequest(id):
|
||||
"key": wi["keys"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["entry"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
@ -2873,6 +3010,8 @@ def wiimportrequest():
|
||||
"key": wi["keys"],
|
||||
"keysecondary": wi.get("keysecondary", ""),
|
||||
"content": wi["entry"],
|
||||
"comment": wi.get("comment", ""),
|
||||
"folder": wi.get("folder", None),
|
||||
"num": num,
|
||||
"init": True,
|
||||
"selective": wi.get("selective", False),
|
||||
@ -2900,6 +3039,8 @@ def newGameRequest():
|
||||
|
||||
vars.authornote = ""
|
||||
vars.worldinfo = []
|
||||
vars.wifolders_d = {}
|
||||
vars.wifolders_l = []
|
||||
vars.lastact = ""
|
||||
vars.lastctx = ""
|
||||
|
||||
|
@ -71,6 +71,7 @@ var storyname = null;
|
||||
var memorymode = false;
|
||||
var memorytext = "";
|
||||
var gamestarted = false;
|
||||
var wiscroll = 0;
|
||||
var editmode = false;
|
||||
var connected = false;
|
||||
var newly_loaded = true;
|
||||
@ -78,6 +79,8 @@ var modified_chunks = new Set();
|
||||
var empty_chunks = new Set();
|
||||
var gametext_bound = false;
|
||||
var saved_prompt = "...";
|
||||
var wifolders_d = {};
|
||||
var wifolders_l = [];
|
||||
var override_focusout = false;
|
||||
var sman_allow_delete = false;
|
||||
var sman_allow_rename = false;
|
||||
@ -196,51 +199,99 @@ function addImportLine(ob) {
|
||||
});
|
||||
}
|
||||
|
||||
function adjustWiCommentHeight(element) {
|
||||
element.style.height = "0px";
|
||||
element.style.height = element.scrollHeight + "px";
|
||||
element.parentNode.parentNode.style.height = element.scrollHeight + 90 + "px";
|
||||
}
|
||||
|
||||
function adjustWiFolderNameHeight(element) {
|
||||
element.style.height = "0px";
|
||||
element.style.height = element.scrollHeight + "px";
|
||||
element.parentNode.parentNode.parentNode.style.height = element.scrollHeight + 19 + "px";
|
||||
}
|
||||
|
||||
function addWiLine(ob) {
|
||||
var current_wifolder_element = ob.folder === null ? $(".wisortable-body:not([folder-uid])").last() : $(".wisortable-body[folder-uid="+ob.folder+"]");
|
||||
if(ob.init) {
|
||||
if(ob.selective){
|
||||
wi_menu.append("<div class=\"wilistitem wilistitem-selective "+(ob.constant ? "wilistitem-constant" : "")+"\">\
|
||||
current_wifolder_element.append("<div class=\"wilistitem wilistitem-selective "+(ob.constant ? "wilistitem-constant" : "")+"\" num=\""+ob.num+"\" id=\"wilistitem"+ob.num+"\">\
|
||||
<div class=\"wicomment\">\
|
||||
<textarea class=\"form-control\" placeholder=\"Comment\" id=\"wicomment"+ob.num+"\">"+ob.comment+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wihandle\" id=\"wihandle"+ob.num+"\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wiremove\">\
|
||||
<button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">X</button>\
|
||||
<button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">⮌</button>\
|
||||
</div>\
|
||||
<div class=\"icon-container wikey\">\
|
||||
<input class=\"form-control heightfull hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheightfull hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<span class=\"selective-key-icon "+(ob.selective ? "selective-key-icon-enabled" : "")+" oi oi-layers\" id=\"selective-key-"+ob.num+"\" title=\"Toggle Selective Key mode (if enabled, this world info entry will be included in memory only if at least one PRIMARY KEY and at least one SECONDARY KEY are both present in the story)\" aria-hidden=\"true\"></span>\
|
||||
<span class=\"constant-key-icon "+(ob.constant ? "constant-key-icon-enabled" : "")+" oi oi-pin\" id=\"constant-key-"+ob.num+"\" title=\"Toggle Constant Key mode (if enabled, this world info entry will always be included in memory)\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
<div class=\"wientry\">\
|
||||
<textarea class=\"layer-bottom form-control\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\">"+ob.content+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wiselective\">\
|
||||
<button type=\"button\" class=\"btn btn-success heightfull hidden\" id=\"btn_wiselon"+ob.num+"\">Enable Selective Mode</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heightfull\" id=\"btn_wiseloff"+ob.num+"\">Disable Selective Mode</button>\
|
||||
</div>\
|
||||
</div>");
|
||||
} else {
|
||||
wi_menu.append("<div class=\"wilistitem "+(ob.constant ? "wilistitem-constant" : "")+"\">\
|
||||
current_wifolder_element.append("<div class=\"wilistitem "+(ob.constant ? "wilistitem-constant" : "")+"\" num=\""+ob.num+"\" id=\"wilistitem"+ob.num+"\">\
|
||||
<div class=\"wicomment\">\
|
||||
<textarea class=\"form-control\" placeholder=\"Comment\" id=\"wicomment"+ob.num+"\">"+ob.comment+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wihandle\" id=\"wihandle"+ob.num+"\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wiremove\">\
|
||||
<button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">X</button>\
|
||||
<button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">⮌</button>\
|
||||
</div>\
|
||||
<div class=\"icon-container wikey\">\
|
||||
<input class=\"form-control heightfull\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf hidden\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf hidden\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheightfull\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf hidden\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf hidden\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<span class=\"selective-key-icon "+(ob.selective ? "selective-key-icon-enabled" : "")+" oi oi-layers\" id=\"selective-key-"+ob.num+"\" title=\"Toggle Selective Key mode (if enabled, this world info entry will be included in memory only if at least one PRIMARY KEY and at least one SECONDARY KEY are both present in the story)\" aria-hidden=\"true\"></span>\
|
||||
<span class=\"constant-key-icon "+(ob.constant ? "constant-key-icon-enabled" : "")+" oi oi-pin\" id=\"constant-key-"+ob.num+"\" title=\"Toggle Constant Key mode (if enabled, this world info entry will always be included in memory)\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
<div class=\"wientry\">\
|
||||
<textarea class=\"form-control\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\">"+ob.content+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wiselective\">\
|
||||
<button type=\"button\" class=\"btn btn-success heightfull\" id=\"btn_wiselon"+ob.num+"\">Enable Selective Mode</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heightfull hidden\" id=\"btn_wiseloff"+ob.num+"\">Disable Selective Mode</button>\
|
||||
</div>\
|
||||
</div>");
|
||||
}
|
||||
adjustWiCommentHeight($("#wicomment"+ob.num)[0]);
|
||||
// Send key value to text input
|
||||
$("#wikey"+ob.num).val(ob.key);
|
||||
$("#wikeyprimary"+ob.num).val(ob.key);
|
||||
@ -251,81 +302,212 @@ function addWiLine(ob) {
|
||||
});
|
||||
} else {
|
||||
// Show WI line item with form fields hidden (uninitialized)
|
||||
wi_menu.append("<div class=\"wilistitem\">\
|
||||
current_wifolder_element.append("<div class=\"wilistitem wilistitem-uninitialized wisortable-excluded\" num=\""+ob.num+"\" id=\"wilistitem"+ob.num+"\">\
|
||||
<div class=\"wicomment\">\
|
||||
<textarea class=\"form-control hidden\" placeholder=\"Comment\" id=\"wicomment"+ob.num+"\">"+ob.comment+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wihandle-inactive hidden\" id=\"wihandle"+ob.num+"\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wiremove\">\
|
||||
<button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wi"+ob.num+"\">+</button>\
|
||||
<button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_widel"+ob.num+"\">✓</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wican"+ob.num+"\">X</button>\
|
||||
</div>\
|
||||
<div class=\"icon-container wikey\">\
|
||||
<input class=\"form-control heightfull hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf hidden\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control heighthalf hidden\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheightfull hidden\" type=\"text\" placeholder=\"Key(s)\" id=\"wikey"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf hidden\" type=\"text\" placeholder=\"Primary Key(s)\" id=\"wikeyprimary"+ob.num+"\">\
|
||||
<input class=\"form-control wiheighthalf hidden\" type=\"text\" placeholder=\"Secondary Key(s)\" id=\"wikeysecondary"+ob.num+"\">\
|
||||
<span class=\"selective-key-icon oi oi-layers hidden\" id=\"selective-key-"+ob.num+"\" title=\"Toggle Selective Key mode (if enabled, this world info entry will be included in memory only if at least one PRIMARY KEY and at least one SECONDARY KEY are both present in the story)\" aria-hidden=\"true\"></span>\
|
||||
<span class=\"constant-key-icon oi oi-pin hidden\" id=\"constant-key-"+ob.num+"\" title=\"Toggle Constant Key mode (if enabled, this world info entry will always be included in memory)\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
<div class=\"wientry\">\
|
||||
<textarea class=\"layer-bottom form-control hidden\" id=\"wientry"+ob.num+"\" placeholder=\"What To Remember\">"+ob.content+"</textarea>\
|
||||
</div>\
|
||||
<div class=\"wiselective\">\
|
||||
<button type=\"button\" class=\"btn btn-success heightfull hidden\" id=\"btn_wiselon"+ob.num+"\">Enable Selective Mode</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heightfull hidden\" id=\"btn_wiseloff"+ob.num+"\">Disable Selective Mode</button>\
|
||||
</div>\
|
||||
</div>");
|
||||
// Assign function to expand WI item to button
|
||||
$("#btn_wi"+ob.num).on("click", function () {
|
||||
expandWiLine(ob.num);
|
||||
socket.send({'cmd': 'wiexpand', 'data': ob.num});
|
||||
socket.send({'cmd': 'wiinit', 'folder': parseInt($("#wilistitem"+ob.num).parent().attr("folder-uid")) || null, 'data': ob.num});
|
||||
});
|
||||
}
|
||||
// Assign actions to other elements
|
||||
wientry_onfocus = function () {
|
||||
$("#selective-key-"+ob.num).addClass("selective-key-icon-clickthrough");
|
||||
$("#constant-key-"+ob.num).addClass("constant-key-icon-clickthrough");
|
||||
}
|
||||
wientry_onfocusout = function () {
|
||||
$("#selective-key-"+ob.num).removeClass("selective-key-icon-clickthrough");
|
||||
$("#constant-key-"+ob.num).removeClass("constant-key-icon-clickthrough");
|
||||
// Tell server about updated WI fields
|
||||
var selective = $("#wilistitem"+ob.num)[0].classList.contains("wilistitem-selective");
|
||||
socket.send({'cmd': 'wiupdate', 'num': ob.num, 'data': {
|
||||
key: selective ? $("#wikeyprimary"+ob.num).val() : $("#wikey"+ob.num).val(),
|
||||
keysecondary: $("#wikeysecondary"+ob.num).val(),
|
||||
content: $("#wientry"+ob.num).val(),
|
||||
comment: $("#wicomment"+ob.num).val(),
|
||||
}});
|
||||
}
|
||||
$("#wikey"+ob.num).on("focus", wientry_onfocus);
|
||||
$("#wikeyprimary"+ob.num).on("focus", wientry_onfocus);
|
||||
$("#wikeysecondary"+ob.num).on("focus", wientry_onfocus);
|
||||
$("#wientry"+ob.num).on("focus", wientry_onfocus);
|
||||
$("#wicomment"+ob.num).on("focus", wientry_onfocus);
|
||||
$("#wikey"+ob.num).on("focusout", wientry_onfocusout);
|
||||
$("#wikeyprimary"+ob.num).on("focusout", wientry_onfocusout);
|
||||
$("#wikeysecondary"+ob.num).on("focusout", wientry_onfocusout);
|
||||
$("#wientry"+ob.num).on("focusout", wientry_onfocusout);
|
||||
$("#wicomment"+ob.num).on("focusout", wientry_onfocusout);
|
||||
$("#btn_wican"+ob.num).on("click", function () {
|
||||
hideWiDeleteConfirm(ob.num);
|
||||
});
|
||||
$("#btn_widel"+ob.num).on("click", function () {
|
||||
socket.send({'cmd': 'widelete', 'data': ob.num});
|
||||
});
|
||||
$("#btn_wiselon"+ob.num).on("click", function () {
|
||||
enableWiSelective(ob.num);
|
||||
$("#wikey"+ob.num).addClass("wilistitem-selective");
|
||||
});
|
||||
$("#btn_wiseloff"+ob.num).on("click", function () {
|
||||
disableWiSelective(ob.num);
|
||||
$("#wikey"+ob.num).removeClass("wilistitem-selective");
|
||||
$("#selective-key-"+ob.num).on("click", function () {
|
||||
var element = $("#selective-key-"+ob.num);
|
||||
if(element.hasClass("selective-key-icon-enabled")) {
|
||||
socket.send({'cmd': 'wiseloff', 'data': ob.num});
|
||||
} else {
|
||||
socket.send({'cmd': 'wiselon', 'data': ob.num});
|
||||
}
|
||||
});
|
||||
$("#constant-key-"+ob.num).on("click", function () {
|
||||
var element = $("#constant-key-"+ob.num);
|
||||
if(element.hasClass("constant-key-icon-enabled")) {
|
||||
socket.send({'cmd': 'wiconstantoff', 'data': ob.num});
|
||||
element.removeClass("constant-key-icon-enabled");
|
||||
$("#wikey"+ob.num).removeClass("wilistitem-constant");
|
||||
} else {
|
||||
socket.send({'cmd': 'wiconstanton', 'data': ob.num});
|
||||
element.addClass("constant-key-icon-enabled");
|
||||
$("#wikey"+ob.num).addClass("wilistitem-constant");
|
||||
}
|
||||
});
|
||||
$("#wihandle"+ob.num).off().on("mousedown", wientry_onfocusout);
|
||||
}
|
||||
|
||||
function addWiFolder(uid, ob) {
|
||||
if(uid !== null) {
|
||||
var uninitialized = $("#wilistfoldercontainer"+null);
|
||||
var html = "<div class=\"wisortable-container\" id=\"wilistfoldercontainer"+uid+"\" folder-uid=\""+uid+"\">\
|
||||
<div class=\"wilistfolder\" id=\"wilistfolder"+uid+"\">\
|
||||
<div class=\"wiremove\">\
|
||||
<button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wifolder"+uid+"\">X</button>\
|
||||
<button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_wifolderdel"+uid+"\">✓</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wifoldercan"+uid+"\">⮌</button>\
|
||||
</div>\
|
||||
<div class=\"wifoldericon\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-folder\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wifoldername\">\
|
||||
<div class=\"wicentered-vertical\">\
|
||||
<textarea class=\"form-control\" placeholder=\"Untitled Folder\" id=\"wifoldername"+uid+"\">"+ob.name+"</textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wihandle wifolderhandle\" id=\"wifolderhandle"+uid+"\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wisortable-body\" folder-uid=\""+uid+"\">\
|
||||
<div class=\"wisortable-dummy\"></div>\
|
||||
</div>\
|
||||
</div>";
|
||||
if(uninitialized.length) {
|
||||
$(html).insertBefore(uninitialized);
|
||||
} else {
|
||||
wi_menu.append(html);
|
||||
}
|
||||
var onfocusout = function () {
|
||||
socket.send({'cmd': 'wifolderupdate', 'uid': uid, 'data': {
|
||||
name: $("#wifoldername"+uid).val(),
|
||||
collapsed: false,
|
||||
}});
|
||||
};
|
||||
$("#btn_wifolder"+uid).on("click", function () {
|
||||
showWiFolderDeleteConfirm(uid);
|
||||
});
|
||||
$("#btn_wifolderdel"+uid).on("click", function () {
|
||||
socket.send({'cmd': 'wifolderdelete', 'data': uid});
|
||||
});
|
||||
$("#btn_wifoldercan"+uid).on("click", function () {
|
||||
hideWiFolderDeleteConfirm(uid);
|
||||
})
|
||||
$("#wifoldername"+uid).on("focusout", onfocusout);
|
||||
$("#wifolderhandle"+uid).off().on("mousedown", onfocusout);
|
||||
adjustWiFolderNameHeight($("#wifoldername"+uid)[0]);
|
||||
} else {
|
||||
wi_menu.append("<div class=\"wisortable-container\" id=\"wilistfoldercontainer"+uid+"\">\
|
||||
<div class=\"wilistfolder\" id=\"wilistfolder"+uid+"\">\
|
||||
<div class=\"wiremove\">\
|
||||
<button type=\"button\" class=\"btn btn-primary heightfull\" id=\"btn_wifolder"+uid+"\">+</button>\
|
||||
<button type=\"button\" class=\"btn btn-success heighthalf hidden\" id=\"btn_wifolderdel"+uid+"\">✓</button>\
|
||||
<button type=\"button\" class=\"btn btn-danger heighthalf hidden\" id=\"btn_wifoldercan"+uid+"\">⮌</button>\
|
||||
</div>\
|
||||
<div class=\"wifoldericon\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-folder\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wifoldername\">\
|
||||
<div class=\"wicentered-vertical\">\
|
||||
<textarea class=\"form-control hidden\" placeholder=\"Untitled Folder\" id=\"wifoldername"+uid+"\"></textarea>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wihandle-inactive wifolderhandle hidden\" id=\"wifolderhandle"+uid+"\">\
|
||||
<div class=\"wicentered\">\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
<br/>\
|
||||
<span class=\"oi oi-grid-two-up\" aria-hidden=\"true\"></span>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class=\"wisortable-body\">\
|
||||
<div class=\"wisortable-dummy\"></div>\
|
||||
</div>\
|
||||
</div>");
|
||||
$("#btn_wifolder"+uid).on("click", function () {
|
||||
expandWiFolderLine(uid);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function expandWiLine(num) {
|
||||
show([$("#wikey"+num), $("#wientry"+num), $("#constant-key-"+num), $("#btn_wiselon"+num)]);
|
||||
show([$("#wikey"+num), $("#wientry"+num), $("#wihandle"+num), $("#selective-key-"+num), $("#constant-key-"+num), $("#btn_wiselon"+num), $("#wicomment"+num)]);
|
||||
$("#wihandle"+num).removeClass("wihandle-inactive").addClass("wihandle");
|
||||
$("#btn_wi"+num).html("X");
|
||||
$("#btn_wi"+num).off();
|
||||
$("#wilistitem"+num).removeClass("wilistitem-uninitialized").removeClass("wisortable-excluded");
|
||||
// Tell server the WI entry was initialized
|
||||
socket.send({'cmd': 'wiinit', 'data': num});
|
||||
$("#btn_wi"+num).on("click", function () {
|
||||
showWiDeleteConfirm(num);
|
||||
});
|
||||
|
||||
adjustWiCommentHeight($("#wicomment"+num)[0]);
|
||||
}
|
||||
|
||||
function expandWiFolderLine(num) {
|
||||
socket.send({'cmd': 'wifolderinit', 'data': ''});
|
||||
}
|
||||
|
||||
function showWiDeleteConfirm(num) {
|
||||
@ -333,25 +515,51 @@ function showWiDeleteConfirm(num) {
|
||||
show([$("#btn_widel"+num), $("#btn_wican"+num)]);
|
||||
}
|
||||
|
||||
function showWiFolderDeleteConfirm(num) {
|
||||
hide([$("#btn_wifolder"+num)]);
|
||||
show([$("#btn_wifolderdel"+num), $("#btn_wifoldercan"+num)]);
|
||||
}
|
||||
|
||||
function hideWiDeleteConfirm(num) {
|
||||
show([$("#btn_wi"+num)]);
|
||||
hide([$("#btn_widel"+num), $("#btn_wican"+num)]);
|
||||
}
|
||||
|
||||
function hideWiFolderDeleteConfirm(num) {
|
||||
show([$("#btn_wifolder"+num)]);
|
||||
hide([$("#btn_wifolderdel"+num), $("#btn_wifoldercan"+num)]);
|
||||
}
|
||||
|
||||
function enableWiSelective(num) {
|
||||
hide([$("#btn_wiselon"+num), $("#wikey"+num)]);
|
||||
// Tell server the WI entry is now selective
|
||||
socket.send({'cmd': 'wiselon', 'data': num});
|
||||
hide([$("#wikey"+num)]);
|
||||
$("#wikeyprimary"+num).val($("#wikey"+num).val());
|
||||
show([$("#wikeyprimary"+num), $("#wikeysecondary"+num), $("#btn_wiseloff"+num)]);
|
||||
show([$("#wikeyprimary"+num), $("#wikeysecondary"+num)]);
|
||||
|
||||
var element = $("#selective-key-"+num);
|
||||
element.addClass("selective-key-icon-enabled");
|
||||
$("#wikey"+num).addClass("wilistitem-selective");
|
||||
}
|
||||
|
||||
function disableWiSelective(num) {
|
||||
hide([$("#btn_wiseloff"+num), $("#wikeyprimary"+num), $("#wikeysecondary"+num)]);
|
||||
// Tell server the WI entry is now non-selective
|
||||
socket.send({'cmd': 'wiseloff', 'data': num});
|
||||
hide([$("#wikeyprimary"+num), $("#wikeysecondary"+num)]);
|
||||
$("#wikey"+num).val($("#wikeyprimary"+num).val());
|
||||
show([$("#btn_wiselon"+num), $("#wikey"+num)]);
|
||||
show([$("#wikey"+num)]);
|
||||
|
||||
var element = $("#selective-key-"+num);
|
||||
element.removeClass("selective-key-icon-enabled");
|
||||
$("#wikey"+num).removeClass("wilistitem-selective");
|
||||
}
|
||||
|
||||
function enableWiConstant(num) {
|
||||
var element = $("#constant-key-"+num);
|
||||
element.addClass("constant-key-icon-enabled");
|
||||
$("#wikey"+num).addClass("wilistitem-constant");
|
||||
}
|
||||
|
||||
function disableWiConstant(num) {
|
||||
var element = $("#constant-key-"+num);
|
||||
element.removeClass("constant-key-icon-enabled");
|
||||
$("#wikey"+num).removeClass("wilistitem-constant");
|
||||
}
|
||||
|
||||
function highlightImportLine(ref) {
|
||||
@ -491,11 +699,13 @@ function returnWiList(ar) {
|
||||
var list = [];
|
||||
var i;
|
||||
for(i=0; i<ar.length; i++) {
|
||||
var ob = {"key": "", "keysecondary": "", "content": "", "num": ar[i], "selective": false, "constant": false};
|
||||
var ob = {"key": "", "keysecondary": "", "content": "", "comment": "", "folder": null, "num": ar[i], "selective": false, "constant": false};
|
||||
ob.selective = $("#wikeyprimary"+ar[i]).css("display") != "none"
|
||||
ob.key = ob.selective ? $("#wikeyprimary"+ar[i]).val() : $("#wikey"+ar[i]).val();
|
||||
ob.keysecondary = $("#wikeysecondary"+ar[i]).val()
|
||||
ob.keysecondary = $("#wikeysecondary"+ar[i]).val();
|
||||
ob.content = $("#wientry"+ar[i]).val();
|
||||
ob.comment = $("#wicomment"+i).val();
|
||||
ob.folder = parseInt($("#wilistitem"+i).parent().attr("folder-uid")) || null;
|
||||
ob.constant = $("#constant-key-"+ar[i]).hasClass("constant-key-icon-enabled");
|
||||
list.push(ob);
|
||||
}
|
||||
@ -805,6 +1015,33 @@ function autofocus(event) {
|
||||
}
|
||||
}
|
||||
|
||||
function sortableOnStart(event, ui) {
|
||||
}
|
||||
|
||||
function sortableOnStop(event, ui) {
|
||||
if(ui.item.hasClass("wilistitem")) {
|
||||
// When a WI entry is dragged and dropped, tell the server which WI
|
||||
// entry was dropped and which WI entry comes immediately after the
|
||||
// dropped position so that the server can internally move around
|
||||
// the WI entries
|
||||
var next_sibling = ui.item.next(".wilistitem").attr("num");
|
||||
if(next_sibling === undefined) {
|
||||
next_sibling = ui.item.next().next().attr("num");
|
||||
}
|
||||
next_sibling = parseInt(next_sibling);
|
||||
socket.send({'cmd': 'wimoveitem', 'destination': next_sibling, 'data': parseInt(ui.item.attr("num"))});
|
||||
} else {
|
||||
// Do the same thing for WI folders
|
||||
var next_sibling = ui.item.next(".wisortable-container").attr("folder-uid");
|
||||
if(next_sibling === undefined) {
|
||||
next_sibling = null;
|
||||
} else {
|
||||
next_sibling = parseInt(next_sibling);
|
||||
}
|
||||
socket.send({'cmd': 'wimovefolder', 'destination': next_sibling, 'data': parseInt(ui.item.attr("folder-uid"))});
|
||||
}
|
||||
}
|
||||
|
||||
function chunkOnTextInput(event) {
|
||||
// The enter key does not behave correctly in almost all non-Firefox
|
||||
// browsers, so we (attempt to) shim all enter keystrokes here to behave the
|
||||
@ -948,7 +1185,7 @@ function downloadStory(format) {
|
||||
actionlist_compiled.push(actionlist[i].innerText.replace(/\u00a0/g, " "));
|
||||
}
|
||||
var last = actionlist_compiled[actionlist_compiled.length-1];
|
||||
if(last.slice(-1) === '\n') {
|
||||
if(last && last.slice(-1) === '\n') {
|
||||
actionlist_compiled[actionlist_compiled.length-1] = last.slice(0, -1);
|
||||
}
|
||||
|
||||
@ -963,12 +1200,17 @@ function downloadStory(format) {
|
||||
|
||||
var wilist = $(".wilistitem");
|
||||
var wilist_compiled = [];
|
||||
for(var i = 0; i < wilist.length-1; i++) {
|
||||
for(var i = 0; i < wilist.length; i++) {
|
||||
if(wilist[i].classList.contains("wilistitem-uninitialized")) {
|
||||
continue;
|
||||
}
|
||||
var selective = wilist[i].classList.contains("wilistitem-selective");
|
||||
wilist_compiled.push({
|
||||
key: selective ? $("#wikeyprimary"+i).val() : $("#wikey"+i).val(),
|
||||
keysecondary: $("#wikeysecondary"+i).val(),
|
||||
content: $("#wientry"+i).val(),
|
||||
comment: $("#wicomment"+i).val(),
|
||||
folder: parseInt($("#wilistitem"+i).parent().attr("folder-uid")) || null,
|
||||
selective: selective,
|
||||
constant: wilist[i].classList.contains("wilistitem-constant"),
|
||||
});
|
||||
@ -985,6 +1227,8 @@ function downloadStory(format) {
|
||||
authorsnote: $("#anoteinput").val(),
|
||||
actions: actionlist_compiled,
|
||||
worldinfo: wilist_compiled,
|
||||
wifolders_d: wifolders_d,
|
||||
wifolders_l: wifolders_l,
|
||||
}, null, 3)]));
|
||||
anchor.setAttribute('href', objectURL);
|
||||
anchor.setAttribute('download', filename_without_extension + ".json");
|
||||
@ -1562,13 +1806,74 @@ $(document).ready(function(){
|
||||
} else {
|
||||
exitWiMode();
|
||||
}
|
||||
} else if(msg.cmd == "wiupdate") {
|
||||
var selective = $("#wilistitem"+msg.num)[0].classList.contains("wilistitem-selective");
|
||||
if(selective) {
|
||||
$("#wikeyprimary"+msg.num).val(msg.data.key);
|
||||
} else {
|
||||
$("#wikey"+msg.num).val(msg.data.key);
|
||||
}
|
||||
$("#wikeysecondary"+msg.num).val(msg.data.keysecondary);
|
||||
$("#wientry"+msg.num).val(msg.data.content);
|
||||
$("#wicomment"+msg.num).val(msg.data.comment);
|
||||
adjustWiCommentHeight($("#wicomment"+msg.num)[0]);
|
||||
} else if(msg.cmd == "wifolderupdate") {
|
||||
$("#wifoldername"+msg.uid).val(msg.data.name);
|
||||
adjustWiFolderNameHeight($("#wifoldername"+msg.uid)[0]);
|
||||
} else if(msg.cmd == "wiexpand") {
|
||||
expandWiLine(msg.data);
|
||||
} else if(msg.cmd == "wiexpandfolder") {
|
||||
expandWiFolderLine(msg.data);
|
||||
} else if(msg.cmd == "wiselon") {
|
||||
enableWiSelective(msg.data);
|
||||
} else if(msg.cmd == "wiseloff") {
|
||||
disableWiSelective(msg.data);
|
||||
} else if(msg.cmd == "wiconstanton") {
|
||||
enableWiConstant(msg.data);
|
||||
} else if(msg.cmd == "wiconstantoff") {
|
||||
disableWiConstant(msg.data);
|
||||
} else if(msg.cmd == "addwiitem") {
|
||||
// Add WI entry to WI Menu
|
||||
addWiLine(msg.data);
|
||||
} else if(msg.cmd == "clearwi") {
|
||||
} else if(msg.cmd == "addwifolder") {
|
||||
addWiFolder(msg.uid, msg.data);
|
||||
} else if(msg.cmd == "wistart") {
|
||||
// Save scroll position for later so we can restore it later
|
||||
wiscroll = $("#gamescreen").scrollTop();
|
||||
// Clear previous contents of WI list
|
||||
wi_menu.html("");
|
||||
} else if(msg.cmd == "requestwiitem") {
|
||||
// Save wifolders_d and wifolders_l
|
||||
wifolders_d = msg.wifolders_d;
|
||||
wifolders_l = msg.wifolders_l;
|
||||
} else if(msg.cmd == "wifinish") {
|
||||
// Allow drag-and-drop rearranging of world info entries (via JQuery UI's "sortable widget")
|
||||
$(".wifolderhandle").on("mousedown", function () {
|
||||
$(".wilistitem, .wisortable-dummy").addClass("wisortable-excluded-dynamic");
|
||||
}).on("mouseup", function () {
|
||||
$(".wisortable-excluded-dynamic").removeClass("wisortable-excluded-dynamic");
|
||||
});
|
||||
$(".wihandle:not(.wifolderhandle)").on("mousedown", function () {
|
||||
$(".wisortable-container").addClass("wisortable-excluded");
|
||||
}).on("mouseup", function () {
|
||||
$(".wisortable-excluded-dynamic").removeClass("wisortable-excluded-dynamic");
|
||||
});
|
||||
$("#gamescreen").sortable({
|
||||
items: "#wimenu .wisortable-body > :not(.wisortable-excluded):not(.wisortable-excluded-dynamic), #wimenu .wisortable-container[folder-uid]:not(.wisortable-excluded):not(.wisortable-excluded-dynamic)",
|
||||
containment: "#wimenu",
|
||||
connectWith: "#wimenu .wisortable-body",
|
||||
handle: ".wihandle",
|
||||
start: sortableOnStart,
|
||||
stop: sortableOnStop,
|
||||
cursor: "move",
|
||||
tolerance: "pointer",
|
||||
opacity: 0.42,
|
||||
revert: 173,
|
||||
scrollSensitivity: 64,
|
||||
scrollSpeed: 10,
|
||||
});
|
||||
// Restore previously-saved scroll position
|
||||
$("#gamescreen").scrollTop(wiscroll);
|
||||
} else if(msg.cmd == "requestwiitem") {
|
||||
// Package WI contents and send back to server
|
||||
returnWiList(msg.data);
|
||||
} else if(msg.cmd == "saveas") {
|
||||
@ -1846,7 +2151,17 @@ $(document).ready(function(){
|
||||
anote_slider.on("input", function () {
|
||||
socket.send({'cmd': 'anotedepth', 'data': $(this).val()});
|
||||
});
|
||||
|
||||
|
||||
// Dynamically change vertical size of world info "Comment" text box
|
||||
wi_menu.on("input", ".wicomment > textarea", function () {
|
||||
adjustWiCommentHeight(this);
|
||||
});
|
||||
|
||||
// Dynamically change vertical size of world info folder name text box
|
||||
wi_menu.on("input", ".wifoldername > div > textarea", function () {
|
||||
adjustWiFolderNameHeight(this);
|
||||
});
|
||||
|
||||
saveasinput.on("input", function () {
|
||||
if(saveasinput.val() == "") {
|
||||
disableButtons([saveas_accept]);
|
||||
|
@ -73,6 +73,7 @@ chunk.editing, chunk.editing * {
|
||||
}
|
||||
|
||||
#gamescreen {
|
||||
overflow-x: hidden;
|
||||
height: 490px;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
@ -509,6 +510,70 @@ chunk.editing, chunk.editing * {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.wiheightfull {
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
.wiheighthalf {
|
||||
height: 45%;
|
||||
}
|
||||
|
||||
.wicomment {
|
||||
height: 10%;
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 4;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 6px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.wihandle, .wifolderhandle {
|
||||
grid-row: span 2;
|
||||
line-height: 100%;
|
||||
opacity: 30%;
|
||||
font-size: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wifoldericon {
|
||||
font-size: 28px;
|
||||
position: relative;
|
||||
grid-row: span 2;
|
||||
}
|
||||
|
||||
.wicentered {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
-o-transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wicentered-vertical {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(0%, -50%);
|
||||
-moz-transform: translate(0%, -50%);
|
||||
-webkit-transform: translate(0%, -50%);
|
||||
-ms-transform: translate(0%, -50%);
|
||||
-o-transform: translate(0%, -50%);
|
||||
}
|
||||
|
||||
.wihandle:hover {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.wisortable-body {
|
||||
|
||||
}
|
||||
|
||||
.wisortable-dummy {
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.helpicon {
|
||||
display: inline-block;
|
||||
font-family: sans-serif;
|
||||
@ -578,6 +643,45 @@ chunk.editing, chunk.editing * {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.selective-key-icon {
|
||||
position: absolute !important;
|
||||
top: 5px !important;
|
||||
right: 28px !important;
|
||||
z-index: 1;
|
||||
opacity: 20%;
|
||||
}
|
||||
|
||||
*:hover > .selective-key-icon {
|
||||
opacity: 40%;
|
||||
}
|
||||
|
||||
.selective-key-icon:hover {
|
||||
opacity: 65%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selective-key-icon-enabled {
|
||||
color: #3bf723;
|
||||
opacity: 65%
|
||||
}
|
||||
|
||||
*:hover > .selective-key-icon-enabled {
|
||||
opacity: 65%;
|
||||
}
|
||||
|
||||
.selective-key-icon-enabled:hover {
|
||||
opacity: 100%
|
||||
}
|
||||
|
||||
.selective-key-icon-clickthrough {
|
||||
opacity: 0% !important;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.selective-key-icon-clickthrough.selective-key-icon-enabled {
|
||||
opacity: 35% !important;
|
||||
}
|
||||
|
||||
.constant-key-icon {
|
||||
position: absolute !important;
|
||||
top: 5px !important;
|
||||
@ -888,26 +992,62 @@ chunk.editing, chunk.editing * {
|
||||
}
|
||||
|
||||
.wilistitem {
|
||||
height: 80px;
|
||||
height: 120px;
|
||||
display: grid;
|
||||
grid-template-columns: 4% 30% 58% 8%;
|
||||
margin-bottom: 10px;
|
||||
grid-template-columns: 4% 30% 63.5% 2.5%;
|
||||
margin-bottom: 24px;
|
||||
background-color: #212122;
|
||||
}
|
||||
|
||||
.wilistfolder {
|
||||
height: 60px;
|
||||
display: grid;
|
||||
grid-template-columns: 4% 5% 88.5% 2.5%;
|
||||
margin-bottom: 24px;
|
||||
background-color: #212122;
|
||||
}
|
||||
|
||||
.wientry {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
padding-right: 0px;
|
||||
background-color: #212122;
|
||||
}
|
||||
|
||||
.wientry > textarea {
|
||||
height: 100%;
|
||||
height: 90%;
|
||||
resize: none;
|
||||
overflow:auto;
|
||||
background-color: #404040;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.wicomment > textarea {
|
||||
resize: none;
|
||||
height: 0px;
|
||||
overflow: hidden;
|
||||
background-color: #404040;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.wifoldername {
|
||||
position: relative;
|
||||
grid-row: span 2;
|
||||
}
|
||||
|
||||
.wifoldername > div {
|
||||
width: 100%;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.wifoldername > div > textarea {
|
||||
font-size: 20px;
|
||||
resize: none;
|
||||
height: 0px;
|
||||
overflow: hidden;
|
||||
background-color: #404040;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.wikey {
|
||||
background-color: #212122;
|
||||
}
|
||||
@ -917,12 +1057,13 @@ chunk.editing, chunk.editing * {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.wiremove {
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
||||
.wiremove > button {
|
||||
width: 80%;
|
||||
overflow: hidden;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.wiselective > button {
|
||||
white-space: normal;
|
||||
}
|
||||
|
6
static/jquery-ui.sortable.min.css
vendored
Normal file
6
static/jquery-ui.sortable.min.css
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/*! jQuery UI - v1.13.0 - 2021-12-02
|
||||
* http://jqueryui.com
|
||||
* Includes: sortable.css
|
||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||
|
||||
.ui-sortable-handle{-ms-touch-action:none;touch-action:none}
|
6
static/jquery-ui.sortable.min.js
vendored
Normal file
6
static/jquery-ui.sortable.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -5,12 +5,14 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="static/jquery-3.6.0.min.js"></script>
|
||||
<script src="static/jquery-ui.sortable.min.js"></script>
|
||||
<script src="static/socket.io.min.js"></script>
|
||||
<script src="static/application.js?ver=1.16.4b"></script>
|
||||
<script src="static/application.js?ver=1.16.4c"></script>
|
||||
<script src="static/bootstrap.min.js"></script>
|
||||
<script src="static/bootstrap-toggle.min.js"></script>
|
||||
<script src="static/rangy-core.min.js"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="static/jquery-ui.sortable.min.css">
|
||||
<link rel="stylesheet" href="static/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="static/bootstrap-toggle.min.css">
|
||||
<link rel="stylesheet" href="static/custom.css?ver=1.16.4b">
|
||||
|
Loading…
x
Reference in New Issue
Block a user