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"); } }