diff --git a/src/KodiApiInterface/View/if.html b/src/KodiApiInterface/View/if.html
index 913e19e..6ef24f1 100644
--- a/src/KodiApiInterface/View/if.html
+++ b/src/KodiApiInterface/View/if.html
@@ -62,10 +62,10 @@
function okClicked() {
let path = document.getElementById("endpoint").value;
paths = [""];
- loadApiPath(path);
+ loadApiPath(path, "replace");
}
- function loadApiPath(path) {
+ function loadApiPath(path, historyMode) {
$.ajax({
url: path,
success: function(result) {
@@ -75,14 +75,37 @@
} else {
$("#debug").html("");
}
+ // mirror our in-memory navigation into the browser history so the
+ // back/forward buttons move between views instead of leaving /if
+ if (historyMode === "push") {
+ history.pushState({ paths: paths.slice(), url: path }, "");
+ } else if (historyMode === "replace") {
+ history.replaceState({ paths: paths.slice(), url: path }, "");
+ }
processApiResult(result);
}
});
}
+ window.addEventListener("popstate", function(e) {
+ if (e.state && e.state.paths) {
+ paths = e.state.paths.slice();
+ loadApiPath(e.state.url);
+ }
+ });
+
function processApiResult(result) {
if (!result) return; //todo error
+ let endpoint = document.getElementById("endpoint").value;
+
+ // context-menu actions don't refresh the container by default, so the api
+ // can return forceUpdate to re-query and re-render the current list
+ if (result.forceUpdate) {
+ loadApiPath(endpoint + "?path=" + result.forceUpdate.urlParams.path);
+ return;
+ }
+
if (result.msgBoxOK) {
$("#modalBody").text(result.msgBoxOK);
$("#modal").modal("show");
@@ -91,6 +114,13 @@
if (result.notification) {
$("#modalBody").text(result.notification);
$("#modal").modal("show");
+ if (result.refreshContainer === false) {
+ paths.pop();
+ } else {
+ // reload the current container so the action's effect is visible
+ loadApiPath(endpoint + "?path=" + paths[paths.length - 1]);
+ }
+ return;
}
if (result.play) {
@@ -170,7 +200,15 @@
for (let i = 0; i < result.items.length; i++) {
let item = result.items[i];
- let itemHtml = "";
+
+ if (hasContextMenus) {
+ let menuHtml = "
";
+ menuHtml = menuHtml + "";
+ menuHtml = menuHtml + "
";
+
+ itemHtml = "" + itemHtml + menuHtml + "
";
+ }
+
itemsHtml = itemsHtml + itemHtml;
}
itemsHtml = itemsHtml + "";
@@ -197,30 +250,48 @@
}
- $(document).click("button", function(e) {
+ $(document).click(function(e) {
//todo - disable navigation after click
- let path = $(e.target).data("path");
- let folder = $(e.target).data("folder");
- let playable = $(e.target).data("playable");
- let action = $(e.target).data("action");
- let searchFor = $(e.target).data("searchfor");
let endpoint = document.getElementById("endpoint").value;
+ // a context-menu option was selected -> query its path, same as action "query"
+ let cmEl = $(e.target).closest("[data-cm-path]");
+ if (cmEl.length) {
+ loadApiPath(endpoint + "?path=" + cmEl.attr("data-cm-path"));
+ return;
+ }
+
+ // resolve the clicked item from the closest element holding item data,
+ // so clicks on the inner icon/plot still navigate
+ let itemEl = $(e.target).closest("[data-path]");
+ if (!itemEl.length) {
+ return;
+ }
+
+ let path = itemEl.data("path");
+ let folder = itemEl.data("folder");
+ let playable = itemEl.data("playable");
+ let action = itemEl.data("action");
+ let searchFor = itemEl.data("searchfor");
+
if (folder && path) {
//navigate?
- if (path === ".." || path === ".") {
- if (paths.length > 1 && path === "..") {
- paths.pop();
- }
-
- path = paths[paths.length - 1];
-
- } else {
- paths.push(path);
+ if (path === "..") {
+ // go up a level via history so browser-back and in-page back stay in
+ // sync; popstate restores the parent's paths snapshot and reloads it
+ history.back();
+ return;
}
- loadApiPath(endpoint + "?path=" + path);
+ if (path === ".") {
+ // refresh the current container (e.g. player "Back"), no history change
+ loadApiPath(endpoint + "?path=" + paths[paths.length - 1]);
+ return;
+ }
+
+ paths.push(path);
+ loadApiPath(endpoint + "?path=" + path, "push");
return;
}
@@ -242,7 +313,7 @@
let searchText = prompt("What are you searching for?", iSearchFor);
if (searchText) {
paths.push(path + "&search=" + searchText);
- loadApiPath(endpoint + "?path=" + path + "&search=" + searchText);
+ loadApiPath(endpoint + "?path=" + path + "&search=" + searchText, "push");
}
}