Command palette - initial implementation (#388)

This commit is contained in:
Piotr Rogowski 2022-01-23 19:21:45 +01:00 committed by GitHub
parent a3b2291d5d
commit 449f5c2708
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 541 additions and 94 deletions

305
package-lock.json generated
View File

@ -15,7 +15,8 @@
"@speedy-tuner/ini": "^0.3.0",
"@speedy-tuner/types": "^0.3.0",
"antd": "^4.18.4",
"firebase": "^9.6.3",
"firebase": "^9.6.4",
"kbar": "^0.1.0-beta.27",
"mlg-converter": "^0.5.1",
"nanoid": "^3.2.0",
"pako": "^2.0.4",
@ -42,7 +43,7 @@
"eslint-plugin-prettier": "^4.0.0",
"less-loader": "^6.1.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
"typescript": "^4.5.5",
"worker-loader": "^3.0.8"
}
},
@ -2035,9 +2036,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@firebase/app": {
"version": "0.7.13",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.13.tgz",
"integrity": "sha512-nMnz+lxASVZrWcAgLIgvs2QcsySjYvNpGjDeyhMzrbyBoBLgTux0cGWtm5RrJKx7arqueRpIihxcJtKAzCcIsw==",
"version": "0.7.14",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.14.tgz",
"integrity": "sha512-15Pv8Rt45GlDwqlnFRXqlNjjERx2VkWDyWGLsXlCZYg9+F8c++GTWezacFoZfkLzUZ4W54iyofDujfUadzHv1g==",
"dependencies": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
@ -2090,11 +2091,11 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@firebase/app-compat": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.14.tgz",
"integrity": "sha512-CvT7/TdfWNRudrExAyWiPcMVtaqljE4mch/KfmfSz1mGmK0j/y1DN6PDJ+NZxkI+Za+YRkOI55H6DdIBsYQ0Qg==",
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.15.tgz",
"integrity": "sha512-hfk6eHKUb+qHPZLtQuUdNFY4gTYD47Q64oajKAtb6r6YcErYvxRoZPDJ2Xjv4PCioG+3q+f0YDUKfMJlRtK0IA==",
"dependencies": {
"@firebase/app": "0.7.13",
"@firebase/app": "0.7.14",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
@ -2117,9 +2118,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@firebase/auth": {
"version": "0.19.5",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.19.5.tgz",
"integrity": "sha512-3+9XUnxaNb+ck6yULtEwOZbikWpL9KXuNLR34GxRv3mpOKD3uNbbONT149zMo3C6asI1bdv4+hCM78aS8VhZ0w==",
"version": "0.19.6",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.19.6.tgz",
"integrity": "sha512-hlIX9jJWk/4E6JiEf9H4LLv8dNJLR17iryR1MaC58Y4U9ioYcxz8q7NMSUTyr5mJjYD/YBWrQXkE1V+gUnMnJw==",
"dependencies": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
@ -2133,11 +2134,11 @@
}
},
"node_modules/@firebase/auth-compat": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.5.tgz",
"integrity": "sha512-Ft9PkmWOioxPMts6CMopN7sHpSXipQigOdm4BQ5HYTGHyLZpid2cj+2LxWsOYqQlhA1YBtzwE7sBRpV0W6bblQ==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.6.tgz",
"integrity": "sha512-gBxhGGJ/jiL4LfMC6Nlx7LteKNMlKV+0SsyrXT3SFzpseCX8ayOVo+qKCTAkTJqupm4li1lIgwIXhrD2OsbHBw==",
"dependencies": {
"@firebase/auth": "0.19.5",
"@firebase/auth": "0.19.6",
"@firebase/auth-types": "0.11.0",
"@firebase/component": "0.5.10",
"@firebase/util": "1.4.3",
@ -2374,9 +2375,9 @@
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@firebase/messaging": {
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.6.tgz",
"integrity": "sha512-weDGzgU0MNtC6FCFJu/AW+pXbuX/YasHqR42NcLyoHNL8EgjXLPC0EYeMi7B8dY7MCsbc5lbPtqiveOP97L1jQ==",
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.7.tgz",
"integrity": "sha512-qRPWO5fvS1yahe0As0rlpo+Gc3v5IKHlULGJPYvWGJWE3W5aCvooxsT3vYgYNmAMFjgLlugfg8KKd41O1ebgqg==",
"dependencies": {
"@firebase/component": "0.5.10",
"@firebase/installations": "0.5.5",
@ -2390,12 +2391,12 @@
}
},
"node_modules/@firebase/messaging-compat": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.6.tgz",
"integrity": "sha512-VzNM5ew8YAH7tzyukY0QqrCKdmaIe1FsWJSNPWcfzMNri8mpfKALIjeFzle+6DrRWZweFsp8ejvcvvulIDILGw==",
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.7.tgz",
"integrity": "sha512-EKKcMin7myL8GXu2Mq6daje6o13VZtgxUKe+sLVL4DfxPbJdhVvNirYTi14KM81tDPdKAIakZNIGiIm/r8S2zA==",
"dependencies": {
"@firebase/component": "0.5.10",
"@firebase/messaging": "0.9.6",
"@firebase/messaging": "0.9.7",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
},
@ -3710,6 +3711,48 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"node_modules/@reach/observe-rect": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz",
"integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ=="
},
"node_modules/@reach/portal": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@reach/portal/-/portal-0.16.2.tgz",
"integrity": "sha512-9ur/yxNkuVYTIjAcfi46LdKUvH0uYZPfEp4usWcpt6PIp+WDF57F/5deMe/uGi/B/nfDweQu8VVwuMVrCb97JQ==",
"dependencies": {
"@reach/utils": "0.16.0",
"tiny-warning": "^1.0.3",
"tslib": "^2.3.0"
},
"peerDependencies": {
"react": "^16.8.0 || 17.x",
"react-dom": "^16.8.0 || 17.x"
}
},
"node_modules/@reach/portal/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@reach/utils": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.16.0.tgz",
"integrity": "sha512-PCggBet3qaQmwFNcmQ/GqHSefadAFyNCUekq9RrWoaU9hh/S4iaFgf2MBMdM47eQj5i/Bk0Mm07cP/XPFlkN+Q==",
"dependencies": {
"tiny-warning": "^1.0.3",
"tslib": "^2.3.0"
},
"peerDependencies": {
"react": "^16.8.0 || 17.x",
"react-dom": "^16.8.0 || 17.x"
}
},
"node_modules/@reach/utils/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/@reduxjs/toolkit": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.1.tgz",
@ -10119,6 +10162,11 @@
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
"node_modules/fast-equals": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz",
"integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w=="
},
"node_modules/fast-glob": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
@ -10370,19 +10418,19 @@
}
},
"node_modules/firebase": {
"version": "9.6.3",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-9.6.3.tgz",
"integrity": "sha512-CMzv2LJGruZNtKI6pk1XLVaDC7ujIcq/S57wbC9XGllykIh86GLNPwVEWuCqCWmQDAZLyhi0t6tW/F2NX3HcPA==",
"version": "9.6.4",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-9.6.4.tgz",
"integrity": "sha512-f9DpaBeesOKhF1mkAzAmDQ8pWq9VMvjV9y27BDtih+0VrAlHgmGPTt58y9IFZbjQyRsegpuVXjml1hMXe7qG+A==",
"dependencies": {
"@firebase/analytics": "0.7.5",
"@firebase/analytics-compat": "0.1.6",
"@firebase/app": "0.7.13",
"@firebase/app": "0.7.14",
"@firebase/app-check": "0.5.3",
"@firebase/app-check-compat": "0.2.3",
"@firebase/app-compat": "0.1.14",
"@firebase/app-compat": "0.1.15",
"@firebase/app-types": "0.7.0",
"@firebase/auth": "0.19.5",
"@firebase/auth-compat": "0.2.5",
"@firebase/auth": "0.19.6",
"@firebase/auth-compat": "0.2.6",
"@firebase/database": "0.12.5",
"@firebase/database-compat": "0.1.5",
"@firebase/firestore": "3.4.3",
@ -10390,8 +10438,8 @@
"@firebase/functions": "0.7.7",
"@firebase/functions-compat": "0.1.8",
"@firebase/installations": "0.5.5",
"@firebase/messaging": "0.9.6",
"@firebase/messaging-compat": "0.1.6",
"@firebase/messaging": "0.9.7",
"@firebase/messaging-compat": "0.1.7",
"@firebase/performance": "0.5.5",
"@firebase/performance-compat": "0.1.5",
"@firebase/polyfill": "0.3.36",
@ -14308,6 +14356,22 @@
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"node_modules/kbar": {
"version": "0.1.0-beta.27",
"resolved": "https://registry.npmjs.org/kbar/-/kbar-0.1.0-beta.27.tgz",
"integrity": "sha512-4knRJxDQqx3LUduhjuJh9EDGxnFpaQKjXt11UOsjKQ4ByXTTQpPjfAaKagVcTp9uVwEXGDhvGrsGbMfrI+6/Kg==",
"dependencies": {
"@reach/portal": "^0.16.0",
"fast-equals": "^2.0.3",
"match-sorter": "^6.3.0",
"react-virtual": "^2.8.2",
"tiny-invariant": "^1.2.0"
},
"peerDependencies": {
"react": "^16.0.0 || ^17.0.0",
"react-dom": "^16.0.0 || ^17.0.0"
}
},
"node_modules/killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -14652,6 +14716,15 @@
"node": ">=0.10.0"
}
},
"node_modules/match-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
"integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"remove-accents": "0.4.2"
}
},
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -19311,6 +19384,20 @@
"node": ">=10"
}
},
"node_modules/react-virtual": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/react-virtual/-/react-virtual-2.10.3.tgz",
"integrity": "sha512-ZcQ+4oTQnJw79gmIzoEx6gfobADLj+9gdIiG4TTK5mUI6BAkEh83lmNU9WZPzi3FI77tXOYlWKC3fnHRH6kR5w==",
"funding": [
"https://github.com/sponsors/tannerlinsley"
],
"dependencies": {
"@reach/observe-rect": "^1.1.0"
},
"peerDependencies": {
"react": "^16.6.3 || ^17.0.0"
}
},
"node_modules/read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -19631,6 +19718,11 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/remove-accents": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
"integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U="
},
"node_modules/remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@ -22546,9 +22638,9 @@
}
},
"node_modules/typescript": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -26530,9 +26622,9 @@
"integrity": "sha512-DNE2Waiwy5+zZnCfintkDtBfaW6MjIG883474v6Z0K1XZIvl76cLND4iv0YUb48leyF+PJK1KO2XrgHb/KpmhQ=="
},
"@firebase/app": {
"version": "0.7.13",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.13.tgz",
"integrity": "sha512-nMnz+lxASVZrWcAgLIgvs2QcsySjYvNpGjDeyhMzrbyBoBLgTux0cGWtm5RrJKx7arqueRpIihxcJtKAzCcIsw==",
"version": "0.7.14",
"resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.7.14.tgz",
"integrity": "sha512-15Pv8Rt45GlDwqlnFRXqlNjjERx2VkWDyWGLsXlCZYg9+F8c++GTWezacFoZfkLzUZ4W54iyofDujfUadzHv1g==",
"requires": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
@ -26590,11 +26682,11 @@
"integrity": "sha512-uZfn9s4uuRsaX5Lwx+gFP3B6YsyOKUE+Rqa6z9ojT4VSRAsZFko9FRn6OxQUA1z5t5d08fY4pf+/+Dkd5wbdbA=="
},
"@firebase/app-compat": {
"version": "0.1.14",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.14.tgz",
"integrity": "sha512-CvT7/TdfWNRudrExAyWiPcMVtaqljE4mch/KfmfSz1mGmK0j/y1DN6PDJ+NZxkI+Za+YRkOI55H6DdIBsYQ0Qg==",
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.1.15.tgz",
"integrity": "sha512-hfk6eHKUb+qHPZLtQuUdNFY4gTYD47Q64oajKAtb6r6YcErYvxRoZPDJ2Xjv4PCioG+3q+f0YDUKfMJlRtK0IA==",
"requires": {
"@firebase/app": "0.7.13",
"@firebase/app": "0.7.14",
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
"@firebase/util": "1.4.3",
@ -26614,9 +26706,9 @@
"integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg=="
},
"@firebase/auth": {
"version": "0.19.5",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.19.5.tgz",
"integrity": "sha512-3+9XUnxaNb+ck6yULtEwOZbikWpL9KXuNLR34GxRv3mpOKD3uNbbONT149zMo3C6asI1bdv4+hCM78aS8VhZ0w==",
"version": "0.19.6",
"resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.19.6.tgz",
"integrity": "sha512-hlIX9jJWk/4E6JiEf9H4LLv8dNJLR17iryR1MaC58Y4U9ioYcxz8q7NMSUTyr5mJjYD/YBWrQXkE1V+gUnMnJw==",
"requires": {
"@firebase/component": "0.5.10",
"@firebase/logger": "0.3.2",
@ -26634,11 +26726,11 @@
}
},
"@firebase/auth-compat": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.5.tgz",
"integrity": "sha512-Ft9PkmWOioxPMts6CMopN7sHpSXipQigOdm4BQ5HYTGHyLZpid2cj+2LxWsOYqQlhA1YBtzwE7sBRpV0W6bblQ==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.2.6.tgz",
"integrity": "sha512-gBxhGGJ/jiL4LfMC6Nlx7LteKNMlKV+0SsyrXT3SFzpseCX8ayOVo+qKCTAkTJqupm4li1lIgwIXhrD2OsbHBw==",
"requires": {
"@firebase/auth": "0.19.5",
"@firebase/auth": "0.19.6",
"@firebase/auth-types": "0.11.0",
"@firebase/component": "0.5.10",
"@firebase/util": "1.4.3",
@ -26857,9 +26949,9 @@
}
},
"@firebase/messaging": {
"version": "0.9.6",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.6.tgz",
"integrity": "sha512-weDGzgU0MNtC6FCFJu/AW+pXbuX/YasHqR42NcLyoHNL8EgjXLPC0EYeMi7B8dY7MCsbc5lbPtqiveOP97L1jQ==",
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.9.7.tgz",
"integrity": "sha512-qRPWO5fvS1yahe0As0rlpo+Gc3v5IKHlULGJPYvWGJWE3W5aCvooxsT3vYgYNmAMFjgLlugfg8KKd41O1ebgqg==",
"requires": {
"@firebase/component": "0.5.10",
"@firebase/installations": "0.5.5",
@ -26877,12 +26969,12 @@
}
},
"@firebase/messaging-compat": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.6.tgz",
"integrity": "sha512-VzNM5ew8YAH7tzyukY0QqrCKdmaIe1FsWJSNPWcfzMNri8mpfKALIjeFzle+6DrRWZweFsp8ejvcvvulIDILGw==",
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.1.7.tgz",
"integrity": "sha512-EKKcMin7myL8GXu2Mq6daje6o13VZtgxUKe+sLVL4DfxPbJdhVvNirYTi14KM81tDPdKAIakZNIGiIm/r8S2zA==",
"requires": {
"@firebase/component": "0.5.10",
"@firebase/messaging": "0.9.6",
"@firebase/messaging": "0.9.7",
"@firebase/util": "1.4.3",
"tslib": "^2.1.0"
},
@ -27906,6 +27998,44 @@
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"@reach/observe-rect": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@reach/observe-rect/-/observe-rect-1.2.0.tgz",
"integrity": "sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ=="
},
"@reach/portal": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@reach/portal/-/portal-0.16.2.tgz",
"integrity": "sha512-9ur/yxNkuVYTIjAcfi46LdKUvH0uYZPfEp4usWcpt6PIp+WDF57F/5deMe/uGi/B/nfDweQu8VVwuMVrCb97JQ==",
"requires": {
"@reach/utils": "0.16.0",
"tiny-warning": "^1.0.3",
"tslib": "^2.3.0"
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"@reach/utils": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/@reach/utils/-/utils-0.16.0.tgz",
"integrity": "sha512-PCggBet3qaQmwFNcmQ/GqHSefadAFyNCUekq9RrWoaU9hh/S4iaFgf2MBMdM47eQj5i/Bk0Mm07cP/XPFlkN+Q==",
"requires": {
"tiny-warning": "^1.0.3",
"tslib": "^2.3.0"
},
"dependencies": {
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"@reduxjs/toolkit": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.7.1.tgz",
@ -32843,6 +32973,11 @@
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
"dev": true
},
"fast-equals": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-2.0.4.tgz",
"integrity": "sha512-caj/ZmjHljPrZtbzJ3kfH5ia/k4mTJe/qSiXAGzxZWRZgsgDV0cvNaQULqUX8t0/JVlzzEdYOwCN5DmzTxoD4w=="
},
"fast-glob": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz",
@ -33038,19 +33173,19 @@
}
},
"firebase": {
"version": "9.6.3",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-9.6.3.tgz",
"integrity": "sha512-CMzv2LJGruZNtKI6pk1XLVaDC7ujIcq/S57wbC9XGllykIh86GLNPwVEWuCqCWmQDAZLyhi0t6tW/F2NX3HcPA==",
"version": "9.6.4",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-9.6.4.tgz",
"integrity": "sha512-f9DpaBeesOKhF1mkAzAmDQ8pWq9VMvjV9y27BDtih+0VrAlHgmGPTt58y9IFZbjQyRsegpuVXjml1hMXe7qG+A==",
"requires": {
"@firebase/analytics": "0.7.5",
"@firebase/analytics-compat": "0.1.6",
"@firebase/app": "0.7.13",
"@firebase/app": "0.7.14",
"@firebase/app-check": "0.5.3",
"@firebase/app-check-compat": "0.2.3",
"@firebase/app-compat": "0.1.14",
"@firebase/app-compat": "0.1.15",
"@firebase/app-types": "0.7.0",
"@firebase/auth": "0.19.5",
"@firebase/auth-compat": "0.2.5",
"@firebase/auth": "0.19.6",
"@firebase/auth-compat": "0.2.6",
"@firebase/database": "0.12.5",
"@firebase/database-compat": "0.1.5",
"@firebase/firestore": "3.4.3",
@ -33058,8 +33193,8 @@
"@firebase/functions": "0.7.7",
"@firebase/functions-compat": "0.1.8",
"@firebase/installations": "0.5.5",
"@firebase/messaging": "0.9.6",
"@firebase/messaging-compat": "0.1.6",
"@firebase/messaging": "0.9.7",
"@firebase/messaging-compat": "0.1.7",
"@firebase/performance": "0.5.5",
"@firebase/performance-compat": "0.1.5",
"@firebase/polyfill": "0.3.36",
@ -35967,6 +36102,18 @@
}
}
},
"kbar": {
"version": "0.1.0-beta.27",
"resolved": "https://registry.npmjs.org/kbar/-/kbar-0.1.0-beta.27.tgz",
"integrity": "sha512-4knRJxDQqx3LUduhjuJh9EDGxnFpaQKjXt11UOsjKQ4ByXTTQpPjfAaKagVcTp9uVwEXGDhvGrsGbMfrI+6/Kg==",
"requires": {
"@reach/portal": "^0.16.0",
"fast-equals": "^2.0.3",
"match-sorter": "^6.3.0",
"react-virtual": "^2.8.2",
"tiny-invariant": "^1.2.0"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -36247,6 +36394,15 @@
"object-visit": "^1.0.0"
}
},
"match-sorter": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.1.tgz",
"integrity": "sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==",
"requires": {
"@babel/runtime": "^7.12.5",
"remove-accents": "0.4.2"
}
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -39772,6 +39928,14 @@
}
}
},
"react-virtual": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/react-virtual/-/react-virtual-2.10.3.tgz",
"integrity": "sha512-ZcQ+4oTQnJw79gmIzoEx6gfobADLj+9gdIiG4TTK5mUI6BAkEh83lmNU9WZPzi3FI77tXOYlWKC3fnHRH6kR5w==",
"requires": {
"@reach/observe-rect": "^1.1.0"
}
},
"read-pkg": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
@ -40018,6 +40182,11 @@
"unified": "^10.0.0"
}
},
"remove-accents": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz",
"integrity": "sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U="
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@ -42294,9 +42463,9 @@
}
},
"typescript": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
"version": "4.5.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA=="
},
"unbox-primitive": {
"version": "1.0.1",

View File

@ -37,7 +37,8 @@
"@speedy-tuner/ini": "^0.3.0",
"@speedy-tuner/types": "^0.3.0",
"antd": "^4.18.4",
"firebase": "^9.6.3",
"firebase": "^9.6.4",
"kbar": "^0.1.0-beta.27",
"mlg-converter": "^0.5.1",
"nanoid": "^3.2.0",
"pako": "^2.0.4",
@ -64,7 +65,7 @@
"eslint-plugin-prettier": "^4.0.0",
"less-loader": "^6.1.0",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
"typescript": "^4.5.5",
"worker-loader": "^3.0.8"
}
}

