Skip to content
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: improved UX when opening IPFS URIs #1966

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
534b1aa
wip: ask when opening external protocol
hacdias Jan 28, 2022
715303d
feat: ask when opening external protocol
hacdias Feb 2, 2022
46b20bd
Update assets/locales/en.json
hacdias Feb 9, 2022
98314a9
Update assets/locales/en.json
hacdias Feb 9, 2022
70018f2
Update assets/locales/en.json
hacdias Feb 9, 2022
a39f015
Update assets/locales/en.json
hacdias Feb 9, 2022
03db51d
remove explore option for now and ensure app and i18n are ready
hacdias Feb 9, 2022
d91f453
refactor: i18n export
hacdias Feb 17, 2022
8b21910
refactor: rename setup to ready
hacdias Feb 17, 2022
abdeea2
add IPFS logo to dialog
hacdias Feb 17, 2022
3a5a2ab
fetch public gateway from webui window
hacdias Feb 18, 2022
3b7806e
fix styles
hacdias Mar 11, 2022
7de9e9f
only two options, detect localhost subdomains
hacdias Mar 17, 2022
2aca7be
Merge branch 'main' into feat/ux-protocol-handler
hacdias Apr 1, 2022
92cdc43
rename makeButtons and makeInputs
hacdias May 10, 2022
32e6032
refactor prompt html and jsdocs
hacdias May 10, 2022
24ecde4
refactor: separate protocol handler url tools
hacdias May 10, 2022
c0290bb
revert changes to index and wait on protocol hanlers
hacdias May 10, 2022
9dcf458
revert index.js
hacdias May 10, 2022
e6d8dff
Merge branch 'main' into feat/ux-protocol-handler
hacdias May 27, 2022
91f255e
refactor: remove comments
hacdias Jul 15, 2022
e7cd90b
refactor: rename ask askWhenOpeningUri
hacdias Jul 15, 2022
c4752d7
refactor: add comment and be more explicit
hacdias Jul 15, 2022
a861ffb
refactor: add comment, cleanupo
hacdias Jul 15, 2022
4d54b5a
fix: add null to return types
hacdias Jul 15, 2022
18e8b14
fix: wrap JSON.parse around try catch
hacdias Jul 20, 2022
5af40c7
Merge branch 'main' into feat/ux-protocol-handler
hacdias Jul 20, 2022
270d60d
Update assets/locales/en.json
hacdias Aug 2, 2022
b73c451
Merge branch 'main' into feat/ux-protocol-handler
hacdias Sep 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions assets/icons/ipfs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"yes": "Yes",
"no": "No",
"close": "Close",
"continue": "Continue",
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
"ok": "OK",
"cancel": "Cancel",
"enable": "Enable",
Expand Down Expand Up @@ -173,6 +174,7 @@
"appPreferences": "App Preferences",
"launchOnStartup": "Launch at Login",
"openWebUIAtLaunch": "Open Web UI at Launch",
"askWhenOpeningIpfsURIs": "Ask How to Open IPFS Address",
hacdias marked this conversation as resolved.
Show resolved Hide resolved
"pubsub": "Enable PubSub",
"namesysPubsub": "Enable IPNS over PubSub",
"automaticGC": "Automatic Garbage Collection",
Expand Down Expand Up @@ -207,6 +209,17 @@
"title": "IPFS Desktop Startup Has Failed",
"message": "IPFS node has encountered an error and startup could not be completed:"
},
"migrationFailedDialog": {
"title": "IPFS Desktop Migration Has Failed",
"message": "IPFS has encountered an error and migration could not be completed:"
},
"protocolHandlerDialog": {
"title": "Opening IPFS address",
"message": "How would you like IPFS Desktop to open IPFS addresses?",
hacdias marked this conversation as resolved.
Show resolved Hide resolved
"openInBrowser": "Open in my default browser",
"openInIpfsDesktop": "Open in IPFS Desktop",
"rememberThisChoice": "Remember this choice for all IPFS addresses"
},
hacdias marked this conversation as resolved.
Show resolved Hide resolved
"invalidRepositoryDialog": {
"title": "Invalid IPFS Repository or Configuration File",
"message": "The repository at “{ path }” is invalid. The “config” file must be a valid JSON.\n\nBefore starting IPFS Desktop again, please fix the configuration file or rename the old repository to “.ipfs.backup”."
Expand Down
14 changes: 8 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
"it-last": "^1.0.6",
"multiaddr": "10.0.1",
"multiaddr-to-uri": "8.0.0",
"multiformats": "^9.6.4",
"node-fetch": "^2.6.7",
"portfinder": "^1.0.28",
"sudo-prompt": "^9.2.1",
"untildify": "^4.0.0",
Expand Down
43 changes: 41 additions & 2 deletions src/dialogs/prompt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,52 @@ const dock = require('../../utils/dock')
const makePage = require('./template')
const { getBackgroundColor } = require('./styles')

function generatePage ({ message, defaultValue = '', buttons }, id) {
function makeButtons (buttons) {
hacdias marked this conversation as resolved.
Show resolved Hide resolved
buttons = buttons.map((txt, i) => `<button ${i === 0 ? 'class="default"' : ''} id="${i}">${txt}</button>`)

if (IS_MAC) {
buttons.reverse()
}

const page = makePage({ message, defaultValue, buttons, id })
return buttons.join('\n')
}

function makeInputs (inputs) {
hacdias marked this conversation as resolved.
Show resolved Hide resolved
return inputs.map(({ type, name, label, defaultValue, labels = {} }) => {
let str = '<div>'

switch (type) {
case 'checkbox':
str += '<div class="inline">'
str += `<input type="checkbox" name="${name}" id="${name}" ${defaultValue} />`
str += `<label for="${name}">${label}</label>`
str += '</div>'
break
case 'radio':
str += '<div class="group">'
for (const key in labels) {
str += '<div class="inline">'
str += `<input type="radio" name="${name}" id="${key}" value="${key}" ${defaultValue === key ? 'checked' : ''} />`
str += `<label for="${key}">${labels[key]}</label>`
str += '</div>'
}
str += '</div>'

break
case 'text':
str += `<input type="text" name="${name}" id="${name}" value="${defaultValue}" />`
}

str += '</div>'
return str
}).join('\n')
hacdias marked this conversation as resolved.
Show resolved Hide resolved
}

function generatePage ({ message, inputs, defaultValue = '', buttons }, id) {
buttons = makeButtons(buttons)
inputs = makeInputs(inputs)

const page = makePage({ message, inputs, defaultValue, buttons, id })
return `data:text/html;base64,${Buffer.from(page, 'utf8').toString('base64')}`
}

Expand All @@ -27,6 +65,7 @@ module.exports = async function showPrompt (options) {
show: false,
width: 350,
height: 330,
useContentSize: true,
hacdias marked this conversation as resolved.
Show resolved Hide resolved
resizable: false,
autoHideMenuBar: true,
fullscreenable: false,
Expand Down
18 changes: 18 additions & 0 deletions src/dialogs/prompt/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,27 @@ input {
padding: 0.15rem;
outline: 0;
}
div.group {
margin: 0.5rem 0;
}
div.inline input,
div.inline label {
display: inline-block;
width: auto;
vertical-align: middle;
}
input[type=radio],
input[type=checkbox] {
margin-right: 0.25rem;
}
#buttons {
text-align: right;
}
#logo {
width: 4rem;
margin: 0 auto .5rem;
display: block;
}
SgtPooki marked this conversation as resolved.
Show resolved Hide resolved
button {
margin-left: 0.5rem;
padding: 0.25rem 0.5rem;
Expand Down
19 changes: 14 additions & 5 deletions src/dialogs/prompt/template.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
const { styles } = require('./styles')

module.exports = ({ message, defaultValue, buttons, id }) => (`<!DOCTYPE html>
const fs = require('fs-extra')
const path = require('path')

const ipfsLogoPath = path.join(__dirname, '../../../assets/icons/ipfs.svg')
const ipfsLogo = 'data:image/svg+xml;base64,' + fs.readFileSync(ipfsLogoPath).toString('base64')
hacdias marked this conversation as resolved.
Show resolved Hide resolved

module.exports = ({ message, inputs, buttons, id }) => (`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta charset="utf-8" />
</head>
<body>
<img src="${ipfsLogo}" id="logo">
<p>${message}</p>
<input type="text" value="${defaultValue}" />
<div id="buttons">${buttons.join('\n')}</div>
<form>
${inputs}
<div id="buttons">${buttons}</div>
</form>
</body>
<style>
${styles}
Expand All @@ -19,7 +28,7 @@ module.exports = ({ message, defaultValue, buttons, id }) => (`<!DOCTYPE html>
for (const button of document.querySelectorAll('button')) {
button.addEventListener('click', event => {
ipcRenderer.send('${id}', {
input: document.querySelector('input').value,
input: Object.fromEntries(new FormData(document.querySelector('form')).entries()),
button: Number(button.id)
})
})
Expand Down
4 changes: 3 additions & 1 deletion src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const ICU = require('i18next-icu')
const Backend = require('i18next-fs-backend')
const store = require('./common/store')

module.exports = async function () {
const setupI18n = async () => {
await i18n
.use(ICU)
.use(Backend)
Expand Down Expand Up @@ -33,3 +33,5 @@ module.exports = async function () {
ipcMain.emit('languageUpdated', lang)
})
}

module.exports = setupI18n()
hacdias marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 6 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ if (process.env.NODE_ENV === 'test') {
const fixPath = require('fix-path')
hacdias marked this conversation as resolved.
Show resolved Hide resolved
const { criticalErrorDialog } = require('./dialogs')
const logger = require('./common/logger')
const i18nReady = require('./i18n')
const setupProtocolHandlers = require('./protocol-handlers')
const setupI18n = require('./i18n')
const setupNpmOnIpfs = require('./npm-on-ipfs')
const setupDaemon = require('./daemon')
const setupWebUI = require('./webui')
Expand Down Expand Up @@ -45,8 +45,10 @@ if (!app.requestSingleInstanceLock()) {

const ctx = {}

app.on('will-finish-launching', () => {
setupProtocolHandlers(ctx)
app.on('will-finish-launching', async () => {
await app.whenReady()
await i18nReady // Ensure i18n is ready for the dialog.
await setupProtocolHandlers(ctx)
})

function handleError (err) {
Expand All @@ -72,8 +74,8 @@ async function run () {
}

try {
await i18nReady
await setupAnalytics(ctx) // ctx.countlyDeviceId
await setupI18n(ctx)
await setupAppMenu(ctx)

await setupWebUI(ctx) // ctx.webui, launchWebUI
Expand Down
Loading