From 12f7d44c43b47906e4a04643499374897d1312e1 Mon Sep 17 00:00:00 2001 From: Baltazar Gomez Date: Wed, 18 Oct 2017 23:58:19 -0600 Subject: [PATCH 1/6] auto hide menubar update menu tidy up menu items fix help label improve help submenu --- app/main.js | 9 +++- app/menu/main-menu.js | 99 ++++++++++++++++++++++++++----------------- 2 files changed, 68 insertions(+), 40 deletions(-) diff --git a/app/main.js b/app/main.js index e51928139..c11468b8f 100644 --- a/app/main.js +++ b/app/main.js @@ -1,6 +1,7 @@ const {app, BrowserWindow, ipcMain} = require('electron'); const url = require('url'); -const isDebug = process.env.NODE_ENV === 'development' +const isDebug = process.env.NODE_ENV === 'development'; +const setMenu = require('./menu/main-menu.js'); if (isDebug) { try @@ -169,6 +170,12 @@ function createWindow () { win.on('closed', () => { win = null }) + + // Menu bar + win.setAutoHideMenuBar(true); + win.setMenuBarVisibility(isDebug); + setMenu(); + }; function handleOpenUriRequested(uri) { diff --git a/app/menu/main-menu.js b/app/menu/main-menu.js index 082b116ac..c35621613 100644 --- a/app/menu/main-menu.js +++ b/app/menu/main-menu.js @@ -1,6 +1,4 @@ -const {Menu} = require('electron'); -const electron = require('electron'); -const app = electron.app; +const { app, shell, Menu } = require('electron'); const baseTemplate = [ { @@ -30,16 +28,71 @@ const baseTemplate = [ ] }, { - label: 'Help', + label: 'View', submenu: [ { - label: 'Help', + role: 'reload' + }, + { + label: 'Developer', + submenu: [ + { + role: 'forcereload' + }, + { + role: 'toggledevtools' + }, + ] + }, + { + type: 'separator' + }, + { + role: 'togglefullscreen' + } + ] + }, + { + role: 'help', + submenu: [ + { + label: 'Learn More', click(item, focusedWindow) { if (focusedWindow) { focusedWindow.webContents.send('open-menu', '/help'); } } + }, + { + label: 'Frequently Asked Questions', + click(item, focusedWindow){ + shell.openExternal('https://lbry.io/faq') } + }, + { + type: 'separator' + }, + { + label: 'Report Issue', + click(item, focusedWindow){ + shell.openExternal('https://lbry.io/faq/contributing#report-a-bug'); + } + }, + { + label: 'Search Issues', + click(item, focusedWindow){ + shell.openExternal('https://github.com/lbryio/lbry-app/issues') + } + }, + { + type: 'separator' + }, + { + label: 'Quickstart Guide', + click(item, focusedWindow){ + shell.openExternal('https://lbry.io/quickstart') + } + }, ] } ]; @@ -71,40 +124,8 @@ const macOSAppMenuTemplate = { ] }; -const developerMenuTemplate = { - label: 'Developer', - submenu: [ - { - label: 'Reload', - accelerator: 'CmdOrCtrl+R', - click(item, focusedWindow) { - if (focusedWindow) { - focusedWindow.reload(); - } - } - }, - { - label: 'Toggle Developer Tools', - accelerator: process.platform == 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I', - click(item, focusedWindow) { - if (focusedWindow) { - focusedWindow.webContents.toggleDevTools(); - } - } - }, - ] -}; - -module.exports = { - showMenubar(showDeveloperMenu) { +module.exports = () => { let template = baseTemplate.slice(); - if (process.platform === 'darwin') { - template.unshift(macOSAppMenuTemplate); - } - if (showDeveloperMenu) { - template.push(developerMenuTemplate); - } - + (process.platform === 'darwin') && template.unshift(macOSAppMenuTemplate); Menu.setApplicationMenu(Menu.buildFromTemplate(template)); - }, }; From cd4bedc873fbd552bdb98e100135781e568067e4 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Fri, 27 Oct 2017 15:11:03 -0400 Subject: [PATCH 2/6] small menu tweak --- app/menu/main-menu.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/menu/main-menu.js b/app/menu/main-menu.js index c35621613..7b214bfca 100644 --- a/app/menu/main-menu.js +++ b/app/menu/main-menu.js @@ -78,17 +78,11 @@ const baseTemplate = [ shell.openExternal('https://lbry.io/faq/contributing#report-a-bug'); } }, - { - label: 'Search Issues', - click(item, focusedWindow){ - shell.openExternal('https://github.com/lbryio/lbry-app/issues') - } - }, { type: 'separator' }, { - label: 'Quickstart Guide', + label: 'Developer API Guide', click(item, focusedWindow){ shell.openExternal('https://lbry.io/quickstart') } From 6d45b7c1c3356b035e82a2894d2e08dab06af654 Mon Sep 17 00:00:00 2001 From: thujeevan Date: Thu, 12 Oct 2017 23:39:58 +0530 Subject: [PATCH 3/6] Replace xmlhttprequest with fetch fixes https://github.com/lbryio/lbry-app/issues/650 add fetch and es6-Promise polyfills update webpack config accordingly --- ui/js/actions/settings.js | 43 ++++++------- ui/js/jsonrpc.js | 124 ++++++++++++++++++++------------------ ui/js/lbryio.js | 120 +++++++++++++++--------------------- 3 files changed, 135 insertions(+), 152 deletions(-) diff --git a/ui/js/actions/settings.js b/ui/js/actions/settings.js index 79c098a95..6a2455bf9 100644 --- a/ui/js/actions/settings.js +++ b/ui/js/actions/settings.js @@ -133,30 +133,27 @@ export function doDownloadLanguages() { fs.mkdirSync(app.i18n.directory); } - const xhr = new XMLHttpRequest(); - xhr.onreadystatechange = () => { - if (xhr.readyState === XMLHttpRequest.DONE) { - if (xhr.status === 200) { - try { - const files = JSON.parse(xhr.responseText); - const actions = []; - files.forEach(file => { - actions.push(doDownloadLanguage(file)); - }); - - dispatch(batchActions(...actions)); - } catch (err) { - throw err; - } - } else { - throw new Error( - __("The list of available languages could not be retrieved.") - ); - } + function checkStatus(response) { + if (response.status >= 200 && response.status < 300) { + return response; + } else { + throw new Error( + __("The list of available languages could not be retrieved.") + ); } - }; - xhr.open("get", "http://i18n.lbry.io"); - xhr.send(); + } + + function parseJSON(response) { + return response.json(); + } + + return fetch("http://i18n.lbry.io") + .then(checkStatus) + .then(parseJSON) + .then(files => { + const actions = files.map(doDownloadLanguage); + dispatch(batchActions(...actions)); + }); }; } diff --git a/ui/js/jsonrpc.js b/ui/js/jsonrpc.js index 4d1ed5bd3..f6c638083 100644 --- a/ui/js/jsonrpc.js +++ b/ui/js/jsonrpc.js @@ -9,80 +9,90 @@ jsonrpc.call = function( connectFailedCallback, timeout ) { - var xhr = new XMLHttpRequest(); - if (typeof connectFailedCallback !== "undefined") { - if (timeout) { - xhr.timeout = timeout; + function checkStatus(response) { + if (response.status >= 200 && response.status < 300) { + return response; + } else { + var error = new Error(response.statusText); + error.response = response; + throw error; } + } - xhr.addEventListener("error", function(e) { - connectFailedCallback(e); - }); - xhr.addEventListener("timeout", function() { - connectFailedCallback( - new Error(__("XMLHttpRequest connection timed out")) - ); + function parseJSON(response) { + return response.json(); + } + + function makeRequest(url, options) { + return new Promise((resolve, reject) => { + fetch(url, options).then(resolve).catch(reject); + + if (timeout) { + const e = new Error(__("XMLHttpRequest connection timed out")); + setTimeout(() => { + return reject(e); + }, timeout); + } }); } - xhr.addEventListener("load", function() { - var response = JSON.parse(xhr.responseText); - let error = response.error || (response.result && response.result.error); - if (error) { - if (errorCallback) { - errorCallback(error); - } else { - var errorEvent = new CustomEvent("unhandledError", { - detail: { - connectionString: connectionString, - method: method, - params: params, - code: error.code, - message: error.message || error, - data: error.data, - }, - }); - document.dispatchEvent(errorEvent); + const counter = parseInt(sessionStorage.getItem("JSONRPCCounter") || 0); + const url = connectionString; + const options = { + method: "POST", + body: JSON.stringify({ + jsonrpc: "2.0", + method: method, + params: params, + id: counter, + }), + }; + + sessionStorage.setItem("JSONRPCCounter", counter + 1); + + return fetch(url, options) + .then(checkStatus) + .then(parseJSON) + .then(response => { + const error = + response.error || (response.result && response.result.error); + + if (!error && typeof callback === "function") { + return callback(response.result); + } + + if (error && typeof errorCallback === "function") { + return errorCallback(error); } - } else if (callback) { - callback(response.result); - } - }); - if (connectFailedCallback) { - xhr.addEventListener("error", function(event) { - connectFailedCallback(event); - }); - } else { - xhr.addEventListener("error", function(event) { var errorEvent = new CustomEvent("unhandledError", { detail: { connectionString: connectionString, method: method, params: params, - code: xhr.status, + code: error.code, + message: error.message || error, + data: error.data, + }, + }); + document.dispatchEvent(errorEvent); + }) + .catch(e => { + if (connectFailedCallback) { + return connectFailedCallback(e); + } + + var errorEvent = new CustomEvent("unhandledError", { + detail: { + connectionString: connectionString, + method: method, + params: params, + code: e.response && e.response.status, message: __("Connection to API server failed"), }, }); document.dispatchEvent(errorEvent); }); - } - - const counter = parseInt(sessionStorage.getItem("JSONRPCCounter") || 0); - - xhr.open("POST", connectionString, true); - xhr.send( - JSON.stringify({ - jsonrpc: "2.0", - method: method, - params: params, - id: counter, - }) - ); - - sessionStorage.setItem("JSONRPCCounter", counter + 1); - - return xhr; }; export default jsonrpc; diff --git a/ui/js/lbryio.js b/ui/js/lbryio.js index 336bd3d76..573f6e7c6 100644 --- a/ui/js/lbryio.js +++ b/ui/js/lbryio.js @@ -36,80 +36,56 @@ lbryio.getExchangeRates = function() { }; lbryio.call = function(resource, action, params = {}, method = "get") { - return new Promise((resolve, reject) => { - if (!lbryio.enabled && (resource != "discover" || action != "list")) { - console.log(__("Internal API disabled")); - reject(new Error(__("LBRY internal API is disabled"))); - return; + if (!lbryio.enabled && (resource != "discover" || action != "list")) { + console.log(__("Internal API disabled")); + return Promise.reject(new Error(__("LBRY internal API is disabled"))); + } + + if (!(method == "get" || method == "post")) { + return Promise.reject(new Error(__("Invalid method"))); + } + + function checkStatus(response) { + if (response.status >= 200 && response.status < 300) { + return response; + } else { + var error = new Error(response.statusText); + error.response = response; + throw error; + } + } + + function parseJSON(response) { + return response.json(); + } + + function makeRequest(url, options) { + return fetch(url, options).then(checkStatus).then(parseJSON).catch(e => { + throw new Error(__("Something went wrong making an internal API call.")); + }); + } + + return lbryio.getAuthToken().then(token => { + const fullParams = { auth_token: token, ...params }; + const qs = querystring.stringify(fullParams); + let url = `${CONNECTION_STRING}${resource}/${action}?${qs}`; + + let options = { + method: "GET", + }; + + if (method == "post") { + options = { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: qs, + }; + url = `${CONNECTION_STRING}${resource}/${action}`; } - const xhr = new XMLHttpRequest(); - - xhr.addEventListener("error", function(event) { - reject( - new Error(__("Something went wrong making an internal API call.")) - ); - }); - - xhr.addEventListener("timeout", function() { - reject(new Error(__("XMLHttpRequest connection timed out"))); - }); - - xhr.addEventListener("load", function() { - const response = JSON.parse(xhr.responseText); - - if (!response.success) { - if (reject) { - const error = new Error(response.error); - error.xhr = xhr; - reject(error); - } else { - document.dispatchEvent( - new CustomEvent("unhandledError", { - detail: { - connectionString: connectionString, - method: action, - params: params, - message: response.error.message, - ...(response.error.data ? { data: response.error.data } : {}), - }, - }) - ); - } - } else { - resolve(response.data); - } - }); - - lbryio - .getAuthToken() - .then(token => { - const fullParams = { auth_token: token, ...params }; - - if (method == "get") { - xhr.open( - "get", - CONNECTION_STRING + - resource + - "/" + - action + - "?" + - querystring.stringify(fullParams), - true - ); - xhr.send(); - } else if (method == "post") { - xhr.open("post", CONNECTION_STRING + resource + "/" + action, true); - xhr.setRequestHeader( - "Content-type", - "application/x-www-form-urlencoded" - ); - xhr.send(querystring.stringify(fullParams)); - } else { - reject(new Error(__("Invalid method"))); - } - }) - .catch(reject); + return makeRequest(url, options).then(response => response.data); }); }; From f758a5bdbe8d171a68334d7a031a38916fe022a6 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Fri, 27 Oct 2017 15:37:05 -0400 Subject: [PATCH 4/6] remove old endpoint reference --- ui/js/lbryio.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/js/lbryio.js b/ui/js/lbryio.js index 573f6e7c6..03b08496d 100644 --- a/ui/js/lbryio.js +++ b/ui/js/lbryio.js @@ -36,7 +36,7 @@ lbryio.getExchangeRates = function() { }; lbryio.call = function(resource, action, params = {}, method = "get") { - if (!lbryio.enabled && (resource != "discover" || action != "list")) { + if (!lbryio.enabled) { console.log(__("Internal API disabled")); return Promise.reject(new Error(__("LBRY internal API is disabled"))); } From 8f1e2ea72b42f4f87614b63c032b6e4a0406a667 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Fri, 27 Oct 2017 17:14:42 -0400 Subject: [PATCH 5/6] fix settings bug and update changelog --- CHANGELOG.md | 6 +++--- ui/js/page/settings/view.jsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a64cc392f..a29075676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,16 +8,16 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added - * + * Added new window menu options for reloading and help. * ### Changed * + * Replaced all instances of `XMLHttpRequest` with native `Fetch` API. * ### Fixed - * - * + * Fixed console errors on settings page related to improper React input properties. ### Deprecated * diff --git a/ui/js/page/settings/view.jsx b/ui/js/page/settings/view.jsx index e11a2443f..a4a3a2547 100644 --- a/ui/js/page/settings/view.jsx +++ b/ui/js/page/settings/view.jsx @@ -237,7 +237,7 @@ class SettingsPage extends React.PureComponent { { this.onInstantPurchaseEnabledChange(false); @@ -247,7 +247,7 @@ class SettingsPage extends React.PureComponent { Date: Fri, 20 Oct 2017 18:31:54 +0530 Subject: [PATCH 6/6] Rewards marked in txn list --- CHANGELOG.md | 2 +- ui/js/component/transactionList/index.js | 2 +- .../transactionList/internal/TransactionListItem.jsx | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a29075676..ca0ac67d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,10 @@ Web UI version numbers should always match the corresponding version of LBRY App ## [Unreleased] ### Added * Added new window menu options for reloading and help. + * Rewards are now marked in transaction history (#660) * ### Changed - * * Replaced all instances of `XMLHttpRequest` with native `Fetch` API. * diff --git a/ui/js/component/transactionList/index.js b/ui/js/component/transactionList/index.js index 5a6c10b6b..f6ffc976d 100644 --- a/ui/js/component/transactionList/index.js +++ b/ui/js/component/transactionList/index.js @@ -12,4 +12,4 @@ const perform = dispatch => ({ navigate: (path, params) => dispatch(doNavigate(path, params)), }); -export default connect(null, perform)(TransactionList); +export default connect(select, perform)(TransactionList); diff --git a/ui/js/component/transactionList/internal/TransactionListItem.jsx b/ui/js/component/transactionList/internal/TransactionListItem.jsx index fd4429bd3..22b35cb12 100644 --- a/ui/js/component/transactionList/internal/TransactionListItem.jsx +++ b/ui/js/component/transactionList/internal/TransactionListItem.jsx @@ -6,6 +6,10 @@ import Link from "component/link"; import lbryuri from "lbryuri"; class TransactionListItem extends React.PureComponent { + capitalize(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } + render() { const { reward, transaction } = this.props; const { @@ -60,7 +64,7 @@ class TransactionListItem extends React.PureComponent { />} - {type} + {this.capitalize(type)} {reward &&