Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,32 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
unregisterFirefoxContentScript(request.id)
return false;
case "tabs": {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
// A popup hosted inside a tab (e.g. the in-page popup, which has no
// chrome.tabs of its own on Firefox) is identified by the sender's
// tab, even when that tab is not the currently active one. Only fall
// back to the active tab for popups that are not hosted in a tab.
if (sender.tab?.id !== undefined) {
chrome.tabs.sendMessage(
tabs[0].id,
sender.tab.id,
request.data,
(response) => {
callback(response);
}
);
});
} else {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
request.data,
(response) => {
callback(response);
}
);
});
}
return true;
}
case "time":
Expand Down Expand Up @@ -101,12 +115,34 @@ chrome.runtime.onMessageExternal.addListener((request, sender, callback) => {

chrome.runtime.onConnect.addListener((port) => {
if (port.name === "popup") {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
popupPort[tabs[0].id] = port;
});
// When the popup is hosted inside a tab (the in-page popup), the sender
// identifies that tab directly. Guessing the active tab instead breaks
// whenever the port reconnects while a different tab is active: updates
// meant for the popup's real tab then get posted to a dead port and the
// popup silently stops tracking video changes.
const tabID = port.sender?.tab?.id;
if (tabID !== undefined) {
popupPort[tabID] = port;

port.onDisconnect.addListener(() => {
if (popupPort[tabID] === port) {
delete popupPort[tabID];
}
});
} else {
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
popupPort[tabs[0].id] = port;

port.onDisconnect.addListener(() => {
if (popupPort[tabs[0].id] === port) {
delete popupPort[tabs[0].id];
}
});
});
}
}
});

Expand Down
23 changes: 20 additions & 3 deletions src/popup/PopupComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,26 @@ function sendMessage(request: Message): Promise<MessageResponse> {
}

function setupComPort(props: SegmentsLoadedProps): void {
const port = chrome.runtime.connect({ name: "popup" });
port.onDisconnect.addListener(() => setupComPort(props));
port.onMessage.addListener((msg) => onMessage(props, msg));
let reconnected = false;
const connect = () => {
const port = chrome.runtime.connect({ name: "popup" });
port.onDisconnect.addListener(() => {
reconnected = true;
connect();
});
port.onMessage.addListener((msg) => onMessage(props, msg));

// Updates may have been missed while the port was down (e.g. the video
// changed in the meantime), so resync instead of trusting stale state
if (reconnected) {
loadSegments({
...props,
updating: true
});
}
};

connect();
}

function onMessage(props: SegmentsLoadedProps, msg: PopupMessage) {
Expand Down
17 changes: 15 additions & 2 deletions src/popup/SegmentSubmissionComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,12 @@ export const SegmentSubmissionComponent = (props: SegmentSubmissionComponentProp
className="sbMediumButton"
style={{ marginRight: "8px" }}
onClick={() => {
let response: MessageResponse | undefined;
props.sendMessage({
from: "popup",
message: "sponsorStart"
}).then((res) => {
response = res;
});

setShowStartSegment(!showStartSegment);
Expand All @@ -41,9 +44,19 @@ export const SegmentSubmissionComponent = (props: SegmentSubmissionComponentProp
// Once data is saved, make sure it is correct
setTimeout(() => {
const segments = Config.local.unsubmittedSegments[props.videoID];
setShowStartSegment(!segments || segments[segments.length - 1].segment.length === 2);
if ((!segments || segments.length === 0) && response && "creatingSegment" in response) {
// Nothing is stored under this videoID, which
// happens when this popup's videoID is stale.
// The content script answered for the video it
// is actually on, so trust its report instead
// of snapping back to the pre-click state.
setShowStartSegment(!response.creatingSegment);
setShowSubmitButton(true);
} else {
setShowStartSegment(!segments || segments[segments.length - 1].segment.length === 2);

setShowSubmitButton(segments && segments.length > 0);
setShowSubmitButton(segments && segments.length > 0);
}
}, 200);
}}>
{showStartSegment ? chrome.i18n.getMessage("sponsorStart") : chrome.i18n.getMessage("sponsorEnd")}
Expand Down