diff --git a/src/gui/quicklinks.js b/src/gui/quicklinks.js new file mode 100644 index 0000000000000000000000000000000000000000..6a3eacbc41091c8573c6e626d83b42ee63a88036 --- /dev/null +++ b/src/gui/quicklinks.js @@ -0,0 +1,106 @@ +App.UI.quickMenu = (function() { + // setup safe passages + const jumpFrom = Story.lookup("tags", "jump-from-safe").map(passage => passage.title); + const jumpTo = Story.lookup("tags", "jump-to-safe").map(passage => passage.title); + + // setup hotkeys list + const hotkeys = cleanHotkeys({ + Main: "m", + "Manage Personal Affairs": "x" + }); + + let hotkeysEnabled = false; + + // register hotkeys + for (const passage in hotkeys) { + Mousetrap.bind(hotkeys[passage], () => { + if (hotkeysEnabled) { + Engine.play(passage); + } + }); + } + + // setup history + let history = []; + let currentPassage; + let historyNavigation = false; + $(document).on(':passageend', function() { + if (currentPassage === State.passage) { + // only reloaded page + return; + } + + // if navigated here normally, add passage to history, otherwise remove last entry from history + if (!historyNavigation) { + // if last passage can be jumped to add passage to history, otherwise clear history + if (jumpTo.includes(currentPassage)) { + history.push(currentPassage); + } else { + history = []; + } + } else { + historyNavigation = false; + history.shift(); + } + currentPassage = State.passage; + }); + Mousetrap.bind("backspace", () => { + // jump back in history + if (history.length > 0 && jumpFrom.includes(State.passage)) { + historyNavigation = true; + Engine.play(history[0]); + } + }); + + function generateMenu() { + if (!jumpFrom.includes(State.passage)) { + hotkeysEnabled = false; + return ""; + } + + const fragment = document.createDocumentFragment(); + + for (let i = 0; i < jumpTo.length; i++) { + if (jumpTo[i] !== State.passage) { + fragment.append(generatePassageLink(jumpTo[i])); + } + } + + hotkeysEnabled = true; + return fragment; + } + + function generatePassageLink(passage) { + const div = document.createElement("div"); + const a = document.createElement("a"); + a.append(passage); + a.onclick = () => { + Engine.play(passage); + }; + div.append(a); + if (hotkeys[passage]) { + div.append(" ", App.UI.DOM.makeElement("span", `[${hotkeys[passage]}]`, "hotkey")); + } + return div; + } + + /** + * Cleans out all keys that are not contained in jumpTo and therefore not considered safe. + * + * @param {object} keys + * @returns {object} + */ + function cleanHotkeys(keys) { + const result = {}; + for (const key in keys) { + if (jumpTo.includes(key)) { + result[key] = keys[key]; + } else { + console.log("Found hotkey to unsafe passage: " + key); + } + } + return result; + } + + return generateMenu; +})(); diff --git a/src/gui/storyCaption.tw b/src/gui/storyCaption.tw index 9f9122d65aa7659f1bfe398125e72ff70922d8e3..0872e8865101c8e7c79bce9aa4b32cef3535c86f 100644 --- a/src/gui/storyCaption.tw +++ b/src/gui/storyCaption.tw @@ -1,5 +1,7 @@ :: StoryCaption [nobr] +<<includeDOM App.UI.quickMenu()>> + <<set _Pass = passage()>> <<if $ui != "start">> <<userButton>> <br> <</if>> diff --git a/src/pregmod/managePersonalAffairs.tw b/src/pregmod/managePersonalAffairs.tw index d60db9032171b75d3ee8cc760518052e5b7fbd4a..3b36ea4884a7679a7d43e8a72de958a43d492823 100644 --- a/src/pregmod/managePersonalAffairs.tw +++ b/src/pregmod/managePersonalAffairs.tw @@ -1,4 +1,4 @@ -:: Manage Personal Affairs [nobr] +:: Manage Personal Affairs [nobr jump-to-safe jump-from-safe] <<set $nextButton = "Back", $nextLink = "Main", $encyclopedia = "Being in Charge">> <<run PCTitle()>> diff --git a/src/uncategorized/main.tw b/src/uncategorized/main.tw index 44bfce82fbbb268ef73226909e9cb80ea59bbdcf..7df482f44febb0ff06a6ef8ff6f8579e28a618bd 100644 --- a/src/uncategorized/main.tw +++ b/src/uncategorized/main.tw @@ -1,4 +1,4 @@ -:: Main [nobr] +:: Main [nobr jump-to-safe jump-from-safe] /* make sure the first thing that happens is the error check */ <<set _errors = App.MainView.errors()>> diff --git a/src/uncategorized/manageArcology.tw b/src/uncategorized/manageArcology.tw index c197b19c1e850893ba0e1eef01d2187bcbe3cf2f..a3f4578e91d990e977a9a02412ef1ce0e142d8f0 100644 --- a/src/uncategorized/manageArcology.tw +++ b/src/uncategorized/manageArcology.tw @@ -1,4 +1,4 @@ -:: Manage Arcology [nobr] +:: Manage Arcology [nobr jump-to-safe jump-from-safe] <<set $nextButton = "Back", $nextLink = "Main", $encyclopedia = "The X-Series Arcology">> diff --git a/src/uncategorized/managePenthouse.tw b/src/uncategorized/managePenthouse.tw index f7e0b11df9e2bd2f4a1dfde8a9e60d06e72b907d..a12ed7c07e5568abfcf7c67dba912e5642aea109 100644 --- a/src/uncategorized/managePenthouse.tw +++ b/src/uncategorized/managePenthouse.tw @@ -1,4 +1,4 @@ -:: Manage Penthouse [nobr] +:: Manage Penthouse [nobr jump-to-safe jump-from-safe] <<set $nextButton = "Back", $nextLink = "Main", $encyclopedia = "What the Upgrades Do">> diff --git a/src/uncategorized/options.tw b/src/uncategorized/options.tw index d48ba7a26b461764ad0497c379954319ed68d1fa..cb985f3f58f57cd7a2856d59783f93b2eb9d530a 100644 --- a/src/uncategorized/options.tw +++ b/src/uncategorized/options.tw @@ -1,4 +1,4 @@ -:: Options [nobr] +:: Options [nobr jump-to-safe jump-from-safe] <style> .subHeading { diff --git a/src/uncategorized/slaveInteract.tw b/src/uncategorized/slaveInteract.tw index 1ea450e187455c25a1cfd1eee126a104d82b6ce5..3052912793446c8b4de549988409c765eda39cec 100644 --- a/src/uncategorized/slaveInteract.tw +++ b/src/uncategorized/slaveInteract.tw @@ -1,4 +1,4 @@ -:: Slave Interact [nobr] +:: Slave Interact [nobr jump-from-safe] <<set $nextButton = "Confirm changes", $nextLink = "Main">> <<set _SL = $slaves.length, _CL = $canines.length, _HL = $hooved.length, _FL = $felines.length>>