-
Notifications
You must be signed in to change notification settings - Fork 335
feat: recovery page when local gateway is unreachable #1125
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
Changes from all commits
b9232a1
3ac7e12
5103b60
3a53c02
3256407
fb301e0
df31834
a3feda0
e389d45
133ca93
cd5f4bf
03c14c6
23412e4
a438c19
0561ea3
e31cbbf
0561045
4a139d8
5ce8b18
baad760
4ff97b6
d3018f4
41881ec
8a3db25
ab2d990
956863a
885d63f
7454d62
5b617fd
66485d0
2ea33c2
4c5642b
20f71b6
414df96
c6e6dc5
c7e6956
ba6e573
0ca8d4a
2d8f803
97be393
3e76bf8
6f53132
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 |
|---|---|---|
|
|
@@ -33,7 +33,10 @@ | |
| "icons/png/ipfs-logo-off_38.png", | ||
| "icons/png/ipfs-logo-off_128.png", | ||
| "icons/ipfs-logo-on.svg", | ||
| "icons/ipfs-logo-off.svg" | ||
| "icons/ipfs-logo-off.svg", | ||
|
Contributor
Author
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. I am not sure how this is persisted on CI, locally this gets overwritten.
Member
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 This file is a template used for generating final Generation happens in |
||
| "dist/recovery/recovery.css", | ||
| "dist/recovery/recovery.html", | ||
| "dist/recovery/recovery.js" | ||
lidel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ], | ||
| "content_security_policy": "script-src 'self'; object-src 'self'; frame-src 'self';", | ||
| "default_locale": "en" | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,8 +50,11 @@ export function initState (options, overrides) { | |
| return false | ||
| } | ||
| } | ||
| // TODO state.connected ~= state.peerCount > 0 | ||
| // TODO state.nodeActive ~= API is online,eg. state.peerCount > offlinePeerCount | ||
| // TODO refactor this into a class. It's getting too big and messy. | ||
| Object.defineProperty(state, 'nodeActive', { | ||
|
Member
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. Do you know if things defined via I vaguely remember that we did not do getters like this in the past because it did not survive serialization (maybe browser fixed it these days?). That is why we read By adding these getters here, we are having two ways of doing online check in the codebase, which over time leads to errors. My suggestion is to remove these
Contributor
Author
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. It looks like it does: https://github.com/ipfs/ipfs-companion/pull/1125/files#diff-cf4a768af4d2baab2a1c0a5862f50af6239b155754f4a9ea90b43e465f115d88R148 I need this to validate if we need to recover the client. However I didn't want to touch too much of this, I'm just trying to follow the adjacent code pattern. I created #1129 to tackle this again in the future. |
||
| // TODO: make quick fetch to confirm it works? | ||
| get: function () { return this.peerCount !== offlinePeerCount } | ||
| }) | ||
| Object.defineProperty(state, 'localGwAvailable', { | ||
| // TODO: make quick fetch to confirm it works? | ||
| get: function () { return this.ipfsNodeType !== 'embedded' } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| @import url('~tachyons/css/tachyons.css'); | ||
| @import url('~ipfs-css/ipfs.css'); | ||
|
|
||
| #left-col { | ||
| background-image: url('../../images/stars.png'), linear-gradient(to bottom, #041727 0%, #043b55 100%); | ||
| background-size: 100%; | ||
| background-repeat: repeat; | ||
| } | ||
|
|
||
| a:hover { | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| a:visited { | ||
| color: inherit; | ||
| } | ||
|
|
||
| /* | ||
| https://github.com/tachyons-css/tachyons-queries | ||
| Tachyons: $point == large | ||
| */ | ||
| @media (min-width: 60em) { | ||
| #left-col { | ||
| position: fixed; | ||
| top: 0; | ||
| right: 55%; | ||
| width: 45%; | ||
| background-image: url('../../images/stars.png'), linear-gradient(to bottom, #041727 0%, #043b55 100%); | ||
| background-size: 100%; | ||
| background-repeat: repeat; | ||
| } | ||
|
|
||
| #right-col { | ||
| margin-left: 54%; | ||
| margin-right: 6%; | ||
| } | ||
| } | ||
|
|
||
| @media (max-height: 800px) { | ||
| #left-col img { | ||
| width: 98px !important; | ||
| height: 98px !important; | ||
| } | ||
|
|
||
| #left-col svg { | ||
| width: 60px; | ||
| } | ||
| } | ||
|
|
||
| .recovery-root { | ||
| width: 100%; | ||
| height: 100%; | ||
| text-align: left; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <!DOCTYPE html> | ||
lidel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <html> | ||
| <head> | ||
| <title>IPFS Node is Offline</title> | ||
| <meta charset="utf-8"> | ||
| <meta name="viewport" content="width=device-width"> | ||
| <link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlo89/56ZQ/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUjDu1lo89/6mhTP+zrVP/nplD/5+aRK8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNiIS6Wjz3/ubFY/761W/+vp1D/urRZ/8vDZf/GvmH/nplD/1BNIm8AAAAAAAAAAAAAAAAAAAAAAAAAAJaPPf+knEj/vrVb/761W/++tVv/r6dQ/7q0Wf/Lw2X/y8Nl/8vDZf+tpk7/nplD/wAAAAAAAAAAAAAAAJaPPf+2rVX/vrVb/761W/++tVv/vrVb/6+nUP+6tFn/y8Nl/8vDZf/Lw2X/y8Nl/8G6Xv+emUP/AAAAAAAAAACWjz3/vrVb/761W/++tVv/vrVb/761W/+vp1D/urRZ/8vDZf/Lw2X/y8Nl/8vDZf/Lw2X/nplD/wAAAAAAAAAAlo89/761W/++tVv/vrVb/761W/++tVv/r6dQ/7q0Wf/Lw2X/y8Nl/8vDZf/Lw2X/y8Nl/56ZQ/8AAAAAAAAAAJaPPf++tVv/vrVb/761W/++tVv/vbRa/5aPPf+emUP/y8Nl/8vDZf/Lw2X/y8Nl/8vDZf+emUP/AAAAAAAAAACWjz3/vrVb/761W/++tVv/vrVb/5qTQP+inkb/op5G/6KdRv/Lw2X/y8Nl/8vDZf/Lw2X/nplD/wAAAAAAAAAAlo89/761W/++tVv/sqlS/56ZQ//LxWb/0Mlp/9DJaf/Kw2X/oJtE/7+3XP/Lw2X/y8Nl/56ZQ/8AAAAAAAAAAJaPPf+9tFr/mJE+/7GsUv/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+xrFL/nplD/8vDZf+emUP/AAAAAAAAAACWjz3/op5G/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+inkb/nplD/wAAAAAAAAAAAAAAAKKeRv+3slb/0cpq/9HKav/Rymr/0cpq/9HKav/Rymr/0cpq/9HKav+1sFX/op5G/wAAAAAAAAAAAAAAAAAAAAAAAAAAop5GUKKeRv/Nxmf/0cpq/9HKav/Rymr/0cpq/83GZ/+inkb/op5GSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAop5G16KeRv/LxWb/y8Vm/6KeRv+inkaPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAop5G/6KeRtcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n8AAPgfAADwDwAAwAMAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAwAMAAPAPAAD4HwAA/n8AAA==" /> | ||
| <link rel="stylesheet" href="/dist/bundles/uiCommons.css"> | ||
| <link rel="stylesheet" href="/dist/bundles/recoveryPage.css"> | ||
| </head> | ||
| <body class="navy bg-white sans-serif"> | ||
| <app class="flex flex-column transition-all vh-100"> | ||
| <main class="bg-white flex-grow-1"> | ||
| <div id="root"></div> | ||
| </main> | ||
| <script src="/dist/bundles/uiCommons.bundle.js"></script> | ||
| <script src="/dist/bundles/recoveryPage.bundle.js"></script> | ||
| </app> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| 'use strict' | ||
| /* eslint-env browser, webextensions */ | ||
|
|
||
| import choo from 'choo' | ||
| import html from 'choo/html/index.js' | ||
| import browser, { i18n, runtime } from 'webextension-polyfill' | ||
| import { nodeOffSvg } from '../landing-pages/welcome/page.js' | ||
| import createWelcomePageStore from '../landing-pages/welcome/store.js' | ||
| import { optionsPage } from '../lib/constants.js' | ||
| import './recovery.css' | ||
|
|
||
| const app = choo() | ||
|
|
||
| const learnMoreLink = html`<a class="navy link underline-under hover-aqua" href="https://docs.ipfs.tech/how-to/companion-node-types/" target="_blank" rel="noopener noreferrer">${i18n.getMessage('recovery_page_learn_more')}</a>` | ||
|
|
||
| const optionsPageLink = html`<a class="navy link underline-under hover-aqua" id="learn-more" href="${optionsPage}" target="_blank" rel="noopener noreferrer">${i18n.getMessage('recovery_page_update_preferences')}</a>` | ||
|
|
||
| // TODO (whizzzkid): refactor base store to be more generic. | ||
| app.use(createWelcomePageStore(i18n, runtime)) | ||
| // Register our single route | ||
| app.route('*', (state) => { | ||
| browser.runtime.sendMessage({ telemetry: { trackView: 'recovery' } }) | ||
|
Contributor
Author
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. @SgtPooki added view for recovery pages. |
||
| const { hash } = window.location | ||
| const { href: publicURI } = new URL(decodeURIComponent(hash.slice(1))) | ||
|
|
||
| if (!publicURI) { | ||
| return | ||
| } | ||
|
|
||
| const openURLFromHash = () => { | ||
| try { | ||
| console.log('Opening URL from hash:', publicURI) | ||
| window.location.replace(publicURI) | ||
| } catch (err) { | ||
| console.error('Failed to open URL from hash:', err) | ||
| } | ||
| } | ||
|
|
||
| // if the IPFS node is online, open the URL from the hash, this will redirect to the local node. | ||
| if (state.isIpfsOnline) { | ||
| openURLFromHash() | ||
| return | ||
| } | ||
|
|
||
| return html`<div class="flex flex-column flex-row-l"> | ||
| <div id="left-col" class="min-vh-100 flex flex-column justify-center items-center bg-navy white"> | ||
| <div class="mb4 flex flex-column justify-center items-center"> | ||
| ${nodeOffSvg(200)} | ||
| <p class="mt0 mb0 f3 tc">${i18n.getMessage('recovery_page_sub_header')}</p> | ||
| </div> | ||
| </div> | ||
|
|
||
| <div id="right-col" class="pt7 mt5 w-100 flex flex-column justify-around items-center"> | ||
| <p class="f3 fw5">${i18n.getMessage('recovery_page_message_p1')}</p> | ||
| <p class="f4 fw4">${i18n.getMessage('recovery_page_message_p2')}</p> | ||
| <p class="f4 fw4 w-100"><span class="b-ns">Public URL:</span> <a class="no-underline no-underline navy link hover-aqua" href="${publicURI}" rel="noopener noreferrer" target="_blank">${publicURI}</a></p> | ||
| <button | ||
| class="fade-in ba bw1 b--teal bg-teal snow f7 ph2 pv3 br2 ma4 pointer" | ||
| onclick=${openURLFromHash} | ||
| href="${publicURI}" | ||
| > | ||
| <span class="f5 fw6">${i18n.getMessage('recovery_page_button')}</span> | ||
| </button> | ||
| <p class="f5 fw2 pt5"> | ||
| ${learnMoreLink} | ${optionsPageLink} | ||
| </span> | ||
| </div> | ||
| </div>` | ||
| }) | ||
|
|
||
| // Start the application and render it to the given querySelector | ||
| app.mount('#root') | ||
|
|
||
| // Set page title and header translation | ||
| document.title = i18n.getMessage('recovery_page_title') | ||
Uh oh!
There was an error while loading. Please reload this page.