diff --git a/public/_locales b/public/_locales index 7cedce21..3c5a80ca 160000 --- a/public/_locales +++ b/public/_locales @@ -1 +1 @@ -Subproject commit 7cedce215851872be28bd50a9f690b680dd54442 +Subproject commit 3c5a80ca9cc600c7c03b8d513cd80df8aa17b240 diff --git a/public/popup.html b/public/popup.html index bee090c4..2b5034f7 100644 --- a/public/popup.html +++ b/public/popup.html @@ -196,6 +196,8 @@ Discord Matrix __MSG_Donate__ +
+ __MSG_copyDebugLogs__ diff --git a/src/config.ts b/src/config.ts index 3fbe23ba..383bfcf6 100644 --- a/src/config.ts +++ b/src/config.ts @@ -477,4 +477,26 @@ const localDefaults = { }; const Config = new ConfigClass(syncDefaults, localDefaults, migrateOldSyncFormats); -export default Config; \ No newline at end of file +export default Config; + +export function generateDebugDetails(): string { + // Build output debug information object + const output = { + debug: { + userAgent: navigator.userAgent, + platform: navigator.platform, + language: navigator.language, + extensionVersion: chrome.runtime.getManifest().version + }, + config: JSON.parse(JSON.stringify(Config.cachedSyncConfig)) // Deep clone config object + }; + + // Sanitise sensitive user config values + delete output.config.userID; + output.config.serverAddress = (output.config.serverAddress === CompileConfig.serverAddress) + ? "Default server address" : "Custom server address"; + output.config.invidiousInstances = output.config.invidiousInstances.length; + output.config.whitelistedChannels = output.config.whitelistedChannels.length; + + return JSON.stringify(output, null, 4); +} \ No newline at end of file diff --git a/src/content.ts b/src/content.ts index 398102aa..04c2dcd3 100644 --- a/src/content.ts +++ b/src/content.ts @@ -346,6 +346,12 @@ function messageListener(request: Message, sender: unknown, sendResponse: (respo metaKey: request.metaKey })); break; + case "getLogs": + sendResponse({ + debug: window["SBLogs"].debug, + warn: window["SBLogs"].warn + }); + break; } sendResponse({}); diff --git a/src/messageTypes.ts b/src/messageTypes.ts index 191166a0..6b9f3225 100644 --- a/src/messageTypes.ts +++ b/src/messageTypes.ts @@ -17,7 +17,8 @@ interface DefaultMessage { | "isChannelWhitelisted" | "submitTimes" | "refreshSegments" - | "closePopup"; + | "closePopup" + | "getLogs"; } interface BoolValueMessage { @@ -104,7 +105,8 @@ export type MessageResponse = | Record // empty object response {} | VoteResponse | ImportSegmentsResponse - | RefreshSegmentsResponse; + | RefreshSegmentsResponse + | LogResponse; export interface VoteResponse { successType: number; @@ -120,6 +122,11 @@ export interface RefreshSegmentsResponse { hasVideo: boolean; } +export interface LogResponse { + debug: string[]; + warn: string[]; +} + export interface TimeUpdateMessage { message: "time"; time: number; diff --git a/src/options.ts b/src/options.ts index e983498f..f6ba2663 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,7 +1,7 @@ import * as React from "react"; import { createRoot } from 'react-dom/client'; -import Config from "./config"; +import Config, { generateDebugDetails } from "./config"; import * as CompileConfig from "../config.json"; import * as invidiousList from "../ci/invidiouslist.json"; @@ -698,32 +698,14 @@ function validateServerAddress(input: string): string { } function copyDebugOutputToClipboard() { - // Build output debug information object - const output = { - debug: { - userAgent: navigator.userAgent, - platform: navigator.platform, - language: navigator.language, - extensionVersion: chrome.runtime.getManifest().version - }, - config: JSON.parse(JSON.stringify(Config.cachedSyncConfig)) // Deep clone config object - }; - - // Sanitise sensitive user config values - delete output.config.userID; - output.config.serverAddress = (output.config.serverAddress === CompileConfig.serverAddress) - ? "Default server address" : "Custom server address"; - output.config.invidiousInstances = output.config.invidiousInstances.length; - output.config.whitelistedChannels = output.config.whitelistedChannels.length; - // Copy object to clipboard - navigator.clipboard.writeText(JSON.stringify(output, null, 4)) - .then(() => { + navigator.clipboard.writeText(generateDebugDetails()) + .then(() => { alert(chrome.i18n.getMessage("copyDebugInformationComplete")); - }) - .catch(() => { + }) + .catch(() => { alert(chrome.i18n.getMessage("copyDebugInformationFailed")); - }); + }); } function isIncognitoAllowed(): Promise { diff --git a/src/popup.ts b/src/popup.ts index 27984cee..b20723a2 100644 --- a/src/popup.ts +++ b/src/popup.ts @@ -1,4 +1,4 @@ -import Config from "./config"; +import Config, { generateDebugDetails } from "./config"; import Utils from "./utils"; import { @@ -12,6 +12,7 @@ import { GetChannelIDResponse, IsChannelWhitelistedResponse, IsInfoFoundMessageResponse, + LogResponse, Message, MessageResponse, PopupMessage, @@ -184,7 +185,8 @@ async function runThePopup(messageListener?: MessageListener): Promise { "exportSegmentsButton", "importSegmentsMenu", "importSegmentsText", - "importSegmentsSubmit" + "importSegmentsSubmit", + "debugLogs" ].forEach(id => PageElements[id] = document.getElementById(id)); @@ -255,6 +257,7 @@ async function runThePopup(messageListener?: MessageListener): Promise { PageElements.helpButton.addEventListener("click", openHelp); PageElements.refreshSegmentsButton.addEventListener("click", refreshSegments); PageElements.sbPopupIconCopyUserID.addEventListener("click", async () => copyToClipboard(await getHash(Config.config.userID))); + PageElements.debugLogs.addEventListener("click", copyDebgLogs); // Forward click events if (window !== window.top) { @@ -1143,6 +1146,12 @@ async function runThePopup(messageListener?: MessageListener): Promise { } } + function copyDebgLogs() { + sendTabMessage({ message: "getLogs" }, (logs: LogResponse) => { + copyToClipboard(`${generateDebugDetails()}\n\nWarn:\n${logs.warn.join("\n")}\n\nDebug:\n${logs.debug.join("\n")}`); + }); + } + function onMessage(msg: PopupMessage) { switch (msg.message) { case "time":