diff --git a/.github/stale.yml b/.github/stale.yml index 45faa989..e34d8a49 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,5 +1,5 @@ # Number of days of inactivity before an issue becomes stale -daysUntilStale: 60 +daysUntilStale: 30 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Issues with these labels will never be considered stale diff --git a/app/config.js b/app/config.js index f9023ec8..4f7f5fc7 100644 --- a/app/config.js +++ b/app/config.js @@ -17,10 +17,14 @@ export const IS_WINDOWS = navigator && navigator.platform && navigator.platform.startsWith('Win'); export const INPUT_FILTER_DELAY = 300; // ms, dalay before filtering projects, libs, platorms -export const PLATFORMIO_API_ENDPOINT = 'http://api.platformio.org'; +export const PLATFORMIO_API_ENDPOINT = 'https://api.platformio.org'; -let wsrpc = 'ws://127.0.0.1:8008/wsrpc'; +let pathname = window.location ? window.location.pathname : '/'; +if (pathname[pathname.length - 1] !== '/') { + pathname += '/'; +} +let wsrpc = `ws://127.0.0.1:8008${pathname}wsrpc`; if (process.env.NODE_ENV === 'production' && window.location && window.location.host) { - wsrpc = `ws://${window.location.host}/wsrpc`; + wsrpc = `ws://${window.location.host}${pathname}wsrpc`; } export const BACKEND_ENDPOINT = wsrpc; diff --git a/app/index.html b/app/index.html index 769963b4..958c8495 100755 --- a/app/index.html +++ b/app/index.html @@ -54,7 +54,11 @@ theme = 'dark'; }; var link = document.createElement('link'); - link.href = './themes/' + workspace + '-' + theme + '.css'; + var pathname = (window.location? window.location.pathname : '/'); + if (pathname[pathname.length - 1] !== '/') { + pathname += '/'; + } + link.href = pathname + 'themes/' + workspace + '-' + theme + '.css'; link.type = 'text/css'; link.rel = 'stylesheet'; document.getElementsByTagName('head')[0].appendChild(link); diff --git a/app/modules/account/sagas.js b/app/modules/account/sagas.js index bf9a4480..69871faa 100644 --- a/app/modules/account/sagas.js +++ b/app/modules/account/sagas.js @@ -23,7 +23,7 @@ import { call, put, select, take, takeLatest } from 'redux-saga/effects'; import { deleteEntity, updateEntity } from '../../store/actions'; import { notifyError, notifySuccess, osOpenUrl } from '../core/actions'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { inIframe } from '../core/helpers'; import jsonrpc from 'jsonrpc-lite'; import { message } from 'antd'; @@ -74,7 +74,7 @@ function* watchLoadAccountInfo() { } try { - data = yield call(apiFetchData, { + data = yield call(backendFetchData, { query: 'core.call', params: [ ['account', 'show', '--json-output', ...(extended ? [] : ['--offline'])] @@ -96,7 +96,7 @@ function* watchLoadAccountInfo() { function* watchLoginAccount() { yield takeLatest(actions.LOGIN_ACCOUNT, function*({ username, password, onEnd }) { try { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [['account', 'login', '--username', username, '--password', password]] }); @@ -134,7 +134,7 @@ function* watchLoginWithProvider() { function* loginAccountWithCode(client_id, code, redirectUri) { try { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'account.call_client', params: ['login_with_code', client_id, code, redirectUri] }); @@ -150,7 +150,7 @@ function* watchLogoutAccount() { yield takeLatest(actions.LOGOUT_ACCOUNT, function*() { try { yield put(updateEntity('accountInfo', {})); - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [['account', 'logout']] }); @@ -174,7 +174,7 @@ function* watchRegisterAccount() { }) { let err = null; try { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [ [ @@ -217,7 +217,7 @@ function* watchForgotAccount() { yield takeLatest(actions.FORGOT_ACCOUNT, function*({ username, onEnd }) { let err = null; try { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [['account', 'forgot', '--username', username]] }); @@ -249,7 +249,7 @@ function* watchPasswordAccount() { }) { let err = null; try { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [ [ @@ -288,7 +288,7 @@ function* watchTokenAccount() { if (regenerate) { args.push('--regenerate'); } - const data = yield call(apiFetchData, { + const data = yield call(backendFetchData, { query: 'core.call', params: [args] }); @@ -317,7 +317,7 @@ function* watchUpdateProfile() { }) { let err = null; try { - const response = yield call(apiFetchData, { + const response = yield call(backendFetchData, { query: 'core.call', params: [ [ diff --git a/app/modules/core/containers/code-beautifier.jsx b/app/modules/core/containers/code-beautifier.jsx index a245ee26..98e4d7fe 100644 --- a/app/modules/core/containers/code-beautifier.jsx +++ b/app/modules/core/containers/code-beautifier.jsx @@ -21,7 +21,7 @@ import { Icon, Spin } from 'antd'; import PropTypes from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; -import hljs from 'highlight.js/lib/highlight'; +import hljs from 'highlight.js/lib/core'; import { requestContent } from '../actions'; import { selectRequestedContent } from '../selectors'; diff --git a/app/modules/core/sagas.jsx b/app/modules/core/sagas.jsx index 38e2cd67..67939182 100644 --- a/app/modules/core/sagas.jsx +++ b/app/modules/core/sagas.jsx @@ -28,7 +28,7 @@ import { ConsentRejectedError } from '@core/errors'; import React from 'react'; import URL from 'url-parse'; import { USER_CONSENTS_KEY } from '@core/constants'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { getStore } from '../../store/index'; import jsonrpc from 'jsonrpc-lite'; import qs from 'querystringify'; @@ -91,6 +91,14 @@ function* watchNotifyError() { [ /Updating.+VCS.+recurse-submodules/g, 'https://github.com/platformio/platformio-home/issues/143' + ], + [ + /Error: Detected a whitespace character/g, + 'https://github.com/platformio/platform-espressif32/issues/470' + ], + [ + /Error: Could not find the package/g, + 'https://github.com/platformio/platformio-home/issues/2144' ] ]; for (const [regex, url] of knownIssues) { @@ -191,7 +199,7 @@ function* watchOSRequests() { const redirectWindow = window.open(url.toString(), '_blank'); redirectWindow.location; } else { - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'os.open_url', params: [url.toString()] }); @@ -199,28 +207,28 @@ function* watchOSRequests() { break; case actions.OS_REVEAL_FILE: - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'os.reveal_file', params: [action.path] }); break; case actions.OS_RENAME_FILE: - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'os.rename', params: [action.src, action.dst] }); break; case actions.OS_COPY_FILE: - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'os.copy', params: [action.src, action.dst] }); break; case actions.OS_MAKE_DIRS: - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'os.make_dirs', params: [action.path] }); @@ -265,7 +273,7 @@ function* watchRequestContent() { } if (!content) { - content = yield call(apiFetchData, { + content = yield call(backendFetchData, { query: 'os.request_content', params: [uri, data, headers, cacheValid] }); @@ -297,7 +305,7 @@ function* watchOsFSGlob() { return; } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'os.glob', params: [pathnames, rootDir] }); @@ -328,7 +336,7 @@ function* watchLoadLogicalDevices() { return; } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'os.get_logical_devices' }); yield put(updateEntity('logicalDevices', items)); @@ -347,7 +355,7 @@ function* watchOsListDir() { items = {}; } try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'os.list_dir', params: [/^[A-Z]:$/.test(path) ? path + '\\' : path] }); @@ -369,7 +377,7 @@ function* watchOsIsFile() { items = {}; } try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'os.is_file', params: [path] }); @@ -391,7 +399,7 @@ function* watchOsIsDir() { items = {}; } try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'os.is_dir', params: [path] }); @@ -428,7 +436,7 @@ function* watchToggleFavoriteFolder() { function* watchOpenTextDocument() { yield takeEvery(actions.OPEN_TEXT_DOCUMENT, function*({ path, line, column }) { - const is_file = yield call(apiFetchData, { + const is_file = yield call(backendFetchData, { query: 'os.is_file', params: [path] }); @@ -436,13 +444,13 @@ function* watchOpenTextDocument() { return message.error(`File does not exist on disk ${path}`); } try { - return yield call(apiFetchData, { + return yield call(backendFetchData, { query: 'ide.open_text_document', params: [getSessionId(), path, line, column] }); } catch (err) { console.warn(err); - return yield call(apiFetchData, { + return yield call(backendFetchData, { query: 'os.open_file', params: [path] }); diff --git a/app/modules/device/sagas.js b/app/modules/device/sagas.js index eff35903..8c9f5730 100644 --- a/app/modules/device/sagas.js +++ b/app/modules/device/sagas.js @@ -22,7 +22,7 @@ import * as selectors from './selectors'; import { call, put, select, take } from 'redux-saga/effects'; import { deleteEntity, updateEntity } from '../../store/actions'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { notifyError } from '../core/actions'; function* watchLoadSerialDevices() { @@ -37,7 +37,7 @@ function* watchLoadSerialDevices() { } yield call(function*() { try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'core.call', params: [['device', 'list', '--serial', '--json-output']] }); @@ -61,7 +61,7 @@ function* watchLoadMDNSDevices() { } yield call(function*() { try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'core.call', params: [ ['device', 'list', '--mdns', '--json-output'], diff --git a/app/modules/home/sagas.js b/app/modules/home/sagas.js index ca7b62b7..a37fcfb1 100644 --- a/app/modules/home/sagas.js +++ b/app/modules/home/sagas.js @@ -21,7 +21,7 @@ import * as selectors from './selectors'; import { call, put, select, takeLatest } from 'redux-saga/effects'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { updateEntity } from '../../store/actions'; function* watchLoadLatestTweets() { @@ -31,7 +31,7 @@ function* watchLoadLatestTweets() { return; } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'misc.load_latest_tweets', params: [`https://news.platformio.org/tweets/${username}/data.json`] }); diff --git a/app/modules/inspect/sagas.js b/app/modules/inspect/sagas.js index 3686e18e..c0b4f690 100644 --- a/app/modules/inspect/sagas.js +++ b/app/modules/inspect/sagas.js @@ -27,7 +27,7 @@ import { selectSavedConfiguration } from '@inspect/selectors'; -import { apiFetchData } from '@store/api'; +import { backendFetchData } from '@store/backend'; import { goTo } from '@core/helpers'; import jsonrpc from 'jsonrpc-lite'; import { selectProjectInfo } from '@project/selectors'; @@ -44,7 +44,7 @@ function* _updateMetric(name, projectDir, env, duration) { function* _inspectMemory({ projectDir, env }) { const start = Date.now(); - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'core.call', params: [ ['run', '-d', projectDir, '-e', env, '-t', 'sizedata'], @@ -52,7 +52,7 @@ function* _inspectMemory({ projectDir, env }) { ] }); - const buildDir = yield call(apiFetchData, { + const buildDir = yield call(backendFetchData, { query: 'project.config_call', params: [ { path: pathlib.join(projectDir, 'platformio.ini') }, @@ -62,7 +62,7 @@ function* _inspectMemory({ projectDir, env }) { }); const sizedataPath = pathlib.join(buildDir, env, 'sizedata.json'); - const jsonContent = yield call(apiFetchData, { + const jsonContent = yield call(backendFetchData, { query: 'os.request_content', params: [sizedataPath] }); @@ -79,7 +79,7 @@ function* _inspectCode({ projectDir, env }) { const start = Date.now(); let codeCheckResults; try { - codeCheckResults = yield call(apiFetchData, { + codeCheckResults = yield call(backendFetchData, { query: 'core.call', params: [ ['check', '-d', projectDir, '-e', env, '--json-output'], diff --git a/app/modules/library/sagas.js b/app/modules/library/sagas.js index a89559b8..7042f4b2 100644 --- a/app/modules/library/sagas.js +++ b/app/modules/library/sagas.js @@ -37,7 +37,7 @@ import { } from 'redux-saga/effects'; import { notifyError, notifySuccess, updateRouteBadge } from '../core/actions'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { checkRegistryPlatformsAndFrameworks } from '../platform/sagas'; import jsonrpc from 'jsonrpc-lite'; import { preloadProjects } from '../project/sagas'; @@ -64,7 +64,7 @@ function* watchLoadStats() { } try { - data = yield call(apiFetchData, { + data = yield call(backendFetchData, { query: 'core.call', params: [['lib', 'stats', '--json-output']] }); @@ -93,7 +93,7 @@ function* watchLoadSearchResult() { args.push(query); } args = args.concat(['--page', page, '--json-output']); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'core.call', params: [args] }); @@ -123,7 +123,7 @@ function* watchLoadLibraryData() { return; } try { - const data = yield call(apiFetchData, { + const data = yield call(backendFetchData, { query: 'core.call', params: [['lib', 'show', idOrManifest, '--json-output']] }); @@ -154,7 +154,7 @@ function* watchLoadBuiltinLibs() { continue; } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'core.call', params: [['lib', 'builtin', '--json-output'], { force_subprocess: true }] }); @@ -183,7 +183,7 @@ function* watchLoadInstalledLibs() { args.push('--global'); } args = args.concat(['list', '--json-output']); - const items = yield call(apiFetchData, { + const items = yield call(backendFetchData, { query: 'core.call', params: [args, { force_subprocess: true }] }); @@ -217,7 +217,7 @@ function* fetchStorageUpdates(storage) { args.push('--global'); } args = args.concat(['update', '--only-check', '--json-output']); - return yield call(apiFetchData, { + return yield call(backendFetchData, { query: 'core.call', params: [args, { force_subprocess: true }] }); @@ -299,7 +299,7 @@ function* watchInstallLibrary() { args.push('--global'); } args = args.concat(['install', lib]); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'core.call', params: [args, { force_subprocess: true }] }); @@ -322,7 +322,7 @@ function* watchUninstallOrUpdateLibrary() { const { storage, pkg, onEnd } = action; let err; try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'core.call', params: [ action.type === actions.UNINSTALL_LIBRARY && diff --git a/app/modules/platform/sagas.js b/app/modules/platform/sagas.js index b6129807..28ab898d 100644 --- a/app/modules/platform/sagas.js +++ b/app/modules/platform/sagas.js @@ -38,7 +38,7 @@ import { notifyError, notifySuccess, updateRouteBadge } from '../core/actions'; import { PLATFORMIO_API_ENDPOINT } from '../../config'; import ReactGA from 'react-ga'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { goTo } from '../core/helpers'; import jsonrpc from 'jsonrpc-lite'; import requests from 'superagent'; @@ -50,7 +50,7 @@ const INSTALLED_PLATFORMS_DATA_CACHE = 10; function* _loadRegistryPlatforms(silent) { let items = []; try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'core.call', params: [['platform', 'search', '--json-output']] }); @@ -63,7 +63,7 @@ function* _loadRegistryPlatforms(silent) { function* _loadRegistryFrameworks(silent) { let items = []; try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'core.call', params: [['platform', 'frameworks', '--json-output']] }); @@ -89,7 +89,7 @@ function* checkBoards() { return; } try { - let items = yield call(apiFetchData, { + let items = yield call(backendFetchData, { query: 'core.call', params: [['boards', '--json-output']] }); @@ -153,7 +153,7 @@ function* watchLoadPlatformData() { return; } try { - const data = yield call(apiFetchData, { + const data = yield call(backendFetchData, { query: 'core.call', params: [['platform', 'show', name, '--json-output']] }); @@ -193,24 +193,35 @@ function* watchLoadFrameworkData() { } function* watchLoadInstalledPlatforms() { - while (true) { - yield take(actions.LOAD_INSTALLED_PLATFORMS); + yield takeLatest(actions.LOAD_INSTALLED_PLATFORMS, function*() { const items = yield select(selectors.selectInstalledPlatforms); if (items) { - continue; + return; } yield call(function*() { - try { - const items = yield call(apiFetchData, { - query: 'core.call', - params: [['platform', 'list', '--json-output']] - }); - yield put(updateEntity('installedPlatforms', items)); - } catch (err) { - yield put(notifyError('Could not load installed platforms', err)); + let attempts = 0; + let lastError = undefined; + while (attempts < 3) { + attempts++; + try { + const items = yield call(backendFetchData, { + query: 'core.call', + params: [['platform', 'list', '--json-output']] + }); + return yield put(updateEntity('installedPlatforms', items)); + } catch (err) { + lastError = err; + } + if ( + lastError instanceof jsonrpc.JsonRpcError && + !lastError.data.includes('Error: Unknown development platform') + ) { + break; + } } + yield put(notifyError('Could not load installed platforms', lastError)); }); - } + }); } function* watchLoadPlatformUpdates() { @@ -223,7 +234,7 @@ function* watchLoadPlatformUpdates() { yield call(function*() { try { - const items = yield call(apiFetchData, { + const items = yield call(backendFetchData, { query: 'core.call', params: [ ['platform', 'update', '--only-check', '--json-output'], @@ -257,7 +268,7 @@ function* watchAutoCheckPlatformUpdates() { } yield put(updateStorageItem(lastCheckKey, now)); try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'core.call', params: [ ['platform', 'update', '--only-check', '--json-output'], @@ -277,7 +288,7 @@ function* watchInstallPlatform() { try { const start = new Date().getTime(); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'core.call', params: [['platform', 'install', platform], { force_subprocess: true }] }); @@ -310,7 +321,7 @@ function* watchUninstallOrUpdatePlatform() { const { pkgDir, onEnd } = action; let err = null; try { - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'core.call', params: [ [ diff --git a/app/modules/project/sagas.jsx b/app/modules/project/sagas.jsx index b4944ad7..8890a17c 100644 --- a/app/modules/project/sagas.jsx +++ b/app/modules/project/sagas.jsx @@ -52,7 +52,7 @@ import { ConfigFileModifiedError } from '@project/errors'; import { ConsentRejectedError } from '@core/errors'; import React from 'react'; import ReactGA from 'react-ga'; -import { apiFetchData } from '../../store/api'; +import { backendFetchData } from '../../store/backend'; import { ensureUserConsent } from '@core/sagas'; import jsonrpc from 'jsonrpc-lite'; @@ -62,7 +62,7 @@ const RECENT_PROJECTS_STORAGE_KEY = 'recentProjects'; function* watchAddProject() { yield takeEvery(actions.ADD_PROJECT, function*({ projectDir, withOpen, onEnd }) { const iniPath = pathlib.join(projectDir, 'platformio.ini'); - const fileExists = yield call(apiFetchData, { + const fileExists = yield call(backendFetchData, { query: 'os.is_file', params: [iniPath] }); @@ -143,7 +143,7 @@ function* watchProjectRename() { function* watchOpenProject() { yield takeEvery(actions.OPEN_PROJECT, function*({ projectDir }) { try { - return yield call(apiFetchData, { + return yield call(backendFetchData, { query: 'ide.open_project', params: [getSessionId(), projectDir] }); @@ -184,7 +184,7 @@ function* watchLoadProjects() { } } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'project.get_projects' }); yield put(updateEntity('projects', items)); @@ -203,7 +203,7 @@ function* watchLoadProjectExamples() { continue; } try { - items = yield call(apiFetchData, { + items = yield call(backendFetchData, { query: 'project.get_project_examples' }); yield put(updateEntity('projectExamples', items)); @@ -227,7 +227,7 @@ function* watchImportProject() { try { const start = new Date().getTime(); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'project.import_pio', params: [projectDir] }); @@ -261,7 +261,7 @@ function* watchInitProject() { try { const start = new Date().getTime(); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'project.init', params: [board, framework, projectDir] }); @@ -300,7 +300,7 @@ function* watchImportArduinoProject() { try { const start = new Date().getTime(); - result = yield call(apiFetchData, { + result = yield call(backendFetchData, { query: 'project.import_arduino', params: [board, useArduinoLibs, arduinoProjectDir] }); @@ -342,7 +342,7 @@ function* watchImportArduinoProject() { function* watchLoadConfigSchema() { yield takeLatest(actions.LOAD_CONFIG_SCHEMA, function*() { try { - const schema = yield call(apiFetchData, { + const schema = yield call(backendFetchData, { query: 'project.get_config_schema' }); // group by scope to pass to section without extra processing @@ -368,11 +368,11 @@ function* watchLoadProjectConfig() { try { yield put(deleteEntity(new RegExp(`^${PROJECT_CONFIG_KEY}$`))); const configPath = pathlib.join(projectDir, 'platformio.ini'); - const tupleConfig = yield call(apiFetchData, { + const tupleConfig = yield call(backendFetchData, { query: 'project.config_load', params: [configPath] }); - const mtime = yield call(apiFetchData, { + const mtime = yield call(backendFetchData, { query: 'os.get_file_mtime', params: [configPath] }); @@ -413,7 +413,7 @@ function* watchSaveProjectConfig() { }); const configPath = pathlib.join(projectDir, 'platformio.ini'); if (!force) { - const currentMtime = yield call(apiFetchData, { + const currentMtime = yield call(backendFetchData, { query: 'os.get_file_mtime', params: [configPath] }); @@ -425,13 +425,13 @@ function* watchSaveProjectConfig() { } } - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'project.config_dump', params: [configPath, data] }); message.success('Project configuration saved'); // Refresh mtime - const newMtime = yield call(apiFetchData, { + const newMtime = yield call(backendFetchData, { query: 'os.get_file_mtime', params: [configPath] }); @@ -480,7 +480,7 @@ function* watchUpdateConfigDescription() { undo = yield _patchProjectState(projectDir, { description }); // Patch file via RPC - yield call(apiFetchData, { + yield call(backendFetchData, { query: 'project.config_update_description', params: [pathlib.join(projectDir, 'platformio.ini'), description] }); diff --git a/app/store/api.js b/app/store/backend.js similarity index 73% rename from app/store/api.js rename to app/store/backend.js index 6dd7eab5..f1dfa4c2 100644 --- a/app/store/api.js +++ b/app/store/backend.js @@ -21,38 +21,41 @@ import jsonrpc from 'jsonrpc-lite'; import { message } from 'antd'; export const actions = { - API_CONNECTED: 'API_CONNECTED', - API_DISCONNECTED: 'API_DISCONNECTED', - API_ERRORED: 'API_ERRORED', - API_REQUEST: 'API_REQUEST', - API_RESULT_SUCCESS: 'API_RESULT_SUCCESS', - API_RESULT_ERROR: 'API_RESULT_ERROR' + BACKEND_CONNECTED: 'BACKEND_CONNECTED', + BACKEND_DISCONNECTED: 'BACKEND_DISCONNECTED', + BACKEND_ERRORED: 'BACKEND_ERRORED', + BACKEND_REQUEST: 'BACKEND_REQUEST', + BACKEND_RESULT_SUCCESS: 'BACKEND_RESULT_SUCCESS', + BACKEND_RESULT_ERROR: 'BACKEND_RESULT_ERROR' }; -actions.apiRequest = (id, query, params) => - createAction(actions.API_REQUEST, { +actions.backendRequest = (id, query, params) => + createAction(actions.BACKEND_REQUEST, { id, query, params }); -export function* apiFetchData({ query, params = [] }) { +export function* backendFetchData({ query, params = [] }) { const id = Math.random().toString(); - yield put(actions.apiRequest(id, query, params)); + yield put(actions.backendRequest(id, query, params)); /* eslint-disable no-constant-condition */ while (true) { - const action = yield take([actions.API_RESULT_SUCCESS, actions.API_RESULT_ERROR]); + const action = yield take([ + actions.BACKEND_RESULT_SUCCESS, + actions.BACKEND_RESULT_ERROR + ]); if (action.id !== id) { continue; } - if (action.type === actions.API_RESULT_ERROR) { + if (action.type === actions.BACKEND_RESULT_ERROR) { throw action.error; } return action.result; } } -export function apiMiddleware(options) { +export function backendMiddleware(options) { return store => { let socket = null; let messageQueue = []; @@ -84,14 +87,14 @@ export function apiMiddleware(options) { reconnect.loading(); } - store.dispatch(createAction(actions.API_CONNECTED)); + store.dispatch(createAction(actions.BACKEND_CONNECTED)); const _messageQueue = messageQueue.slice(0); messageQueue = []; // reset messageQueue _messageQueue.forEach(data => sock.send(data)); }; sock.onclose = () => { - store.dispatch(createAction(actions.API_DISCONNECTED)); + store.dispatch(createAction(actions.BACKEND_DISCONNECTED)); // reconnect if (!reconnect.loading) { reconnect.loading = message.loading('Reconnecting...', 0); @@ -110,15 +113,15 @@ export function apiMiddleware(options) { switch (result.type) { case 'success': return store.dispatch( - createAction(actions.API_RESULT_SUCCESS, result.payload) + createAction(actions.BACKEND_RESULT_SUCCESS, result.payload) ); case 'error': return store.dispatch( - createAction(actions.API_RESULT_ERROR, result.payload) + createAction(actions.BACKEND_RESULT_ERROR, result.payload) ); } } catch (err) { - store.dispatch(createAction(actions.API_ERRORED, err)); + store.dispatch(createAction(actions.BACKEND_ERRORED, err)); } }; return sock; @@ -129,7 +132,7 @@ export function apiMiddleware(options) { return undefined; } return next => action => { - if (action && action.type === actions.API_REQUEST) { + if (action && action.type === actions.BACKEND_REQUEST) { const msg = JSON.stringify( jsonrpc.request(action.id, action.query, action.params) ); diff --git a/app/store/index.js b/app/store/index.js index 272611a1..e6f5a76c 100644 --- a/app/store/index.js +++ b/app/store/index.js @@ -19,7 +19,7 @@ import createSagaMiddleware, { END } from 'redux-saga'; import { loadStore, resetStore } from './actions'; import { BACKEND_ENDPOINT } from '../config'; -import { apiMiddleware } from './api'; +import { backendMiddleware } from './backend'; import { crashReporterMiddleware } from './middlewares'; import rootReducer from './reducers'; import rootSaga from './sagas'; @@ -37,7 +37,7 @@ export function configureStore(initialState) { const sagaMiddleware = createSagaMiddleware(); const middlewares = [ crashReporterMiddleware, - apiMiddleware({ + backendMiddleware({ endpoint: BACKEND_ENDPOINT }), sagaMiddleware diff --git a/app/store/sagas.js b/app/store/sagas.js index 30cd5926..f6e1c90b 100644 --- a/app/store/sagas.js +++ b/app/store/sagas.js @@ -22,8 +22,8 @@ import { all, call, put, select, takeLatest } from 'redux-saga/effects'; import { INPUT_FILTER_DELAY } from '../config'; import accountSagas from '../modules/account/sagas'; -import { apiFetchData } from './api'; import { asyncDelay } from '../modules/core/helpers'; +import { backendFetchData } from './backend'; import coreSagas from '../modules/core/sagas'; import deviceSagas from '../modules/device/sagas'; import homeSagas from '../modules/home/sagas'; @@ -37,7 +37,7 @@ import telemetrySagas from './telemetry'; function* watchLoadStore() { yield takeLatest(actions.LOAD_STORE, function*() { try { - const newState = yield call(apiFetchData, { + const newState = yield call(backendFetchData, { query: 'app.get_state' }); if (newState['inputValues']) { @@ -70,7 +70,7 @@ function* autoSaveState() { if (savedState.storage.coreSettings) { delete savedState.storage.coreSettings; } - const result = yield call(apiFetchData, { + const result = yield call(backendFetchData, { query: 'app.save_state', params: [savedState] }); diff --git a/package.json b/package.json index d81a7125..7de2f13c 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "platformio-home", - "version": "3.3.1", + "version": "3.3.2", "description": "PlatformIO Home", "repository": { "type": "git", @@ -20,10 +20,10 @@ "dependencies": { "antd": "~3.26.20", "clipboard": "~2.0.6", - "highlight.js": "~9.18.1", + "highlight.js": "~10.5.0", "humanize": "~0.0.9", "jsonrpc-lite": "~2.2.0", - "marked": "~1.2.2", + "marked": "~1.2.7", "prop-types": "~15.7.2", "querystringify": "~2.2.0", "rc-animate": "~3.1.1", @@ -31,7 +31,7 @@ "react-dnd": "~11.1.3", "react-dnd-html5-backend": "~11.1.3", "react-dom": "~16.13.1", - "react-ga": "~3.2.0", + "react-ga": "~3.3.0", "react-redux": "~5.1.2", "react-router-dom": "~4.3.1", "redux": "~4.0.5", @@ -41,39 +41,39 @@ "url-parse": "~1.4.7" }, "devDependencies": { - "@babel/core": "~7.12.3", + "@babel/core": "~7.12.10", "@babel/plugin-proposal-class-properties": "~7.12.1", "@babel/plugin-proposal-function-bind": "~7.12.1", "@babel/plugin-proposal-object-rest-spread": "~7.12.1", - "@babel/preset-react": "~7.12.1", + "@babel/preset-react": "~7.12.10", "babel-eslint": "~10.1.0", - "babel-loader": "~8.1.0", - "babel-plugin-import": "~1.13.1", + "babel-loader": "~8.2.2", + "babel-plugin-import": "~1.13.3", "babel-plugin-redux-saga": "~1.1.2", - "copy-webpack-plugin": "~6.2.1", - "css-loader": "~5.0.0", - "eslint": "~7.12.1", - "eslint-config-prettier": "~6.15.0", + "copy-webpack-plugin": "~7.0.0", + "css-loader": "~5.0.1", + "eslint": "~7.18.0", + "eslint-config-prettier": "~7.2.0", "eslint-import-resolver-webpack": "~0.13.0", "eslint-plugin-import": "~2.22.1", - "eslint-plugin-prettier": "~3.1.4", - "eslint-plugin-react": "~7.21.5", + "eslint-plugin-prettier": "~3.3.1", + "eslint-plugin-react": "~7.22.0", "file-loader": "~6.2.0", - "html-webpack-plugin": "~4.5.0", + "html-webpack-plugin": "~4.5.1", "less": "~3.12.2", - "less-loader": "~6.0.0", - "mini-css-extract-plugin": "~1.2.1", + "less-loader": "~7.3.0", + "mini-css-extract-plugin": "~1.3.4", "obsolete-webpack-plugin": "~0.5.6", "prettier": "~1.19.1", "react-hot-loader": "~4.13.0", "redux-logger": "~3.0.6", "style-loader": "~2.0.0", "url-loader": "~4.1.1", - "webpack": "~5.3.0", + "webpack": "~5.17.0", "webpack-bundle-analyzer": "~3.9.0", "webpack-cleanup-plugin": "~0.5.1", - "webpack-cli": "~4.1.0", - "webpack-dev-server": "~3.11.0" + "webpack-cli": "~4.4.0", + "webpack-dev-server": "~3.11.2" }, "themes": { "light": { diff --git a/scripts/webpack.dev.config.js b/scripts/webpack.dev.config.js index 3dd16915..113ad30f 100755 --- a/scripts/webpack.dev.config.js +++ b/scripts/webpack.dev.config.js @@ -38,10 +38,7 @@ module.exports = { test: /\.less$/, use: [ { - loader: MiniCssExtractPlugin.loader, - options: { - hmr: process.env.NODE_ENV === 'development' - } + loader: MiniCssExtractPlugin.loader }, { loader: 'css-loader' }, { @@ -82,7 +79,6 @@ module.exports = { new MiniCssExtractPlugin({ filename: 'style.css', ignoreOrder: false, // Enable to remove warnings about conflicting order - allChunks: true }), new HtmlWebpackPlugin({ template: path.join(common.appDir, 'index.html'),