fix skip button
This commit is contained in:
parent
ccabdaff19
commit
dc5fc951ed
@ -1,12 +1,21 @@
|
|||||||
const introSkipper = {
|
const introSkipper = {
|
||||||
originalFetch: window.fetch.bind(window),
|
originalFetch: window.fetch.bind(window),
|
||||||
|
originalXHROpen: XMLHttpRequest.prototype.open,
|
||||||
|
originalXHRSend: XMLHttpRequest.prototype.send,
|
||||||
d: msg => console.debug("[intro skipper] ", msg),
|
d: msg => console.debug("[intro skipper] ", msg),
|
||||||
setup() {
|
setup() {
|
||||||
|
const self = this;
|
||||||
this.initializeState();
|
this.initializeState();
|
||||||
this.initializeObserver();
|
this.initializeObserver();
|
||||||
this.currentOption = localStorage.getItem('introskipperOption') || 'Show Button';
|
this.currentOption = localStorage.getItem('introskipperOption') || 'Show Button';
|
||||||
document.addEventListener("viewshow", this.viewShow.bind(this));
|
|
||||||
window.fetch = this.fetchWrapper.bind(this);
|
window.fetch = this.fetchWrapper.bind(this);
|
||||||
|
XMLHttpRequest.prototype.open = function(...args) {
|
||||||
|
self.xhrOpenWrapper(this, ...args);
|
||||||
|
};
|
||||||
|
XMLHttpRequest.prototype.send = function(...args) {
|
||||||
|
self.xhrSendWrapper(this, ...args);
|
||||||
|
};
|
||||||
|
document.addEventListener("viewshow", this.viewShow.bind(this));
|
||||||
this.videoPositionChanged = this.videoPositionChanged.bind(this);
|
this.videoPositionChanged = this.videoPositionChanged.bind(this);
|
||||||
this.handleEscapeKey = this.handleEscapeKey.bind(this);
|
this.handleEscapeKey = this.handleEscapeKey.bind(this);
|
||||||
this.d("Registered hooks");
|
this.d("Registered hooks");
|
||||||
@ -20,38 +29,65 @@ const introSkipper = {
|
|||||||
if (actionSheet && !actionSheet.querySelector(`[data-id="${'introskipperMenu'}"]`)) this.injectIntroSkipperOptions(actionSheet);
|
if (actionSheet && !actionSheet.querySelector(`[data-id="${'introskipperMenu'}"]`)) this.injectIntroSkipperOptions(actionSheet);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/** Wrapper around fetch() that retrieves skip segments for the currently playing item or metadata. */
|
fetchWrapper(resource, options) {
|
||||||
async fetchWrapper(resource, options) {
|
const response = this.originalFetch(resource, options);
|
||||||
const response = await this.originalFetch(resource, options);
|
const url = new URL(resource);
|
||||||
this.processResource(resource);
|
if (this.injectMetadata && url.pathname.includes("/MetadataEditor"))
|
||||||
|
{
|
||||||
|
this.processMetadata(url.pathname);
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
async processResource(resource) {
|
xhrOpenWrapper(xhr, method, url, async, user, password) {
|
||||||
try {
|
this.d(`XHR Open: ${method} ${url}`);
|
||||||
const url = new URL(resource);
|
xhr._introSkipperUrl = url;
|
||||||
const pathname = url.pathname;
|
return this.originalXHROpen.apply(xhr, [method, url, async, user, password]);
|
||||||
if (pathname.includes("/PlaybackInfo")) {
|
},
|
||||||
this.d(`Retrieving skip segments from URL ${pathname}`);
|
xhrSendWrapper(xhr, body) {
|
||||||
const pathArr = pathname.split("/");
|
const originalOnReadyStateChange = xhr.onreadystatechange;
|
||||||
const id = pathArr[pathArr.indexOf("Items") + 1] || pathArr[3];
|
|
||||||
|
xhr.onreadystatechange = () => {
|
||||||
|
if (xhr.readyState === 4 && xhr._introSkipperUrl.includes("/PlaybackInfo")) {
|
||||||
|
this.processPlaybackInfo(xhr._introSkipperUrl);
|
||||||
|
}
|
||||||
|
if (originalOnReadyStateChange) {
|
||||||
|
originalOnReadyStateChange.apply(xhr, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return this.originalXHRSend.apply(xhr, [body]);
|
||||||
|
},
|
||||||
|
async processPlaybackInfo(url) {
|
||||||
|
const id = this.extractId(url);
|
||||||
|
if (id) {
|
||||||
|
try {
|
||||||
this.skipSegments = await this.secureFetch(`Episode/${id}/IntroSkipperSegments`);
|
this.skipSegments = await this.secureFetch(`Episode/${id}/IntroSkipperSegments`);
|
||||||
this.d("Retrieved skip segments", this.skipSegments);
|
} catch (error) {
|
||||||
} else if (this.injectMetadata && pathname.includes("/MetadataEditor")) {
|
this.d(`Error fetching skip segments: ${error.message}`);
|
||||||
this.d(`Metadata editor detected, URL ${pathname}`);
|
}
|
||||||
const pathArr = pathname.split("/");
|
}
|
||||||
this.currentEpisodeId = pathArr[pathArr.indexOf("Items") + 1] || pathArr[3];
|
},
|
||||||
this.skipperData = await this.secureFetch(`Episode/${this.currentEpisodeId}/Timestamps`);
|
async processMetadata(url) {
|
||||||
|
const id = this.extractId(url);
|
||||||
|
if (id) {
|
||||||
|
try {
|
||||||
|
this.skipperData = await this.secureFetch(`Episode/${id}/Timestamps`);
|
||||||
if (this.skipperData) {
|
if (this.skipperData) {
|
||||||
|
this.currentEpisodeId = id;
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const metadataFormFields = document.querySelector('.metadataFormFields');
|
const metadataFormFields = document.querySelector('.metadataFormFields');
|
||||||
metadataFormFields && this.injectSkipperFields(metadataFormFields);
|
metadataFormFields && this.injectSkipperFields(metadataFormFields);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error processing", e);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.error("Error processing", resource, e);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
extractId(searchString) {
|
||||||
|
const startIndex = searchString.indexOf('Items/') + 6;
|
||||||
|
const endIndex = searchString.indexOf('/', startIndex);
|
||||||
|
return endIndex !== -1 ? searchString.substring(startIndex, endIndex) : searchString.substring(startIndex);
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Event handler that runs whenever the current view changes.
|
* Event handler that runs whenever the current view changes.
|
||||||
* Used to detect the start of video playback.
|
* Used to detect the start of video playback.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user