Skip to content

Commit

Permalink
Fix: "Loading..." is no longer stuck as the website title
Browse files Browse the repository at this point in the history
  • Loading branch information
nwittwer committed Mar 16, 2023
1 parent 5e0d7a1 commit 852e4ac
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 21 deletions.
90 changes: 81 additions & 9 deletions app/src/extraResources/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ import * as htmlToImage from 'html-to-image'
import fs from 'fs/promises'
import path from 'path'

interface Data {
title: string
favicon: string
}

let data: Data = {
title: '',
favicon: '',
}

if (import.meta.env.MODE === 'development') {
// Ensure that all modules are loaded
console.log('Development mode')
Expand All @@ -37,25 +47,87 @@ if (import.meta.env.MODE === 'development') {
* Collect and send back information from the document context
* Only done during the initial bridging
*/
document.addEventListener('DOMContentLoaded', initiateBridge)
document.addEventListener('DOMContentLoaded', init)
// document.addEventListener('load', initiateBridge)

function initiateBridge() {
const data = {
title: document.title,
favicon:
'https://www.google.com/s2/favicons?domain=' + window.location.href,
}
async function init() {
// Communicate back to the Electron app
await initiateBridge()
}

async function getPageData() {
data.title = await getPageTitle()
console.log('Title:', data.title)

data.favicon =
'https://www.google.com/s2/favicons?domain=' + window.location.href
console.log('Favicon:', data.favicon)
}

function getPageTitle(): Promise<string> {
return new Promise(async (resolve, reject) => {
let title: string | undefined = document.title

if (title) {
resolve(title)
} else {
console.log('Waiting for <title> to be added')

// If no title after 15s, just return as empty
const timer = setTimeout(() => {
reject('No title found')
}, 2500)

// Wait for a <title> to be added
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (!mutation.addedNodes) return

for (let i = 0; i < mutation.addedNodes.length; i++) {
let node = mutation.addedNodes[i]
if (node.nodeName !== 'TITLE') continue
// Only look for <title> node
if (node.nodeName === 'TITLE') {
// Title set!
title = document.title

// Cancel the timer
clearTimeout(timer)

// Kill the observer
observer.disconnect()

// Return the final title
resolve(title)
}
}
})
})

// Watch the <head> for the <title> to be added
observer.observe(document.head, {
childList: true,
subtree: true,
characterData: true,
})
}
})
}

async function initiateBridge() {
// Listen for initial connection to the frame
ipcRenderer.once('bridgeToFrame', (event, args) => {
ipcRenderer.on('bridgeToFrame', async (event, args) => {
// We get the ID of the artboard we're connected to
console.log('Passed from parent:', args)
const { id, syncFns } = args
state.id = id

// Get the page title and favicon
await getPageData()

// Respond to the parent component
ipcRenderer.sendToHost('initiateBridge', data)
document.removeEventListener('DOMContentLoaded', initiateBridge)
// document.removeEventListener('DOMContentLoaded', initiateBridge)

// Run our functions
startSync()
Expand Down
17 changes: 7 additions & 10 deletions app/src/renderer/components/Screens/WebPage.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
<template>
<webview
ref="frame"
class="frame"
:preload="injectScriptPath"
v-bind="webviewOptions"
:electronConfig="webpreferences"
/>
<webview ref="frame" class="frame" :preload="injectScriptPath" v-bind="webviewOptions"
:electronConfig="webpreferences" />
</template>

<script lang="ts">
Expand Down Expand Up @@ -302,8 +297,6 @@ export default {
this.$emit('loadstart') // Show loading spinner
// Change the title to Loading...
// TODO Add a VueX action for this?
const history = useHistoryStore()
history.changeSiteData({
title: 'Loading...',
Expand Down Expand Up @@ -347,7 +340,6 @@ export default {
const title = returnedData.title
const favicon = returnedData.favicon
// TODO Add to VueX Action
const history = useHistoryStore()
history.changeSiteData({
title,
Expand All @@ -364,6 +356,11 @@ export default {
const frame = this.$refs.frame
this.$emit('loadend') // Hide loading spinner
// Get the final <title> after the page finished loading
frame.send('bridgeToFrame', {
id: this.id,
})
// History
// TODO: webContents.history is no longer around https://github.com/electron/electron/issues/26727
// how should we track the page history?
Expand Down
7 changes: 5 additions & 2 deletions app/src/renderer/store/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ export const useHistoryStore = defineStore('history', {
// This function may be called just to trigger a new URL navigation
// but it can also be called from an <artboard> once it has access to the new URL

// @TODO: Throttle this fn, as it will be called by
// each <webview> when it loads, and doesn't need to keep changing
// TODO: Only log in dev
console.log('Changing site data', val)

// TODO: Each artboard will call this fn right now
// But really we should only update the title once
// We could use a throttle fn, or a debounce fn, but this is also a bit hacky
if (val.title && val.title !== this.currentPage.title) {
this.currentPage.title = val.title
}
Expand Down

0 comments on commit 852e4ac

Please sign in to comment.