-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: reload failed IPFS tabs when API becomes available #1092
Changes from all commits
5275c15
2f68cbd
75579fc
0e0cfd5
1714406
c334d06
4e6a86c
1686606
3c6c2af
7f6287d
0fde4f9
2f37bab
e437eec
0652353
6faff55
a645a85
b69a468
b420dc7
404a6ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
root=true | ||
|
||
[*] | ||
end_of_line = lf | ||
insert_final_newline = true | ||
charset = utf-8 | ||
indent_style = space | ||
indent_size = 2 | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
const { InternalTabReloader } = require('./internalTabReloader') | ||
const { LocalGatewayReloader } = require('./localGatewayReloader') | ||
const { WebUiReloader } = require('./webUiReloader') | ||
|
||
/** | ||
* Prepares extension by creating an instance and awaiting for init. | ||
* | ||
* @param {Array.[InternalTabReloader|LocalGatewayReloader|WebUiReloader]} extensions | ||
* @param {Browser} browserInstance | ||
* @param {Logger} loggerInstance | ||
* @returns {Promise<Array.[InternalTabReloader|LocalGatewayReloader|WebUiReloader]>} | ||
*/ | ||
function prepareReloadExtensions (extensions, browserInstance, loggerInstance) { | ||
const reloadExtensions = Array.isArray(extensions) ? extensions : [extensions] | ||
return Promise.all(reloadExtensions | ||
.map(async Ext => { | ||
try { | ||
const ext = new Ext(browserInstance, loggerInstance) | ||
await ext.init() | ||
return ext | ||
} catch (e) { | ||
loggerInstance(`Extension Instance Failed to Initialize with error: ${e}. Extension: ${Ext}`) | ||
} | ||
}) | ||
) | ||
} | ||
|
||
module.exports = { | ||
InternalTabReloader, | ||
LocalGatewayReloader, | ||
WebUiReloader, | ||
prepareReloadExtensions | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const { ReloaderBase } = require('./reloaderBase') | ||
|
||
class InternalTabReloader extends ReloaderBase { | ||
/** | ||
* Setting up the extension origin. | ||
*/ | ||
init () { | ||
this.extensionOrigin = this._browserInstance.runtime.getURL('/') | ||
this._log('InternalTabReloader Ready for use.') | ||
} | ||
|
||
/** | ||
* Performs url validation for the tab. If tab is a WebUI tab. | ||
* | ||
* @param {Object} tab | ||
* @param {string} tab.url | ||
* @returns {boolean} | ||
*/ | ||
validation ({ url }) { | ||
return url.startsWith(this.extensionOrigin) | ||
} | ||
|
||
/** | ||
* Returns message when reloading the tab. | ||
* | ||
* @param {Object} tab | ||
* @param {string} tab.url | ||
* @returns {string} message. | ||
*/ | ||
message ({ url }) { | ||
return `reloading internal extension page at ${url}` | ||
} | ||
} | ||
|
||
module.exports = { | ||
InternalTabReloader | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
const { ReloaderBase } = require('./reloaderBase') | ||
const isIPFS = require('is-ipfs') | ||
|
||
class LocalGatewayReloader extends ReloaderBase { | ||
/** | ||
* Performs url validation for the tab. If tab is loaded via local gateway. | ||
* | ||
* @param {Object} tab | ||
* @param {string} tab.url | ||
* @param {string} tab.url | ||
* @returns {boolean} | ||
*/ | ||
validation ({ url, title }) { | ||
/** | ||
* Check if the url is the local gateway url and if the title is contained within the url then it was not loaded. | ||
* - This assumes that the title of most pages on the web will be set and hence when not reachable, the browser | ||
* will set title to the url/host (both chrome and brave) and 'problem loading page' for firefox. | ||
* - There is probability that this might be true in case the <title> tag is omitted, but worst case it only reloads | ||
* those pages. | ||
* - The benefit we get from this approach is the static nature of just observing the tabs in their current state | ||
* which reduces the overhead of injecting content scripts to track urls that were loaded after the connection | ||
* was offline, it may also need extra permissions to inject code on error pages. | ||
*/ | ||
return (isIPFS.url(url) || isIPFS.subdomain(url)) && | ||
(url.includes(title) || title.toLowerCase() === 'problem loading page') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. two nits:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, @lidel
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @whizzzkid mind linking to the created issue or creating it and commenting here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
/** | ||
* Returns message when reloading the tab. | ||
* | ||
* @param {Object} tab | ||
* @param {string} tab.url | ||
* @returns {string} message. | ||
*/ | ||
message ({ url }) { | ||
return `reloading local gateway at ${url}` | ||
} | ||
} | ||
|
||
module.exports = { | ||
LocalGatewayReloader | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
class ReloaderBase { | ||
/** | ||
* Constructor for reloader base class. | ||
* | ||
* @param {Browser} browser | ||
* @param {Logger} log | ||
*/ | ||
constructor (browser, log) { | ||
if (!browser || !log) { | ||
throw new Error('Instances of browser and logger are needed!') | ||
} | ||
this._browserInstance = browser | ||
this._log = log | ||
}; | ||
|
||
/** | ||
* Initializes the instance. | ||
*/ | ||
init () { | ||
this._log('Initialized without additional config.') | ||
} | ||
|
||
/** | ||
* To be implemented in child class. | ||
*/ | ||
validation () { | ||
throw new Error('Validation: Method Not Implemented') | ||
} | ||
|
||
/** | ||
* To be implemented in child class. | ||
*/ | ||
message () { | ||
throw new Error('Message: Method Not Implemented') | ||
} | ||
|
||
/** | ||
* Handles reload for all tabs. | ||
* params {Array<tabs>} | ||
*/ | ||
reload (tabs) { | ||
tabs | ||
.filter(tab => this.validation(tab)) | ||
.forEach(tab => { | ||
this._log(this.message(tab)) | ||
this._browserInstance.tabs.reload(tab.id) | ||
}) | ||
} | ||
} | ||
|
||
module.exports = { | ||
ReloaderBase | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const { ReloaderBase } = require('./reloaderBase') | ||
|
||
class WebUiReloader extends ReloaderBase { | ||
/** | ||
* Performs url validation for the tab. If tab is a WebUI tab. | ||
* | ||
* @param {Object} tab | ||
* @returns {boolean} | ||
*/ | ||
validation ({ url }) { | ||
const bundled = !url.startsWith('http') && url.includes('/webui/index.html#/') | ||
const ipns = url.includes('/webui.ipfs.io/#/') | ||
return bundled || ipns | ||
} | ||
Comment on lines
+10
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: built-in webui at It seems to be missing here, is it reloaded by some other means? (if not, we may want to add it) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This functionality was brought in from: https://github.com/ipfs/ipfs-companion/blob/main/add-on/src/lib/ipfs-client/index.js#L64-L68 But now that I think more about it, this will be handled in the |
||
|
||
/** | ||
* Returns message when reloading the tab. | ||
* | ||
* @param {Object} tab | ||
* @param {string} tab.url | ||
* @returns {string} message. | ||
*/ | ||
message ({ url }) { | ||
return `reloading webui at ${url}` | ||
} | ||
} | ||
|
||
module.exports = { | ||
WebUiReloader | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -141,7 +141,7 @@ | |
"webextension-polyfill": "0.7.0" | ||
}, | ||
"engines": { | ||
"node": ">=14.15.0", | ||
"node": ">=14.15.0 <17", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for some reason latest LTS (18) fails to build this. I did not investigate, but added check to prevent this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1. a lot of our packages and their dependencies are out of date, and there have been a lot of changes made w.r.t. esm support, so we've been in a tough spot. However, you can see our support goals at https://github.com/ipfs/ipfs-gui/tree/SgtPooki-version-support-definition#nodejs (We can link to main branch when ipfs/ipfs-gui#97 gets merged) |
||
"npm": ">=6.14.0" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to remove ambiguity from IDEs