From 1d6df88ef74d67cc76a4879d89e05b3bda1742a4 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 5 Jun 2019 17:18:52 +0200 Subject: Fix spellchecker integration --- src/webview/contextMenu.js | 5 +++-- src/webview/spellchecker.js | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index 83914f581..2fdbcdca6 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js @@ -297,12 +297,13 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck }; export default function contextMenu(spellcheckProvider, isSpellcheckEnabled, getDefaultSpellcheckerLanguage, getSpellcheckerLanguage) { - webContents.on('context-menu', (e, props) => { + webContents.on('context-menu', async (e, props) => { e.preventDefault(); let suggestions = []; if (spellcheckProvider && props.misspelledWord) { - suggestions = spellcheckProvider.getSuggestion(props.misspelledWord); + debug('Mispelled word', props.misspelledWord); + suggestions = await spellcheckProvider.getSuggestion(props.misspelledWord); debug('Suggestions', suggestions); } diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index 9158b3b94..64575753f 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js @@ -1,6 +1,8 @@ import { webFrame } from 'electron'; -import { SpellCheckerProvider } from 'electron-hunspell'; +import { attachSpellCheckProvider, SpellCheckerProvider } from 'electron-hunspell'; +import { ENVIRONMENT } from 'hunspell-asm'; import path from 'path'; +import { readFileSync } from 'fs'; import { DICTIONARY_PATH } from '../config'; import { SPELLCHECKER_LOCALES } from '../i18n/languages'; @@ -10,11 +12,12 @@ const debug = require('debug')('Franz:spellchecker'); let provider; let currentDict; let _isEnabled = false; +let attached; async function loadDictionary(locale) { try { const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); - await provider.loadDictionary(locale, `${fileLocation}.dic`, `${fileLocation}.aff`); + await provider.loadDictionary(locale, readFileSync(`${fileLocation}.dic`), readFileSync(`${fileLocation}.aff`)); debug('Loaded dictionary', locale, 'from', fileLocation); } catch (err) { console.error('Could not load dictionary', err); @@ -41,7 +44,7 @@ export async function switchDict(locale) { provider.unloadDictionary(locale); } loadDictionary(locale); - provider.switchDictionary(locale); + attached.switchLanguage(locale); debug('Switched dictionary to', locale); @@ -58,12 +61,15 @@ export default async function initialize(languageCode = 'en-us') { const locale = languageCode.toLowerCase(); debug('Init spellchecker'); - await provider.initialize(); - // await loadDictionaries(); + await provider.initialize({ environment: ENVIRONMENT.NODE }); + + debug('Attaching spellcheck provider'); + attached = await attachSpellCheckProvider(provider); debug('Available spellchecker dictionaries', provider.availableDictionaries); - switchDict(locale); + attached.switchLanguage(locale); + console.log('seas oida', attached, provider); return provider; } catch (err) { -- cgit v1.2.3-70-g09d2 From 9180318200dc2b398bc2ec248f9ff8fa3f035fbb Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 13:56:49 +0200 Subject: Fix spellchecker --- package-lock.json | 43 ++++++++++++++++--------------------------- package.json | 2 +- src/webview/spellchecker.js | 32 ++++++++++++++++---------------- 3 files changed, 33 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/package-lock.json b/package-lock.json index e670c2a03..b0cc72ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7190,12 +7190,11 @@ } }, "electron-hunspell": { - "version": "1.0.0-beta.7", - "resolved": "https://registry.npmjs.org/electron-hunspell/-/electron-hunspell-1.0.0-beta.7.tgz", - "integrity": "sha512-BByCXqU8sZbuzyoxKcBYjycp8ORiqjeYZd2OT8RNjVW+XGPmZkHewXUu4tUa1IXW6ij6IqojV5kr+xhYKLN1DA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/electron-hunspell/-/electron-hunspell-1.0.0.tgz", + "integrity": "sha512-egyioCtGkkNMOYdKBrZsva63JxbPmNjmQVFCZCcmr+uIUs6et6OUvqd6ac9/ujuchiEPDrTfF9gdR9+lPbVyPA==", "requires": { - "hunspell-asm": "^2.0.0", - "tslib": "1.9.3" + "hunspell-asm": "^4.0.0" } }, "electron-is-dev": { @@ -11504,32 +11503,22 @@ } }, "hunspell-asm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hunspell-asm/-/hunspell-asm-2.0.0.tgz", - "integrity": "sha512-FMIUBpy+bRREFAvC63RcYEK9U6+FdlEojGSVsvMTpuZ2CekYyUBwEfG4+ExIQOQyEN0U6f1MoVgrFqvgPNSA2g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hunspell-asm/-/hunspell-asm-4.0.0.tgz", + "integrity": "sha512-EcNwMx0Byq1JHMZiuATmqpMk41bOo+NH4yD5xJ3H0X403MoDBory3zri2lJzYSGj+z/6Bqr3EZn24syCjZoY1w==", "requires": { - "emscripten-wasm-loader": "^2.2.3", - "nanoid": "^2.0.1", - "tslib": "^1.9.3", - "unixify": "^1.0.0" + "emscripten-wasm-loader": "^3.0.3", + "nanoid": "^2.1.1" }, "dependencies": { "emscripten-wasm-loader": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/emscripten-wasm-loader/-/emscripten-wasm-loader-2.2.3.tgz", - "integrity": "sha512-//gI0afvtVnY7smttrPOW/BM+pTJLmdIcXAQV3fgRdQ0o6wm2vdSI0kjLYVOeo/rbtRsGgVuMLu6fT+O//EfaA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/emscripten-wasm-loader/-/emscripten-wasm-loader-3.0.3.tgz", + "integrity": "sha512-fyq2maBt5LOou27LEBlL5H6G04BxgSamXkvmMsAuIT6rd8ioH4BxNQhuyl6jVPeODh6U8Wk1BoFZxzHpg3o8wA==", "requires": { "getroot": "^1.0.0", - "nanoid": "^1.3.4", - "tslib": "^1.9.3", + "nanoid": "^2.0.3", "unixify": "^1.0.0" - }, - "dependencies": { - "nanoid": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.3.4.tgz", - "integrity": "sha512-4ug4BsuHxiVHoRUe1ud6rUFT3WUMmjXt1W0quL0CviZQANdan7D8kqN5/maw53hmAApY/jfzMRkC57BNNs60ZQ==" - } } } } @@ -14525,9 +14514,9 @@ "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" }, "nanoid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.3.tgz", - "integrity": "sha512-NbaoqdhIYmY6FXDRB4eYtDVC9Z9eCbn8TyaiC16LNKtpPv/aqa0tOPD8y6gNE4yUNnaZ7LLhYtXOev/6+cBtfw==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.1.tgz", + "integrity": "sha512-0YbJdaL4JFoejIOoawgLcYValFGJ2iyUuVDIWL3g8Es87SSOWFbWdRUMV3VMSiyPs3SQ3QxCIxFX00q5DLkMCw==" }, "nanomatch": { "version": "1.2.13", diff --git a/package.json b/package.json index 2814df2ab..09874bc59 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "du": "^0.1.0", "electron-dl": "1.12.0", "electron-fetch": "1.3.0", - "electron-hunspell": "1.0.0-beta.7", + "electron-hunspell": "1.0.0", "electron-is-dev": "1.0.1", "electron-react-titlebar": "0.8.1", "electron-updater": "4.0.6", diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index 64575753f..d7bb983dc 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js @@ -1,6 +1,5 @@ import { webFrame } from 'electron'; import { attachSpellCheckProvider, SpellCheckerProvider } from 'electron-hunspell'; -import { ENVIRONMENT } from 'hunspell-asm'; import path from 'path'; import { readFileSync } from 'fs'; @@ -14,6 +13,8 @@ let currentDict; let _isEnabled = false; let attached; +const DEFAULT_LOCALE = 'en-us'; + async function loadDictionary(locale) { try { const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); @@ -24,7 +25,7 @@ async function loadDictionary(locale) { } } -export async function switchDict(locale) { +export async function switchDict(locale = DEFAULT_LOCALE) { try { debug('Trying to load dictionary', locale); @@ -55,13 +56,23 @@ export async function switchDict(locale) { } } -export default async function initialize(languageCode = 'en-us') { +export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) { + const locales = Object.keys(SPELLCHECKER_LOCALES).filter(key => key === identifier.toLowerCase() || key.split('-')[0] === identifier.toLowerCase()); + + if (locales.length >= 1) { + return locales[0]; + } + + return null; +} + +export default async function initialize(languageCode = DEFAULT_LOCALE) { try { provider = new SpellCheckerProvider(); - const locale = languageCode.toLowerCase(); + const locale = getSpellcheckerLocaleByFuzzyIdentifier(languageCode); debug('Init spellchecker'); - await provider.initialize({ environment: ENVIRONMENT.NODE }); + await provider.initialize(); debug('Attaching spellcheck provider'); attached = await attachSpellCheckProvider(provider); @@ -69,7 +80,6 @@ export default async function initialize(languageCode = 'en-us') { debug('Available spellchecker dictionaries', provider.availableDictionaries); attached.switchLanguage(locale); - console.log('seas oida', attached, provider); return provider; } catch (err) { @@ -89,13 +99,3 @@ export function disable() { currentDict = null; } } - -export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) { - const locales = Object.keys(SPELLCHECKER_LOCALES).filter(key => key === identifier.toLowerCase() || key.split('-')[0] === identifier.toLowerCase()); - - if (locales.length >= 1) { - return locales[0]; - } - - return null; -} -- cgit v1.2.3-70-g09d2 From 5ba67233d0b1363c7e0e7c25b33b88c483c17bf9 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 14:16:40 +0200 Subject: feat(Todos): Allow todos to open links in browser --- src/features/todos/store.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/features/todos/store.js b/src/features/todos/store.js index abf176604..4480b2545 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js @@ -162,6 +162,10 @@ export default class TodoStore extends FeatureStore { theme: isDarkThemeActive ? ThemeType.dark : ThemeType.default, }, }); + + this.webview.addEventListener('new-window', ({ url }) => { + this.actions.app.openExternalUrl({ url }); + }); }; _goToService = ({ url, serviceId }) => { -- cgit v1.2.3-70-g09d2 From 71831ec74abc671275da8bfd37b8354b422c0b70 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 14:24:58 +0200 Subject: feat(Mac): Open Franz Window with `Cmd+1` --- src/lib/Menu.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/lib/Menu.js b/src/lib/Menu.js index b72f0df96..e5ff4a841 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -867,6 +867,10 @@ export default class FranzMenu { checked: service.isActive, click: () => { this.actions.service.setActive({ serviceId: service.id }); + + if (isMac && i === 0) { + app.mainWindow.restore(); + } }, }))); -- cgit v1.2.3-70-g09d2 From cc038831ebea767e9a39354c9f5984d874b08377 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 14:54:15 +0200 Subject: fix(Spell checking): Fix "undefined" language in context menu --- src/webview/contextMenu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index 2fdbcdca6..d3b976554 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js @@ -255,9 +255,9 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck }, { id: 'resetToDefault', - label: `Reset to system default (${SPELLCHECKER_LOCALES[defaultSpellcheckerLanguage]})`, + label: `Reset to system default (${defaultSpellcheckerLanguage === 'automatic' ? 'Automatic' : SPELLCHECKER_LOCALES[defaultSpellcheckerLanguage]})`, type: 'radio', - visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, + visible: defaultSpellcheckerLanguage !== spellcheckerLanguage || (defaultSpellcheckerLanguage !== 'automatic' && spellcheckerLanguage === 'automatic'), click() { debug('Resetting service spellchecker to system default'); ipcRenderer.sendToHost('set-service-spellchecker-language', 'reset'); -- cgit v1.2.3-70-g09d2 From 490a9882be8c582eedce00098a205bf363f03f5d Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 16:08:52 +0200 Subject: fix(App): Fix "Paste And Match Style" --- src/lib/Menu.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/lib/Menu.js b/src/lib/Menu.js index e5ff4a841..32bd1644b 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -302,6 +302,9 @@ const _templateFactory = intl => [ label: intl.formatMessage(menuItems.pasteAndMatchStyle), accelerator: 'Cmd+Shift+V', selector: 'pasteAndMatchStyle:', + click() { + getActiveWebview().pasteAndMatchStyle(); + }, }, { label: intl.formatMessage(menuItems.delete), -- cgit v1.2.3-70-g09d2 From 86410c4bc7b3dad824586a7116713318287a6d0e Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Fri, 27 Sep 2019 21:11:24 +0200 Subject: add disablewebsecurity option --- src/components/services/content/ServiceWebview.js | 1 + src/models/Recipe.js | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 7252c695f..07bd17d9c 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js @@ -41,6 +41,7 @@ class ServiceWebview extends Component { }} onUpdateTargetUrl={this.updateTargetUrl} useragent={service.userAgent} + disablewebsecurity={service.recipe.disablewebsecurity} allowpopups /> ); diff --git a/src/models/Recipe.js b/src/models/Recipe.js index b0d60e75e..00c0f699f 100644 --- a/src/models/Recipe.js +++ b/src/models/Recipe.js @@ -36,6 +36,8 @@ export default class Recipe { message = ''; + disablewebsecurity = false; + constructor(data) { if (!data) { throw Error('Recipe config not valid'); @@ -74,6 +76,8 @@ export default class Recipe { this.urlInputPrefix = data.config.urlInputPrefix || this.urlInputPrefix; this.urlInputSuffix = data.config.urlInputSuffix || this.urlInputSuffix; + this.disablewebsecurity = data.config.disablewebsecurity || this.disablewebsecurity; + this.message = data.config.message || this.message; } -- cgit v1.2.3-70-g09d2 From e34fb4401c261f6d8fb01f4d1a07b496af722345 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Sat, 28 Sep 2019 19:58:04 +0200 Subject: enable touchbar in electron 6 --- src/lib/TouchBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/TouchBar.js b/src/lib/TouchBar.js index 97c02d194..e10e53001 100644 --- a/src/lib/TouchBar.js +++ b/src/lib/TouchBar.js @@ -42,7 +42,7 @@ export default class FranzTouchBar { }), new TouchBarSpacer({ size: 'small' })); })); - const touchBar = new TouchBar(buttons); + const touchBar = new TouchBar({ items: buttons }); currentWindow.setTouchBar(touchBar); } else { currentWindow.setTouchBar(null); -- cgit v1.2.3-70-g09d2 From 077ad229bf4ef9e1ba22c8cf3ceb21c82dc77062 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Sat, 28 Sep 2019 20:05:53 +0200 Subject: fix(macOS): Only show services in Touch Bar that should be visible closes #1627 --- src/lib/TouchBar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/TouchBar.js b/src/lib/TouchBar.js index e10e53001..1de46d2a3 100644 --- a/src/lib/TouchBar.js +++ b/src/lib/TouchBar.js @@ -29,7 +29,7 @@ export default class FranzTouchBar { const { TouchBarButton, TouchBarSpacer } = TouchBar; const buttons = []; - this.stores.services.enabled.forEach(((service) => { + this.stores.services.allDisplayed.forEach(((service) => { buttons.push(new TouchBarButton({ label: `${service.name}${service.unreadDirectMessageCount > 0 ? ' 🔴' : ''} ${service.unreadDirectMessageCount === 0 -- cgit v1.2.3-70-g09d2 From 9f4f3e74002d6b5d0b6fe3851b3e467fdafd8887 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Sun, 29 Sep 2019 20:22:10 +0200 Subject: feat(Service API): Share `team`, `url` and `hasCustomIcon` with service --- src/models/Service.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/models/Service.js b/src/models/Service.js index 848a84aa2..023103048 100644 --- a/src/models/Service.js +++ b/src/models/Service.js @@ -134,6 +134,9 @@ export default class Service { id: this.id, spellcheckerLanguage: this.spellcheckerLanguage, isDarkModeEnabled: this.isDarkModeEnabled, + team: this.team, + url: this.url, + hasCustomIcon: this.hasCustomIcon, }; } -- cgit v1.2.3-70-g09d2 From 465a8b1c8a136c8058bf0e790b89434513bac0d7 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Tue, 1 Oct 2019 09:22:21 +0200 Subject: remove unused selector --- src/features/todos/components/TodosWebview.js | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index d052da6f2..f24c0b044 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js @@ -35,9 +35,6 @@ const styles = theme => ({ transform: ({ isVisible, width }) => `translateX(${isVisible ? 0 : width}px)`, - '&:hover $closeTodosButton': { - opacity: 1, - }, '& webview': { height: '100%', }, -- cgit v1.2.3-70-g09d2 From f8fbaad43522b91374eaed5e3df6fe47bc94862f Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Tue, 1 Oct 2019 21:51:34 +0200 Subject: feat(Custom Websites): Add simple browser controls --- src/components/services/content/ServiceView.js | 16 +- src/features/webControls/components/WebControls.js | 190 +++++++++++++++++++++ .../webControls/containers/WebControlsScreen.js | 128 ++++++++++++++ 3 files changed, 329 insertions(+), 5 deletions(-) create mode 100644 src/features/webControls/components/WebControls.js create mode 100644 src/features/webControls/containers/WebControlsScreen.js (limited to 'src') diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index f65f51346..e8df58a1e 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js @@ -12,6 +12,7 @@ import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; import ServiceDisabled from './ServiceDisabled'; import ServiceRestricted from './ServiceRestricted'; import ServiceWebview from './ServiceWebview'; +import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; export default @observer class ServiceView extends Component { static propTypes = { @@ -137,11 +138,16 @@ export default @observer class ServiceView extends Component { type={service.restrictionType} /> ) : ( - + <> + {service.recipe.id === 'franz-custom-website' && ( + + )} + + )} )} diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js new file mode 100644 index 000000000..03f601a17 --- /dev/null +++ b/src/features/webControls/components/WebControls.js @@ -0,0 +1,190 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { observer } from 'mobx-react'; +import injectSheet from 'react-jss'; +import { Icon } from '@meetfranz/ui'; + +import { + mdiReload, mdiArrowRight, mdiArrowLeft, mdiHomeOutline, +} from '@mdi/js'; + +const styles = theme => ({ + root: { + background: theme.colorBackground, + position: 'relative', + borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], + zIndex: 300, + height: 50, + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + padding: [0, 20], + + '& + div': { + height: 'calc(100% - 50px)', + }, + }, + button: { + width: 30, + height: 50, + transition: 'opacity 0.25s', + + '&:hover': { + opacity: 0.8, + }, + + '&:disabled': { + opacity: 0.5, + }, + }, + icon: { + width: '20px !important', + height: 20, + marginTop: 5, + }, + input: { + marginBottom: 0, + height: 'auto', + marginLeft: 10, + flex: 1, + border: 0, + padding: [4, 10], + borderRadius: theme.borderRadius, + background: theme.inputBackground, + color: theme.inputColor, + }, + inputButton: { + color: theme.colorText, + }, +}); + +@injectSheet(styles) @observer +class WebControls extends Component { + static propTypes = { + classes: PropTypes.object.isRequired, + goHome: PropTypes.func.isRequired, + canGoBack: PropTypes.bool.isRequired, + goBack: PropTypes.func.isRequired, + canGoForward: PropTypes.bool.isRequired, + goForward: PropTypes.func.isRequired, + reload: PropTypes.func.isRequired, + url: PropTypes.string.isRequired, + navigate: PropTypes.func.isRequired, + } + + static getDerivedStateFromProps(props, state) { + const { url } = props; + const { editUrl } = state; + + if (!editUrl) { + return { + inputUrl: url, + editUrl: state.editUrl, + }; + } + } + + inputRef = React.createRef(); + + state = { + inputUrl: '', + editUrl: false, + } + + render() { + const { + classes, + goHome, + canGoBack, + goBack, + canGoForward, + goForward, + reload, + url, + navigate, + } = this.props; + + const { + inputUrl, + editUrl, + } = this.state; + + return ( +
+ + + + + this.setState({ + inputUrl: event.target.value, + })} + onFocus={(event) => { + event.target.select(); + this.setState({ + editUrl: true, + }); + }} + onKeyDown={(event) => { + if (event.key === 'Enter') { + this.setState({ + editUrl: false, + }); + navigate(inputUrl); + this.inputRef.current.blur(); + } else if (event.key === 'Escape') { + this.setState({ + editUrl: false, + inputUrl: url, + }); + event.target.blur(); + } + }} + ref={this.inputRef} + /> +
+ ); + } +} + +export default WebControls; diff --git a/src/features/webControls/containers/WebControlsScreen.js b/src/features/webControls/containers/WebControlsScreen.js new file mode 100644 index 000000000..1452d5a3d --- /dev/null +++ b/src/features/webControls/containers/WebControlsScreen.js @@ -0,0 +1,128 @@ +import React, { Component } from 'react'; +import { observer, inject } from 'mobx-react'; +import PropTypes from 'prop-types'; + +import { autorun, observable } from 'mobx'; +import WebControls from '../components/WebControls'; +import ServicesStore from '../../../stores/ServicesStore'; +import Service from '../../../models/Service'; + +const URL_EVENTS = [ + 'load-commit', + // 'dom-ready', + 'will-navigate', + 'did-navigate', + 'did-navigate-in-page', +]; + +@inject('stores', 'actions') @observer +class WebControlsScreen extends Component { + @observable url = ''; + + @observable canGoBack = false; + + @observable canGoForward = false; + + webview = null; + + autorunDisposer = null; + + componentDidMount() { + const { service } = this.props; + + this.autorunDisposer = autorun(() => { + if (service.isAttached) { + this.webview = service.webview; + + URL_EVENTS.forEach((event) => { + this.webview.addEventListener(event, (e) => { + if (!e.isMainFrame) return; + + this.url = e.url; + this.canGoBack = this.webview.canGoBack(); + this.canGoForward = this.webview.canGoForward(); + }); + }); + } + }); + } + + componentWillUnmount() { + this.autorunDisposer(); + } + + goHome() { + const { reloadActive } = this.props.actions.service; + + if (!this.webview) return; + + reloadActive(); + } + + reload() { + if (!this.webview) return; + + this.webview.reload(); + } + + goBack() { + if (!this.webview) return; + + this.webview.goBack(); + } + + goForward() { + if (!this.webview) return; + + this.webview.goForward(); + } + + navigate(newUrl) { + if (!this.webview) return; + + let url = newUrl; + + try { + url = new URL(url).toString(); + } catch (err) { + // eslint-disable-next-line no-useless-escape + if (url.match(/^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/)) { + url = `http://${url}`; + } else { + url = `https://www.google.com/search?query=${url}`; + } + } + + this.webview.loadURL(url); + this.url = url; + } + + render() { + return ( + this.goHome()} + reload={() => this.reload()} + canGoBack={this.canGoBack} + goBack={() => this.goBack()} + canGoForward={this.canGoForward} + goForward={() => this.goForward()} + navigate={url => this.navigate(url)} + url={this.url} + /> + ); + } +} + +export default WebControlsScreen; + +WebControlsScreen.wrappedComponent.propTypes = { + service: PropTypes.instanceOf(Service).isRequired, + stores: PropTypes.shape({ + services: PropTypes.instanceOf(ServicesStore).isRequired, + }).isRequired, + actions: PropTypes.shape({ + service: PropTypes.shape({ + reloadActive: PropTypes.func.isRequired, + }).isRequired, + }).isRequired, +}; -- cgit v1.2.3-70-g09d2 From 8428b4ee25e2e200cd220d483db52e6b7ad1c7fb Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 2 Oct 2019 09:54:51 +0200 Subject: Update clear cache to electron promise APIs --- src/api/server/LocalApi.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js index ab1604a27..383f38b16 100644 --- a/src/api/server/LocalApi.js +++ b/src/api/server/LocalApi.js @@ -45,13 +45,13 @@ export default class LocalApi { const s = session.fromPartition(`persist:service-${serviceId}`); debug('LocalApi::clearCache resolves', serviceId); - return new Promise(resolve => s.clearCache(resolve)); + return s.clearCache(); } async clearAppCache() { const s = session.defaultSession; debug('LocalApi::clearCache clearAppCache'); - return new Promise(resolve => s.clearCache(resolve)); + return s.clearCache(); } } -- cgit v1.2.3-70-g09d2 From a31566db76a20e1cb91de0aa26cace70b450acfa Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 2 Oct 2019 09:55:12 +0200 Subject: fix(Settings): Fix cache size calculation after clearing cache --- src/stores/AppStore.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 315235ba4..0398b7533 100644 --- a/src/stores/AppStore.js +++ b/src/stores/AppStore.js @@ -23,6 +23,7 @@ import { getLocale } from '../helpers/i18n-helpers'; import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js'; import { isValidExternalURL } from '../helpers/url-helpers'; +import { sleep } from '../helpers/async-helpers'; const debug = require('debug')('Franz:AppStore'); @@ -327,6 +328,8 @@ export default class AppStore extends Store { await clearAppCache._promise; + await sleep(ms('1s')); + this.getAppCacheSizeRequest.execute(); this.isClearingAllCache = false; -- cgit v1.2.3-70-g09d2 From 734732f1f901093ec78b166413aa3315f6f61248 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Wed, 2 Oct 2019 10:45:25 +0200 Subject: fix(Spell check): Fix spell checker to initialize without loaded dictionary --- src/webview/spellchecker.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js index d7bb983dc..06cbd283a 100644 --- a/src/webview/spellchecker.js +++ b/src/webview/spellchecker.js @@ -18,8 +18,8 @@ const DEFAULT_LOCALE = 'en-us'; async function loadDictionary(locale) { try { const fileLocation = path.join(DICTIONARY_PATH, `hunspell-dict-${locale}/${locale}`); - await provider.loadDictionary(locale, readFileSync(`${fileLocation}.dic`), readFileSync(`${fileLocation}.aff`)); debug('Loaded dictionary', locale, 'from', fileLocation); + return provider.loadDictionary(locale, readFileSync(`${fileLocation}.dic`), readFileSync(`${fileLocation}.aff`)); } catch (err) { console.error('Could not load dictionary', err); } @@ -44,8 +44,8 @@ export async function switchDict(locale = DEFAULT_LOCALE) { if (currentDict) { provider.unloadDictionary(locale); } - loadDictionary(locale); - attached.switchLanguage(locale); + await loadDictionary(locale); + await attached.switchLanguage(locale); debug('Switched dictionary to', locale); @@ -77,9 +77,11 @@ export default async function initialize(languageCode = DEFAULT_LOCALE) { debug('Attaching spellcheck provider'); attached = await attachSpellCheckProvider(provider); - debug('Available spellchecker dictionaries', provider.availableDictionaries); + const availableDictionaries = await provider.getAvailableDictionaries(); - attached.switchLanguage(locale); + debug('Available spellchecker dictionaries', availableDictionaries); + + await switchDict(locale); return provider; } catch (err) { -- cgit v1.2.3-70-g09d2