View File

@ -5,6 +5,14 @@
@import './themes/common.less';
@import './themes/ant.less';
:root {
--background: @component-background;
--foreground: @text;
--a1: @main;
--border: @border-color-split;
--shadow: @shadow-2;
}
body {
overflow: hidden;
}
@ -90,7 +98,7 @@ html, body {
td {
text-align: center;
border: 1px solid @main-light;
border: 1px solid @component-background;
height: 50px;
// transition: all 0.1s;
@ -142,12 +150,12 @@ select:-webkit-autofill:focus {
}
.markdown-preview {
background-color: @main-light;
background-color: @component-background;
padding: 5px 11px;
border-style: solid;
border-width: 1px;
border-radius: @border-radius-base;
border-color: @main-dark;
border-color: @border-color-split;
h1 {
font-size: 2em;

View File

@ -24,8 +24,6 @@ import { Routes } from './routes';
import { loadTune } from './utils/api';
import store from './store';
import Log from './pages/Log';
import 'react-perfect-scrollbar/dist/css/styles.css';
import './App.less';
import {
AppState,
@ -36,6 +34,8 @@ import useDb from './hooks/useDb';
import useServerStorage from './hooks/useServerStorage';
import Info from './pages/Info';
import 'react-perfect-scrollbar/dist/css/styles.css';
// TODO: fix this
// lazy loading this component causes a weird Curve canvas scaling
// const Log = lazy(() => import('./pages/Log'));

View File

@ -0,0 +1,257 @@
import {
CSSProperties,
forwardRef,
Fragment,
Ref,
useMemo,
ReactNode,
useCallback,
} from 'react';
import {
ActionId,
KBarAnimator,
KBarProvider,
KBarPortal,
KBarPositioner,
KBarSearch,
KBarResults,
useMatches,
ActionImpl,
} from 'kbar';
import {
CloudUploadOutlined,
LoginOutlined,
UserAddOutlined,
LogoutOutlined,
} from '@ant-design/icons';
import { useHistory } from 'react-router';
import { Routes } from '../routes';
import { useAuth } from '../contexts/AuthContext';
import {
logOutFailed,
logOutSuccessful,
} from '../pages/auth/notifications';
import store from '../store';
import { isMac } from '../utils/env';
enum Sections {
NAVIGATION = 'Navigation',
AUTH = 'Authentication',
};
const searchStyle = {
padding: '12px 16px',
fontSize: '16px',
width: '100%',
boxSizing: 'border-box' as CSSProperties['boxSizing'],
outline: 'none',
border: 'none',
background: 'var(--background)',
color: 'var(--foreground)',
};
const animatorStyle = {
maxWidth: '600px',
width: '100%',
background: 'var(--background)',
color: 'var(--foreground)',
borderRadius: '8px',
overflow: 'hidden',
boxShadow: 'var(--shadow)',
};
const groupNameStyle = {
padding: '8px 16px',
fontSize: '10px',
textTransform: 'uppercase' as const,
opacity: 0.5,
};
const ResultItem = forwardRef(
(
{
action,
active,
currentRootActionId,
}: {
action: ActionImpl;
active: boolean;
currentRootActionId: ActionId;
},
ref: Ref<HTMLDivElement>,
) => {
const ancestors = useMemo(() => {
if (!currentRootActionId) return action.ancestors;
const index = action.ancestors.findIndex(
(ancestor) => ancestor.id === currentRootActionId,
);
// +1 removes the currentRootAction (currently active item)
return action.ancestors.slice(index + 1);
}, [action.ancestors, currentRootActionId]);
return (
<div
ref={ref}
style={{
padding: '12px 16px',
background: active ? 'var(--a1)' : 'transparent',
borderLeft: `2px solid ${active ? 'var(--foreground)' : 'transparent'}`,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
cursor: 'pointer',
}}
>
<div
style={{
display: 'flex',
gap: '8px',
alignItems: 'center',
fontSize: 14,
}}
>
{action.icon && action.icon}
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div>
{ancestors.length > 0 &&
ancestors.map((ancestor: any) => (
<Fragment key={ancestor.id}>
<span
style={{
opacity: 0.5,
marginRight: 8,
}}
>
{ancestor.name}
</span>
<span style={{ marginRight: 8 }}>
&rsaquo;
</span>
</Fragment>
))}
<span>{action.name}</span>
</div>
{action.subtitle && (
<span style={{ fontSize: 12 }}>{action.subtitle}</span>
)}
</div>
</div>
{action.shortcut?.length ? (
<div
aria-hidden
style={{ display: 'grid', gridAutoFlow: 'column', gap: '4px' }}
>
{action.shortcut.map((sc: any) => (
<kbd
key={sc}
style={{
padding: '4px 6px',
background: 'rgba(0 0 0 / .1)',
borderRadius: '4px',
fontSize: 14,
}}
>
{sc}
</kbd>
))}
</div>
) : null}
</div>
);
},
);
const RenderResults = () => {
const { results, rootActionId } = useMatches();
const onResultsRender = ({ item, active }: { item: any, active: any }) =>
typeof item === 'string' ? (
<div style={groupNameStyle}>{item}</div>
) : (
<ResultItem
action={item}
active={active}
currentRootActionId={rootActionId as string}
/>
);
return (
<KBarResults
items={results}
onRender={onResultsRender}
/>
);
};
const CommandPalette = (props: { children: ReactNode }) => {
const { children } = props;
const history = useHistory();
const { logout } = useAuth();
const logoutAction = useCallback(async() => {
try {
await logout();
logOutSuccessful();
} catch (error) {
console.warn(error);
logOutFailed(error as Error);
}
}, [logout]);
const initialActions = useMemo(() => [
{
id: 'ToggleSidebar',
name: 'Toggle Sidebar',
shortcut: [isMac ? '⌘' : 'ctrl', '\\'],
perform: () => store.dispatch({ type: 'ui/toggleSidebar' }),
},
{
id: 'UploadAction',
name: 'Upload',
section: Sections.NAVIGATION,
icon: <CloudUploadOutlined />,
subtitle: 'Upload tune and logs.',
perform: () => history.push(Routes.UPLOAD),
},
{
id: 'LoginAction',
name: 'Login',
section: Sections.AUTH,
icon: <LoginOutlined />,
subtitle: 'Login using email, Google or GitHub account.',
perform: () => history.push(Routes.LOGIN),
},
{
id: 'SignUpAction',
name: 'Sign-up',
section: Sections.AUTH,
icon: <UserAddOutlined />,
subtitle: 'Create new account.',
perform: () => history.push(Routes.SIGN_UP),
},
{
id: 'LogoutAction',
name: 'Logout',
section: Sections.AUTH,
icon: <LogoutOutlined />,
subtitle: 'Logout current user.',
perform: logoutAction,
},
], [history, logoutAction]);
return (
<KBarProvider actions={initialActions}>
<KBarPortal>
<KBarPositioner>
<KBarAnimator style={animatorStyle}>
<KBarSearch style={searchStyle} />
<RenderResults />
</KBarAnimator>
</KBarPositioner>
</KBarPortal>
{children}
</KBarProvider>
);
};
export default CommandPalette;

View File

@ -1,3 +1,8 @@
import {
useCallback,
useEffect,
useMemo,
} from 'react';
import {
matchPath,
useLocation,
@ -41,12 +46,7 @@ import {
LogoutOutlined,
InfoCircleOutlined,
} from '@ant-design/icons';
import {
useCallback,
useEffect,
useMemo,
useRef,
} from 'react';
import { useKBar } from 'kbar';
import store from '../store';
import { isMac } from '../utils/env';
import {
@ -69,6 +69,7 @@ const TopBar = ({ tuneId }: { tuneId: string | null }) => {
const { pathname } = useLocation();
const { currentUser, logout } = useAuth();
const history = useHistory();
const { query } = useKBar();
const buildTuneUrl = (route: string) => tuneId ? generatePath(route, { tuneId }) : null;
const matchedTuneRootPath = useMemo(() => matchPath(pathname, {
path: Routes.TUNE_ROOT,
@ -86,20 +87,19 @@ const TopBar = ({ tuneId }: { tuneId: string | null }) => {
}
}, [logout]);
const searchInput = useRef<HTMLElement | null>(null);
const handleGlobalKeyboard = (e: KeyboardEvent) => {
const toggleCommandPalette = useCallback(() => query.toggle(), [query]);
const handleGlobalKeyboard = useCallback((e: KeyboardEvent) => {
if (isCommand(e)) {
if (searchInput) {
e.preventDefault();
searchInput.current!.focus();
}
toggleCommandPalette();
}
if (isToggleSidebar(e)) {
e.preventDefault();
store.dispatch({ type: 'ui/toggleSidebar' });
}
};
}, [toggleCommandPalette]);
useEffect(() => {
document.addEventListener('keydown', handleGlobalKeyboard);
@ -143,21 +143,31 @@ const TopBar = ({ tuneId }: { tuneId: string | null }) => {
</Col>
);
const rightMenuColProps = tuneId ? {
span: 10,
md: 8,
sm: 8,
} : {
span: 14,
md: 10,
sm: 8,
};
return (
<Header className="app-top-bar">
<Row>
<Col span={0} md={4} sm={0} />
{tuneId ? tabs : <Col span={10} md={10} sm={16} />}
<Col span={10} md={8} sm={8} style={{ textAlign: 'right' }}>
<Col {...rightMenuColProps} style={{ textAlign: 'right' }}>
<Space>
{sm && <Tooltip visible={false} title={
{sm && <Tooltip title={
<>
<Typography.Text keyboard>{isMac ? '⌘' : 'CTRL'}</Typography.Text>
<Typography.Text keyboard>SHIFT</Typography.Text>
<Typography.Text keyboard>P</Typography.Text>
</>
}>
<Button disabled icon={<SearchOutlined />} ref={searchInput} />
<Button icon={<SearchOutlined />} onClick={toggleCommandPalette} />
</Tooltip>}
<Link to={Routes.UPLOAD}>
<Button icon={<CloudUploadOutlined />} type={matchedTabPath?.url === Routes.UPLOAD ? 'primary' : 'default'}>
@ -166,7 +176,7 @@ const TopBar = ({ tuneId }: { tuneId: string | null }) => {
</Link>
<Dropdown
overlay={
<Menu>
<Menu disabled>
<SubMenu key="tune-sub" title="Tune" icon={<SlidersOutlined />}>
<Menu.Item key="download" icon={<SaveOutlined />}>
<a href="/tunes/202103.msq" target="__blank" rel="noopener noreferrer">

View File

@ -11,6 +11,7 @@ import {
sentryDsn,
} from './utils/env';
import { AuthProvider } from './contexts/AuthContext';
import CommandPalette from './components/CommandPalette';
if (isProduction) {
Sentry.init({
@ -25,7 +26,9 @@ ReactDOM.render(
<HashRouter>
<AuthProvider>
<Provider store={store}>
<App />
<CommandPalette>
<App />
</CommandPalette>
</Provider>
</AuthProvider>
</HashRouter>,

View File

@ -1,6 +1,5 @@
@main: @white;
@text: @white;
@main-light: #181818;
@body-background: @main;
@menu-bg: @main;