diff --git a/.eslintrc.json b/.eslintrc.json index bd23f27..84bfb0c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,6 +9,7 @@ "parserOptions": { "ecmaVersion": 13 }, + "ignorePatterns": ["test/"], "rules": { "prettier/prettier": "error", "object-curly-newline": [ @@ -24,7 +25,8 @@ "minProperties": 3 } } - ] + ], + "operator-linebreak": ["error", "after"] }, "plugins": ["prettier"] } diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6ae6a01..e7ebf5f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -141,6 +141,9 @@ eslint: script: - npm run lint:check allow_failure: true + artifacts: + reports: + codequality: gl-codequality.json build-windows: stage: build diff --git a/lib/gitlab.js b/lib/gitlab.js index 9fb769d..50d571a 100644 --- a/lib/gitlab.js +++ b/lib/gitlab.js @@ -1,6 +1,7 @@ const fetch = require('node-fetch'); -const { store } = require('./store'); const { JSDOM } = require('jsdom'); +const { store } = require('./store'); + const { DOMParser } = new JSDOM().window; const serializeAndEscapeOptions = (options) => { @@ -23,7 +24,10 @@ module.exports = { */ async get(what, options = {}, host = store.host) { if (!options || !options.access_token) { - options = { ...options, access_token: store.access_token }; + options = { + ...options, + access_token: store.access_token, + }; } return fetch(`${host}/api/v4/${what}?${serializeAndEscapeOptions(options)}`).then((res) => res.json(), @@ -31,7 +35,7 @@ module.exports = { }, async parseUrl(link) { if (!/^(?:f|ht)tps?\:\/\//.test(link)) { - link = 'https://' + link; + link = `https://${link}`; } const urlInfo = await this.fetchUrlInfo(link); @@ -70,27 +74,26 @@ module.exports = { } return object; - } else { - const result = await fetch(gitlabUrl).then((res) => res.text()); - const resultDocument = new DOMParser().parseFromString(result, 'text/html'); - - let type = 'unknown'; - - if (resultDocument.querySelector('.group-home-panel')) { - type = 'groups'; - } else if (resultDocument.querySelector('.project-home-panel')) { - type = 'projects'; - } else if (resultDocument.querySelector('.user-profile')) { - type = 'users'; - } - - return { - namespaceWithProject: path, - type, - id: null, - doc: type === 'unknown' ? resultDocument : null, - }; } + const result = await fetch(gitlabUrl).then((res) => res.text()); + const resultDocument = new DOMParser().parseFromString(result, 'text/html'); + + let type = 'unknown'; + + if (resultDocument.querySelector('.group-home-panel')) { + type = 'groups'; + } else if (resultDocument.querySelector('.project-home-panel')) { + type = 'projects'; + } else if (resultDocument.querySelector('.user-profile')) { + type = 'users'; + } + + return { + namespaceWithProject: path, + type, + id: null, + doc: type === 'unknown' ? resultDocument : null, + }; }, urlHasValidHost(url) { const allowedHosts = [String(store.host), 'gitlab.com', 'https://gitlab.com']; @@ -98,7 +101,7 @@ module.exports = { return allowedHosts.some((host) => url.startsWith(host)); }, commentToNoteableUrl(comment) { - let basePath = `projects/${comment.project_id}`; + const basePath = `projects/${comment.project_id}`; switch (comment.note.noteable_type) { case 'MergeRequest': return `${basePath}/merge_requests/${comment.note.noteable_iid}`; diff --git a/lib/store.js b/lib/store.js index ad5d15d..a05c4ea 100644 --- a/lib/store.js +++ b/lib/store.js @@ -16,11 +16,10 @@ const store = new ElectronStore(); const proxy = new Proxy(store, { get(target, key) { - if (target.get(key) == undefined) { + if (target.get(key) === undefined) { return defaults[key]; - } else { - return target.get(key); } + return target.get(key); }, set(target, key, value) { target.set(key, value); diff --git a/lib/url-parsers/_base.js b/lib/url-parsers/_base.js index 3ac5304..efae027 100644 --- a/lib/url-parsers/_base.js +++ b/lib/url-parsers/_base.js @@ -5,7 +5,7 @@ module.exports = class BaseParser { this.urlInfo = urlInfo; } - static check(type) { + static check() { throw Error(`static ${this.constructor.name}#check(type) is not implemented`); } diff --git a/lib/url-parsers/group.js b/lib/url-parsers/group.js index c95fd4f..c3db1dd 100644 --- a/lib/url-parsers/group.js +++ b/lib/url-parsers/group.js @@ -22,9 +22,9 @@ module.exports = class GroupParser extends BaseParser { avatar_url: group.avatar_url, }; - if (group.full_name.indexOf(' / ' + group.name) != -1) { - groupObject.parent_name = group.full_name.replace(' / ' + group.name, ''); - groupObject.parent_url = group.web_url.replace('/' + group.path, ''); + if (group.full_name.indexOf(` / ${group.name}`) !== -1) { + groupObject.parent_name = group.full_name.replace(` / ${group.name}`, ''); + groupObject.parent_url = group.web_url.replace(`/${group.path}`, ''); } return groupObject; diff --git a/lib/url-parsers/unknown.js b/lib/url-parsers/unknown.js index dc42300..d0e53c4 100644 --- a/lib/url-parsers/unknown.js +++ b/lib/url-parsers/unknown.js @@ -9,16 +9,16 @@ module.exports = class UnknownParser extends BaseParser { async parse() { const { doc } = this.urlInfo; - let titleArray = doc.querySelector('title').text.split(' · '); - let unknownObject = { + const titleArray = doc.querySelector('title').text.split(' · '); + const unknownObject = { title: titleArray[0], }; if (doc.querySelector('.context-header a')) { unknownObject.parent_url = store.host + doc.querySelector('.context-header a').getAttribute('href'); - if (titleArray.length == 3) { + if (titleArray.length === 3) { unknownObject.parent_name = titleArray[1]; - } else if (titleArray.length == 4) { + } else if (titleArray.length === 4) { unknownObject.parent_name = titleArray[2]; } } diff --git a/myApp.js b/myApp.js index a493e1c..967fb6b 100644 --- a/myApp.js +++ b/myApp.js @@ -1,5 +1,11 @@ +/* eslint-env es2021 */ const { menubar } = require('menubar'); const { Menu, Notification, shell, ipcMain, app } = require('electron'); +const fetch = require('node-fetch'); +const { URL } = require('url'); +const ua = require('universal-analytics'); +const jsdom = require('jsdom'); +const nodeCrypto = require('crypto'); const { escapeHtml, escapeQuotes, escapeSingleQuotes, sha256hex } = require('./lib/util'); const GitLab = require('./lib/gitlab'); const { @@ -42,20 +48,16 @@ const { sort, state, } = require('./src/filter-text'); -const fetch = require('node-fetch'); -let { store, deleteFromStore } = require('./lib/store'); +const { store, deleteFromStore } = require('./lib/store'); const BrowserHistory = require('./lib/browser-history'); -const { URL } = require('url'); -const ua = require('universal-analytics'); -const jsdom = require('jsdom'); -const { JSDOM } = jsdom; -const nodeCrypto = require('crypto'); const processInfo = require('./lib/process-info'); -const version = require('./package.json').version; +const { version } = require('./package.json').version; const CommandPalette = require('./src/command-palette'); + +const { JSDOM } = jsdom; let commandPalette; global.DOMParser = new JSDOM().window.DOMParser; -process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'; +process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true'; let visitor; if (store.analytics) { @@ -70,13 +72,13 @@ let lastEventId; let lastTodoId = -1; let recentProjectCommits = []; let currentProjectCommit; -let numberOfRecentlyVisited = 3; -let numberOfFavoriteProjects = 5; -let numberOfRecentComments = 3; -let numberOfIssues = 10; -let numberOfMRs = 10; -let numberOfTodos = 10; -let numberOfComments = 5; +const numberOfRecentlyVisited = 3; +const numberOfFavoriteProjects = 5; +const numberOfRecentComments = 3; +const numberOfIssues = 10; +const numberOfMRs = 10; +const numberOfTodos = 10; +const numberOfComments = 5; let activeIssuesQueryOption = 'assigned_to_me'; let activeIssuesStateOption = 'opened'; let activeIssuesSortOption = 'created_at'; @@ -84,11 +86,11 @@ let activeMRsQueryOption = 'assigned_to_me'; let activeMRsStateOption = 'opened'; let activeMRsSortOption = 'created_at'; let runningPipelineSubscriptions = []; -let timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; +const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; let isOnSubPage = false; -//Anti rebound variables -let delay = 2000; +// Anti rebound variables +const delay = 2000; let lastUserExecution = 0; let lastRecentlyVisitedExecution = 0; let lastLastCommitsExecution = 0; @@ -105,7 +107,7 @@ let challenge = ''; const mb = menubar({ showDockIcon: store.show_dock_icon, showOnAllWorkspaces: false, - icon: __dirname + '/assets/gitlabTemplate.png', + icon: `${__dirname}/assets/gitlabTemplate.png`, preloadWindow: true, browserWindow: { width: 550, @@ -113,7 +115,7 @@ const mb = menubar({ minWidth: 265, minHeight: 300, webPreferences: { - preload: __dirname + '/preload.js', + preload: `${__dirname}/preload.js`, nodeIntegration: process.env.NODE_ENV === 'test', contextIsolation: process.env.NODE_ENV !== 'test', enableRemoteModule: process.env.NODE_ENV === 'test', @@ -129,23 +131,17 @@ ipcMain.on('detail-page', (event, arg) => { mb.window.webContents.executeJavaScript( 'document.getElementById("detail-content").innerHTML = ""', ); - if (arg.page == 'Project') { + if (arg.page === 'Project') { if (store.analytics) { visitor.pageview('/project').send(); } mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes( - '
Commits
', - ) + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + `
Commits
`, + )}"`, ); setupEmptyProjectPage(); - let project = JSON.parse(arg.object); + const project = JSON.parse(arg.object); currentProject = project; displayProjectPage(project); getProjectCommits(project); @@ -156,292 +152,82 @@ ipcMain.on('detail-page', (event, arg) => { 'document.getElementById("detail-header-content").classList.remove("empty")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-header-content").innerHTML = "' + arg.page + '"', + `document.getElementById("detail-header-content").innerHTML = "${arg.page}"`, ); - if (arg.page == 'Issues') { + if (arg.page === 'Issues') { if (store.analytics) { visitor.pageview('/my-issues').send(); } - let issuesQuerySelect = - '
Assigned
'; - let issuesStateSelect = - '
Open
'; - let issuesSortSelect = - '
Sort by recently created
'; + const issuesQuerySelect = `
Assigned
`; + const issuesStateSelect = `
Open
`; + const issuesSortSelect = `
Sort by recently created
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - escapeQuotes('
') + - escapeQuotes(issuesQuerySelect) + - escapeQuotes(issuesStateSelect) + - escapeQuotes(issuesSortSelect) + - '
' + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}${escapeQuotes('
')}${escapeQuotes( + issuesQuerySelect, + )}${escapeQuotes(issuesStateSelect)}${escapeQuotes(issuesSortSelect)}
"`, ); mb.window.webContents.executeJavaScript( 'document.getElementById("detail-headline").classList.add("with-overflow")', ); displaySkeleton(numberOfIssues); getIssues(); - } else if (arg.page == 'Merge requests') { + } else if (arg.page === 'Merge requests') { if (store.analytics) { visitor.pageview('/my-merge-requests').send(); } - let mrsQuerySelect = - '
Assigned
'; - if (store.plan != 'free') { - mrsQuerySelect += - ''; + let mrsQuerySelect = `
Assigned
`; + if (store.plan !== 'free') { + mrsQuerySelect += ``; } - mrsQuerySelect += - '
'; - let mrsStateSelect = - '
Open
'; - let mrsSortSelect = - '
Sort by recently created
'; + mrsQuerySelect += `
`; + const mrsStateSelect = `
Open
`; + const mrsSortSelect = `
Sort by recently created
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - escapeQuotes('
') + - escapeQuotes(mrsQuerySelect) + - escapeQuotes(mrsStateSelect) + - escapeQuotes(mrsSortSelect) + - '
' + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}${escapeQuotes('
')}${escapeQuotes( + mrsQuerySelect, + )}${escapeQuotes(mrsStateSelect)}${escapeQuotes(mrsSortSelect)}
"`, ); mb.window.webContents.executeJavaScript( 'document.getElementById("detail-headline").classList.add("with-overflow")', ); displaySkeleton(numberOfMRs); getMRs(); - } else if (arg.page == 'To-Do list') { + } else if (arg.page === 'To-Do list') { if (store.analytics) { visitor.pageview('/my-to-do-list').send(); } mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - '' + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}"`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-header-content").innerHTML = "' + - arg.page + - escapeQuotes('') + - '"', + `document.getElementById("detail-header-content").innerHTML = "${arg.page}${escapeQuotes( + '`, + )}"`, ); displaySkeleton(numberOfTodos); getTodos(); - } else if (arg.page == 'Recently viewed') { + } else if (arg.page === 'Recently viewed') { if (store.analytics) { visitor.pageview('/my-history').send(); } displaySkeleton(numberOfRecentlyVisited); getMoreRecentlyVisited(); - } else if (arg.page == 'Comments') { + } else if (arg.page === 'Comments') { if (store.analytics) { visitor.pageview('/my-comments').send(); } mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}"`, ); displaySkeleton(numberOfComments); getMoreRecentComments(); @@ -457,7 +243,7 @@ ipcMain.on('sub-detail-page', (event, arg) => { let allChecked = ''; let openChecked = ' checked'; let allChanged = ''; - let project = JSON.parse(arg.project); + const project = JSON.parse(arg.project); mb.window.webContents.executeJavaScript( 'document.getElementById("sub-detail-headline").innerHTML = ""', ); @@ -468,332 +254,76 @@ ipcMain.on('sub-detail-page', (event, arg) => { 'document.getElementById("sub-detail-header-content").classList.remove("empty")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("sub-detail-header-content").innerHTML = "' + arg.page + '"', + `document.getElementById("sub-detail-header-content").innerHTML = "${arg.page}"`, ); - if (arg.page == 'Issues') { + if (arg.page === 'Issues') { if (store.analytics) { visitor.pageview('/project/issues').send(); } - if (arg.all == true) { + if (arg.all === true) { activeIssuesStateOption = 'all'; activeState = 'All'; allChecked = ' checked'; openChecked = ''; allChanged = ' changed'; } - let issuesQuerySelect = - '
All
'; - let issuesStateSelect = - '
' + - activeState + - '
'; - let issuesSortSelect = - '
Sort by recently created
'; + const issuesQuerySelect = `
All
`; + const issuesStateSelect = `
${activeState}
`; + const issuesSortSelect = `
Sort by recently created
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("sub-detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - escapeQuotes('
') + - escapeQuotes(issuesQuerySelect) + - escapeQuotes(issuesStateSelect) + - escapeQuotes(issuesSortSelect) + - '
' + - '"', + `document.getElementById("sub-detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}${escapeQuotes('
')}${escapeQuotes( + issuesQuerySelect, + )}${escapeQuotes(issuesStateSelect)}${escapeQuotes(issuesSortSelect)}
"`, ); mb.window.webContents.executeJavaScript( 'document.getElementById("sub-detail-headline").classList.add("with-overflow")', ); displaySkeleton(numberOfIssues, undefined, 'sub-detail-content'); getIssues( - store.host + - '/api/v4/projects/' + - project.id + - '/issues?scope=all&state=' + - activeIssuesStateOption + - '&order_by=created_at&per_page=' + - numberOfIssues + - '&access_token=' + - store.access_token, + `${store.host}/api/v4/projects/${project.id}/issues?scope=all&state=${activeIssuesStateOption}&order_by=created_at&per_page=${numberOfIssues}&access_token=${store.access_token}`, 'sub-detail-content', ); - } else if (arg.page == 'Merge Requests') { + } else if (arg.page === 'Merge Requests') { if (store.analytics) { visitor.pageview('/project/merge-requests').send(); } - if (arg.all == true) { + if (arg.all === true) { activeMRsStateOption = 'all'; activeState = 'All'; allChecked = ' checked'; openChecked = ''; allChanged = ' changed'; } - let mrsQuerySelect = - '
All
'; - let mrsStateSelect = - '
' + - activeState + - '
'; - let mrsSortSelect = - '
Sort by recently created
'; + const mrsQuerySelect = `
All
`; + const mrsStateSelect = `
${activeState}
`; + const mrsSortSelect = `
Sort by recently created
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("sub-detail-headline").innerHTML = "' + - escapeQuotes('') + - arg.page + - escapeQuotes('
') + - escapeQuotes(mrsQuerySelect) + - escapeQuotes(mrsStateSelect) + - escapeQuotes(mrsSortSelect) + - '
' + - '"', + `document.getElementById("sub-detail-headline").innerHTML = "${escapeQuotes( + '', + )}${arg.page}${escapeQuotes('
')}${escapeQuotes( + mrsQuerySelect, + )}${escapeQuotes(mrsStateSelect)}${escapeQuotes(mrsSortSelect)}
"`, ); mb.window.webContents.executeJavaScript( 'document.getElementById("sub-detail-headline").classList.add("with-overflow")', ); displaySkeleton(numberOfMRs, undefined, 'sub-detail-content'); getMRs( - store.host + - '/api/v4/projects/' + - project.id + - '/merge_requests?scope=all&state=' + - activeMRsStateOption + - '&order_by=created_at&per_page=' + - numberOfMRs + - '&access_token=' + - store.access_token, + `${store.host}/api/v4/projects/${project.id}/merge_requests?scope=all&state=${activeMRsStateOption}&order_by=created_at&per_page=${numberOfMRs}&access_token=${store.access_token}`, 'sub-detail-content', ); } }); -ipcMain.on('back-to-detail-page', (event, arg) => { +ipcMain.on('back-to-detail-page', () => { isOnSubPage = false; activeIssuesQueryOption = 'assigned_to_me'; activeMRsQueryOption = 'assigned_to_me'; }); -ipcMain.on('go-to-overview', (event, arg) => { +ipcMain.on('go-to-overview', () => { if (store.analytics) { visitor.pageview('/').send(); } @@ -822,7 +352,7 @@ ipcMain.on('go-to-overview', (event, arg) => { currentProject = null; }); -ipcMain.on('go-to-settings', (event, arg) => { +ipcMain.on('go-to-settings', () => { openSettingsPage(); }); @@ -830,21 +360,21 @@ ipcMain.on('switch-issues', (event, arg) => { if (store.analytics) { visitor.event('Switch issues', arg.type, arg.label).send(); } - let url = store.host + '/api/v4/'; + let url = `${store.host}/api/v4/`; let id = 'detail-content'; if (isOnSubPage && currentProject) { - url += 'projects/' + currentProject.id + '/'; + url += `projects/${currentProject.id}/`; id = 'sub-detail-content'; } - if (arg.type == 'query' && arg.label != activeIssuesQueryOption) { + if (arg.type === 'query' && arg.label !== activeIssuesQueryOption) { activeIssuesQueryOption = arg.label; displaySkeleton(numberOfIssues, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("issues-query-active").innerHTML = "' + arg.text + '"', + `document.getElementById("issues-query-active").innerHTML = "${arg.text}"`, ); if ( - (isOnSubPage == false && arg.label != 'assigned_to_me') || - (isOnSubPage == true && arg.label != 'all') + (isOnSubPage === false && arg.label !== 'assigned_to_me') || + (isOnSubPage === true && arg.label !== 'all') ) { mb.window.webContents.executeJavaScript( 'document.getElementById("issues-query-active").classList.add("changed")', @@ -854,13 +384,13 @@ ipcMain.on('switch-issues', (event, arg) => { 'document.getElementById("issues-query-active").classList.remove("changed")', ); } - } else if (arg.type == 'state' && arg.label != activeIssuesStateOption) { + } else if (arg.type === 'state' && arg.label !== activeIssuesStateOption) { activeIssuesStateOption = arg.label; displaySkeleton(numberOfIssues, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("issues-state-active").innerHTML = "' + arg.text + '"', + `document.getElementById("issues-state-active").innerHTML = "${arg.text}"`, ); - if (arg.label != 'opened') { + if (arg.label !== 'opened') { mb.window.webContents.executeJavaScript( 'document.getElementById("issues-state-active").classList.add("changed")', ); @@ -869,13 +399,13 @@ ipcMain.on('switch-issues', (event, arg) => { 'document.getElementById("issues-state-active").classList.remove("changed")', ); } - } else if (arg.type == 'sort' && arg.label != activeIssuesSortOption) { + } else if (arg.type === 'sort' && arg.label !== activeIssuesSortOption) { activeIssuesSortOption = arg.label; displaySkeleton(numberOfIssues, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("issues-sort-active").innerHTML = "' + arg.text + '"', + `document.getElementById("issues-sort-active").innerHTML = "${arg.text}"`, ); - if (arg.label != 'created_at') { + if (arg.label !== 'created_at') { mb.window.webContents.executeJavaScript( 'document.getElementById("issues-sort-active").classList.add("changed")', ); @@ -885,17 +415,7 @@ ipcMain.on('switch-issues', (event, arg) => { ); } } - url += - 'issues?scope=' + - activeIssuesQueryOption + - '&state=' + - activeIssuesStateOption + - '&order_by=' + - activeIssuesSortOption + - '&per_page=' + - numberOfIssues + - '&access_token=' + - store.access_token; + url += `issues?scope=${activeIssuesQueryOption}&state=${activeIssuesStateOption}&order_by=${activeIssuesSortOption}&per_page=${numberOfIssues}&access_token=${store.access_token}`; getIssues(url, id); }); @@ -903,19 +423,19 @@ ipcMain.on('switch-mrs', (event, arg) => { if (store.analytics) { visitor.event('Switch merge requests', arg.type, arg.label).send(); } - let url = store.host + '/api/v4/'; + let url = `${store.host}/api/v4/`; let id = 'detail-content'; if (isOnSubPage && currentProject) { - url += 'projects/' + currentProject.id + '/'; + url += `projects/${currentProject.id}/`; id = 'sub-detail-content'; } - if (arg.type == 'query' && arg.label != activeMRsQueryOption) { + if (arg.type === 'query' && arg.label !== activeMRsQueryOption) { activeMRsQueryOption = arg.label; displaySkeleton(numberOfMRs, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("mrs-query-active").innerHTML = "' + arg.text + '"', + `document.getElementById("mrs-query-active").innerHTML = "${arg.text}"`, ); - if (arg.label != 'all') { + if (arg.label !== 'all') { mb.window.webContents.executeJavaScript( 'document.getElementById("mrs-query-active").classList.add("changed")', ); @@ -925,13 +445,13 @@ ipcMain.on('switch-mrs', (event, arg) => { ); } } - if (arg.type == 'state' && arg.label != activeMRsStateOption) { + if (arg.type === 'state' && arg.label !== activeMRsStateOption) { activeMRsStateOption = arg.label; displaySkeleton(numberOfMRs, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("mrs-state-active").innerHTML = "' + arg.text + '"', + `document.getElementById("mrs-state-active").innerHTML = "${arg.text}"`, ); - if (arg.label != 'opened') { + if (arg.label !== 'opened') { mb.window.webContents.executeJavaScript( 'document.getElementById("mrs-state-active").classList.add("changed")', ); @@ -940,13 +460,13 @@ ipcMain.on('switch-mrs', (event, arg) => { 'document.getElementById("mrs-state-active").classList.remove("changed")', ); } - } else if (arg.type == 'sort' && arg.label != activeMRsSortOption) { + } else if (arg.type === 'sort' && arg.label !== activeMRsSortOption) { activeMRsSortOption = arg.label; displaySkeleton(numberOfMRs, undefined, id); mb.window.webContents.executeJavaScript( - 'document.getElementById("mrs-sort-active").innerHTML = "' + arg.text + '"', + `document.getElementById("mrs-sort-active").innerHTML = "${arg.text}"`, ); - if (arg.label != 'created_at') { + if (arg.label !== 'created_at') { mb.window.webContents.executeJavaScript( 'document.getElementById("mrs-sort-active").classList.add("changed")', ); @@ -957,24 +477,16 @@ ipcMain.on('switch-mrs', (event, arg) => { } } url += 'merge_requests?scope='; - if (activeMRsQueryOption == 'assigned_to_me' || activeMRsQueryOption == 'created_by_me') { + if (activeMRsQueryOption === 'assigned_to_me' || activeMRsQueryOption === 'created_by_me') { url += activeMRsQueryOption; - } else if (activeMRsQueryOption == 'approved_by_me') { - url += 'all&approved_by_ids[]=' + store.user_id; - } else if (activeMRsQueryOption == 'review_requests_for_me') { - url += 'all&reviewer_id=' + store.user_id; - } else if (activeMRsQueryOption == 'approval_rule_for_me') { - url += 'all&approver_ids[]=' + store.user_id; + } else if (activeMRsQueryOption === 'approved_by_me') { + url += `all&approved_by_ids[]=${store.user_id}`; + } else if (activeMRsQueryOption === 'review_requests_for_me') { + url += `all&reviewer_id=${store.user_id}`; + } else if (activeMRsQueryOption === 'approval_rule_for_me') { + url += `all&approver_ids[]=${store.user_id}`; } - url += - '&state=' + - activeMRsStateOption + - '&order_by=' + - activeMRsSortOption + - '&per_page=' + - numberOfMRs + - '&access_token=' + - store.access_token; + url += `&state=${activeMRsStateOption}&order_by=${activeMRsSortOption}&per_page=${numberOfMRs}&access_token=${store.access_token}`; getMRs(url, id); }); @@ -985,16 +497,16 @@ ipcMain.on('switch-page', (event, arg) => { } else { id = 'detail-content'; } - if (arg.type == 'Todos') { + if (arg.type === 'Todos') { displaySkeleton(numberOfTodos, true); getTodos(arg.url); - } else if (arg.type == 'Issues') { + } else if (arg.type === 'Issues') { displaySkeleton(numberOfIssues, true, id); getIssues(arg.url, id); - } else if (arg.type == 'MRs') { + } else if (arg.type === 'MRs') { displaySkeleton(numberOfMRs, true, id); getMRs(arg.url, id); - } else if (arg.type == 'Comments') { + } else if (arg.type === 'Comments') { displaySkeleton(numberOfComments, true); getMoreRecentComments(arg.url); } @@ -1016,13 +528,11 @@ ipcMain.on('change-commit', (event, arg) => { } } mb.window.webContents.executeJavaScript( - 'document.getElementById("pipeline").innerHTML = "' + - escapeQuotes( - '
', - ) + - '"', + `document.getElementById("pipeline").innerHTML = "${escapeQuotes( + '
', + )}"`, ); - let nextCommit = changeCommit(arg, recentCommits, currentCommit); + const nextCommit = changeCommit(arg, recentCommits, currentCommit); currentCommit = nextCommit; getCommitDetails(nextCommit.project_id, nextCommit.push_data.commit_to, nextCommit.index); }); @@ -1036,13 +546,11 @@ ipcMain.on('change-project-commit', (event, arg) => { } } mb.window.webContents.executeJavaScript( - 'document.getElementById("project-pipeline").innerHTML = "' + - escapeQuotes( - '
', - ) + - '"', + `document.getElementById("project-pipeline").innerHTML = "${escapeQuotes( + '
', + )}"`, ); - let nextCommit = changeCommit(arg, recentProjectCommits, currentProjectCommit); + const nextCommit = changeCommit(arg, recentProjectCommits, currentProjectCommit); currentProjectCommit = nextCommit; getProjectCommitDetails(currentProject.id, nextCommit.id, nextCommit.index); }); @@ -1068,15 +576,15 @@ ipcMain.on('add-shortcut', (event, arg) => { addShortcut(arg); }); -ipcMain.on('start-bookmark-dialog', (event, arg) => { +ipcMain.on('start-bookmark-dialog', () => { startBookmarkDialog(); }); -ipcMain.on('start-project-dialog', (event, arg) => { +ipcMain.on('start-project-dialog', () => { startProjectDialog(); }); -ipcMain.on('start-shortcut-dialog', (event, arg) => { +ipcMain.on('start-shortcut-dialog', () => { startShortcutDialog(); }); @@ -1085,7 +593,7 @@ ipcMain.on('delete-bookmark', (event, hashedUrl) => { visitor.event('Delete bookmark').send(); } if (store.bookmarks && store.bookmarks.length > 0) { - let newBookmarks = store.bookmarks.filter( + const newBookmarks = store.bookmarks.filter( (bookmark) => sha256hex(bookmark.web_url) !== hashedUrl, ); store.bookmarks = newBookmarks; @@ -1097,12 +605,10 @@ ipcMain.on('delete-project', (event, arg) => { if (store.analytics) { visitor.event('Delete project').send(); } - let projects = store['favorite-projects']; - let newProjects = projects.filter((project) => { - return project.id != arg; - }); + const projects = store['favorite-projects']; + const newProjects = projects.filter((project) => project.id !== arg); store['favorite-projects'] = newProjects; - //TODO Implement better way to refresh view after deleting project + // TODO Implement better way to refresh view after deleting project displayUsersProjects(); openSettingsPage(); }); @@ -1143,15 +649,19 @@ ipcMain.on('change-show-dock-icon', (event, arg) => { }); } else { app.dock.hide(); - app.focus({ steal: true }); + app.focus({ + steal: true, + }); setTimeout(() => { - app.focus({ steal: true }); + app.focus({ + steal: true, + }); mb.window.setAlwaysOnTop(store.keep_visible); }, 200); } }); -ipcMain.on('start-login', (event, arg) => { +ipcMain.on('start-login', () => { startLogin(); }); @@ -1159,7 +669,7 @@ ipcMain.on('start-manual-login', (event, arg) => { saveUser(arg.access_token, arg.host); }); -ipcMain.on('logout', (event, arg) => { +ipcMain.on('logout', () => { if (store.analytics) { visitor.event('Log out', true).send(); } @@ -1173,12 +683,12 @@ mb.on('ready', () => { if (store.access_token && store.user_id && store.username) { mb.on('after-create-window', () => { - //mb.window.webContents.openDevTools(); + // mb.window.webContents.openDevTools(); mb.showWindow(); changeTheme(store.theme, false); - //Preloading content + // Preloading content getUser(); getLastTodo(); getUsersPlan(); @@ -1188,8 +698,8 @@ if (store.access_token && store.user_id && store.username) { displayUsersProjects(); getBookmarks(); - //Regularly relaoading content - setInterval(function () { + // Regularly relaoading content + setInterval(() => { getLastEvent(); getLastTodo(); }, 10000); @@ -1199,7 +709,9 @@ if (store.access_token && store.user_id && store.username) { visitor.event('Visit external link', true).send(); } shell.openExternal(url); - return { action: 'deny' }; + return { + action: 'deny', + }; }); }); @@ -1215,7 +727,7 @@ if (store.access_token && store.user_id && store.username) { }); } else { mb.on('after-create-window', () => { - //mb.window.webContents.openDevTools() + // mb.window.webContents.openDevTools() mb.window.loadURL(`file://${__dirname}/login.html`).then(() => { changeTheme(store.theme, false); mb.showWindow(); @@ -1284,6 +796,7 @@ function setupCommandPalette() { } function openSettingsPage() { + // eslint-disable-next-line no-underscore-dangle if (!mb._isVisible) { mb.showWindow(); } @@ -1301,51 +814,28 @@ function openSettingsPage() { ); mb.window.webContents.executeJavaScript('document.getElementById("detail-view").style.left = 0'); mb.window.webContents.executeJavaScript('document.body.style.overflow = "hidden"'); - let lightString = "'light'"; - let darkString = "'dark'"; + const lightString = "'light'"; + const darkString = "'dark'"; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes('Theme') + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + 'Theme', + )}"`, ); let settingsString = ''; - let theme = - '
Light
Dark
'; + const theme = `
Light
Dark
`; if (store.user_id && store.username) { - let projects = store['favorite-projects']; + const projects = store['favorite-projects']; let favoriteProjects = '
Favorite projects
'; + favoriteProjects += ``; let preferences = '
Preferences
'; preferences += '
Command Palette shortcuts

To learn more about which keyboard shortcuts you can configure, visit the Electron Accelerator page.

'; if (store.shortcuts) { shortcut += '
    '; - store.shortcuts.forEach((keys, index) => { - shortcut += - '
  • ' + - keys + - '
    ' + - removeIcon + - '
  • '; + store.shortcuts.forEach((keys) => { + shortcut += `
  • ${keys}
    ${removeIcon}
  • `; }); - shortcut += - '
'; + shortcut += ``; } shortcut += '
'; let analyticsString = '
Analytics
'; analyticsString += 'To better understand how you make use of GitDock features to navigate around your issues, MRs, and other areas, we would love to collect insights about your usage. All data is 100% anonymous and we do not track the specific content (projects, issues...) you are interacting with, only which kind of areas you are using.
'; - analyticsString += - '
'; - let logout = + analyticsString += `
`; + const logout = '
User
'; settingsString = theme + favoriteProjects + preferences + shortcut + analyticsString + logout; } else { settingsString = theme; } mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + - escapeQuotes(settingsString) + - '
' + + `document.getElementById("detail-content").innerHTML = "${escapeQuotes(settingsString)}` + '"', ); mb.window.webContents.executeJavaScript( @@ -1412,7 +889,7 @@ function openSettingsPage() { 'document.getElementById("dark-mode").classList.remove("active")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("' + store.theme + '-mode").classList.add("active")', + `document.getElementById("${store.theme}-mode").classList.add("active")`, ); } @@ -1420,28 +897,19 @@ function repaintShortcuts() { let shortcut = '

To learn more about which keyboard shortcuts you can configure, visit the Electron Accelerator page.

'; + shortcut += ``; } shortcut += ''; mb.window.webContents.executeJavaScript( - 'document.getElementById("shortcut").innerHTML = "' + escapeQuotes(shortcut) + '"', + `document.getElementById("shortcut").innerHTML = "${escapeQuotes(shortcut)}"`, ); } function openAboutPage() { + // eslint-disable-next-line no-underscore-dangle if (!mb._isVisible) { mb.showWindow(); } @@ -1462,13 +930,17 @@ function openAboutPage() { mb.window.webContents.executeJavaScript( 'document.getElementById("detail-headline").innerHTML = "About GitDock ⚓️"', ); - let aboutString = `

GitDock is a MacOS/Windows/Linux app that displays all your GitLab activities in one place. Instead of the GitLab typical project- or group-centric approach, it collects all your information from a user-centric perspective.

`; - aboutString += `

If you want to learn more about why we built this app, you can have a look at our blog post.

`; - aboutString += `

We use issues to collect bugs, feature requests, and more. You can browse through existing issues. To report a bug, suggest an improvement, or propose a feature, please create a new issue if there is not already an issue for it.

`; - aboutString += `

If you are thinking about contributing directly, check out our contribution guidelines.

`; - aboutString += '

Version ' + version + '

'; + let aboutString = + '

GitDock is a MacOS/Windows/Linux app that displays all your GitLab activities in one place. Instead of the GitLab typical project- or group-centric approach, it collects all your information from a user-centric perspective.

'; + aboutString += + '

If you want to learn more about why we built this app, you can have a look at our blog post.

'; + aboutString += + '

We use issues to collect bugs, feature requests, and more. You can browse through existing issues. To report a bug, suggest an improvement, or propose a feature, please create a new issue if there is not already an issue for it.

'; + aboutString += + '

If you are thinking about contributing directly, check out our contribution guidelines.

'; + aboutString += `

Version ${version}

`; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + aboutString + '"', + `document.getElementById("detail-content").innerHTML = "${aboutString}"`, ); } @@ -1476,17 +948,14 @@ async function startLogin() { verifier = base64URLEncode(nodeCrypto.randomBytes(32)); challenge = base64URLEncode(sha256(verifier)); await mb.window.loadURL( - store.host + - '/oauth/authorize?client_id=2ab9d5c2290a3efcacbd5fc99ef469b7767ef5656cfc09376944b03ef4a8acee&redirect_uri=https://gitdock.org/login-screen/&response_type=code&state=test&scope=read_api&code_challenge=' + - challenge + - '&code_challenge_method=S256', + `${store.host}/oauth/authorize?client_id=2ab9d5c2290a3efcacbd5fc99ef469b7767ef5656cfc09376944b03ef4a8acee&redirect_uri=https://gitdock.org/login-screen/&response_type=code&state=test&scope=read_api&code_challenge=${challenge}&code_challenge_method=S256`, ); mb.window.on('page-title-updated', handleLogin); mb.showWindow(); } function handleLogin() { - if (mb.window.webContents.getURL().indexOf('?code=') != '-1') { + if (mb.window.webContents.getURL().indexOf('?code=') !== '-1') { const code = mb.window.webContents.getURL().split('?code=')[1].replace('&state=test', ''); fetch('https://gitlab.com/oauth/token', { method: 'POST', @@ -1496,20 +965,16 @@ function handleLogin() { }, body: JSON.stringify({ client_id: '2ab9d5c2290a3efcacbd5fc99ef469b7767ef5656cfc09376944b03ef4a8acee', - code: code, + code, grant_type: 'authorization_code', redirect_uri: 'https://gitdock.org/login-screen/', code_verifier: verifier, }), }) - .then((result) => { - return result.json(); - }) + .then((result) => result.json()) .then((result) => { saveUser(result.access_token); }); - } else { - console.log('not loaded'); } } @@ -1523,7 +988,13 @@ function sha256(buffer) { async function saveUser(temp_access_token, url = store.host) { try { - const result = await GitLab.get('user', { access_token: temp_access_token }, url); + const result = await GitLab.get( + 'user', + { + access_token: temp_access_token, + }, + url, + ); if (result && result.id && result.username) { store.access_token = temp_access_token; store.user_id = result.id; @@ -1536,7 +1007,7 @@ async function saveUser(temp_access_token, url = store.host) { mb.window.removeListener('page-title-updated', handleLogin); await mb.window .loadURL(`file://${__dirname}/index.html`) - .then((result) => { + .then(() => { getUser(); displayUsersProjects(); getBookmarks(); @@ -1545,10 +1016,12 @@ async function saveUser(temp_access_token, url = store.host) { getRecentComments(); mb.window.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); - return { action: 'deny' }; + return { + action: 'deny', + }; }); }) - .catch((error) => { + .catch(() => { getUser(); displayUsersProjects(); getBookmarks(); @@ -1557,16 +1030,14 @@ async function saveUser(temp_access_token, url = store.host) { getRecentComments(); mb.window.webContents.setWindowOpenHandler(({ url }) => { shell.openExternal(url); - return { action: 'deny' }; + return { + action: 'deny', + }; }); }); }); - } else { - console.log('not valid'); } - } catch { - console.log('not valid'); - } + } catch {} } async function getUser() { @@ -1578,30 +1049,23 @@ async function getUser() { let avatar_url; if (user.avatar_url) { avatar_url = new URL(user.avatar_url); - if (avatar_url.host != 'secure.gravatar.com') { + if (avatar_url.host !== 'secure.gravatar.com') { avatar_url.href += '?width=64'; } } - let userString = - '
' + - escapeHtml(user.name) + - '@' + - escapeHtml(user.username) + - '
'; + const userString = `
${escapeHtml( + user.name, + )}@${escapeHtml(user.username)}
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("user").innerHTML = "' + escapeQuotes(userString) + '"', + `document.getElementById("user").innerHTML = "${escapeQuotes(userString)}"`, ); lastUserExecution = Date.now(); lastUserExecutionFinished = true; } else { logout(); } - } else { - console.log('User running or not out of delay'); } } @@ -1630,8 +1094,9 @@ async function getLastEvent() { } async function getLastTodo() { - const [todo] = await GitLab.get('todos', { per_page: 1 }); - + const [todo] = await GitLab.get('todos', { + per_page: 1, + }); if (lastTodoId !== todo.id) { if (lastTodoId !== -1 && Date.parse(todo.created_at) > Date.now() - 20000) { const todoNotification = new Notification({ @@ -1652,14 +1117,17 @@ async function getLastCommits(count = 20) { if (lastLastCommitsExecutionFinished && lastLastCommitsExecution + delay < Date.now()) { lastLastCommitsExecutionFinished = false; - const commits = await GitLab.get('events', { action: 'pushed', per_page: count }); + const commits = await GitLab.get('events', { + action: 'pushed', + per_page: count, + }); if (commits && commits.length > 0) { lastEventId = commits[0].id; getLastPipelines(commits); - let committedArray = commits.filter((commit) => { + const committedArray = commits.filter((commit) => { return ( - commit.action_name == 'pushed to' || - (commit.action_name == 'pushed new' && + commit.action_name === 'pushed to' || + (commit.action_name === 'pushed new' && commit.push_data.commit_to && commit.push_data.commit_count > 0) ); @@ -1673,9 +1141,9 @@ async function getLastCommits(count = 20) { 'document.getElementById("commits-pagination").innerHTML = ""', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("pipeline").innerHTML = "' + - escapeQuotes('

You haven't pushed any commits yet.

') + - '"', + `document.getElementById("pipeline").innerHTML = "${escapeQuotes( + '

You haven't pushed any commits yet.

', + )}"`, ); } } else { @@ -1683,9 +1151,9 @@ async function getLastCommits(count = 20) { 'document.getElementById("commits-pagination").innerHTML = ""', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("pipeline").innerHTML = "' + - escapeQuotes('

You haven't pushed any commits yet.

') + - '"', + `document.getElementById("pipeline").innerHTML = "${escapeQuotes( + '

You haven't pushed any commits yet.

', + )}"`, ); } lastLastCommitsExecution = Date.now(); @@ -1706,40 +1174,33 @@ async function getProjectCommits(project, count = 20) { per_page: count, }); - let pagination = - '
Commits
1/' + - recentProjectCommits.length + - '
'; + const pagination = `
Commits
1/${recentProjectCommits.length}
`; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + escapeQuotes(pagination) + '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes(pagination)}"`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("project-pipeline").innerHTML = "' + - escapeQuotes(displayCommit(commit, project, 'author')) + - '"', + `document.getElementById("project-pipeline").innerHTML = "${escapeQuotes( + displayCommit(commit, project, 'author'), + )}"`, ); } else { mb.window.webContents.executeJavaScript( - 'document.getElementById("project-commits-pagination").innerHTML = "' + - escapeQuotes('Commits') + - '"', + `document.getElementById("project-commits-pagination").innerHTML = "${escapeQuotes( + 'Commits', + )}"`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("project-pipeline").innerHTML = "' + - escapeQuotes('

No commits pushed yet.

') + - '"', + `document.getElementById("project-pipeline").innerHTML = "${escapeQuotes( + '

No commits pushed yet.

', + )}"`, ); } } async function getLastPipelines(commits) { - let projectArray = []; + const projectArray = []; if (commits && commits.length > 0) { - for (let commit of commits) { + for (const commit of commits) { if (!projectArray.includes(commit.project_id)) { projectArray.push(commit.project_id); const pipelines = await GitLab.get(`projects/${commit.project_id}/pipelines`, { @@ -1749,19 +1210,19 @@ async function getLastPipelines(commits) { page: 1, }); if (pipelines && pipelines.length > 0) { - mb.tray.setImage(__dirname + '/assets/runningTemplate.png'); - for (let pipeline of pipelines) { + mb.tray.setImage(`${__dirname}/assets/runningTemplate.png`); + for (const pipeline of pipelines) { if ( runningPipelineSubscriptions.findIndex( - (subscriptionPipeline) => subscriptionPipeline.id == pipeline.id, - ) == -1 + (subscriptionPipeline) => subscriptionPipeline.id === pipeline.id, + ) === -1 ) { const commit = await GitLab.get( `projects/${pipeline.project_id}/repository/commits/${pipeline.sha}`, ); pipeline.commit_title = commit.title; runningPipelineSubscriptions.push(pipeline); - let runningNotification = new Notification({ + const runningNotification = new Notification({ title: 'Pipeline running', subtitle: GitLab.fetchUrlInfo(pipeline.web_url).namespaceWithProject, body: pipeline.commit_title, @@ -1780,19 +1241,19 @@ async function getLastPipelines(commits) { } async function subscribeToRunningPipeline() { - let interval = setInterval(async function () { - for (let runningPipeline of runningPipelineSubscriptions) { + const interval = setInterval(async () => { + for (const runningPipeline of runningPipelineSubscriptions) { const pipeline = await GitLab.get( `projects/${runningPipeline.project_id}/pipelines/${runningPipeline.id}`, ); - if (pipeline.status != 'running') { - if (pipeline.status == 'success') { + if (pipeline.status !== 'running') { + if (pipeline.status === 'success') { pipelineStatus = 'succeeded'; } else { pipelineStatus = pipeline.status; } - let updateNotification = new Notification({ - title: 'Pipeline ' + pipelineStatus, + const updateNotification = new Notification({ + title: `Pipeline ${pipelineStatus}`, subtitle: GitLab.fetchUrlInfo(pipeline.web_url).namespaceWithProject, body: runningPipeline.commit_title, }); @@ -1801,11 +1262,11 @@ async function subscribeToRunningPipeline() { }); updateNotification.show(); runningPipelineSubscriptions = runningPipelineSubscriptions.filter( - (subscriptionPipeline) => subscriptionPipeline.id != pipeline.id, + (subscriptionPipeline) => subscriptionPipeline.id !== pipeline.id, ); - if (runningPipelineSubscriptions.length == 0) { + if (runningPipelineSubscriptions.length === 0) { clearInterval(interval); - mb.tray.setImage(__dirname + '/assets/gitlabTemplate.png'); + mb.tray.setImage(`${__dirname}/assets/gitlabTemplate.png`); } } } @@ -1814,22 +1275,20 @@ async function subscribeToRunningPipeline() { function changeCommit(forward = true, commitArray, chosenCommit) { let nextCommit; - let index = commitArray.findIndex((commit) => commit.id == chosenCommit.id); + let index = commitArray.findIndex((commit) => commit.id === chosenCommit.id); if (forward) { - if (index == commitArray.length - 1) { + if (index === commitArray.length - 1) { nextCommit = commitArray[0]; index = 1; } else { nextCommit = commitArray[index + 1]; index += 2; } + } else if (index === 0) { + nextCommit = commitArray[commitArray.length - 1]; + index = commitArray.length; } else { - if (index == 0) { - nextCommit = commitArray[commitArray.length - 1]; - index = commitArray.length; - } else { - nextCommit = commitArray[index - 1]; - } + nextCommit = commitArray[index - 1]; } nextCommit.index = index; return nextCommit; @@ -1840,18 +1299,14 @@ async function getCommitDetails(project_id, sha, index) { 'document.getElementById("commits-count").classList.remove("empty")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("commits-count").innerHTML = "' + - index + - '/' + - recentCommits.length + - '"', + `document.getElementById("commits-count").innerHTML = "${index}/${recentCommits.length}"`, ); const project = await GitLab.get(`projects/${project_id}`); const commit = await GitLab.get(`projects/${project.id}/repository/commits/${sha}`); mb.window.webContents.executeJavaScript( - 'document.getElementById("pipeline").innerHTML = "' + - escapeQuotes(displayCommit(commit, project)) + - '"', + `document.getElementById("pipeline").innerHTML = "${escapeQuotes( + displayCommit(commit, project), + )}"`, ); } @@ -1860,30 +1315,26 @@ async function getProjectCommitDetails(project_id, sha, index) { 'document.getElementById("project-commits-count").classList.remove("empty")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("project-commits-count").innerHTML = "' + - index + - '/' + - recentProjectCommits.length + - '"', + `document.getElementById("project-commits-count").innerHTML = "${index}/${recentProjectCommits.length}"`, ); const commit = await GitLab.get(`projects/${project_id}/repository/commits/${sha}`); mb.window.webContents.executeJavaScript( - 'document.getElementById("project-pipeline").innerHTML = "' + - escapeQuotes(displayCommit(commit, currentProject, 'author')) + - '"', + `document.getElementById("project-pipeline").innerHTML = "${escapeQuotes( + displayCommit(commit, currentProject, 'author'), + )}"`, ); } async function getRecentlyVisited() { if (lastRecentlyVisitedExecutionFinished && lastRecentlyVisitedExecution + delay < Date.now()) { lastRecentlyVisitedExecutionFinished = false; - recentlyVisitedArray = new Array(); + recentlyVisitedArray = []; let recentlyVisitedString = ''; let firstItem = true; await BrowserHistory.getAllHistory().then(async (history) => { - let item = Array.prototype.concat.apply([], history); - item.sort(function (a, b) { + const item = Array.prototype.concat.apply([], history); + item.sort((a, b) => { if (a.utc_time > b.utc_time) { return -1; } @@ -1892,95 +1343,69 @@ async function getRecentlyVisited() { } }); let i = 0; - for (let j = 0; j < item.length; j++) { + for (let j = 0; j < item.length; j += 1) { if ( item[j].title && - item[j].url.indexOf(store.host + '/') == 0 && - (item[j].url.indexOf('/-/issues/') != -1 || - item[j].url.indexOf('/-/merge_requests/') != -1 || - item[j].url.indexOf('/-/epics/') != -1) && + item[j].url.indexOf(`${store.host}/`) === 0 && + (item[j].url.indexOf('/-/issues/') !== -1 || + item[j].url.indexOf('/-/merge_requests/') !== -1 || + item[j].url.indexOf('/-/epics/') !== -1) && !recentlyVisitedArray.includes(item[j].title) && - item[j].title.split('·')[0] != 'Not Found' && - item[j].title.split('·')[0] != 'New Issue ' && - item[j].title.split('·')[0] != 'New Merge Request ' && - item[j].title.split('·')[0] != 'New merge request ' && - item[j].title.split('·')[0] != 'New Epic ' && - item[j].title.split('·')[0] != 'Edit ' && - item[j].title.split('·')[0] != 'Merge requests ' && - item[j].title.split('·')[0] != 'Issues ' + item[j].title.split('·')[0] !== 'Not Found' && + item[j].title.split('·')[0] !== 'New Issue ' && + item[j].title.split('·')[0] !== 'New Merge Request ' && + item[j].title.split('·')[0] !== 'New merge request ' && + item[j].title.split('·')[0] !== 'New Epic ' && + item[j].title.split('·')[0] !== 'Edit ' && + item[j].title.split('·')[0] !== 'Merge requests ' && + item[j].title.split('·')[0] !== 'Issues ' ) { if (firstItem) { recentlyVisitedString = ''; + const moreString = "'Recently viewed'"; + recentlyVisitedString += ``; } else if (BrowserHistory.isSupported()) { - recentlyVisitedString = - '

Recently visited objects will show up here.
Supported browsers: ' + - BrowserHistory.supportedBrowserNames() + - '.

'; + recentlyVisitedString = `

Recently visited objects will show up here.
Supported browsers: ${BrowserHistory.supportedBrowserNames()}.

`; } else { recentlyVisitedString = '

No browsers are supported on your operating system yet.

'; } mb.window.webContents.executeJavaScript( - 'document.getElementById("history").innerHTML = "' + - escapeQuotes(recentlyVisitedString) + - '"', + `document.getElementById("history").innerHTML = "${escapeQuotes(recentlyVisitedString)}"`, ); lastRecentlyVisitedExecution = Date.now(); lastRecentlyVisitedExecutionFinished = true; }); - } else { - console.log('Recently visited running or not out of delay'); } } @@ -1988,8 +1413,8 @@ async function getMoreRecentlyVisited() { recentlyVisitedString = ''; let firstItem = true; await BrowserHistory.getAllHistory().then(async (history) => { - let item = Array.prototype.concat.apply([], history); - item.sort(function (a, b) { + const item = Array.prototype.concat.apply([], history); + item.sort((a, b) => { if (a.utc_time > b.utc_time) { return -1; } @@ -1997,16 +1422,13 @@ async function getMoreRecentlyVisited() { return 1; } }); - let i = 0; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-headline").innerHTML = "' + - escapeQuotes( - '', - ) + - '"', + `document.getElementById("detail-headline").innerHTML = "${escapeQuotes( + '', + )}"`, ); let previousDate = 0; - for (let j = 0; j < item.length; j++) { + for (let j = 0; j < item.length; j += 1) { const { title } = item[j]; let { url } = item[j]; const isHostUrl = url.startsWith(`${store.host}/`); @@ -2014,7 +1436,7 @@ async function getMoreRecentlyVisited() { url.includes('/-/issues/') || url.includes('/-/merge_requests/') || url.includes('/-/epics/'); - const wasNotProcessed = !moreRecentlyVisitedArray.some((item) => item.title == title); + const wasNotProcessed = !moreRecentlyVisitedArray.some((item) => item.title === title); const ignoredTitlePrefixes = [ 'Not Found ', 'New Issue ', @@ -2035,33 +1457,25 @@ async function getMoreRecentlyVisited() { wasNotProcessed && !ignoredTitlePrefixes.includes(titlePrefix) ) { - let nameWithNamespace = item[j].url.replace(store.host + '/', '').split('/-/')[0]; - if (nameWithNamespace.split('/')[0] != 'groups') { - url = - store.host + - '/api/v4/projects/' + - nameWithNamespace.split('/')[0] + - '%2F' + - nameWithNamespace.split('/')[1] + - '?access_token=' + - store.access_token; + const nameWithNamespace = item[j].url.replace(`${store.host}/`, '').split('/-/')[0]; + if (nameWithNamespace.split('/')[0] !== 'groups') { + url = `${store.host}/api/v4/projects/${nameWithNamespace.split('/')[0]}%2F${ + nameWithNamespace.split('/')[1] + }?access_token=${store.access_token}`; } else { - url = - store.host + - '/api/v4/groups/' + - nameWithNamespace.split('/')[0] + - '?access_token=' + - store.access_token; + url = `${store.host}/api/v4/groups/${nameWithNamespace.split('/')[0]}?access_token=${ + store.access_token + }`; } - let currentDate = new Date(item[j].utc_time).toLocaleDateString('en-US', { + const currentDate = new Date(item[j].utc_time).toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', timeZone: timezone, }); - if (previousDate != currentDate) { + if (previousDate !== currentDate) { if ( - currentDate == + currentDate === new Date(Date.now()).toLocaleDateString('en-US', { weekday: 'long', month: 'long', @@ -2074,78 +1488,60 @@ async function getMoreRecentlyVisited() { if (!firstItem) { recentlyVisitedString += ''; } - recentlyVisitedString += '
' + currentDate + '
'; + recentlyVisitedString += `
${currentDate}
`; } recentlyVisitedString += ''; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + - escapeQuotes(recentlyVisitedString) + - '"', + `document.getElementById("detail-content").innerHTML = "${escapeQuotes( + recentlyVisitedString, + )}"`, ); }); } function searchRecentlyVisited(searchterm) { - let foundArray = moreRecentlyVisitedArray.filter((item) => { - return item.title.toLowerCase().includes(searchterm); - }); + const foundArray = moreRecentlyVisitedArray.filter((item) => + item.title.toLowerCase().includes(searchterm), + ); foundString = ''; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + escapeQuotes(foundString) + '"', + `document.getElementById("detail-content").innerHTML = "${escapeQuotes(foundString)}"`, ); } @@ -2175,47 +1571,32 @@ async function getUsersProjects() { function displayUsersProjects() { let favoriteProjectsString = ''; - let projects = store['favorite-projects']; + const projects = store['favorite-projects']; if (projects && projects.length > 0) { favoriteProjectsString += ''; } else { - let projectLink = "'project-overview-link'"; - favoriteProjectsString = - '
Track projects you care about 🌟
Add any project you want a directly accessible shortcut for.
'; + const projectLink = "'project-overview-link'"; + favoriteProjectsString = `
Track projects you care about 🌟
Add any project you want a directly accessible shortcut for.
`; } mb.window.webContents.executeJavaScript( - 'document.getElementById("projects").innerHTML = "' + - escapeQuotes(favoriteProjectsString) + - '"', + `document.getElementById("projects").innerHTML = "${escapeQuotes(favoriteProjectsString)}"`, ); } @@ -2231,7 +1612,7 @@ async function getRecentComments() { if (comments && comments.length > 0) { recentCommentsString += ''; + const moreString = "'Comments'"; + recentCommentsString += ``; mb.window.webContents.executeJavaScript( - 'document.getElementById("comments").innerHTML = "' + - escapeQuotes(recentCommentsString) + - '"', + `document.getElementById("comments").innerHTML = "${escapeQuotes(recentCommentsString)}"`, ); } else { mb.window.webContents.executeJavaScript( - 'document.getElementById("comments").innerHTML = "' + - escapeQuotes('

You haven't written any comments yet.

') + - '"', + `document.getElementById("comments").innerHTML = "${escapeQuotes( + '

You haven't written any comments yet.

', + )}"`, ); } lastRecentCommentsExecution = Date.now(); lastRecentCommentsExecutionFinished = true; - } else { - console.log('Recent comments running or not out of delay'); } } function getMoreRecentComments( - url = store.host + - '/api/v4/events?action=commented&per_page=' + - numberOfComments + - '&access_token=' + - store.access_token, + url = `${store.host}/api/v4/events?action=commented&per_page=${numberOfComments}&access_token=${store.access_token}`, ) { let recentCommentsString = '' + displayPagination(keysetLinks, type); + recentCommentsString += `${displayPagination(keysetLinks, type)}`; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + - escapeQuotes(recentCommentsString) + - '"', + `document.getElementById("detail-content").innerHTML = "${escapeQuotes( + recentCommentsString, + )}"`, ); }); } @@ -2303,51 +1671,35 @@ function renderCollabject(comment, collabject) { if (collabject.message && collabject.message === '404 Not found') { console.log('deleted', collabject.id); } else if (comment.note.noteable_type === 'DesignManagement::Design') { - collabject.web_url += '/designs/' + comment.target_title; - return ( - '
  • ' + - escapeHtml(comment.note.body) + - '' + - timeSince(new Date(comment.created_at)) + - ' ago · ' + - escapeHtml(comment.target_title) + - '
  • ' - ); + collabject.web_url += `/designs/${comment.target_title}`; + return `
  • ${escapeHtml( + comment.note.body, + )}${timeSince( + new Date(comment.created_at), + )} ago · ${escapeHtml( + comment.target_title, + )}
  • `; } else { - return ( - '
  • ' + - escapeHtml(comment.note.body) + - '' + - timeSince(new Date(comment.created_at)) + - ' ago · ' + - escapeHtml(comment.target_title) + - '
  • ' - ); + return `
  • ${escapeHtml( + comment.note.body, + )}${timeSince( + new Date(comment.created_at), + )} ago · ${escapeHtml( + comment.target_title, + )}
  • `; } } function getIssues( - url = store.host + - '/api/v4/issues?scope=assigned_to_me&state=opened&order_by=created_at&per_page=' + - numberOfIssues + - '&access_token=' + - store.access_token, + url = `${store.host}/api/v4/issues?scope=assigned_to_me&state=opened&order_by=created_at&per_page=${numberOfIssues}&access_token=${store.access_token}`, id = 'detail-content', ) { let issuesString = ''; - let type = "'Issues'"; + const type = "'Issues'"; let keysetLinks; fetch(url) .then((result) => { @@ -2357,59 +1709,47 @@ function getIssues( .then((issues) => { if (issues && issues.length > 0) { issuesString += '' + displayPagination(keysetLinks, type); + issuesString += `${displayPagination(keysetLinks, type)}`; } else { - let illustration = todosAllDoneIllustration; - issuesString = - '
    ' + - illustration + - '

    No issues with the specified criteria.

    '; + const illustration = todosAllDoneIllustration; + issuesString = `
    ${illustration}

    No issues with the specified criteria.

    `; } mb.window.webContents.executeJavaScript( - 'document.getElementById("' + id + '").innerHTML = "' + escapeQuotes(issuesString) + '"', + `document.getElementById("${id}").innerHTML = "${escapeQuotes(issuesString)}"`, ); }); } function getMRs( - url = store.host + - '/api/v4/merge_requests?scope=assigned_to_me&state=opened&order_by=created_at&per_page=' + - numberOfMRs + - '&access_token=' + - store.access_token, + url = `${store.host}/api/v4/merge_requests?scope=assigned_to_me&state=opened&order_by=created_at&per_page=${numberOfMRs}&access_token=${store.access_token}`, id = 'detail-content', ) { let mrsString = ''; - let type = "'MRs'"; + const type = "'MRs'"; let keysetLinks; fetch(url) .then((result) => { @@ -2419,50 +1759,36 @@ function getMRs( .then((mrs) => { if (mrs && mrs.length > 0) { mrsString = '' + displayPagination(keysetLinks, type); + mrsString += `${displayPagination(keysetLinks, type)}`; } else { - let illustration = todosAllDoneIllustration; - mrsString = - '
    ' + - illustration + - '

    No merge requests with the specified criteria.

    '; + const illustration = todosAllDoneIllustration; + mrsString = `
    ${illustration}

    No merge requests with the specified criteria.

    `; } mb.window.webContents.executeJavaScript( - 'document.getElementById("' + id + '").innerHTML = "' + escapeQuotes(mrsString) + '"', + `document.getElementById("${id}").innerHTML = "${escapeQuotes(mrsString)}"`, ); }); } function getTodos( - url = store.host + - '/api/v4/todos?per_page=' + - numberOfTodos + - '&access_token=' + - store.access_token, + url = `${store.host}/api/v4/todos?per_page=${numberOfTodos}&access_token=${store.access_token}`, ) { let todosString = ''; - let type = "'Todos'"; + const type = "'Todos'"; let keysetLinks; fetch(url) .then((result) => { @@ -2472,7 +1798,7 @@ function getTodos( .then((todos) => { if (todos && todos.length > 0) { todosString = '' + displayPagination(keysetLinks, type); + todosString += `${displayPagination(keysetLinks, type)}`; } else { - let illustration = todosAllDoneIllustration; - todosString = - '
    ' + - illustration + - '

    Take the day off, you have no To-Dos!

    '; + const illustration = todosAllDoneIllustration; + todosString = `
    ${illustration}

    Take the day off, you have no To-Dos!

    `; } mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + escapeQuotes(todosString) + '"', + `document.getElementById("detail-content").innerHTML = "${escapeQuotes(todosString)}"`, ); }); } function getBookmarks() { - let bookmarks = store.bookmarks; + const { bookmarks } = store; let bookmarksString = ''; if (bookmarks && bookmarks.length > 0) { bookmarksString = ''; + bookmarksString += ``; mb.window.webContents.executeJavaScript( - 'document.getElementById("bookmarks").innerHTML = "' + escapeQuotes(bookmarksString) + '"', + `document.getElementById("bookmarks").innerHTML = "${escapeQuotes(bookmarksString)}"`, ); } else { - let bookmarkLink = "'bookmark-link'"; - bookmarksString = - '
    Add a new GitLab bookmark 🔖
    Bookmarks are helpful when you have an issue/merge request you will have to come back to repeatedly.
    '; + const bookmarkLink = "'bookmark-link'"; + bookmarksString = `
    Add a new GitLab bookmark 🔖
    Bookmarks are helpful when you have an issue/merge request you will have to come back to repeatedly.
    `; mb.window.webContents.executeJavaScript( - 'document.getElementById("bookmarks").innerHTML = "' + escapeQuotes(bookmarksString) + '"', + `document.getElementById("bookmarks").innerHTML = "${escapeQuotes(bookmarksString)}"`, ); } } function displayPagination(keysetLinks, type) { let paginationString = ''; - if (keysetLinks.indexOf('rel="next"') != -1 || keysetLinks.indexOf('rel="prev"') != -1) { + if (keysetLinks.indexOf('rel="next"') !== -1 || keysetLinks.indexOf('rel="prev"') !== -1) { paginationString += ''; - return paginationString; - } else { - return ''; } + return paginationString; } function setupEmptyProjectPage() { @@ -2630,44 +1911,41 @@ function setupEmptyProjectPage() { emptyPage += '
    '; mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-content").innerHTML = "' + escapeQuotes(emptyPage) + '"', + `document.getElementById("detail-content").innerHTML = "${escapeQuotes(emptyPage)}"`, ); } function displayProjectPage(project) { let logo; - if (project.avatar_url && project.avatar_url != null && project.visibility == 'public') { - logo = ''; + if (project.avatar_url && project.avatar_url != null && project.visibility === 'public') { + logo = ``; } else { - logo = - '
    ' + project.name.charAt(0).toUpperCase() + '
    '; + logo = `
    ${project.name.charAt(0).toUpperCase()}
    `; } mb.window.webContents.executeJavaScript( 'document.getElementById("detail-header-content").classList.remove("empty")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("detail-header-content").innerHTML = "' + - escapeQuotes('
    ') + - escapeQuotes(logo) + - escapeQuotes('') + - escapeHtml(project.name) + - escapeQuotes('') + - escapeHtml(project.namespace.name) + - escapeQuotes('
    ') + - '"', + `document.getElementById("detail-header-content").innerHTML = "${escapeQuotes( + '
    ', + )}${escapeQuotes(logo)}${escapeQuotes('')}${escapeHtml( + project.name, + )}${escapeQuotes('')}${escapeHtml( + project.namespace.name, + )}${escapeQuotes('
    `)}"`, ); } async function getProjectIssues(project) { let projectIssuesString = ''; - let jsonProjectObject = JSON.parse(JSON.stringify(project)); + const jsonProjectObject = JSON.parse(JSON.stringify(project)); jsonProjectObject.name_with_namespace = project.name_with_namespace; jsonProjectObject.namespace.name = project.namespace.name; jsonProjectObject.name = project.name; - let projectString = "'" + escapeHtml(JSON.stringify(jsonProjectObject)) + "'"; - let issuesString = "'Issues'"; + const projectString = `'${escapeHtml(JSON.stringify(jsonProjectObject))}'`; + const issuesString = "'Issues'"; const issues = await GitLab.get(`projects/${project.id}/issues`, { state: 'opened', @@ -2676,54 +1954,35 @@ async function getProjectIssues(project) { }); if (issues.length > 0) { projectIssuesString = ''; } else { projectIssuesString = ''; - projectIssuesString += - ''; + projectIssuesString += ``; } mb.window.webContents.executeJavaScript( - 'document.getElementById("project-recent-issues").innerHTML = "' + - escapeQuotes(projectIssuesString) + - '"', + `document.getElementById("project-recent-issues").innerHTML = "${escapeQuotes( + projectIssuesString, + )}"`, ); } async function getProjectMRs(project) { let projectMRsString = ''; - let jsonProjectObject = JSON.parse(JSON.stringify(project)); + const jsonProjectObject = JSON.parse(JSON.stringify(project)); jsonProjectObject.name_with_namespace = project.name_with_namespace; jsonProjectObject.namespace.name = project.namespace.name; jsonProjectObject.name = project.name; - let projectString = "'" + escapeHtml(JSON.stringify(jsonProjectObject)) + "'"; - let mrsString = "'Merge Requests'"; + const projectString = `'${escapeHtml(JSON.stringify(jsonProjectObject))}'`; + const mrsString = "'Merge Requests'"; const mrs = await GitLab.get(`projects/${project.id}/merge_requests`, { state: 'opened', @@ -2733,80 +1992,59 @@ async function getProjectMRs(project) { if (mrs.length > 0) { projectMRsString += ''; } else { projectMRsString = ''; - projectMRsString += - ''; + projectMRsString += ``; } mb.window.webContents.executeJavaScript( - 'document.getElementById("project-recent-mrs").innerHTML = "' + - escapeQuotes(projectMRsString) + - '"', + `document.getElementById("project-recent-mrs").innerHTML = "${escapeQuotes(projectMRsString)}"`, ); } function displayCommit(commit, project, focus = 'project') { let logo = ''; if (commit.last_pipeline) { - logo += ''; - if (commit.last_pipeline.status == 'scheduled') { + logo += ``; + if (commit.last_pipeline.status === 'scheduled') { logo += ''; } else { logo += ''; - if (commit.last_pipeline.status == 'running') { + if (commit.last_pipeline.status === 'running') { logo += ''; - } else if (commit.last_pipeline.status == 'failed') { + } else if (commit.last_pipeline.status === 'failed') { logo += ''; - } else if (commit.last_pipeline.status == 'success') { + } else if (commit.last_pipeline.status === 'success') { logo += ''; - } else if (commit.last_pipeline.status == 'pending') { + } else if (commit.last_pipeline.status === 'pending') { logo += ''; - } else if (commit.last_pipeline.status == 'canceled') { + } else if (commit.last_pipeline.status === 'canceled') { logo += ''; - } else if (commit.last_pipeline.status == 'skipped') { + } else if (commit.last_pipeline.status === 'skipped') { logo += ''; - } else if (commit.last_pipeline.status == 'created') { + } else if (commit.last_pipeline.status === 'created') { logo += ''; - } else if (commit.last_pipeline.status == 'preparing') { + } else if (commit.last_pipeline.status === 'preparing') { logo += ''; - } else if (commit.last_pipeline.status == 'manual') { + } else if (commit.last_pipeline.status === 'manual') { logo += ''; } @@ -2814,42 +2052,29 @@ function displayCommit(commit, project, focus = 'project') { } logo += ''; let subline; - if (focus == 'project') { - subline = - '' + - escapeHtml(project.name_with_namespace) + - ''; + if (focus === 'project') { + subline = `${escapeHtml( + project.name_with_namespace, + )}`; } else { subline = escapeHtml(commit.author_name); } - return ( - '
    ' + - escapeHtml(commit.title) + - '' + - timeSince(new Date(commit.committed_date)) + - ' ago · ' + - subline + - '
    ' + - logo + - '
    ' - ); + return `
    ${escapeHtml(commit.title)}${timeSince( + new Date(commit.committed_date), + )} ago · ${subline}
    ${logo}
    `; } function addBookmark(link) { if (store && store.bookmarks && store.bookmarks.length > 0) { - sameBookmarks = store.bookmarks.filter((item) => { - return item.web_url === link; - }); + sameBookmarks = store.bookmarks.filter((item) => item.web_url === link); if (sameBookmarks.length > 0) { displayAddError('bookmark', '-', 'This bookmark has already been added.'); return; } } - let spinner = + const spinner = ''; mb.window.webContents.executeJavaScript( 'document.getElementById("bookmark-add-button").disabled = "disabled"', @@ -2858,9 +2083,7 @@ function addBookmark(link) { 'document.getElementById("bookmark-link").disabled = "disabled"', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("bookmark-add-button").innerHTML = "' + - escapeQuotes(spinner) + - ' Add"', + `document.getElementById("bookmark-add-button").innerHTML = "${escapeQuotes(spinner)} Add"`, ); if (GitLab.urlHasValidHost(link)) { GitLab.parseUrl(link) @@ -2885,7 +2108,7 @@ function addBookmark(link) { displayAddError('bookmark', '-'); } }) - .catch((error) => { + .catch(() => { displayAddError('bookmark', '-'); }); } else { @@ -2894,34 +2117,32 @@ function addBookmark(link) { } function addProject(link, target) { - if (target == 'project-settings-link') { + if (target === 'project-settings-link') { target = '-settings-'; - } else if (target == 'project-overview-link') { + } else if (target === 'project-overview-link') { target = '-overview-'; } - let spinner = + const spinner = ''; mb.window.webContents.executeJavaScript( - 'document.getElementById("project' + target + 'add-button").disabled = "disabled"', + `document.getElementById("project${target}add-button").disabled = "disabled"`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("project' + target + 'link").disabled = "disabled"', + `document.getElementById("project${target}link").disabled = "disabled"`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("project' + - target + - 'add-button").innerHTML = "' + - escapeQuotes(spinner) + - ' Add"', + `document.getElementById("project${target}add-button").innerHTML = "${escapeQuotes( + spinner, + )} Add"`, ); if (GitLab.urlHasValidHost(link)) { GitLab.parseUrl(link) .then((project) => { - if (project.type && project.type != 'projects') { - let projectWithNamespace = encodeURIComponent(link.split(store.host + '/')[1]); - GitLab.get('projects/' + projectWithNamespace) + if (project.type && project.type !== 'projects') { + const projectWithNamespace = encodeURIComponent(link.split(`${store.host}/`)[1]); + GitLab.get(`projects/${projectWithNamespace}`) .then((project) => { - let projects = store['favorite-projects'] || []; + const projects = store['favorite-projects'] || []; projects.push({ id: project.id, visibility: project.visibility, @@ -2941,25 +2162,25 @@ function addProject(link, target) { forks_count: project.forks_count, }); store['favorite-projects'] = projects; - if (target == '-settings-') { + if (target === '-settings-') { openSettingsPage(); } displayUsersProjects(projects); }) - .catch((error) => { + .catch(() => { displayAddError('project', target); }); } else { - let projects = store['favorite-projects'] || []; + const projects = store['favorite-projects'] || []; projects.push(project); store['favorite-projects'] = projects; - if (target == '-settings-') { + if (target === '-settings-') { openSettingsPage(); } displayUsersProjects(projects); } }) - .catch((error) => { + .catch(() => { displayAddError('project', target); }); } else { @@ -2970,7 +2191,7 @@ function addProject(link, target) { function addShortcut(link) { const tempArray = [link]; store.shortcuts = store.shortcuts.concat(tempArray); - let spinner = + const spinner = ''; mb.window.webContents.executeJavaScript( 'document.getElementById("shortcut-add-button").disabled = "disabled"', @@ -2979,9 +2200,7 @@ function addShortcut(link) { 'document.getElementById("shortcut-link").disabled = "disabled"', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("shortcut-add-button").innerHTML = "' + - escapeQuotes(spinner) + - ' Add"', + `document.getElementById("shortcut-add-button").innerHTML = "${escapeQuotes(spinner)} Add"`, ); setupCommandPalette(); repaintShortcuts(); @@ -2989,71 +2208,49 @@ function addShortcut(link) { function displayAddError(type, target, customMessage) { mb.window.webContents.executeJavaScript( - 'document.getElementById("add-' + type + target + 'error").style.display = "block"', + `document.getElementById("add-${type}${target}error").style.display = "block"`, ); if (customMessage) { mb.window.webContents.executeJavaScript( - 'document.getElementById("add-' + - type + - target + - 'error").innerHTML = "' + - customMessage + - '"', + `document.getElementById("add-${type}${target}error").innerHTML = "${customMessage}"`, ); } else { mb.window.webContents.executeJavaScript( - 'document.getElementById("add-' + - type + - target + - 'error").innerHTML = "This is not a valid GitLab ' + - type + - ' URL."', + `document.getElementById("add-${type}${target}error").innerHTML = "This is not a valid GitLab ${type} URL."`, ); } mb.window.webContents.executeJavaScript( - 'document.getElementById("' + type + target + 'add-button").disabled = false', + `document.getElementById("${type}${target}add-button").disabled = false`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("' + type + target + 'link").disabled = false', + `document.getElementById("${type}${target}link").disabled = false`, ); mb.window.webContents.executeJavaScript( - 'document.getElementById("' + type + target + 'add-button").innerHTML = "Add"', + `document.getElementById("${type}${target}add-button").innerHTML = "Add"`, ); } function startBookmarkDialog() { - let bookmarkLink = "'bookmark-link'"; - let bookmarkInput = - '
    '; + const bookmarkLink = "'bookmark-link'"; + const bookmarkInput = `
    `; mb.window.webContents.executeJavaScript( 'document.getElementById("add-bookmark-dialog").classList.add("opened")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("add-bookmark-dialog").innerHTML = "' + - escapeQuotes(bookmarkInput) + - '"', + `document.getElementById("add-bookmark-dialog").innerHTML = "${escapeQuotes(bookmarkInput)}"`, ); mb.window.webContents.executeJavaScript('window.scrollBy(0, 14)'); mb.window.webContents.executeJavaScript('document.getElementById("bookmark-link").focus()'); } function startProjectDialog() { - let projectLink = "'project-settings-link'"; - let projectInput = - '
    '; + const projectLink = "'project-settings-link'"; + const projectInput = `
    `; mb.window.webContents.executeJavaScript( 'document.getElementById("add-project-dialog").classList.add("opened")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("add-project-dialog").innerHTML = "' + - escapeQuotes(projectInput) + - '"', + `document.getElementById("add-project-dialog").innerHTML = "${escapeQuotes(projectInput)}"`, ); mb.window.webContents.executeJavaScript('window.scrollBy(0, 14)'); mb.window.webContents.executeJavaScript( @@ -3062,67 +2259,68 @@ function startProjectDialog() { } function startShortcutDialog() { - let shortcutLink = "'shortcut-link'"; - let shortcutInput = - '
    '; + const shortcutLink = "'shortcut-link'"; + const shortcutInput = `
    `; mb.window.webContents.executeJavaScript( 'document.getElementById("add-shortcut-dialog").classList.add("opened")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("add-shortcut-dialog").innerHTML = "' + - escapeQuotes(shortcutInput) + - '"', + `document.getElementById("add-shortcut-dialog").innerHTML = "${escapeQuotes(shortcutInput)}"`, ); mb.window.webContents.executeJavaScript('window.scrollBy(0, 14)'); mb.window.webContents.executeJavaScript('document.getElementById("shortcut-link").focus()'); } function timeSince(date, direction = 'since') { - var seconds; - if (direction == 'since') { + let seconds; + if (direction === 'since') { seconds = Math.floor((new Date() - date) / 1000); - } else if (direction == 'to') { + } else if (direction === 'to') { seconds = Math.floor((date - new Date()) / 1000); } - var interval = seconds / 31536000; + let interval = seconds / 31536000; if (interval >= 2) { - return Math.floor(interval) + ' years'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' year'; + return `${Math.floor(interval)} years`; + } + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} year`; } interval = seconds / 2592000; if (interval > 2) { - return Math.floor(interval) + ' months'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' month'; + return `${Math.floor(interval)} months`; + } + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} month`; } interval = seconds / 604800; if (interval > 2) { - return Math.floor(interval) + ' weeks'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' week'; + return `${Math.floor(interval)} weeks`; + } + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} week`; } interval = seconds / 86400; if (interval > 2) { - return Math.floor(interval) + ' days'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' day'; + return `${Math.floor(interval)} days`; + } + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} day`; } interval = seconds / 3600; if (interval >= 2) { - return Math.floor(interval) + ' hours'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' hour'; + return `${Math.floor(interval)} hours`; + } + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} hour`; } interval = seconds / 60; if (interval > 2) { - return Math.floor(interval) + ' minutes'; - } else if (interval > 1 && interval < 2) { - return Math.floor(interval) + ' minute'; + return `${Math.floor(interval)} minutes`; } - return Math.floor(seconds) + ' seconds'; + if (interval > 1 && interval < 2) { + return `${Math.floor(interval)} minute`; + } + return `${Math.floor(seconds)} seconds`; } function displaySkeleton(count, pagination = false, id = 'detail-content') { @@ -3132,23 +2330,23 @@ function displaySkeleton(count, pagination = false, id = 'detail-content') { } else { skeletonString += '">'; } - for (let i = 0; i < count; i++) { + for (let i = 0; i < count; i += 1) { skeletonString += '
  • '; } skeletonString += ''; mb.window.webContents.executeJavaScript( - 'document.getElementById("' + id + '").innerHTML = "' + escapeQuotes(skeletonString) + '"', + `document.getElementById("${id}").innerHTML = "${escapeQuotes(skeletonString)}"`, ); } function changeTheme(option = 'light', manual = false) { store.theme = option; - if (option == 'light') { + if (option === 'light') { mb.window.webContents.executeJavaScript( 'document.documentElement.setAttribute("data-theme", "light");', ); - } else if (option == 'dark') { + } else if (option === 'dark') { mb.window.webContents.executeJavaScript( 'document.documentElement.setAttribute("data-theme", "dark");', ); @@ -3161,7 +2359,7 @@ function changeTheme(option = 'light', manual = false) { 'document.getElementById("dark-mode").classList.remove("active")', ); mb.window.webContents.executeJavaScript( - 'document.getElementById("' + option + '-mode").classList.add("active")', + `document.getElementById("${option}-mode").classList.add("active")`, ); } } diff --git a/package-lock.json b/package-lock.json index 3f894ad..3340cd6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "name": "gitdock", "version": "0.1.20", "dependencies": { - "electron": "^13.5.2", "electron-squirrel-startup": "^1.0.0", "electron-store": "^8.0.0", "jsdom": "^17.0.0", @@ -28,9 +27,10 @@ "@electron-forge/maker-zip": "^6.0.0-beta.59", "@electron-forge/publisher-github": "^6.0.0-beta.59", "electron": "^16.0.4", - "eslint": "^8.4.1", + "eslint": "^8.9.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^8.3.0", + "eslint-formatter-gitlab": "^3.0.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", "mocha": "^9.1.2", @@ -1010,14 +1010,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", + "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -1029,6 +1029,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1378,9 +1387,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/acorn": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", - "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", "bin": { "acorn": "bin/acorn" }, @@ -3894,18 +3903,6 @@ "once": "^1.4.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -4023,24 +4020,23 @@ } }, "node_modules/eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", + "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.1.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -4048,7 +4044,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -4059,9 +4055,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -4108,6 +4102,19 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-formatter-gitlab": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-gitlab/-/eslint-formatter-gitlab-3.0.0.tgz", + "integrity": "sha512-fqZ2G45rgbrHcFunqmwuG5Qo6QAOlxEsR+KdOP08T1Xegw5tJhHh9KFWMSct8q6x8xCMUyYGHypZd342bLUttA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "js-yaml": "^4.0.0" + }, + "peerDependencies": { + "eslint": "^5 || ^6 || ^7 || ^8" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -4250,9 +4257,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -4290,9 +4297,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4349,21 +4356,6 @@ "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4389,14 +4381,14 @@ } }, "node_modules/espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "dependencies": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5328,9 +5320,9 @@ } }, "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -5614,9 +5606,9 @@ ] }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -10976,14 +10968,14 @@ } }, "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", + "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", @@ -10992,6 +10984,12 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11295,9 +11293,9 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.6.0.tgz", - "integrity": "sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==" + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" }, "acorn-globals": { "version": "6.0.0", @@ -13165,15 +13163,6 @@ "once": "^1.4.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -13258,24 +13247,23 @@ } }, "eslint": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", - "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", + "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.1.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", + "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.1.0", - "espree": "^9.2.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -13283,7 +13271,7 @@ "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", @@ -13294,9 +13282,7 @@ "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", "regexpp": "^3.2.0", - "semver": "^7.2.1", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0", @@ -13342,15 +13328,6 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -13387,6 +13364,16 @@ "dev": true, "requires": {} }, + "eslint-formatter-gitlab": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-gitlab/-/eslint-formatter-gitlab-3.0.0.tgz", + "integrity": "sha512-fqZ2G45rgbrHcFunqmwuG5Qo6QAOlxEsR+KdOP08T1Xegw5tJhHh9KFWMSct8q6x8xCMUyYGHypZd342bLUttA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "js-yaml": "^4.0.0" + } + }, "eslint-import-resolver-node": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", @@ -13505,9 +13492,9 @@ } }, "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -13532,20 +13519,20 @@ } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.2.0.tgz", - "integrity": "sha512-oP3utRkynpZWF/F2x/HZJ+AGtnIclaR7z1pYPxy7NYM2fSO6LgK/Rkny8anRSPK/VwEA1eqm2squui0T7ZMOBg==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "requires": { - "acorn": "^8.6.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "eslint-visitor-keys": "^3.3.0" } }, "esprima": { @@ -14286,9 +14273,9 @@ } }, "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -14483,9 +14470,9 @@ "dev": true }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "ignore-walk": { diff --git a/package.json b/package.json index 06caa9c..358d2bb 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "publish": "electron-forge publish", "prettier:check": "prettier --check .", "prettier:fix": "prettier --write .", - "lint:check": "eslint --ignore-path .prettierignore .", + "lint:check": "eslint --ignore-path .prettierignore --format gitlab .", "lint:fix": "eslint --ignore-path .prettierignore --fix ." }, "repository": "https://github.com/mvremmerden/gitdock", @@ -33,9 +33,10 @@ "@electron-forge/maker-zip": "^6.0.0-beta.59", "@electron-forge/publisher-github": "^6.0.0-beta.59", "electron": "^16.0.4", - "eslint": "^8.4.1", + "eslint": "^8.9.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^8.3.0", + "eslint-formatter-gitlab": "^3.0.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-prettier": "^4.0.0", "mocha": "^9.1.2", @@ -51,7 +52,6 @@ "node-browser-history": "^2.4.6", "node-fetch": "^2.6.1", "playwright": "^1.17.1", - "electron": "^13.5.2", "universal-analytics": "^0.4.23", "uuid": "^8.3.2" }, diff --git a/preload.js b/preload.js index 8b9eff8..08c6195 100644 --- a/preload.js +++ b/preload.js @@ -30,24 +30,25 @@ const api = { logout: () => ipcRenderer.send('logout'), }; +function deepFreeze(o) { + Object.freeze(o); + + Object.getOwnPropertyNames(o).forEach((prop) => { + if ( + Object.prototype.hasOwnProperty.call(o, prop) && + o[prop] !== null && + (typeof o[prop] === 'object' || typeof o[prop] === 'function') && + !Object.isFrozen(o[prop]) + ) { + deepFreeze(o[prop]); + } + }); + return o; +} + if (process.contextIsolated) { contextBridge.exposeInMainWorld('electron', api); } else { - function deepFreeze(o) { - Object.freeze(o); - - Object.getOwnPropertyNames(o).forEach((prop) => { - if ( - o.hasOwnProperty(prop) && - o[prop] !== null && - (typeof o[prop] === 'object' || typeof o[prop] === 'function') && - !Object.isFrozen(o[prop]) - ) { - deepFreeze(o[prop]); - } - }); - return o; - } deepFreeze(api); // @ts-expect-error https://github.com/electron-userland/spectron#node-integration window.electronRequire = require; @@ -61,7 +62,7 @@ window.addEventListener('DOMContentLoaded', () => { if (element) element.innerText = text; }; - for (const type of ['chrome', 'node', 'electron']) { + ['chrome', 'node', 'electron'].forEach((type) => { replaceText(`${type}-version`, process.versions[type]); - } + }); }); diff --git a/renderer.js b/renderer.js index ab14875..2ed87c7 100644 --- a/renderer.js +++ b/renderer.js @@ -1,7 +1,8 @@ +/* eslint-disable no-unused-vars */ function goToDetail(page, object) { - let value = { - page: page, - object: object, + const value = { + page, + object, }; document.getElementById('detail-view').style.left = 0; document.body.style.overflow = 'hidden'; @@ -14,10 +15,10 @@ function goBackToDetail() { } function goToSubDetail(page, project, all = false) { - let value = { - page: page, - project: project, - all: all, + const value = { + page, + project, + all, }; document.getElementById('sub-detail-view').style.left = 0; window.electron.goToSubDetail(value); @@ -36,27 +37,27 @@ function goToSettings() { } function switchIssues(value, type, text) { - let object = { + const object = { label: value, - type: type, - text: text, + type, + text, }; window.electron.switchIssues(object); } function switchMRs(value, type, text) { - let object = { + const object = { label: value, - type: type, - text: text, + type, + text, }; window.electron.switchMRs(object); } function switchPage(url, type) { - let value = { - url: url, - type: type, + const value = { + url, + type, }; window.electron.switchPage(value); } @@ -78,9 +79,9 @@ function addBookmark(value) { } function addProject(input, target) { - let value = { - input: input, - target: target, + const value = { + input, + target, }; window.electron.addProject(value); } @@ -133,10 +134,10 @@ function startLogin() { window.electron.startLogin(); } -function startManualLogin(access_token, host) { - let value = { - access_token: access_token, - host: host, +function startManualLogin(accessToken, host) { + const value = { + access_token: accessToken, + host, }; window.electron.startManualLogin(value); } diff --git a/src/command-palette/bar.js b/src/command-palette/bar.js index 4c95737..546db6d 100644 --- a/src/command-palette/bar.js +++ b/src/command-palette/bar.js @@ -2,9 +2,16 @@ const $search = document.querySelector('input'); const $results = document.querySelector('#results'); let html = []; let $selected = 0; -const mrIcon = ``; -const issueIcon = ``; -const projectIcon = ``; +const mrIcon = + ''; +const issueIcon = + ''; +const projectIcon = + ''; + +let ALL_FAVORITES = gitdock.getFavorites() || []; +let ALL_BOOKMARKS = gitdock.getBookmarks() || []; +let ALL_RECENTS = gitdock.getRecents() || []; const ALL_ACTIONS = { newProject: { @@ -16,14 +23,14 @@ const ALL_ACTIONS = { }, newGroup: { title: 'New group', - icon: ``, + icon: '', execute() { gitdock.openGitLab('/groups/new'); }, }, newSnippet: { title: 'New snippet', - icon: ``, + icon: '', execute() { gitdock.openGitLab('/-/snippets/new'); }, @@ -33,9 +40,9 @@ const ALL_ACTIONS = { const ALL_OVERVIEWS = { overviewTodos: { title: 'To-Do list', - icon: ``, + icon: '', execute() { - gitdock.openGitLab(`/dashboard/todos`); + gitdock.openGitLab('/dashboard/todos'); }, }, overviewAssignedIssues: { @@ -58,7 +65,7 @@ const ALL_OVERVIEWS = { }, overviewMRsToReview: { title: 'Review requests', - icon: ``, + icon: '', execute() { const username = encodeURIComponent(gitdock.getUsername()); gitdock.openGitLab(`/dashboard/merge_requests?reviewer_username=${username}`); @@ -66,6 +73,25 @@ const ALL_OVERVIEWS = { }, }; +function matcher({ title }) { + let lowerCaseTitle = title.toLowerCase(); + const searchTerm = $search.value; + const terms = searchTerm.toLowerCase().split(' ').filter(Boolean); + + let matchCount = 1; + + for (const term of terms) { + matchCount += lowerCaseTitle.split(' ').filter((x) => x.includes(term)).length; + const newTitle = lowerCaseTitle.replace(term, ''); + if (newTitle === lowerCaseTitle) { + return false; + } + lowerCaseTitle = newTitle; + } + + return matchCount; +} + function loadActions() { const actions = Object.entries(ALL_ACTIONS); @@ -99,7 +125,10 @@ function loadFavorites() { function loadBookmarks() { const bookmarks = ALL_BOOKMARKS.map((bookmark) => [ `open-bookmark::${bookmark.added}`, - { title: `${bookmark.title}`, type: `${bookmark.type}` }, + { + title: `${bookmark.title}`, + type: `${bookmark.type}`, + }, ]); return [...bookmarks] @@ -110,7 +139,10 @@ function loadBookmarks() { function loadRecents() { const recents = ALL_RECENTS.map((recent) => [ `open-recent::${new Date(recent.utc_time).getTime()}`, - { title: `${recent.title}`, type: `${recent.type}` }, + { + title: `${recent.title}`, + type: `${recent.type}`, + }, ]); return [...recents] @@ -118,9 +150,19 @@ function loadRecents() { .sort(([, recentA], [, recentB]) => matcher(recentB) - matcher(recentA)); } -let ALL_FAVORITES = gitdock.getFavorites() || []; -let ALL_BOOKMARKS = gitdock.getBookmarks() || []; -let ALL_RECENTS = gitdock.getRecents() || []; +function changeTheme() { + if (gitdock.getTheme() === 'light') { + document.documentElement.setAttribute('data-theme', 'light'); + } else if (gitdock.getTheme() === 'dark') { + document.documentElement.setAttribute('data-theme', 'dark'); + } +} + +function changeHighlight(i) { + document.getElementById(`item-${$selected}`)?.classList.remove('selected'); + document.getElementById(`item-${i}`).classList.add('selected'); + $selected = i; +} function search() { html = []; @@ -137,7 +179,7 @@ function search() { const availableRecents = loadRecents(); if (availableOverviews.length > 0) { - html.push(`
    Overview
    `); + html.push('
    Overview
    '); for (const [key, action] of availableOverviews) { const icon = action.icon ? `${action.icon}` : ''; @@ -148,12 +190,12 @@ function search() {
    ${action.title}
    `, ); - i++; + i += 1; } } if (availableFavorites.length > 0) { - html.push(`
    Favorite projects
    `); + html.push('
    Favorite projects
    '); for (const [key, action] of availableFavorites) { const avatar = action.avatar_url ? `` : projectIcon; @@ -164,21 +206,22 @@ function search() {
    ${action.title}
    `, ); - i++; + i += 1; } } if (availableBookmarks.length > 0) { - html.push(`
    Bookmarks
    `); + html.push('
    Bookmarks
    '); for (const [key, action] of availableBookmarks) { let icon; - if (action.type == 'issues') { + if (action.type === 'issues') { icon = issueIcon; - } else if (action.type == 'merge_requests') { + } else if (action.type === 'merge_requests') { icon = mrIcon; } else { - icon = ``; + icon = + ''; } html.push( `
  • ${action.title}
  • `, ); - i++; + i += 1; } } if (availableRecents.length > 0) { - html.push(`
    Recently viewed
    `); + html.push('
    Recently viewed
    '); for (const [key, action] of availableRecents) { let icon; - if (action.type == 'issues') { + if (action.type === 'issues') { icon = issueIcon; - } else if (action.type == 'merge_requests') { + } else if (action.type === 'merge_requests') { icon = mrIcon; } else { - icon = ``; + icon = + ''; } html.push( `
  • ${action.title}
  • `, ); - i++; + i += 1; } } if (availableActions.length > 0) { - html.push(`
    Actions
    `); + html.push('
    Actions
    '); for (const [key, action] of availableActions) { const icon = action.icon ? `${action.icon}` : ''; @@ -226,7 +270,7 @@ function search() {
    ${action.title}
    `, ); - i++; + i += 1; } } @@ -235,27 +279,20 @@ function search() { changeTheme(); } -function matcher({ title }) { - let lowerCaseTitle = title.toLowerCase(); - const term = $search.value; - const terms = term.toLowerCase().split(' ').filter(Boolean); +const hide = () => { + gitdock.hideCommandPalette(); + $search.value = ''; + search(); +}; - let matchCount = 1; - - for (const term of terms) { - matchCount += lowerCaseTitle.split(' ').filter((x) => x.includes(term)).length; - const newTitle = lowerCaseTitle.replace(term, ''); - if (newTitle === lowerCaseTitle) { - return false; - } - lowerCaseTitle = newTitle; - } - - return matchCount; +function hideCursor() { + document.querySelector('body').style.cursor = 'none'; + document.getElementById('mouseoverDisabler').style.display = 'block'; } let lastClick = Date.now(); +// eslint-disable-next-line no-unused-vars function handleClick(target) { if (Date.now() - lastClick < 500) { return; @@ -265,12 +302,12 @@ function handleClick(target) { if (key.startsWith('open-favorite::')) { const favoriteId = parseInt(key.split('::')[1], 10); - const { web_url } = ALL_FAVORITES.find((favorite) => favorite.id === favoriteId); - gitdock.openGitLab(web_url); + const webUrl = ALL_FAVORITES.find((favorite) => favorite.id === favoriteId).web_url; + gitdock.openGitLab(webUrl); } else if (key.startsWith('open-bookmark::')) { const bookmarkAdded = parseInt(key.split('::')[1], 10); - const { web_url } = ALL_BOOKMARKS.find((bookmark) => bookmark.added === bookmarkAdded); - gitdock.openGitLab(web_url); + const webUrl = ALL_BOOKMARKS.find((bookmark) => bookmark.added === bookmarkAdded).web_url; + gitdock.openGitLab(webUrl); } else if (key.startsWith('open-recent::')) { const recentVisited = parseInt(key.split('::')[1], 10); const { url } = ALL_RECENTS.find( @@ -288,61 +325,16 @@ function handleClick(target) { }, 10); } -function changeHighlight(i) { - document.getElementById('item-' + $selected)?.classList.remove('selected'); - document.getElementById('item-' + i).classList.add('selected'); - $selected = i; -} - $search.addEventListener('input', search); search(); -document.getElementById('search').addEventListener('keydown', function (e) { +document.getElementById('search').addEventListener('keydown', (e) => { if (e.which === 38 || e.which === 40) { e.preventDefault(); } }); -document.addEventListener('keydown', (x) => { - if (x.key === 'Escape') { - hide(); - } else { - switch (x.keyCode) { - case 13: - document.getElementById('item-' + $selected).click(); - case 38: - if ($selected > 0) { - changeHighlight($selected - 1); - scroll(document.querySelector('ul').querySelectorAll('li')[$selected], true); - } else { - changeHighlight(html.filter((item) => item.indexOf(' { - document.querySelector('body').style.cursor = 'auto'; - document.getElementById('mouseoverDisabler').style.display = 'none'; -}); - -function hideCursor() { - document.querySelector('body').style.cursor = 'none'; - document.getElementById('mouseoverDisabler').style.display = 'block'; -} - function scroll(element, up) { hideCursor(); let top; @@ -352,20 +344,55 @@ function scroll(element, up) { top = element.offsetTop - (window.innerHeight - 89); } if (element.getBoundingClientRect().top < 89) { - window.scrollTo({ top: top, behavior: 'smooth' }); + window.scrollTo({ + top, + behavior: 'smooth', + }); } if (element.getBoundingClientRect().bottom > window.innerHeight - 40) { - window.scrollTo({ top: top, behavior: 'smooth' }); + window.scrollTo({ + top, + behavior: 'smooth', + }); } } -function changeTheme() { - if (gitdock.getTheme() == 'light') { - document.documentElement.setAttribute('data-theme', 'light'); - } else if (gitdock.getTheme() == 'dark') { - document.documentElement.setAttribute('data-theme', 'dark'); +document.addEventListener('keydown', (x) => { + if (x.key === 'Escape') { + hide(); + } else { + switch (x.keyCode) { + case 13: + document.getElementById(`item-${$selected}`).click(); + break; + case 38: + if ($selected > 0) { + changeHighlight($selected - 1); + scroll(document.querySelector('ul').querySelectorAll('li')[$selected], true); + } else { + changeHighlight(html.filter((item) => item.indexOf(' { + document.querySelector('body').style.cursor = 'auto'; + document.getElementById('mouseoverDisabler').style.display = 'none'; +}); window.addEventListener('blur', () => { search(); @@ -374,9 +401,3 @@ window.addEventListener('blur', () => { window.addEventListener('focus', () => { search(); }); - -const hide = () => { - gitdock.hideCommandPalette(); - $search.value = ''; - search(); -}; diff --git a/src/command-palette/index.js b/src/command-palette/index.js index 6c5ff31..2ed6fc1 100644 --- a/src/command-palette/index.js +++ b/src/command-palette/index.js @@ -1,6 +1,6 @@ const { globalShortcut, BrowserWindow, ipcMain, shell } = require('electron'); -const { store } = require('../../lib/store'); const path = require('path'); +const { store } = require('../../lib/store'); const BrowserHistory = require('../../lib/browser-history'); const gitdock = require('../../lib/gitlab'); @@ -11,8 +11,8 @@ let cpWindow; async function getRecentlyVisited() { recentlyVisitedArray = []; await BrowserHistory.getAllHistory().then(async (history) => { - let item = Array.prototype.concat.apply([], history); - item.sort(function (a, b) { + const item = Array.prototype.concat.apply([], history); + item.sort((a, b) => { if (a.utc_time > b.utc_time) { return -1; } @@ -21,16 +21,16 @@ async function getRecentlyVisited() { } }); let i = 0; - for (let j = 0; j < item.length; j++) { + for (let j = 0; j < item.length; j += 1) { const { title } = item[j]; let { url } = item[j]; const isHostUrl = url.startsWith(`${store.host}/`); - const isIssuable = - url.includes('/-/issues/') || - url.includes('/-/merge_requests/') || - url.includes('/-/epics/'); + const isIssuable = url.includes('/-/issues/'); + url.includes('/-/merge_requests/') || url.includes('/-/epics/'); const displayedTitle = (title || '').split(' · ')[0].split(' (')[0]; - const wasNotProcessed = !recentlyVisitedArray.some((item) => item.title == displayedTitle); + const wasNotProcessed = !recentlyVisitedArray.some( + (arrayItem) => arrayItem.title === displayedTitle, + ); const ignoredTitlePrefixes = [ 'Not Found ', 'New Issue ', @@ -51,23 +51,15 @@ async function getRecentlyVisited() { wasNotProcessed && !ignoredTitlePrefixes.includes(titlePrefix) ) { - let nameWithNamespace = item[j].url.replace(store.host + '/', '').split('/-/')[0]; - if (nameWithNamespace.split('/')[0] != 'groups') { - url = - store.host + - '/api/v4/projects/' + - nameWithNamespace.split('/')[0] + - '%2F' + - nameWithNamespace.split('/')[1] + - '?access_token=' + - store.access_token; + const nameWithNamespace = item[j].url.replace(`${store.host}/`, '').split('/-/')[0]; + if (nameWithNamespace.split('/')[0] !== 'groups') { + url = store.host; + `/api/v4/projects/${nameWithNamespace.split('/')[0]}%2F${ + nameWithNamespace.split('/')[1] + }?access_token=${store.access_token}`; } else { - url = - store.host + - '/api/v4/groups/' + - nameWithNamespace.split('/')[0] + - '?access_token=' + - store.access_token; + url = `${store.host}/api/v4/groups/`; + `${nameWithNamespace.split('/')[0]}?access_token=${store.access_token}`; } await gitdock.fetchUrlInfo(item[j].url).then((result) => { item[j].type = result.type; @@ -75,8 +67,8 @@ async function getRecentlyVisited() { item[j].title = item[j].title.split(' · ')[0]; item[j].title = item[j].title.split(' (')[0]; recentlyVisitedArray.push(item[j]); - i++; - if (i == 5) { + i += 1; + if (i === 5) { break; } } @@ -123,7 +115,7 @@ module.exports = class CommandPalette { async open() { cpWindow.show(); - //cpWindow.openDevTools(); + // cpWindow.openDevTools(); } newWindow(show = false) { diff --git a/src/command-palette/preload.js b/src/command-palette/preload.js index 2729b68..36a9a4d 100644 --- a/src/command-palette/preload.js +++ b/src/command-palette/preload.js @@ -6,7 +6,7 @@ const api = { hideCommandPalette: () => ipcRenderer.send('hide-command-palette'), getUsername: () => store.username, getFavorites: () => store['favorite-projects'], - getBookmarks: () => store['bookmarks'], + getBookmarks: () => store.bookmarks, getRecents: () => store['recently-visited'], getTheme: () => store.theme, }; diff --git a/test/bookmarks.spec.js b/test/bookmarks.spec.js index f5c1cd0..6a14fd5 100644 --- a/test/bookmarks.spec.js +++ b/test/bookmarks.spec.js @@ -9,9 +9,11 @@ describe('"Bookmarks" section', function () { await window.click('#bookmark-add-button'); }; - describe('without bookmarks', function () { + describe('without bookmarks', () => { beforeEach(async function () { - await newApp(this, { loggedIn: true }); + await newApp(this, { + loggedIn: true, + }); }); stopAppAfterEach(); @@ -30,7 +32,7 @@ describe('"Bookmarks" section', function () { }); }); - describe('with bookmarks', function () { + describe('with bookmarks', () => { const FIRST_BOOKMARK_URL = 'https://gitlab.com/user/project/-/merge_requests/1'; beforeEach(async function () { diff --git a/test/favorite-projects.spec.js b/test/favorite-projects.spec.js index 62d8647..1ce43e9 100644 --- a/test/favorite-projects.spec.js +++ b/test/favorite-projects.spec.js @@ -12,7 +12,9 @@ describe('Favorite projects', function () { visibility: 'public', name: 'GitDock ⚓️', title: 'GitDock ⚓️', - namespace: { name: 'Marcel van Remmerden' }, + namespace: { + name: 'Marcel van Remmerden', + }, parent_name: 'Marcel van Remmerden / GitDock ⚓️', parent_url: 'https://gitlab.com/mvanremmerden', name_with_namespace: 'Marcel van Remmerden / GitDock ⚓️', @@ -39,7 +41,9 @@ describe('Favorite projects', function () { }; beforeEach(async function () { - await newApp(this, { loggedIn: true }); + await newApp(this, { + loggedIn: true, + }); }); stopAppAfterEach(); diff --git a/test/features.spec.js b/test/features.spec.js index 76b3b85..f588b33 100644 --- a/test/features.spec.js +++ b/test/features.spec.js @@ -5,7 +5,9 @@ describe('Feature tests', function () { this.timeout(25000); beforeEach(async function () { - await newApp(this, { loggedIn: true }); + await newApp(this, { + loggedIn: true, + }); }); stopAppAfterEach(); diff --git a/test/recently-viewed.spec.js b/test/recently-viewed.spec.js index 9a58db6..841e022 100644 --- a/test/recently-viewed.spec.js +++ b/test/recently-viewed.spec.js @@ -19,21 +19,22 @@ describe('"Recently viewed" section', function () { }, ]; - const supportedBrowsersText = async (page) => { - return page.innerText('.supported-browsers'); - }; + const supportedBrowsersText = async (page) => page.innerText('.supported-browsers'); const historyTexts = async (page) => { const elements = await page.locator('.history-entry'); return elements.allInnerTexts(); }; - SUPPORTED_PLATFORMS.forEach(function ({ platform, emptyMessage }) { - describe(`${platform} platform`, function () { + SUPPORTED_PLATFORMS.forEach(({ platform, emptyMessage }) => { + describe(`${platform} platform`, () => { describe('without history', function () { stopAppAfterEach(); this.beforeEach(async function () { - await newApp(this, { platform, loggedIn: true }); + await newApp(this, { + platform, + loggedIn: true, + }); }); it('renders the correct message', async function () { @@ -72,14 +73,17 @@ describe('"Recently viewed" section', function () { }); }); - describe('unsupported platform', function () { + describe('unsupported platform', () => { const platform = 'android'; const emptyMessage = 'No browsers are supported on your operating system yet.'; describe('without history', function () { stopAppAfterEach(); this.beforeEach(async function () { - await newApp(this, { platform, loggedIn: true }); + await newApp(this, { + platform, + loggedIn: true, + }); }); it('renders the correct message', async function () { @@ -95,7 +99,10 @@ describe('"Recently viewed" section', function () { platform, loggedIn: true, browserHistory: [ - { title: 'Test Issue #1', url: 'https://gitlab.com/user/project/-/issues/1' }, + { + title: 'Test Issue #1', + url: 'https://gitlab.com/user/project/-/issues/1', + }, ], }); }); diff --git a/test/themes.spec.js b/test/themes.spec.js index 8d6d060..2dd7b09 100644 --- a/test/themes.spec.js +++ b/test/themes.spec.js @@ -9,7 +9,7 @@ describe('Themes', function () { return await body.evaluate((button) => getComputedStyle(button).backgroundColor); }; - describe('default theme', function () { + describe('default theme', () => { stopAppAfterEach(); beforeEach(async function () { @@ -23,11 +23,13 @@ describe('Themes', function () { }); }); - describe('dark theme', function () { + describe('dark theme', () => { stopAppAfterEach(); beforeEach(async function () { - await newApp(this, { theme: 'dark' }); + await newApp(this, { + theme: 'dark', + }); }); it('has the correct background color', async function () { @@ -37,11 +39,13 @@ describe('Themes', function () { }); }); - describe('light theme', function () { + describe('light theme', () => { stopAppAfterEach(); beforeEach(async function () { - await newApp(this, { theme: 'light' }); + await newApp(this, { + theme: 'light', + }); }); it('has the correct background color', async function () { diff --git a/test/util/__mocks__/store.js b/test/util/__mocks__/store.js index e462e2c..4e96125 100644 --- a/test/util/__mocks__/store.js +++ b/test/util/__mocks__/store.js @@ -15,11 +15,10 @@ const store = JSON.parse(process.env.MOCK_STORE || '{}'); const proxy = new Proxy(store, { get(target, key) { - if (target[key] == undefined) { + if (target[key] === undefined) { return defaults[key]; - } else { - return target[key]; } + return target[key]; }, set(target, key, value) { target[key] = value; diff --git a/test/util/index.js b/test/util/index.js index 9fd08ec..8442ad7 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -71,7 +71,10 @@ module.exports = { thisValue.window = window; } - return { app, window }; + return { + app, + window, + }; }, stopAppAfterEach() { afterEach(async function () { diff --git a/test/util/mocks.js b/test/util/mocks.js index 5b1e82b..ad63369 100644 --- a/test/util/mocks.js +++ b/test/util/mocks.js @@ -18,6 +18,7 @@ const mockRegistry = { // Below is the dependency replace logic const path = require('path'); + const nodeRequire = require.extensions['.js']; const PROJECT_ROOT = path.join(__dirname, '..', '..');