Support Jellyfin 10.7

This commit is contained in:
crobibero
2021-02-24 10:29:09 -07:00
parent 1458fd7534
commit 84a1d0934e
35 changed files with 699 additions and 751 deletions
@@ -4,52 +4,61 @@
<title>Simkl's TV Tracker</title>
</head>
<body>
<div data-role="page" class="page type-interior pluginConfigurationPage" id="SimklConfigurationPage" data-require="emby-button,emby-checkbox,emby-input,emby-select">
<div data-role="page" class="page type-interior pluginConfigurationPage" id="SimklConfigurationPage"
data-require="emby-button,emby-checkbox,emby-input,emby-select">
<div data-role="content">
<div class="content-primary">
<h1>Simkl's TV Tracker</h1>
<form id="SimklConfigurationForm">
<div id="selectContainer">
<select onchange="SimklConfig.onSelectorChange();" is="emby-select" id="user-selector" label="Showing plugin settings for...">
<select onchange="SimklConfig.onSelectorChange();" is="emby-select" id="user-selector"
label="Showing plugin settings for...">
<!-- This will be populated by SimklConfig.populateUsers -->
</select>
</div>
<div id="loginButtonContainer" hidden>
<h3>It seems you are not logged in, do you wish to log in?</h3>
<button onclick="SimklConfig.startLoginProcess();" is="emby-button" type="button" class="raised button-submit block"><span>Log In</span></button>
<button onclick="location.href='https://simkl.com/';" is="emby-button" type="button" class="raised block"><span>Create an account</span></button>
<button onclick="SimklConfig.startLoginProcess();" is="emby-button" type="button"
class="raised button-submit block"><span>Log In</span></button>
<button onclick="location.href='https://simkl.com/';" is="emby-button" type="button"
class="raised block"><span>Create an account</span></button>
</div>
<div id="loggingIn" hidden>
<h2>Logging In</h2>
<div id="loginText"></div>
<h3 id="loginPin"></h3>
<span id="loginSecondsRemaining">900</span> seconds remaining
<button onclick="SimklConfig.stopLoginProcess();" is="emby-button" type="button" class="raised button-cancel block"><span>Cancel</span></button>
<button onclick="SimklConfig.stopLoginProcess();" is="emby-button" type="button"
class="raised button-cancel block"><span>Cancel</span></button>
</div>
<div id="configOptionsContainer" hidden>
<h3>Hello again <span id="simklName">USERNAME</span>!</h3>
<button onclick="SimklConfig.logOut();" is="emby-button" type="button" class="raised button block"><span>Log Out</span></button>
<button onclick="SimklConfig.logOut();" is="emby-button" type="button" class="raised button block">
<span>Log Out</span></button>
<h2>Scrobbling options:</h2>
<div class="checkboxcontainer">
<label>
<input is="emby-checkbox" type="checkbox" id="ScrobbleMovies" />
<input is="emby-checkbox" type="checkbox" id="ScrobbleMovies"/>
<span>Autoscrobbling Movies</span>
</label>
</div>
<div class="checkboxcontainer">
<label>
<input is="emby-checkbox" type="checkbox" id="ScrobbleShows" />
<input is="emby-checkbox" type="checkbox" id="ScrobbleShows"/>
<span>Autoscrobbling TV Shows</span>
</label>
</div>
<div class="inputContainer">
<input is="emby-input" id="ScrobblePercentage" type="number" min="0" max="100" pattern="[0-9]*" label="Scrobbling percentage:" />
<input is="emby-input" id="ScrobblePercentage" type="number" min="0" max="100" pattern="[0-9]*"
label="Scrobbling percentage:"/>
<div class="fieldDescription">
Percentage watched needed to scrobble
</div>
</div>
<button is="emby-button" type="submit" class="raised button-submit block"><span>${ButtonSave}</span></button>
<button is="emby-button" type="button" class="raised block" onclick="history.back();"><span>${Cancel}</span></button>
<button is="emby-button" type="submit" class="raised button-submit block"><span>${Save}</span>
</button>
<button is="emby-button" type="button" class="raised block" onclick="history.back();"><span>${Cancel}</span>
</button>
</div>
</form>
</div>
@@ -57,42 +66,57 @@
<script type="text/javascript">
var SimklConfig = {
guid: "07CAEF58-A94B-4211-A62C-F9774E04EBDB",
onLoginProccess: false,
onLoginProcess: false,
configCache: [],
loginTimer: null,
remainingTimer: null,
finish: null,
populateUsers : async function (users) {
users.forEach(function(user) {
$("#user-selector").append(new Option(user.Name, user.Id));
userSelector: document.querySelector('#user-selector'),
loginButtonContainer: document.querySelector('#loginButtonContainer'),
configOptionsContainer: document.querySelector('#configOptionsContainer'),
simklName: document.querySelector('#simklName'),
loginSecondsRemaining: document.querySelector('#loginSecondsRemaining'),
loginText: document.querySelector('#loginText'),
loginPin: document.querySelector('#loginPin'),
loggingIn: document.querySelector('#loggingIn'),
populateUsers: async function (users) {
users.forEach(function (user) {
SimklConfig.userSelector.append(new Option(user.Name, user.Id));
});
},
loadConfig : async function(user, config) {
if (config != null) this.configCache = config;
else config = this.configCache;
loadConfig: async function (user, config) {
if (config != null) {
this.configCache = config;
} else {
config = this.configCache;
}
console.log("Simkl: Loading config for user " + user);
console.log(config);
$("#loginButtonContainer").hide();
$("#configOptionsContainer").hide();
SimklConfig.loginButtonContainer.setAttribute('hidden', '');
SimklConfig.configOptionsContainer.setAttribute('hidden', '')
if (config.UserConfigs.some(e => e.Id === user && e.UserToken != null && e.UserToken !== "")) {
$("#configOptionsContainer").show();
this.populateOptionsContainer(config.UserConfigs.filter(e => e.Id === user)[0]);
SimklConfig.configOptionsContainer.removeAttribute('hidden');
await this.populateOptionsContainer(config.UserConfigs.filter(e => e.Id === user)[0]);
} else {
$("#loginButtonContainer").show();
SimklConfig.loginButtonContainer.removeAttribute('hidden');
}
},
saveConfig : async function(guid) {
var uconfig = this.configCache.UserConfigs.filter(e => e.Id === guid)[0];
saveConfig: async function (guid) {
const uconfig = this.configCache.UserConfigs.filter(e => e.Id === guid)[0];
for (var key in uconfig) {
var element = $("#configOptionsContainer #"+key);
if (element.is(":checkbox")) {
uconfig[key] = element.is(':checked');
for (const key in uconfig) {
const element = document.querySelector("#configOptionsContainer #" + key);
if (element.type === 'checkbox') {
uconfig[key] = element.checked;
} else {
if (element.val() != null) uconfig[key] = element.val();
if (element.value != null) {
uconfig[key] = element.value;
}
}
}
@@ -100,51 +124,59 @@
console.log(this.configCache);
ApiClient.updatePluginConfiguration(this.guid, this.configCache).then(Dashboard.processPluginConfigurationUpdateResult);
},
populateOptionsContainer : async function(userConfig) {
$("#simklName").html(SimklAPI.getUserSettings(userConfig.Id).user.name);
populateOptionsContainer: async function (userConfig) {
SimklConfig.simklName.innerText = (await SimklAPI.getUserSettings(userConfig.Id)).user.name;
for (var key in userConfig) {
for (const key in userConfig) {
console.log(key, userConfig[key]);
$("#configOptionsContainer input[type=checkbox]#"+key).attr("checked", userConfig[key]);
$("#configOptionsContainer input[type=number]#"+key).val(userConfig[key]);
const chk = document.querySelector("#configOptionsContainer input[type=checkbox]#" + key);
if (chk) {
chk.checked = userConfig[key];
}
const input = document.querySelector("#configOptionsContainer input[type=number]#" + key);
if (input) {
input.value = userConfig[key];
}
}
},
startLoginProcess : async function () {
startLoginProcess: async function () {
this.onLoginProcess = true;
var code = SimklAPI.getCode();
const code = await SimklAPI.getCode();
console.log(code);
this.finish = new Date();
this.finish.setSeconds(this.finish.getSeconds() + code.expires_in);
this.nextInterval = new Date();
this.loginTimer = window.setTimeout(this.checkLoginProcess.bind(this,code), code.Interval*1000);
this.remainingTimer = window.setInterval(function() {
$("#loginSecondsRemaining").html(Math.round((SimklConfig.finish.getTime() - (new Date().getTime()))/1000));
} ,1000);
this.loginTimer = window.setTimeout(this.checkLoginProcess.bind(this, code), code.Interval * 1000);
this.remainingTimer = window.setInterval(function () {
SimklConfig.loginSecondsRemaining.innerText = Math.round((SimklConfig.finish.getTime() - (new Date().getTime())) / 1000);
}, 1000);
$("#loginText").html("Please visit <a href='" + code.verification_url + "/" + code.user_code +
"' target='_blank'>" + code.verification_url + "</a> on your phone or computer and enter the following code:");
$("#loginPin").html(code.user_code);
SimklConfig.loginText.innerHTML = 'Please visit <a href="' + code.verification_url + '/' + code.user_code + '" target="_blank">' + code.verification_url + '</a> on your phone or compouter and enter the following code:';
$("#loginButtonContainer").hide();
await $("#loggingIn").show();
SimklConfig.loginPin.innerText = code.user_code;
SimklConfig.loginButtonContainer.setAttribute('hidden', '');
SimklConfig.loggingIn.removeAttribute('hidden');
},
checkLoginProcess : function (code) {
var response = SimklAPI.checkCode(code.user_code);
checkLoginProcess: async function (code) {
const response = await SimklAPI.checkCode(code.user_code);
console.log("Response:");
console.log(response);
if (new Date() > this.finish) {
Dashboard.alert("Timed out!");
this.stopLoginProcess();
await this.stopLoginProcess();
} else if (response.Result === "KO") {
this.loginTimer = window.setTimeout(this.checkLoginProcess.bind(this,code), code.Interval*1000);
this.loginTimer = window.setTimeout(this.checkLoginProcess.bind(this, code), code.Interval * 1000);
} else if (response.Result === "OK") {
this.stopLoginProcess();
await this.stopLoginProcess();
// Save key on settings
var uguid = $("#user-selector").val();
var filter = this.configCache.UserConfigs.filter(function(c) {
const uguid = SimklConfig.userSelector.value;
const filter = this.configCache.UserConfigs.filter(function (c) {
return c.Id === uguid;
});
if (filter.length > 0) {
@@ -159,26 +191,29 @@
console.log(this.configCache);
ApiClient.updatePluginConfiguration(this.guid, this.configCache);
this.loadConfig(uguid);
await this.loadConfig(uguid);
} else {
Dashboard.alert("Error logging in");
}
},
stopLoginProcess : async function () {
stopLoginProcess: async function () {
this.onLoginProcess = false;
window.clearTimeout(this.loginTimer);
window.clearInterval(this.remainingTimer);
$("#loginButtonContainer").show();
$("#loggingIn").hide();
SimklConfig.loginButtonContainer.removeAttribute('hidden');
SimklConfig.loggingIn.setAttribute('hidden', '');
},
onSelectorChange : async function () {
if (this.onLoginProcess) this.stopLoginProcess();
this.loadConfig($("#user-selector").val(), null);
onSelectorChange: async function () {
if (this.onLoginProcess) {
await this.stopLoginProcess();
}
await this.loadConfig(SimklConfig.userSelector.value, null);
},
logOut : function(uguid) {
if (uguid == null) uguid = $("#user-selector").val();
logOut: function (uguid) {
if (uguid == null) {
uguid = SimklConfig.userSelector.value;
}
// e1f34a57cb3c4767ab6f29cc5c7c0566
var filter = this.configCache.UserConfigs.filter(function (c) {
return c.Id === uguid;
});
@@ -191,70 +226,87 @@
}
console.log(this.configCache);
ApiClient.updatePluginConfiguration(this.guid, this.configCache);
window.ApiClient.updatePluginConfiguration(this.guid, this.configCache);
this.loadConfig(uguid);
}
}
var SimklAPI = {
getCode: function () {
var uri = "/Simkl/oauth/pin";
var request = new XMLHttpRequest();
request.open("GET", uri, false);
request.send();
if (request.status === 200) {
return $.parseJSON(request.response);
} else {
console.log(request);
Dashboard.alert("Some error occurred, see browser log for more details");
SimklConfig.stopLoginProcess();
const request = {
url: window.ApiClient.getUrl('Simkl/oauth/pin'),
type: 'GET',
headers: {
accept: 'application/json'
}
}
return window.ApiClient.fetch(request)
.then(function (result) {
return result;
})
.catch(function (result) {
console.log(result);
Dashboard.alert("Some error occurred, see browser log for more details");
SimklConfig.stopLoginProcess();
});
},
checkCode : function (user_code) {
var uri = "/Simkl/oauth/pin/" + user_code;
var request = new XMLHttpRequest();
request.open("GET", uri, false);
request.send();
if (request.status === 200) {
return $.parseJSON(request.response);
} else {
console.log(request);
Dashboard.alert("Some error occurred, see browser log for more details");
SimklConfig.stopLoginProcess();
checkCode: function (user_code) {
const request = {
url: window.ApiClient.getUrl('Simkl/oauth/pin/' + user_code),
type: 'GET',
headers: {
accept: 'application/json'
}
}
return window.ApiClient.fetch(request)
.then(function (result) {
return result;
})
.catch(function (result) {
console.log(result);
Dashboard.alert("Some error occurred, see browser log for more details");
SimklConfig.stopLoginProcess();
});
},
getUserSettings: function (secret) {
var uri = "/Simkl/users/settings/" + secret;
var request = new XMLHttpRequest();
request.open("GET", uri, false);
request.send();
if (request.status === 200) {
return $.parseJSON(request.response);
} else {
console.log(request);
Dashboard.alert("Something went wrong, see logs for more details");
const request = {
url: window.ApiClient.getUrl('Simkl/users/settings/' + secret),
type: 'GET',
headers: {
accept: 'application/json'
}
}
return window.ApiClient.fetch(request)
.then(function (result) {
return result;
})
.catch(function (result) {
console.log(result);
Dashboard.alert("Something went wrong, see logs for more details");
});
}
}
$("#SimklConfigurationPage").on("pageshow", async function(e) {
Dashboard.showLoadingMsg();
await Promise.all([
ApiClient.getUsers().then(SimklConfig.populateUsers),
ApiClient.getPluginConfiguration(SimklConfig.guid).then(SimklConfig.loadConfig.bind(SimklConfig, ApiClient.getCurrentUserId()))]);
Dashboard.hideLoadingMsg();
});
document.querySelector('#SimklConfigurationPage')
.addEventListener('pageshow', async function () {
Dashboard.showLoadingMsg();
await Promise.all([
window.ApiClient.getUsers().then(SimklConfig.populateUsers),
window.ApiClient.getPluginConfiguration(SimklConfig.guid).then(SimklConfig.loadConfig.bind(SimklConfig, ApiClient.getCurrentUserId()))]);
Dashboard.hideLoadingMsg();
});
$("#SimklConfigurationForm").on("submit", function(e) {
Dashboard.showLoadingMsg();
SimklConfig.saveConfig($("#user-selector").val());
Dashboard.hideLoadingMsg();
document.querySelector('#SimklConfigurationForm')
.addEventListener('submit', function (e) {
e.preventDefault();
return false;
});
Dashboard.showLoadingMsg();
SimklConfig.saveConfig(SimklConfig.userSelector.value);
Dashboard.hideLoadingMsg();
});
</script>
</div>
</body>