From bf0897061068f79b8ee171ce6de5a8f9f6788a78 Mon Sep 17 00:00:00 2001 From: skarab42 Date: Fri, 5 Mar 2021 13:06:43 +0100 Subject: [PATCH] fix: Twitch (chat) login in electron --- app/main/window/chatWindow.js | 67 +-------------------------- app/main/window/injectTitlebar.js | 69 ++++++++++++++++++++++++++++ app/main/window/loginWindow.js | 39 ++++++++++++++++ app/main/window/openLinkInBrowser.js | 4 +- 4 files changed, 113 insertions(+), 66 deletions(-) create mode 100644 app/main/window/injectTitlebar.js create mode 100644 app/main/window/loginWindow.js diff --git a/app/main/window/chatWindow.js b/app/main/window/chatWindow.js index 0201d8a5..5c42c6a0 100644 --- a/app/main/window/chatWindow.js +++ b/app/main/window/chatWindow.js @@ -1,6 +1,6 @@ const openLinkInBrowser = require("./openLinkInBrowser"); -const { getServerURL } = require("../../server/utils"); const { staticPath, watch } = require("../../utils"); +const injectTitlebar = require("./injectTitlebar"); const webPreferences = require("./webPreferences"); const { BrowserWindow } = require("electron"); const storeBounds = require("./storeBounds"); @@ -36,70 +36,7 @@ module.exports = function chatWindow({ channel, showOnLoad = true } = {}) { storeBounds({ win, name: "chat" }); win.webContents.on("did-finish-load", async () => { - const serverURL = await getServerURL(); - - win.webContents.insertCSS(` - #root > div.tw-top-0 { - top: 30px !important; - } - #electron-titlebar { - display: flex; - font-size: 14px; - user-select: none; - align-items: center; - color: rgb(226, 232, 240); - background-color: rgb(26, 32, 44); - } - #electron-titlebar > div { - display: flex; - height: 29px; - padding-left: 8px; - padding-right: 8px; - align-items: center; - } - #electron-titlebar > div.icon { - display: flex; - } - #electron-titlebar > div.title { - padding: 1px 0; - flex: 1 1 auto; - display: flex; - height: 24px; - } - #electron-titlebar > div.title > div { - flex: 1 1 auto; - -webkit-app-region: drag; - } - #electron-titlebar > div.cross { - cursor: pointer; - } - #electron-titlebar > div.cross:hover { - background-color: rgb(197, 48, 48); - } - `); - win.webContents.executeJavaScript(` - const $html = document.querySelector("html"); - const $body = document.querySelector("body"); - $html.classList.toggle("tw-root--theme-dark", true); - $html.classList.toggle("tw-root--theme-light", false); - const $titlebar = document.createElement('div'); - const $icon = document.createElement('div'); - const $title = document.createElement('div'); - const $cross = document.createElement('div'); - const $iconSVG = document.createElement('img'); - $titlebar.setAttribute('id', 'electron-titlebar'); - $iconSVG.setAttribute('src', '${serverURL}/icon.svg'); - $iconSVG.setAttribute('height', '16px'); - $icon.classList.add('icon'); - $title.classList.add('title'); - $cross.classList.add('cross'); - $icon.append($iconSVG); - $title.innerHTML = '
${channel} - Twitch chat
'; - $cross.innerHTML = '✕'; - $titlebar.append($icon, $title, $cross); - $cross.addEventListener('click', () => window.close()); - $body.prepend($titlebar); - `); + await injectTitlebar({ win, title: `${channel} - Twitch chat` }); showOnLoad && win.show(); }); diff --git a/app/main/window/injectTitlebar.js b/app/main/window/injectTitlebar.js new file mode 100644 index 00000000..561db5f3 --- /dev/null +++ b/app/main/window/injectTitlebar.js @@ -0,0 +1,69 @@ +const { getServerURL } = require("../../server/utils"); + +module.exports = async ({ win, title }) => { + const serverURL = await getServerURL(); + + win.webContents.insertCSS(` + #root > div.tw-top-0 { + top: 30px !important; + } + #electron-titlebar { + display: flex; + font-size: 14px; + user-select: none; + align-items: center; + color: rgb(226, 232, 240); + background-color: rgb(26, 32, 44); + } + #electron-titlebar > div { + display: flex; + height: 29px; + padding-left: 8px; + padding-right: 8px; + align-items: center; + } + #electron-titlebar > div.icon { + display: flex; + } + #electron-titlebar > div.title { + padding: 1px 0; + flex: 1 1 auto; + display: flex; + height: 24px; + } + #electron-titlebar > div.title > div { + flex: 1 1 auto; + -webkit-app-region: drag; + } + #electron-titlebar > div.cross { + cursor: pointer; + } + #electron-titlebar > div.cross:hover { + background-color: rgb(197, 48, 48); + } + `); + + win.webContents.executeJavaScript(` + const $html = document.querySelector("html"); + const $body = document.querySelector("body"); + $html.classList.toggle("tw-root--theme-dark", true); + $html.classList.toggle("tw-root--theme-light", false); + const $titlebar = document.createElement('div'); + const $icon = document.createElement('div'); + const $title = document.createElement('div'); + const $cross = document.createElement('div'); + const $iconSVG = document.createElement('img'); + $titlebar.setAttribute('id', 'electron-titlebar'); + $iconSVG.setAttribute('src', '${serverURL}/icon.svg'); + $iconSVG.setAttribute('height', '16px'); + $icon.classList.add('icon'); + $title.classList.add('title'); + $cross.classList.add('cross'); + $icon.append($iconSVG); + $title.innerHTML = '
${title}
'; + $cross.innerHTML = '✕'; + $titlebar.append($icon, $title, $cross); + $cross.addEventListener('click', () => window.close()); + $body.prepend($titlebar); + `); +}; diff --git a/app/main/window/loginWindow.js b/app/main/window/loginWindow.js new file mode 100644 index 00000000..a990936c --- /dev/null +++ b/app/main/window/loginWindow.js @@ -0,0 +1,39 @@ +const { BrowserWindow, session } = require("electron"); +const { staticPath, watch } = require("../../utils"); +const injectTitlebar = require("./injectTitlebar"); +const webPreferences = require("./webPreferences"); +const path = require("path"); + +let win = null; + +session.defaultSession.webRequest.onCompleted( + { urls: ["https://passport.twitch.tv/login"] }, + ({ statusCode }) => { + if (win && statusCode === 200) { + win.getParentWindow().reload(); + win.close(); + win = null; + } + } +); + +module.exports = function loginWindow({ parent, url }) { + win = new BrowserWindow({ + parent, + width: 800, + height: 600, + show: false, + frame: false, + icon: path.join(staticPath, "icon.png"), + webPreferences: { ...webPreferences, devTools: watch }, + }); + + win.webContents.on("did-finish-load", async () => { + await injectTitlebar({ win, title: `Twitch chat login` }); + win.show(); + }); + + win.removeMenu(); + win.loadURL(url); + watch && win.webContents.openDevTools(); +}; diff --git a/app/main/window/openLinkInBrowser.js b/app/main/window/openLinkInBrowser.js index 27410cf6..d686bd09 100644 --- a/app/main/window/openLinkInBrowser.js +++ b/app/main/window/openLinkInBrowser.js @@ -1,8 +1,10 @@ const open = require("open"); +const loginWindow = require("./loginWindow"); module.exports = function openLinkInBrowser(win) { win.webContents.on("new-window", (event, url) => { event.preventDefault(); - open(url); + const isTwitchLogin = url === "https://www.twitch.tv/login?popup=true"; + isTwitchLogin ? loginWindow({ parent: win, url }) : open(url); }); };