diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c80d49c1c2..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# Editor configuration, see https://editorconfig.org -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 4 -insert_final_newline = true -trim_trailing_whitespace = true - -[*.md] -max_line_length = off -trim_trailing_whitespace = false - -[{*.ts,*.js,*.json}] -indent_size = 4 - -[package.json] -indent_size = 2 \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 19b8ae12a6..74d93013d1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,45 +1,46 @@ module.exports = { - parser: '@typescript-eslint/parser', - extends: [ - 'plugin:@typescript-eslint/recommended', - 'prettier', - 'prettier/@typescript-eslint', - 'plugin:import/errors', - 'plugin:import/warnings', - 'plugin:import/typescript' - ], - parserOptions: { - ecmaVersion: 2018, - sourceType: 'module', + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint", "prettier", "import", "simple-import-sort"], + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript", + ], + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, + rules: { + "@typescript-eslint/no-parameter-properties": "off", + "@typescript-eslint/no-use-before-define": "off", + "prettier/prettier": "warn", + "import/no-unresolved": "off", + camelcase: "warn", + "simple-import-sort/sort": "warn", + "sort-imports": "off", + "import/first": "warn", + "import/newline-after-import": "warn", + "import/no-duplicates": "warn", + "import/no-absolute-path": "warn", + "import/no-unused-modules": "warn", + "import/no-deprecated": "warn", + "import/no-self-import": "error", + "max-len": ["warn", { code: 170, tabWidth: 2, ignoreUrls: true }], + }, + overrides: [ + { + files: "**/*.ts", + rules: { + "import/order": [ + "off", + { + "newlines-between": "always", + }, + ], + }, }, - rules: { - '@typescript-eslint/no-parameter-properties': 'off', - '@typescript-eslint/no-use-before-define': 'off', - 'prettier/prettier': 'warn', - 'import/no-unresolved': 'off', - 'camelcase': 'warn', - 'simple-import-sort/sort': 'warn', - 'sort-imports': 'off', - "import/first": "warn", - "import/newline-after-import": "warn", - "import/no-duplicates": "warn", - 'import/no-absolute-path': 'warn', - 'import/no-unused-modules': 'warn', - 'import/no-deprecated': 'warn', - 'import/no-self-import': 'error' - }, - plugins: [ - '@typescript-eslint', - 'prettier', - 'import', - 'simple-import-sort' - ], - overrides: [{ - 'files': '**/*.ts', - 'rules': { - 'import/order': ['off', { - 'newlines-between': 'always' - }], - } - }] -} + ], +}; diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 54477b3cf0..0000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - arrowParens: 'avoid', - bracketSpacing: true, - endOfLine: 'lf', - jsxBracketSameLine: true, - printWidth: 120, - semi: true, - singleQuote: true, - tabWidth: 4, - trailingComma: 'all' -}; diff --git a/package-lock.json b/package-lock.json index 214c05e6c1..4dc05132f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2300,12 +2300,6 @@ "tsutils": "^3.17.1" }, "dependencies": { - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -2335,15 +2329,6 @@ "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } } } }, @@ -2357,74 +2342,6 @@ "@typescript-eslint/experimental-utils": "3.3.0", "@typescript-eslint/typescript-estree": "3.3.0", "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.3.0.tgz", - "integrity": "sha512-d4pGIAbu/tYsrPrdHCQ5xfadJGvlkUxbeBB56nO/VGmEDi/sKmfa5fGty5t5veL1OyJBrUmSiRn1R1qfVDydrg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "3.3.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.3.0.tgz", - "integrity": "sha512-3SqxylENltEvJsjjMSDCUx/edZNSC7wAqifUU1Ywp//0OWEZwMZJfecJud9XxJ/40rAKEbJMKBOQzeOjrLJFzQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "eslint-scope": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", - "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } } }, "@typescript-eslint/typescript-estree": { @@ -6167,6 +6084,15 @@ "tapable": "^1.0.0" } }, + "enquirer": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz", + "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==", + "dev": true, + "requires": { + "ansi-colors": "^3.2.1" + } + }, "entities": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", @@ -6273,79 +6199,126 @@ "dev": true }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.3.0.tgz", + "integrity": "sha512-dJMVXwfU5PT1cj2Nv2VPPrKahKTGdX+5Dh0Q3YuKt+Y2UhdL2YbzsVaBMyG9HC0tBismlv/r1+eZqs6SMIV38Q==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.2.0", + "espree": "^7.1.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash": "^4.17.14", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "ansi-regex": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "restore-cursor": "^2.0.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "type-fest": "^0.8.1" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -6362,96 +6335,76 @@ "resolve-from": "^4.0.0" } }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "shebang-regex": "^3.0.0" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "ansi-regex": "^5.0.0" } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", "dev": true }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" } } } @@ -6654,35 +6607,35 @@ } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.2.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.2.0" }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", "dev": true } } @@ -6694,12 +6647,20 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } } }, "esrecurse": { @@ -7286,9 +7247,9 @@ } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "flush-write-stream": { @@ -9012,13 +8973,13 @@ } }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "license-webpack-plugin": { @@ -10259,17 +10220,17 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "ora": { @@ -11478,9 +11439,9 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prepend-http": { @@ -12029,9 +11990,9 @@ } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true }, "regexpu-core": { @@ -13950,12 +13911,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-fest": { @@ -14358,6 +14319,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index 5d91f882c3..85a7903cf8 100644 --- a/package.json +++ b/package.json @@ -96,18 +96,15 @@ "@typescript-eslint/eslint-plugin": "^3.3.0", "@typescript-eslint/parser": "^3.3.0", "codelyzer": "^5.2.2", + "electron": "^9.0.4", "electron-builder": "^22.7.0", "electron-reload": "^1.5.0", - "electron": "^9.0.4", - "eslint-config-prettier": "^6.11.0", + "eslint": "7.3.0", "eslint-plugin-import": "^2.21.2", - "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-simple-import-sort": "^5.0.3", - "eslint": "^5.16.0", "npm-run-all": "^4.1.5", - "prettier": "^2.0.5", "ts-node": "~8.10.2", - "typescript": "~3.7.5", + "typescript": "^3.7.5", "wait-on": "^5.0.1" } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index de2c5d6f4a..ca944e8e63 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,46 +1,46 @@ -import { Component } from '@angular/core'; -import { Router } from '@angular/router'; -import _ from 'lodash'; +import { Component } from "@angular/core"; +import { Router } from "@angular/router"; +import _ from "lodash"; -import { AppService } from './app.service'; -import { ConfigService } from './config/config.service'; +import { AppService } from "./app.service"; +import { ConfigService } from "./config/config.service"; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.scss'], + selector: "app-root", + templateUrl: "./app.component.html", + styleUrls: ["./app.component.scss"], }) export class AppComponent { - public constructor(private configService: ConfigService, private service: AppService, private router: Router) { - this.initialize(); - } + public constructor(private configService: ConfigService, private service: AppService, private router: Router) { + this.initialize(); + } - private initialize(): void { - if (this.configService && this.configService.isInitialized()) { - if (this.configService.isLoaded()) { - if (this.configService.isValid()) { - if (this.configService.isTouchscreen()) { - this.router.navigate(['/main-screen']); - } else { - this.router.navigate(['/main-screen-no-touch']); - } - } else { - if (_.isEqual(this.configService.getErrors(), this.service.getUpdateError())) { - if (this.service.autoFixError()) { - this.initialize(); - } else { - this.configService.setUpdate(); - this.router.navigate(['/no-config']); - } - } else { - this.router.navigate(['/invalid-config']); - } - } + private initialize(): void { + if (this.configService && this.configService.isInitialized()) { + if (this.configService.isLoaded()) { + if (this.configService.isValid()) { + if (this.configService.isTouchscreen()) { + this.router.navigate(["/main-screen"]); + } else { + this.router.navigate(["/main-screen-no-touch"]); + } + } else { + if (_.isEqual(this.configService.getErrors(), this.service.getUpdateError())) { + if (this.service.autoFixError()) { + this.initialize(); } else { - this.router.navigate(['/no-config']); + this.configService.setUpdate(); + this.router.navigate(["/no-config"]); } - } else { - setTimeout(this.initialize.bind(this), 1000); + } else { + this.router.navigate(["/invalid-config"]); + } } + } else { + this.router.navigate(["/no-config"]); + } + } else { + setTimeout(this.initialize.bind(this), 1000); } + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 79d2c0999c..25a3332349 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,76 +1,76 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { MatRippleModule } from '@angular/material/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { FaIconLibrary, FontAwesomeModule } from '@fortawesome/angular-fontawesome'; -import { fas } from '@fortawesome/free-solid-svg-icons'; -import { RoundProgressModule } from 'angular-svg-round-progressbar'; -import { NgxSpinnerModule } from 'ngx-spinner'; +import { HttpClientModule } from "@angular/common/http"; +import { NgModule } from "@angular/core"; +import { FormsModule } from "@angular/forms"; +import { MatRippleModule } from "@angular/material/core"; +import { BrowserModule } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { FaIconLibrary, FontAwesomeModule } from "@fortawesome/angular-fontawesome"; +import { fas } from "@fortawesome/free-solid-svg-icons"; +import { RoundProgressModule } from "angular-svg-round-progressbar"; +import { NgxSpinnerModule } from "ngx-spinner"; -import { AppComponent } from './app.component'; -import { AppRoutingModule } from './app.routing.module'; -import { AppService } from './app.service'; -import { BottomBarComponent } from './bottom-bar/bottom-bar.component'; -import { ConfigService } from './config/config.service'; -import { InvalidConfigComponent } from './config/invalid-config/invalid-config.component'; -import { NoConfigComponent } from './config/no-config/no-config.component'; -import { ControlComponent } from './control/control.component'; -import { FilamentComponent } from './filament/filament.component'; -import { FilesComponent } from './files/files.component'; -import { JobStatusComponent } from './job-status/job-status.component'; -import { JobService } from './job.service'; -import { LayerProgressComponent } from './layer-progress/layer-progress.component'; -import { MainMenuComponent } from './main-menu/main-menu.component'; -import { MainScreenComponent } from './main-screen/main-screen.component'; -import { MainScreenNoTouchComponent } from './main-screen/no-touch/main-screen-no-touch.component'; -import { NotificationComponent } from './notification/notification.component'; -import { NotificationService } from './notification/notification.service'; -import { PrintControlComponent } from './print-control/print-control.component'; -import { PrinterStatusComponent } from './printer-status/printer-status.component'; -import { PrinterService } from './printer.service'; -import { SettingsComponent } from './settings/settings.component'; -import { StandbyComponent } from './standby/standby.component'; -import { URLSafePipe } from './url.pipe'; +import { AppComponent } from "./app.component"; +import { AppRoutingModule } from "./app.routing.module"; +import { AppService } from "./app.service"; +import { BottomBarComponent } from "./bottom-bar/bottom-bar.component"; +import { ConfigService } from "./config/config.service"; +import { InvalidConfigComponent } from "./config/invalid-config/invalid-config.component"; +import { NoConfigComponent } from "./config/no-config/no-config.component"; +import { ControlComponent } from "./control/control.component"; +import { FilamentComponent } from "./filament/filament.component"; +import { FilesComponent } from "./files/files.component"; +import { JobStatusComponent } from "./job-status/job-status.component"; +import { JobService } from "./job.service"; +import { LayerProgressComponent } from "./layer-progress/layer-progress.component"; +import { MainMenuComponent } from "./main-menu/main-menu.component"; +import { MainScreenComponent } from "./main-screen/main-screen.component"; +import { MainScreenNoTouchComponent } from "./main-screen/no-touch/main-screen-no-touch.component"; +import { NotificationComponent } from "./notification/notification.component"; +import { NotificationService } from "./notification/notification.service"; +import { PrintControlComponent } from "./print-control/print-control.component"; +import { PrinterStatusComponent } from "./printer-status/printer-status.component"; +import { PrinterService } from "./printer.service"; +import { SettingsComponent } from "./settings/settings.component"; +import { StandbyComponent } from "./standby/standby.component"; +import { URLSafePipe } from "./url.pipe"; @NgModule({ - declarations: [ - AppComponent, - BottomBarComponent, - PrinterStatusComponent, - JobStatusComponent, - LayerProgressComponent, - InvalidConfigComponent, - NoConfigComponent, - PrintControlComponent, - NotificationComponent, - MainMenuComponent, - ControlComponent, - MainScreenComponent, - MainScreenNoTouchComponent, - FilamentComponent, - FilesComponent, - SettingsComponent, - URLSafePipe, - StandbyComponent, - ], - imports: [ - BrowserModule, - HttpClientModule, - AppRoutingModule, - RoundProgressModule, - FormsModule, - FontAwesomeModule, - NgxSpinnerModule, - BrowserAnimationsModule, - MatRippleModule, - ], - providers: [AppService, ConfigService, NotificationService, PrinterService, JobService], - bootstrap: [AppComponent], + declarations: [ + AppComponent, + BottomBarComponent, + PrinterStatusComponent, + JobStatusComponent, + LayerProgressComponent, + InvalidConfigComponent, + NoConfigComponent, + PrintControlComponent, + NotificationComponent, + MainMenuComponent, + ControlComponent, + MainScreenComponent, + MainScreenNoTouchComponent, + FilamentComponent, + FilesComponent, + SettingsComponent, + URLSafePipe, + StandbyComponent, + ], + imports: [ + BrowserModule, + HttpClientModule, + AppRoutingModule, + RoundProgressModule, + FormsModule, + FontAwesomeModule, + NgxSpinnerModule, + BrowserAnimationsModule, + MatRippleModule, + ], + providers: [AppService, ConfigService, NotificationService, PrinterService, JobService], + bootstrap: [AppComponent], }) export class AppModule { - public constructor(library: FaIconLibrary) { - library.addIconPacks(fas); - } + public constructor(library: FaIconLibrary) { + library.addIconPacks(fas); + } } diff --git a/src/app/app.routing.module.ts b/src/app/app.routing.module.ts index b0e5da8cd7..56912272de 100644 --- a/src/app/app.routing.module.ts +++ b/src/app/app.routing.module.ts @@ -1,59 +1,59 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; +import { CommonModule } from "@angular/common"; +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; -import { InvalidConfigComponent } from './config/invalid-config/invalid-config.component'; -import { NoConfigComponent } from './config/no-config/no-config.component'; -import { ControlComponent } from './control/control.component'; -import { FilamentComponent } from './filament/filament.component'; -import { FilesComponent } from './files/files.component'; -import { MainScreenComponent } from './main-screen/main-screen.component'; -import { MainScreenNoTouchComponent } from './main-screen/no-touch/main-screen-no-touch.component'; -import { SettingsComponent } from './settings/settings.component'; -import { StandbyComponent } from './standby/standby.component'; +import { InvalidConfigComponent } from "./config/invalid-config/invalid-config.component"; +import { NoConfigComponent } from "./config/no-config/no-config.component"; +import { ControlComponent } from "./control/control.component"; +import { FilamentComponent } from "./filament/filament.component"; +import { FilesComponent } from "./files/files.component"; +import { MainScreenComponent } from "./main-screen/main-screen.component"; +import { MainScreenNoTouchComponent } from "./main-screen/no-touch/main-screen-no-touch.component"; +import { SettingsComponent } from "./settings/settings.component"; +import { StandbyComponent } from "./standby/standby.component"; const routes: Routes = [ - { - path: 'main-screen', - component: MainScreenComponent, - }, - { - path: 'main-screen-no-touch', - component: MainScreenNoTouchComponent, - }, - { - path: 'control', - component: ControlComponent, - }, - { - path: 'filament', - component: FilamentComponent, - }, - { - path: 'files', - component: FilesComponent, - }, - { - path: 'invalid-config', - component: InvalidConfigComponent, - }, - { - path: 'no-config', - component: NoConfigComponent, - }, - { - path: 'settings', - component: SettingsComponent, - }, - { - path: 'standby', - component: StandbyComponent, - }, + { + path: "main-screen", + component: MainScreenComponent, + }, + { + path: "main-screen-no-touch", + component: MainScreenNoTouchComponent, + }, + { + path: "control", + component: ControlComponent, + }, + { + path: "filament", + component: FilamentComponent, + }, + { + path: "files", + component: FilesComponent, + }, + { + path: "invalid-config", + component: InvalidConfigComponent, + }, + { + path: "no-config", + component: NoConfigComponent, + }, + { + path: "settings", + component: SettingsComponent, + }, + { + path: "standby", + component: StandbyComponent, + }, ]; @NgModule({ - declarations: [], - imports: [CommonModule, RouterModule.forRoot(routes)], - exports: [RouterModule], + declarations: [], + imports: [CommonModule, RouterModule.forRoot(routes)], + exports: [RouterModule], }) export class AppRoutingModule {} diff --git a/src/app/app.service.ts b/src/app/app.service.ts index 5638a09072..f30491a4ef 100644 --- a/src/app/app.service.ts +++ b/src/app/app.service.ts @@ -1,162 +1,162 @@ -import { HttpClient } from '@angular/common/http'; -import { Injectable, OnInit } from '@angular/core'; +import { HttpClient } from "@angular/common/http"; +import { Injectable } from "@angular/core"; -import { ConfigService } from './config/config.service'; -import { NotificationService } from './notification/notification.service'; +import { ConfigService } from "./config/config.service"; +import { NotificationService } from "./notification/notification.service"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class AppService { - private updateError: string[]; - private loadedFile = false; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private ipc: any; - private version: string; - private latestVersion: string; - - public constructor( - private configService: ConfigService, - private notificationService: NotificationService, - private http: HttpClient, - ) { - if (window.require) { - try { - this.ipc = window.require('electron').ipcRenderer; - this.enableVersionListener(); - this.enableCustomCSSListener(); - setTimeout(() => { - this.ipc.send('appInfo'); - }, 0); - } catch (e) { - this.notificationService.setError( - "Can't retrieve version information", - "Please open an issue for GitHub as this shouldn't happen.", - ); - } - } - - this.updateError = [".octodash should have required property 'preferPreviewWhilePrinting'"]; - } - - // If the errors can be automatically fixed return true here - public autoFixError(): boolean { - let config = this.configService.getCurrentConfig(); - config.octodash.preferPreviewWhilePrinting = false; - this.configService.saveConfig(config); - this.configService.updateConfig(); - return true; - } - - private enableVersionListener(): void { - this.ipc.on('versionInformation', ({}, versionInformation: VersionInformation): void => { - this.version = versionInformation.version; - this.checkUpdate(); - }); - } - - private enableCustomCSSListener(): void { - this.ipc.on('customStyles', ({}, customCSS: string): void => { - console.log(customCSS); - let css = document.createElement('style'); - css.type = 'text/css'; - css.appendChild(document.createTextNode(customCSS)); - document.head.append(css); - }); - - this.ipc.on('customStylesError', ({}, customCSSError: string): void => { - this.notificationService.setError("Can't get custom styles!", customCSSError); - }); - } - - private checkUpdate(): void { - this.http.get('https://api.github.com/repos/UnchartedBull/OctoDash/releases/latest').subscribe( - (data: GitHubReleaseInformation): void => { - if (this.version !== data.name.replace('v', '')) { - this.notificationService.setUpdate( - "It's time for an update", - `Version ${data.name} is available now, while you're on v${this.version}. Consider updating :)`, - ); - } - this.latestVersion = data.name.replace('v', ''); - }, - (): void => null, + private updateError: string[]; + private loadedFile = false; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private ipc: any; + private version: string; + private latestVersion: string; + + public constructor( + private configService: ConfigService, + private notificationService: NotificationService, + private http: HttpClient + ) { + if (window.require) { + try { + this.ipc = window.require("electron").ipcRenderer; + this.enableVersionListener(); + this.enableCustomCSSListener(); + setTimeout(() => { + this.ipc.send("appInfo"); + }, 0); + } catch (e) { + this.notificationService.setError( + "Can't retrieve version information", + "Please open an issue for GitHub as this shouldn't happen." ); - setTimeout(this.checkUpdate.bind(this), 21.6 * 1000000); - } - - public getVersion(): string { - return this.version; - } - - public getLatestVersion(): string { - return this.latestVersion; - } - - public turnDisplayOff(): void { - if (this.ipc) { - this.ipc.send('screenSleep', ''); - } - } - - public turnDisplayOn(): void { - if (this.ipc) { - this.ipc.send('screenWakeup', ''); - } - } - - public getUpdateError(): string[] { - return this.updateError; - } - - public setLoadedFile(value: boolean): void { - this.loadedFile = value; - } - - public getLoadedFile(): boolean { - return this.loadedFile; - } - - public convertByteToMegabyte(byte: number): string { - return (byte / 1000000).toFixed(1); - } - - public convertDateToString(date: Date): string { - return `${('0' + date.getDate()).slice(-2)}.${('0' + (date.getMonth() + 1)).slice(-2)}.${date.getFullYear()} ${( - '0' + date.getHours() - ).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}:${('0' + date.getSeconds()).slice(-2)}`; - } - - public convertSecondsToHours(input: number): string { - const hours = input / 60 / 60; - let roundedHours = Math.floor(hours); - const minutes = (hours - roundedHours) * 60; - let roundedMinutes = Math.round(minutes); - if (roundedMinutes === 60) { - roundedMinutes = 0; - roundedHours += 1; + } + } + + this.updateError = [".octodash should have required property 'preferPreviewWhilePrinting'"]; + } + + // If the errors can be automatically fixed return true here + public autoFixError(): boolean { + const config = this.configService.getCurrentConfig(); + config.octodash.preferPreviewWhilePrinting = false; + this.configService.saveConfig(config); + this.configService.updateConfig(); + return true; + } + + private enableVersionListener(): void { + this.ipc.on("versionInformation", (_, versionInformation: VersionInformation): void => { + this.version = versionInformation.version; + this.checkUpdate(); + }); + } + + private enableCustomCSSListener(): void { + this.ipc.on("customStyles", (_, customCSS: string): void => { + console.log(customCSS); + const css = document.createElement("style"); + css.type = "text/css"; + css.appendChild(document.createTextNode(customCSS)); + document.head.append(css); + }); + + this.ipc.on("customStylesError", (_, customCSSError: string): void => { + this.notificationService.setError("Can't get custom styles!", customCSSError); + }); + } + + private checkUpdate(): void { + this.http.get("https://api.github.com/repos/UnchartedBull/OctoDash/releases/latest").subscribe( + (data: GitHubReleaseInformation): void => { + if (this.version !== data.name.replace("v", "")) { + this.notificationService.setUpdate( + "It's time for an update", + `Version ${data.name} is available now, while you're on v${this.version}. Consider updating :)` + ); } - return roundedHours + ':' + ('0' + roundedMinutes).slice(-2); - } - - public convertFilamentLengthToAmount(filamentLength: number): number { - return ( - Math.round( - (Math.PI * - (this.configService.getFilamentThickness() / 2) * - filamentLength * - this.configService.getFilamentDensity()) / - 100, - ) / 10 - ); - } + this.latestVersion = data.name.replace("v", ""); + }, + (): void => null + ); + setTimeout(this.checkUpdate.bind(this), 21.6 * 1000000); + } + + public getVersion(): string { + return this.version; + } + + public getLatestVersion(): string { + return this.latestVersion; + } + + public turnDisplayOff(): void { + if (this.ipc) { + this.ipc.send("screenSleep", ""); + } + } + + public turnDisplayOn(): void { + if (this.ipc) { + this.ipc.send("screenWakeup", ""); + } + } + + public getUpdateError(): string[] { + return this.updateError; + } + + public setLoadedFile(value: boolean): void { + this.loadedFile = value; + } + + public getLoadedFile(): boolean { + return this.loadedFile; + } + + public convertByteToMegabyte(byte: number): string { + return (byte / 1000000).toFixed(1); + } + + public convertDateToString(date: Date): string { + return `${("0" + date.getDate()).slice(-2)}.${("0" + (date.getMonth() + 1)).slice(-2)}.${date.getFullYear()} ${( + "0" + date.getHours() + ).slice(-2)}:${("0" + date.getMinutes()).slice(-2)}:${("0" + date.getSeconds()).slice(-2)}`; + } + + public convertSecondsToHours(input: number): string { + const hours = input / 60 / 60; + let roundedHours = Math.floor(hours); + const minutes = (hours - roundedHours) * 60; + let roundedMinutes = Math.round(minutes); + if (roundedMinutes === 60) { + roundedMinutes = 0; + roundedHours += 1; + } + return roundedHours + ":" + ("0" + roundedMinutes).slice(-2); + } + + public convertFilamentLengthToAmount(filamentLength: number): number { + return ( + Math.round( + (Math.PI * + (this.configService.getFilamentThickness() / 2) * + filamentLength * + this.configService.getFilamentDensity()) / + 100 + ) / 10 + ); + } } interface VersionInformation { - version: string; + version: string; } interface GitHubReleaseInformation { - name: string; - [key: string]: string; + name: string; + [key: string]: string; } diff --git a/src/app/bottom-bar/bottom-bar.component.ts b/src/app/bottom-bar/bottom-bar.component.ts index 75fa6570cc..b9fb700efd 100644 --- a/src/app/bottom-bar/bottom-bar.component.ts +++ b/src/app/bottom-bar/bottom-bar.component.ts @@ -1,57 +1,57 @@ -import { Component, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy } from "@angular/core"; +import { Subscription } from "rxjs"; -import { ConfigService } from '../config/config.service'; -import { EnclosureService } from '../plugin-service/enclosure.service'; -import { PrinterService, PrinterStatusAPI } from '../printer.service'; +import { ConfigService } from "../config/config.service"; +import { EnclosureService } from "../plugin-service/enclosure.service"; +import { PrinterService, PrinterStatusAPI } from "../printer.service"; @Component({ - selector: 'app-bottom-bar', - templateUrl: './bottom-bar.component.html', - styleUrls: ['./bottom-bar.component.scss'], + selector: "app-bottom-bar", + templateUrl: "./bottom-bar.component.html", + styleUrls: ["./bottom-bar.component.scss"], }) export class BottomBarComponent implements OnDestroy { - private subscriptions: Subscription = new Subscription(); - public printer: Printer; - public enclosureTemperature: TemperatureReading; + private subscriptions: Subscription = new Subscription(); + public printer: Printer; + public enclosureTemperature: TemperatureReading; - public constructor( - private printerService: PrinterService, - private configService: ConfigService, - private enclosureService: EnclosureService, - ) { - if (this.configService.getAmbientTemperatureSensorName() !== null) { - this.subscriptions.add( - this.enclosureService.getObservable().subscribe((temperatureReading: TemperatureReading): void => { - this.enclosureTemperature = temperatureReading; - }), - ); - } else { - this.enclosureTemperature = null; - } - this.printer = { - name: this.configService.getPrinterName(), - status: 'connecting ...', - }; - this.subscriptions.add( - this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { - this.printer.status = printerStatus.status; - }), - ); + public constructor( + private printerService: PrinterService, + private configService: ConfigService, + private enclosureService: EnclosureService + ) { + if (this.configService.getAmbientTemperatureSensorName() !== null) { + this.subscriptions.add( + this.enclosureService.getObservable().subscribe((temperatureReading: TemperatureReading): void => { + this.enclosureTemperature = temperatureReading; + }) + ); + } else { + this.enclosureTemperature = null; } + this.printer = { + name: this.configService.getPrinterName(), + status: "connecting ...", + }; + this.subscriptions.add( + this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { + this.printer.status = printerStatus.status; + }) + ); + } - public ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } + public ngOnDestroy(): void { + this.subscriptions.unsubscribe(); + } } interface Printer { - name: string; - status: string; + name: string; + status: string; } export interface TemperatureReading { - temperature: number; - humidity: number; - unit: string; + temperature: number; + humidity: number; + unit: string; } diff --git a/src/app/config/config.service.ts b/src/app/config/config.service.ts index 60156c598a..2a4d8ce0f5 100644 --- a/src/app/config/config.service.ts +++ b/src/app/config/config.service.ts @@ -1,633 +1,637 @@ -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import Ajv from 'ajv'; -import _ from 'lodash'; +import { HttpClient, HttpHeaders } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import Ajv from "ajv"; +import _ from "lodash"; -import { environment } from '../../environments/environment'; +import { environment } from "../../environments/environment"; declare global { - interface Window { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - require: any; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - process: any; - } + interface Window { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + require: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + process: any; + } } @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class ConfigService { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private store: any | undefined; - private validator: Ajv.ValidateFunction; - - private config: Config; - private valid: boolean; - private update = false; - private initialized = false; - - private httpHeaders: object; - - public constructor(private http: HttpClient) { - const ajv = new Ajv({ allErrors: true }); - this.validator = ajv.compile(schema); - if (window && window.process && window.process.type) { - const Store = window.require('electron-store'); - this.store = new Store(); - this.initialize(this.store.get('config')); - } else { - console.warn( - 'Detected non-electron environment. Fallback to assets/config.json. Any changes are non-persistent!', - ); - this.http.get(environment.config).subscribe((config: Config): void => { - this.initialize(config); - }); - } - } - - private initialize(config: Config): void { - this.config = config; - this.valid = this.validate(); - if (this.valid) { - this.httpHeaders = { - headers: new HttpHeaders({ - 'x-api-key': this.config.octoprint.accessToken, - 'Cache-Control': 'no-cache', - Pragma: 'no-cache', - Expires: '0', - }), - }; - } - this.initialized = true; - } - - public getRemoteConfig(): Config { - return this.store.get('config'); - } - - public getCurrentConfig(): Config { - return _.cloneDeep(this.config); - } - - public isEqualToCurrentConfig(changedConfig: Config): boolean { - return _.isEqual(this.config, changedConfig); - } - - public validate(): boolean { - return this.validator(this.config) ? true : false; - } - - public validateGiven(config: Config): boolean { - return this.validator(config) ? true : false; - } - - public getErrors(): string[] { - const errors = []; - this.validator.errors.forEach((error): void => { - if (error.keyword === 'type') { - errors.push(`${error.dataPath} ${error.message}`); - } else { - errors.push(`${error.dataPath === '' ? '.' : error.dataPath} ${error.message}`); - } - }); - console.error(errors); - return errors; - } - - public saveConfig(config?: Config): string { - if (!config) { - config = this.config; - } - if (window && window.process && window.process.type) { - this.store.set('config', config); - const configStored = this.store.get('config'); - if (this.validateGiven(configStored)) { - return null; - } else { - return 'Saved config is invalid!'; - } - } else { - return 'Browser version doesn\'t support saving!'; - } - } - - public updateConfig(): void { - if (window && window.process && window.process.type) { - this.update = false; - this.initialize(this.store.get('config')); - } - } - - public revertConfigForInput(config: Config): Config { - config.octoprint.urlSplit = { - url: config.octoprint.url.split(':')[1].replace('//', ''), - port: parseInt(config.octoprint.url.split(':')[2].replace('/api/', ''), 10), - }; - if (isNaN(config.octoprint.urlSplit.port)) { - config.octoprint.urlSplit.port = null; - } - return config; - } - - public createConfigFromInput(config: Config): Config { - const configOut = _.cloneDeep(config); - if (config.octoprint.urlSplit.port !== null || !isNaN(config.octoprint.urlSplit.port)) { - configOut.octoprint.url = `http://${config.octoprint.urlSplit.url}:${config.octoprint.urlSplit.port}/api/`; - } else { - configOut.octoprint.url = `http://${config.octoprint.urlSplit.url}/api/`; - } - delete configOut.octoprint.urlSplit; - return configOut; - } - - public isLoaded(): boolean { - return this.config ? true : false; - } - - public setUpdate(): void { - this.update = true; - } - - public getHTTPHeaders(): object { - return this.httpHeaders; - } - - public getURL(path: string): string { - return this.config.octoprint.url + path; - } - - public getAPIPollingInterval(): number { - return this.config.octodash.pollingInterval; - } - - public getPrinterName(): string { - return this.config.printer.name; - } - - public getCustomActions(): CustomAction[] { - return this.config.octodash.customActions; - } - - public getXYSpeed(): number { - return this.config.printer.xySpeed; - } - - public getZSpeed(): number { - return this.config.printer.zSpeed; - } - - public isInitialized(): boolean { - return this.initialized; - } - - public isValid(): boolean { - return this.valid; - } - - public isUpdate(): boolean { - return this.update; - } - - public isTouchscreen(): boolean { - return this.config.octodash.touchscreen; - } - - public getAmbientTemperatureSensorName(): number { - return this.config.plugins.enclosure.ambientSensorID; - } - - public getAutomaticScreenSleep(): boolean { - return this.config.octodash.turnScreenOffWhileSleeping; - } - - public turnOnPSUWhenExitingSleep(): boolean { - return this.config.plugins.psuControl.turnOnPSUWhenExitingSleep; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private store: any | undefined; + private validator: Ajv.ValidateFunction; + + private config: Config; + private valid: boolean; + private update = false; + private initialized = false; + + private httpHeaders: HttpHeader; + + public constructor(private http: HttpClient) { + const ajv = new Ajv({ allErrors: true }); + this.validator = ajv.compile(schema); + if (window && window.process && window.process.type) { + const Store = window.require("electron-store"); + this.store = new Store(); + this.initialize(this.store.get("config")); + } else { + console.warn( + "Detected non-electron environment. Fallback to assets/config.json. Any changes are non-persistent!" + ); + this.http.get(environment.config).subscribe((config: Config): void => { + this.initialize(config); + }); + } + } + + private initialize(config: Config): void { + this.config = config; + this.valid = this.validate(); + if (this.valid) { + this.httpHeaders = { + headers: new HttpHeaders({ + "x-api-key": this.config.octoprint.accessToken, + "Cache-Control": "no-cache", + Pragma: "no-cache", + Expires: "0", + }), + }; + } + this.initialized = true; + } + + public getRemoteConfig(): Config { + return this.store.get("config"); + } + + public getCurrentConfig(): Config { + return _.cloneDeep(this.config); + } + + public isEqualToCurrentConfig(changedConfig: Config): boolean { + return _.isEqual(this.config, changedConfig); + } + + public validate(): boolean { + return this.validator(this.config) ? true : false; + } + + public validateGiven(config: Config): boolean { + return this.validator(config) ? true : false; + } + + public getErrors(): string[] { + const errors = []; + this.validator.errors.forEach((error): void => { + if (error.keyword === "type") { + errors.push(`${error.dataPath} ${error.message}`); + } else { + errors.push(`${error.dataPath === "" ? "." : error.dataPath} ${error.message}`); + } + }); + console.error(errors); + return errors; + } + + public saveConfig(config?: Config): string { + if (!config) { + config = this.config; + } + if (window && window.process && window.process.type) { + this.store.set("config", config); + const configStored = this.store.get("config"); + if (this.validateGiven(configStored)) { + return null; + } else { + return "Saved config is invalid!"; + } + } else { + return 'Browser version doesn\'t support saving!'; + } + } + + public updateConfig(): void { + if (window && window.process && window.process.type) { + this.update = false; + this.initialize(this.store.get("config")); + } + } + + public revertConfigForInput(config: Config): Config { + config.octoprint.urlSplit = { + url: config.octoprint.url.split(":")[1].replace("//", ""), + port: parseInt(config.octoprint.url.split(":")[2].replace("/api/", ""), 10), + }; + if (isNaN(config.octoprint.urlSplit.port)) { + config.octoprint.urlSplit.port = null; } + return config; + } - public getFilamentThickness(): number { - return this.config.filament.thickness; + public createConfigFromInput(config: Config): Config { + const configOut = _.cloneDeep(config); + if (config.octoprint.urlSplit.port !== null || !isNaN(config.octoprint.urlSplit.port)) { + configOut.octoprint.url = `http://${config.octoprint.urlSplit.url}:${config.octoprint.urlSplit.port}/api/`; + } else { + configOut.octoprint.url = `http://${config.octoprint.urlSplit.url}/api/`; } + delete configOut.octoprint.urlSplit; + return configOut; + } - public getFilamentDensity(): number { - return this.config.filament.density; - } + public isLoaded(): boolean { + return this.config ? true : false; + } - public getDefaultSortingAttribute(): 'name' | 'date' | 'size' { - return this.config.octodash.fileSorting.attribute; - } + public setUpdate(): void { + this.update = true; + } - public getDefaultSortingOrder(): 'asc' | 'dsc' { - return this.config.octodash.fileSorting.order; - } + public getHTTPHeaders(): HttpHeader { + return this.httpHeaders; + } - public getDefaultHotendTemperature(): number { - return this.config.printer.defaultTemperatureFanSpeed.hotend; - } + public getURL(path: string): string { + return this.config.octoprint.url + path; + } - public getDefaultHeatbedTemperature(): number { - return this.config.printer.defaultTemperatureFanSpeed.heatbed; - } + public getAPIPollingInterval(): number { + return this.config.octodash.pollingInterval; + } - public getDefaultFanSpeed(): number { - return this.config.printer.defaultTemperatureFanSpeed.fan; - } + public getPrinterName(): string { + return this.config.printer.name; + } + + public getCustomActions(): CustomAction[] { + return this.config.octodash.customActions; + } + + public getXYSpeed(): number { + return this.config.printer.xySpeed; + } + + public getZSpeed(): number { + return this.config.printer.zSpeed; + } + + public isInitialized(): boolean { + return this.initialized; + } + + public isValid(): boolean { + return this.valid; + } + + public isUpdate(): boolean { + return this.update; + } + + public isTouchscreen(): boolean { + return this.config.octodash.touchscreen; + } + + public getAmbientTemperatureSensorName(): number { + return this.config.plugins.enclosure.ambientSensorID; + } + + public getAutomaticScreenSleep(): boolean { + return this.config.octodash.turnScreenOffWhileSleeping; + } + + public turnOnPSUWhenExitingSleep(): boolean { + return this.config.plugins.psuControl.turnOnPSUWhenExitingSleep; + } + + public getFilamentThickness(): number { + return this.config.filament.thickness; + } + + public getFilamentDensity(): number { + return this.config.filament.density; + } + + public getDefaultSortingAttribute(): "name" | "date" | "size" { + return this.config.octodash.fileSorting.attribute; + } + + public getDefaultSortingOrder(): "asc" | "dsc" { + return this.config.octodash.fileSorting.order; + } + + public getDefaultHotendTemperature(): number { + return this.config.printer.defaultTemperatureFanSpeed.hotend; + } + + public getDefaultHeatbedTemperature(): number { + return this.config.printer.defaultTemperatureFanSpeed.heatbed; + } + + public getDefaultFanSpeed(): number { + return this.config.printer.defaultTemperatureFanSpeed.fan; + } + + public isPreheatPluginEnabled(): boolean { + return this.config.plugins.preheatButton.enabled; + } - public isPreheatPluginEnabled(): boolean { - return this.config.plugins.preheatButton.enabled; - } + public isFilamentManagerEnabled(): boolean { + return this.config.plugins.filamentManager.enabled; + } - public isFilamentManagerEnabled(): boolean { - return this.config.plugins.filamentManager.enabled; - } + public getFeedLength(): number { + return this.config.filament.feedLength; + } - public getFeedLength(): number { - return this.config.filament.feedLength; - } + public getFeedSpeed(): number { + return this.config.filament.feedSpeed; + } - public getFeedSpeed(): number { - return this.config.filament.feedSpeed; - } + public getFeedSpeedSlow(): number { + return this.config.filament.feedSpeedSlow; + } - public getFeedSpeedSlow(): number { - return this.config.filament.feedSpeedSlow; - } + public getPurgeDistance(): number { + return this.config.filament.purgeDistance; + } - public getPurgeDistance(): number { - return this.config.filament.purgeDistance; - } + public useM600(): boolean { + return this.config.filament.useM600; + } - public useM600(): boolean { - return this.config.filament.useM600; - } + public showThumbnailByDefault(): boolean { + return this.config.octodash.preferPreviewWhilePrinting; + } +} - public showThumbnailByDefault(): boolean { - return this.config.octodash.preferPreviewWhilePrinting; - } +interface HttpHeader { + headers: HttpHeaders; } export interface Config { - octoprint: Octoprint; - printer: Printer; - filament: Filament; - plugins: Plugins; - octodash: OctoDash; + octoprint: Octoprint; + printer: Printer; + filament: Filament; + plugins: Plugins; + octodash: OctoDash; } interface Octoprint { + url: string; + accessToken: string; + urlSplit?: { url: string; - accessToken: string; - urlSplit?: { - url: string; - port: number; - }; + port: number; + }; } interface Printer { - name: string; - xySpeed: number; - zSpeed: number; - defaultTemperatureFanSpeed: DefaultTemperatureFanSpeed; + name: string; + xySpeed: number; + zSpeed: number; + defaultTemperatureFanSpeed: DefaultTemperatureFanSpeed; } interface DefaultTemperatureFanSpeed { - hotend: number; - heatbed: number; - fan: number; + hotend: number; + heatbed: number; + fan: number; } interface Filament { - thickness: number; - density: number; - feedLength: number; - feedSpeed: number; - feedSpeedSlow: number; - purgeDistance: number; - useM600: boolean; + thickness: number; + density: number; + feedLength: number; + feedSpeed: number; + feedSpeedSlow: number; + purgeDistance: number; + useM600: boolean; } interface Plugins { - displayLayerProgress: Plugin; - enclosure: EnclosurePlugin; - filamentManager: Plugin; - preheatButton: Plugin; - printTimeGenius: Plugin; - psuControl: PSUControlPlugin; + displayLayerProgress: Plugin; + enclosure: EnclosurePlugin; + filamentManager: Plugin; + preheatButton: Plugin; + printTimeGenius: Plugin; + psuControl: PSUControlPlugin; } interface Plugin { - enabled: boolean; + enabled: boolean; } interface EnclosurePlugin extends Plugin { - ambientSensorID: number | null; - filament1SensorID: number | null; - filament2SensorID: number | null; + ambientSensorID: number | null; + filament1SensorID: number | null; + filament2SensorID: number | null; } interface PSUControlPlugin extends Plugin { - turnOnPSUWhenExitingSleep: boolean; + turnOnPSUWhenExitingSleep: boolean; } interface OctoDash { - customActions: CustomAction[]; - fileSorting: FileSorting; - pollingInterval: number; - touchscreen: boolean; - turnScreenOffWhileSleeping: boolean; - preferPreviewWhilePrinting: boolean; + customActions: CustomAction[]; + fileSorting: FileSorting; + pollingInterval: number; + touchscreen: boolean; + turnScreenOffWhileSleeping: boolean; + preferPreviewWhilePrinting: boolean; } interface CustomAction { - icon: string; - command: string; - color: string; - confirm: boolean; - exit: boolean; + icon: string; + command: string; + color: string; + confirm: boolean; + exit: boolean; } interface FileSorting { - attribute: 'name' | 'date' | 'size'; - order: 'asc' | 'dsc'; + attribute: "name" | "date" | "size"; + order: "asc" | "dsc"; } const schema = { - definitions: {}, - $schema: 'http://json-schema.org/draft-07/schema#', - $id: 'http://example.com/root.json', - type: 'object', - required: ['octoprint', 'printer', 'filament', 'plugins', 'octodash'], - properties: { - octoprint: { - $id: '#/properties/octoprint', - type: 'object', - required: ['accessToken', 'url'], - properties: { - accessToken: { - $id: '#/properties/octoprint/properties/accessToken', - type: 'string', - pattern: '^(.*)$', - }, - url: { - $id: '#/properties/octoprint/properties/url', - type: 'string', - pattern: '^(.*)$', - }, + definitions: {}, + $schema: "http://json-schema.org/draft-07/schema#", + $id: "http://example.com/root.json", + type: "object", + required: ["octoprint", "printer", "filament", "plugins", "octodash"], + properties: { + octoprint: { + $id: "#/properties/octoprint", + type: "object", + required: ["accessToken", "url"], + properties: { + accessToken: { + $id: "#/properties/octoprint/properties/accessToken", + type: "string", + pattern: "^(.*)$", + }, + url: { + $id: "#/properties/octoprint/properties/url", + type: "string", + pattern: "^(.*)$", + }, + }, + }, + printer: { + $id: "#/properties/printer", + type: "object", + required: ["name", "xySpeed", "zSpeed", "defaultTemperatureFanSpeed"], + properties: { + name: { + $id: "#/properties/printer/properties/name", + type: "string", + pattern: "^(.*)$", + }, + xySpeed: { + $id: "#/properties/printer/properties/xySpeed", + type: "integer", + }, + zSpeed: { + $id: "#/properties/printer/properties/zSpeed", + type: "integer", + }, + defaultTemperatureFanSpeed: { + $id: "#/properties/printer/properties/defaultTemperatureFanSpeed", + type: "object", + required: ["hotend", "heatbed", "fan"], + properties: { + hotend: { + $id: "#/properties/printer/properties/defaultTemperatureFanSpeed/hotend", + type: "integer", + }, + heatbed: { + $id: "#/properties/printer/properties/defaultTemperatureFanSpeed/heatbed", + type: "integer", }, + fan: { + $id: "#/properties/printer/properties/defaultTemperatureFanSpeed/fan", + type: "integer", + }, + }, }, - printer: { - $id: '#/properties/printer', - type: 'object', - required: ['name', 'xySpeed', 'zSpeed', 'defaultTemperatureFanSpeed'], - properties: { - name: { - $id: '#/properties/printer/properties/name', - type: 'string', - pattern: '^(.*)$', - }, - xySpeed: { - $id: '#/properties/printer/properties/xySpeed', - type: 'integer', - }, - zSpeed: { - $id: '#/properties/printer/properties/zSpeed', - type: 'integer', - }, - defaultTemperatureFanSpeed: { - $id: '#/properties/printer/properties/defaultTemperatureFanSpeed', - type: 'object', - required: ['hotend', 'heatbed', 'fan'], - properties: { - hotend: { - $id: '#/properties/printer/properties/defaultTemperatureFanSpeed/hotend', - type: 'integer', - }, - heatbed: { - $id: '#/properties/printer/properties/defaultTemperatureFanSpeed/heatbed', - type: 'integer', - }, - fan: { - $id: '#/properties/printer/properties/defaultTemperatureFanSpeed/fan', - type: 'integer', - }, - }, - }, + }, + }, + filament: { + $id: "#/properties/filament", + type: "object", + required: ["density", "thickness", "feedLength", "feedSpeed", "feedSpeedSlow", "purgeDistance", "useM600"], + properties: { + density: { + $id: "#/properties/filament/properties/density", + type: "number", + }, + thickness: { + $id: "#/properties/filament/properties/thickness", + type: "number", + }, + feedLength: { + $id: "#/properties/filament/properties/feedLength", + type: "integer", + }, + feedSpeed: { + $id: "#/properties/filament/properties/feedSpeed", + type: "integer", + }, + feedSpeedSlow: { + $id: "#/properties/filament/properties/feedSpeedSlow", + type: "integer", + }, + purgeDistance: { + $id: "#/properties/filament/properties/purgeDistance", + type: "integer", + }, + useM600: { + $id: "#/properties/filament/properties/useM600", + type: "boolean", + }, + }, + }, + plugins: { + $id: "#/properties/plugins", + type: "object", + required: [ + "displayLayerProgress", + "enclosure", + "filamentManager", + "preheatButton", + "printTimeGenius", + "psuControl", + ], + properties: { + displayLayerProgress: { + $id: "#/properties/plugins/properties/displayLayerProgress", + type: "object", + required: ["enabled"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/displayLayerProgress/properties/enabled", + type: "boolean", }, + }, }, - filament: { - $id: '#/properties/filament', - type: 'object', - required: ['density', 'thickness', 'feedLength', 'feedSpeed', 'feedSpeedSlow', 'purgeDistance', 'useM600'], - properties: { - density: { - $id: '#/properties/filament/properties/density', - type: 'number', - }, - thickness: { - $id: '#/properties/filament/properties/thickness', - type: 'number', - }, - feedLength: { - $id: '#/properties/filament/properties/feedLength', - type: 'integer', - }, - feedSpeed: { - $id: '#/properties/filament/properties/feedSpeed', - type: 'integer', - }, - feedSpeedSlow: { - $id: '#/properties/filament/properties/feedSpeedSlow', - type: 'integer', - }, - purgeDistance: { - $id: '#/properties/filament/properties/purgeDistance', - type: 'integer', - }, - useM600: { - $id: '#/properties/filament/properties/useM600', - type: 'boolean', - }, + enclosure: { + $id: "#/properties/plugins/properties/enclosure", + type: "object", + required: ["enabled", "ambientSensorID", "filament1SensorID", "filament2SensorID"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/enclosure/properties/enabled", + type: "boolean", + }, + ambientSensorID: { + $id: "#/properties/plugins/properties/enclosure/properties/ambientSensorID", + type: ["number", "null"], + pattern: "^(.*)$", + }, + filament1SensorID: { + $id: "#/properties/plugins/properties/enclosure/properties/filament1SensorID", + type: ["number", "null"], + pattern: "^(.*)$", }, + filament2SensorID: { + $id: "#/properties/plugins/properties/enclosure/properties/filament2SensorID", + type: ["number", "null"], + pattern: "^(.*)$", + }, + }, }, - plugins: { - $id: '#/properties/plugins', - type: 'object', - required: [ - 'displayLayerProgress', - 'enclosure', - 'filamentManager', - 'preheatButton', - 'printTimeGenius', - 'psuControl', - ], - properties: { - displayLayerProgress: { - $id: '#/properties/plugins/properties/displayLayerProgress', - type: 'object', - required: ['enabled'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/displayLayerProgress/properties/enabled', - type: 'boolean', - }, - }, - }, - enclosure: { - $id: '#/properties/plugins/properties/enclosure', - type: 'object', - required: ['enabled', 'ambientSensorID', 'filament1SensorID', 'filament2SensorID'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/enclosure/properties/enabled', - type: 'boolean', - }, - ambientSensorID: { - $id: '#/properties/plugins/properties/enclosure/properties/ambientSensorID', - type: ['number', 'null'], - pattern: '^(.*)$', - }, - filament1SensorID: { - $id: '#/properties/plugins/properties/enclosure/properties/filament1SensorID', - type: ['number', 'null'], - pattern: '^(.*)$', - }, - filament2SensorID: { - $id: '#/properties/plugins/properties/enclosure/properties/filament2SensorID', - type: ['number', 'null'], - pattern: '^(.*)$', - }, - }, - }, - filamentManager: { - $id: '#/properties/plugins/properties/filamentManager', - type: 'object', - required: ['enabled'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/filamentManager/properties/enabled', - type: 'boolean', - }, - }, - }, - preheatButton: { - $id: '#/properties/plugins/properties/preheatButton', - type: 'object', - required: ['enabled'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/preheatButton/properties/enabled', - type: 'boolean', - }, - }, - }, - printTimeGenius: { - $id: '#/properties/plugins/properties/printTimeGenius', - type: 'object', - required: ['enabled'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/printTimeGenius/properties/enabled', - type: 'boolean', - }, - }, - }, - psuControl: { - $id: '#/properties/plugins/properties/psuControl', - type: 'object', - required: ['enabled', 'turnOnPSUWhenExitingSleep'], - properties: { - enabled: { - $id: '#/properties/plugins/properties/printTimeGenius/properties/enabled', - type: 'boolean', - }, - turnOnPSUWhenExitingSleep: { - $id: '#/properties/plugins/properties/turnOnPSUWhenExitingSleep', - type: 'boolean', - }, - }, - }, + filamentManager: { + $id: "#/properties/plugins/properties/filamentManager", + type: "object", + required: ["enabled"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/filamentManager/properties/enabled", + type: "boolean", + }, + }, + }, + preheatButton: { + $id: "#/properties/plugins/properties/preheatButton", + type: "object", + required: ["enabled"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/preheatButton/properties/enabled", + type: "boolean", + }, + }, + }, + printTimeGenius: { + $id: "#/properties/plugins/properties/printTimeGenius", + type: "object", + required: ["enabled"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/printTimeGenius/properties/enabled", + type: "boolean", }, + }, }, - octodash: { - $id: '#/properties/octodash', - type: 'object', - required: [ - 'customActions', - 'fileSorting', - 'pollingInterval', - 'touchscreen', - 'turnScreenOffWhileSleeping', - 'preferPreviewWhilePrinting', - ], + psuControl: { + $id: "#/properties/plugins/properties/psuControl", + type: "object", + required: ["enabled", "turnOnPSUWhenExitingSleep"], + properties: { + enabled: { + $id: "#/properties/plugins/properties/printTimeGenius/properties/enabled", + type: "boolean", + }, + turnOnPSUWhenExitingSleep: { + $id: "#/properties/plugins/properties/turnOnPSUWhenExitingSleep", + type: "boolean", + }, + }, + }, + }, + }, + octodash: { + $id: "#/properties/octodash", + type: "object", + required: [ + "customActions", + "fileSorting", + "pollingInterval", + "touchscreen", + "turnScreenOffWhileSleeping", + "preferPreviewWhilePrinting", + ], + properties: { + customActions: { + $id: "#/properties/octodash/properties/customActions", + type: "array", + items: { + $id: "#/properties/octodash/properties/customActions/items", + type: "object", + required: ["icon", "command", "color", "confirm", "exit"], properties: { - customActions: { - $id: '#/properties/octodash/properties/customActions', - type: 'array', - items: { - $id: '#/properties/octodash/properties/customActions/items', - type: 'object', - required: ['icon', 'command', 'color', 'confirm', 'exit'], - properties: { - icon: { - $id: '#/properties/octodash/properties/customActions/items/properties/icon', - type: 'string', - pattern: '^(.*)$', - }, - command: { - $id: '#/properties/octodash/properties/customActions/items/properties/command', - type: 'string', - pattern: '^(.*)$', - }, - color: { - $id: '#/properties/octodash/properties/customActions/items/properties/color', - type: 'string', - pattern: '^(.*)$', - }, - confirm: { - $id: '#/properties/octodash/properties/customActions/items/properties/confirm', - type: 'boolean', - }, - exit: { - $id: '#/properties/octodash/properties/customActions/items/properties/exit', - type: 'boolean', - }, - }, - }, - }, - fileSorting: { - $id: '#/properties/octodash/properties/fileSorting', - type: 'object', - required: ['attribute', 'order'], - properties: { - attribute: { - $id: '#/properties/octodash/properties/fileSorting/properties/attribute', - type: 'string', - pattern: '^(name|date|size)$', - }, - order: { - $id: '#/properties/octodash/properties/fileSorting/properties/order', - type: 'string', - pattern: '^(asc|dsc)$', - }, - }, - }, - pollingInterval: { - $id: '#/properties/octodash/properties/pollingInterval', - type: 'integer', - }, - touchscreen: { - $id: '#/properties/octodash/properties/touchscreen', - type: 'boolean', - }, - turnScreenOffWhileSleeping: { - $id: '#/properties/octodash/properties/turnScreenOffWhileSleeping', - type: 'boolean', - }, - preferPreviewWhilePrinting: { - $id: '#/properties/octodash/properties/preferPreviewWhilePrinting', - type: 'boolean', - }, + icon: { + $id: "#/properties/octodash/properties/customActions/items/properties/icon", + type: "string", + pattern: "^(.*)$", + }, + command: { + $id: "#/properties/octodash/properties/customActions/items/properties/command", + type: "string", + pattern: "^(.*)$", + }, + color: { + $id: "#/properties/octodash/properties/customActions/items/properties/color", + type: "string", + pattern: "^(.*)$", + }, + confirm: { + $id: "#/properties/octodash/properties/customActions/items/properties/confirm", + type: "boolean", + }, + exit: { + $id: "#/properties/octodash/properties/customActions/items/properties/exit", + type: "boolean", + }, }, + }, + }, + fileSorting: { + $id: "#/properties/octodash/properties/fileSorting", + type: "object", + required: ["attribute", "order"], + properties: { + attribute: { + $id: "#/properties/octodash/properties/fileSorting/properties/attribute", + type: "string", + pattern: "^(name|date|size)$", + }, + order: { + $id: "#/properties/octodash/properties/fileSorting/properties/order", + type: "string", + pattern: "^(asc|dsc)$", + }, + }, + }, + pollingInterval: { + $id: "#/properties/octodash/properties/pollingInterval", + type: "integer", + }, + touchscreen: { + $id: "#/properties/octodash/properties/touchscreen", + type: "boolean", + }, + turnScreenOffWhileSleeping: { + $id: "#/properties/octodash/properties/turnScreenOffWhileSleeping", + type: "boolean", + }, + preferPreviewWhilePrinting: { + $id: "#/properties/octodash/properties/preferPreviewWhilePrinting", + type: "boolean", }, + }, }, + }, }; diff --git a/src/app/config/invalid-config/invalid-config.component.ts b/src/app/config/invalid-config/invalid-config.component.ts index 95d8f9620b..405f55bc80 100644 --- a/src/app/config/invalid-config/invalid-config.component.ts +++ b/src/app/config/invalid-config/invalid-config.component.ts @@ -1,18 +1,18 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; -import { ConfigService } from '../config.service'; +import { ConfigService } from "../config.service"; @Component({ - selector: 'app-invalid-config', - templateUrl: './invalid-config.component.html', - styleUrls: ['./invalid-config.component.scss'], + selector: "app-invalid-config", + templateUrl: "./invalid-config.component.html", + styleUrls: ["./invalid-config.component.scss"], }) export class InvalidConfigComponent implements OnInit { - public errors: string[]; + public errors: string[]; - public constructor(private configService: ConfigService) {} + public constructor(private configService: ConfigService) {} - public ngOnInit(): void { - this.errors = this.configService.getErrors(); - } + public ngOnInit(): void { + this.errors = this.configService.getErrors(); + } } diff --git a/src/app/config/no-config/no-config.component.ts b/src/app/config/no-config/no-config.component.ts index 550a8f356a..840b5eceb9 100644 --- a/src/app/config/no-config/no-config.component.ts +++ b/src/app/config/no-config/no-config.component.ts @@ -1,206 +1,206 @@ -import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { HttpClient, HttpErrorResponse, HttpHeaders } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; -import { Config, ConfigService } from '../config.service'; +import { Config, ConfigService } from "../config.service"; @Component({ - selector: 'app-no-config', - templateUrl: './no-config.component.html', - styleUrls: ['./no-config.component.scss'], + selector: "app-no-config", + templateUrl: "./no-config.component.html", + styleUrls: ["./no-config.component.scss"], }) export class NoConfigComponent implements OnInit { - public page = 0; - public totalPages = 6; + public page = 0; + public totalPages = 6; - private configUpdate: boolean; - public config: Config; - public configErrors: string[]; - public configValid: boolean; - public configSaved: string; + private configUpdate: boolean; + public config: Config; + public configErrors: string[]; + public configValid: boolean; + public configSaved: string; - public octoprintConnection: boolean; - public octoprintConnectionError: string; + public octoprintConnection: boolean; + public octoprintConnectionError: string; - public constructor(private configService: ConfigService, private http: HttpClient, private router: Router) { - this.configUpdate = this.configService.isUpdate(); - console.log(this.configUpdate); - if (this.configUpdate) { - this.config = configService.getCurrentConfig(); - } else { - this.config = { - octoprint: { - url: 'http://localhost:5000/api/', - accessToken: '', - }, - printer: { - name: '', - xySpeed: 150, - zSpeed: 5, - defaultTemperatureFanSpeed: { - hotend: 200, - heatbed: 60, - fan: 100, - }, - }, - filament: { - thickness: 1.75, - density: 1.25, - feedLength: 0, - feedSpeed: 30, - feedSpeedSlow: 3, - purgeDistance: 30, - useM600: false, - }, - plugins: { - displayLayerProgress: { - enabled: true, - }, - enclosure: { - enabled: false, - ambientSensorID: null, - filament1SensorID: null, - filament2SensorID: null, - }, - filamentManager: { - enabled: true, - }, - preheatButton: { - enabled: true, - }, - printTimeGenius: { - enabled: true, - }, - psuControl: { - enabled: false, - turnOnPSUWhenExitingSleep: false, - }, - }, - octodash: { - customActions: [ - { - icon: 'home', - command: 'G28', - color: '#dcdde1', - confirm: false, - exit: true, - }, - { - icon: 'ruler-vertical', - command: 'G29', - color: '#44bd32', - confirm: false, - exit: true, - }, - { - icon: 'fire-alt', - command: 'M140 S50; M104 S185', - color: '#e1b12c', - confirm: false, - exit: true, - }, - { - icon: 'snowflake', - command: 'M140 S0; M104 S0', - color: '#0097e6', - confirm: false, - exit: true, - }, - { - icon: 'redo-alt', - command: '[!RELOAD]', - color: '#7f8fa6', - confirm: true, - exit: false, - }, - { - icon: 'skull', - command: '[!KILL]', - color: '#e84118', - confirm: true, - exit: false, - }, - ], - fileSorting: { - attribute: 'name', - order: 'asc', - }, - pollingInterval: 2000, - touchscreen: true, - turnScreenOffWhileSleeping: false, - preferPreviewWhilePrinting: false, - }, - }; - } - this.config = this.configService.revertConfigForInput(this.config); - } - - public ngOnInit(): void { - this.changeProgress(); - } - - public testOctoprintAPI(): boolean { - const httpHeaders = { - headers: new HttpHeaders({ - 'x-api-key': this.config.octoprint.accessToken, - }), - }; - this.http.get(this.config.octoprint.url + 'connection', httpHeaders).subscribe( - (): void => { - this.octoprintConnection = true; - this.saveConfig(); + public constructor(private configService: ConfigService, private http: HttpClient, private router: Router) { + this.configUpdate = this.configService.isUpdate(); + console.log(this.configUpdate); + if (this.configUpdate) { + this.config = configService.getCurrentConfig(); + } else { + this.config = { + octoprint: { + url: "http://localhost:5000/api/", + accessToken: "", + }, + printer: { + name: "", + xySpeed: 150, + zSpeed: 5, + defaultTemperatureFanSpeed: { + hotend: 200, + heatbed: 60, + fan: 100, + }, + }, + filament: { + thickness: 1.75, + density: 1.25, + feedLength: 0, + feedSpeed: 30, + feedSpeedSlow: 3, + purgeDistance: 30, + useM600: false, + }, + plugins: { + displayLayerProgress: { + enabled: true, + }, + enclosure: { + enabled: false, + ambientSensorID: null, + filament1SensorID: null, + filament2SensorID: null, + }, + filamentManager: { + enabled: true, + }, + preheatButton: { + enabled: true, + }, + printTimeGenius: { + enabled: true, + }, + psuControl: { + enabled: false, + turnOnPSUWhenExitingSleep: false, + }, + }, + octodash: { + customActions: [ + { + icon: "home", + command: "G28", + color: "#dcdde1", + confirm: false, + exit: true, + }, + { + icon: "ruler-vertical", + command: "G29", + color: "#44bd32", + confirm: false, + exit: true, + }, + { + icon: "fire-alt", + command: "M140 S50; M104 S185", + color: "#e1b12c", + confirm: false, + exit: true, + }, + { + icon: "snowflake", + command: "M140 S0; M104 S0", + color: "#0097e6", + confirm: false, + exit: true, }, - (error: HttpErrorResponse): void => { - this.octoprintConnection = false; - this.octoprintConnectionError = error.message; + { + icon: "redo-alt", + command: "[!RELOAD]", + color: "#7f8fa6", + confirm: true, + exit: false, }, - ); - return true; + { + icon: "skull", + command: "[!KILL]", + color: "#e84118", + confirm: true, + exit: false, + }, + ], + fileSorting: { + attribute: "name", + order: "asc", + }, + pollingInterval: 2000, + touchscreen: true, + turnScreenOffWhileSleeping: false, + preferPreviewWhilePrinting: false, + }, + }; } + this.config = this.configService.revertConfigForInput(this.config); + } - public createConfig(): boolean { - this.configErrors = []; - this.octoprintConnectionError = null; - this.config = this.configService.createConfigFromInput(this.config); - this.validateConfig(); - return true; - } + public ngOnInit(): void { + this.changeProgress(); + } - public validateConfig(): void { - this.configValid = this.configService.validateGiven(this.config); - if (!this.configValid) { - this.configErrors = this.configService.getErrors(); - } else { - this.testOctoprintAPI(); - } - } + public testOctoprintAPI(): boolean { + const httpHeaders = { + headers: new HttpHeaders({ + "x-api-key": this.config.octoprint.accessToken, + }), + }; + this.http.get(this.config.octoprint.url + "connection", httpHeaders).subscribe( + (): void => { + this.octoprintConnection = true; + this.saveConfig(); + }, + (error: HttpErrorResponse): void => { + this.octoprintConnection = false; + this.octoprintConnectionError = error.message; + } + ); + return true; + } - public saveConfig(): void { - this.configSaved = this.configService.saveConfig(this.config); - } + public createConfig(): boolean { + this.configErrors = []; + this.octoprintConnectionError = null; + this.config = this.configService.createConfigFromInput(this.config); + this.validateConfig(); + return true; + } - public finishWizard(): void { - this.configService.updateConfig(); - this.router.navigate(['/main-screen']); + public validateConfig(): void { + this.configValid = this.configService.validateGiven(this.config); + if (!this.configValid) { + this.configErrors = this.configService.getErrors(); + } else { + this.testOctoprintAPI(); } + } - public increasePage(): void { - this.page += 1; - if (this.page === this.totalPages) { - this.createConfig(); - } - this.changeProgress(); - } + public saveConfig(): void { + this.configSaved = this.configService.saveConfig(this.config); + } + + public finishWizard(): void { + this.configService.updateConfig(); + this.router.navigate(["/main-screen"]); + } - public decreasePage(): void { - if (this.page === 5) { - this.config = this.configService.revertConfigForInput(this.config); - } - this.page -= 1; - this.changeProgress(); + public increasePage(): void { + this.page += 1; + if (this.page === this.totalPages) { + this.createConfig(); } + this.changeProgress(); + } - public changeProgress(): void { - document.getElementById('progressBar').style.width = this.page * (20 / this.totalPages) + 'vw'; + public decreasePage(): void { + if (this.page === 5) { + this.config = this.configService.revertConfigForInput(this.config); } + this.page -= 1; + this.changeProgress(); + } + + public changeProgress(): void { + document.getElementById("progressBar").style.width = this.page * (20 / this.totalPages) + "vw"; + } } diff --git a/src/app/control/control.component.ts b/src/app/control/control.component.ts index 6930832740..c744e34cc3 100644 --- a/src/app/control/control.component.ts +++ b/src/app/control/control.component.ts @@ -1,162 +1,162 @@ -import { Component } from '@angular/core'; -import { SafeResourceUrl } from '@angular/platform-browser'; -import { Router } from '@angular/router'; +import { Component } from "@angular/core"; +import { SafeResourceUrl } from "@angular/platform-browser"; +import { Router } from "@angular/router"; -import { ConfigService } from '../config/config.service'; -import { OctoprintService } from '../octoprint.service'; -import { PsuControlService } from '../plugin-service/psu-control.service'; -import { PrinterService } from '../printer.service'; +import { ConfigService } from "../config/config.service"; +import { OctoprintService } from "../octoprint.service"; +import { PsuControlService } from "../plugin-service/psu-control.service"; +import { PrinterService } from "../printer.service"; @Component({ - selector: 'app-control', - templateUrl: './control.component.html', - styleUrls: ['./control.component.scss'], + selector: "app-control", + templateUrl: "./control.component.html", + styleUrls: ["./control.component.scss"], }) export class ControlComponent { - public jogDistance = 10; - public customActions = []; - public showHelp = false; - public iFrameURL: SafeResourceUrl = 'about:blank'; - public actionToConfirm: ActionToConfirm; - - public constructor( - private printerService: PrinterService, - private octoprintService: OctoprintService, - private configService: ConfigService, - private psuControlService: PsuControlService, - private router: Router, - ) { - this.customActions = this.configService.getCustomActions(); + public jogDistance = 10; + public customActions = []; + public showHelp = false; + public iFrameURL: SafeResourceUrl = "about:blank"; + public actionToConfirm: ActionToConfirm; + + public constructor( + private printerService: PrinterService, + private octoprintService: OctoprintService, + private configService: ConfigService, + private psuControlService: PsuControlService, + private router: Router + ) { + this.customActions = this.configService.getCustomActions(); + } + + public setDistance(distance: number): void { + this.jogDistance = distance; + } + + public moveAxis(axis: string, direction: "+" | "-"): void { + const distance = Number(direction + this.jogDistance); + this.printerService.jog(axis === "x" ? distance : 0, axis === "y" ? distance : 0, axis === "z" ? distance : 0); + } + + public doAction(command: string, exit: boolean, confirm: boolean): void { + if (confirm) { + this.actionToConfirm = { + command, + exit, + }; + } else { + this.executeGCode(command); + if (exit) { + this.router.navigate(["/main-screen"]); + } } - - public setDistance(distance: number): void { - this.jogDistance = distance; - } - - public moveAxis(axis: string, direction: '+' | '-'): void { - const distance = Number(direction + this.jogDistance); - this.printerService.jog(axis === 'x' ? distance : 0, axis === 'y' ? distance : 0, axis === 'z' ? distance : 0); - } - - public doAction(command: string, exit: boolean, confirm: boolean): void { - if (confirm) { - this.actionToConfirm = { - command, - exit, - }; - } else { - this.executeGCode(command); - if (exit) { - this.router.navigate(['/main-screen']); - } - } + } + + public doActionConfirm(): void { + this.executeGCode(this.actionToConfirm.command); + if (this.actionToConfirm.exit) { + this.router.navigate(["/main-screen"]); + } else { + this.actionToConfirm = null; } - - public doActionConfirm(): void { - this.executeGCode(this.actionToConfirm.command); - if (this.actionToConfirm.exit) { - this.router.navigate(['/main-screen']); + } + + public doActionNoConfirm(): void { + this.actionToConfirm = null; + } + + private executeGCode(command: string): void { + switch (command) { + case "[!DISCONNECT]": + this.disconnectPrinter(); + break; + case "[!STOPDASHBOARD]": + this.stopOctoDash(); + break; + case "[!RELOAD]": + this.reloadOctoPrint(); + break; + case "[!REBOOT]": + this.rebootPi(); + break; + case "[!SHUTDOWN]": + this.shutdownPi(); + break; + case "[!KILL]": + this.kill(); + break; + case "[!POWEROFF]": + this.psuControlService.changePSUState(false); + break; + case "[!POWERON]": + this.psuControlService.changePSUState(true); + break; + case "[!POWERTOGGLE]": + this.psuControlService.togglePSU(); + break; + default: { + if (command.includes("[!WEB]")) { + this.openIFrame(command.replace("[!WEB]", "")); } else { - this.actionToConfirm = null; - } - } - - public doActionNoConfirm(): void { - this.actionToConfirm = null; - } - - private executeGCode(command: string): void { - switch (command) { - case '[!DISCONNECT]': - this.disconnectPrinter(); - break; - case '[!STOPDASHBOARD]': - this.stopOctoDash(); - break; - case '[!RELOAD]': - this.reloadOctoPrint(); - break; - case '[!REBOOT]': - this.rebootPi(); - break; - case '[!SHUTDOWN]': - this.shutdownPi(); - break; - case '[!KILL]': - this.kill(); - break; - case '[!POWEROFF]': - this.psuControlService.changePSUState(false); - break; - case '[!POWERON]': - this.psuControlService.changePSUState(true); - break; - case '[!POWERTOGGLE]': - this.psuControlService.togglePSU(); - break; - default: { - if (command.includes('[!WEB]')) { - this.openIFrame(command.replace('[!WEB]', '')); - } else { - this.printerService.executeGCode(command); - } - break; - } + this.printerService.executeGCode(command); } + break; + } } - - // [!DISCONNECT] - public disconnectPrinter(): void { - this.octoprintService.disconnectPrinter(); - } - - // [!STOPDASHBOARD] - public stopOctoDash(): void { - window.close(); - } - - // [!RELOAD] - public reloadOctoPrint(): void { - this.octoprintService.sendSystemCommand('restart'); - } - - // [!REBOOT] - public rebootPi(): void { - this.octoprintService.sendSystemCommand('reboot'); - } - - // [!SHUTDOWN] - public shutdownPi(): void { - this.octoprintService.sendSystemCommand('shutdown'); - } - - // [!KILL] - public kill(): void { - this.shutdownPi(); - setTimeout(this.stopOctoDash, 500); - } - - // [!WEB] - public openIFrame(url: string): void { - this.iFrameURL = url; - const iFrameDOM = document.getElementById('iFrame'); - iFrameDOM.style.display = 'block'; - setTimeout((): void => { - iFrameDOM.style.opacity = '1'; - }, 50); - } - - public hideIFrame(): void { - const iFrameDOM = document.getElementById('iFrame'); - iFrameDOM.style.opacity = '0'; - setTimeout((): void => { - iFrameDOM.style.display = 'none'; - this.iFrameURL = 'about:blank'; - }, 500); - } + } + + // [!DISCONNECT] + public disconnectPrinter(): void { + this.octoprintService.disconnectPrinter(); + } + + // [!STOPDASHBOARD] + public stopOctoDash(): void { + window.close(); + } + + // [!RELOAD] + public reloadOctoPrint(): void { + this.octoprintService.sendSystemCommand("restart"); + } + + // [!REBOOT] + public rebootPi(): void { + this.octoprintService.sendSystemCommand("reboot"); + } + + // [!SHUTDOWN] + public shutdownPi(): void { + this.octoprintService.sendSystemCommand("shutdown"); + } + + // [!KILL] + public kill(): void { + this.shutdownPi(); + setTimeout(this.stopOctoDash, 500); + } + + // [!WEB] + public openIFrame(url: string): void { + this.iFrameURL = url; + const iFrameDOM = document.getElementById("iFrame"); + iFrameDOM.style.display = "block"; + setTimeout((): void => { + iFrameDOM.style.opacity = "1"; + }, 50); + } + + public hideIFrame(): void { + const iFrameDOM = document.getElementById("iFrame"); + iFrameDOM.style.opacity = "0"; + setTimeout((): void => { + iFrameDOM.style.display = "none"; + this.iFrameURL = "about:blank"; + }, 500); + } } interface ActionToConfirm { - command: string; - exit: boolean; + command: string; + exit: boolean; } diff --git a/src/app/filament/filament.component.ts b/src/app/filament/filament.component.ts index 4d089cc007..4f336d0ec6 100644 --- a/src/app/filament/filament.component.ts +++ b/src/app/filament/filament.component.ts @@ -1,326 +1,326 @@ -import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; -import { ConfigService } from '../config/config.service'; -import { FilamentManagerService, FilamentSpool, FilamentSpoolList } from '../plugin-service/filament-manager.service'; -import { PrinterService, PrinterStatusAPI } from '../printer.service'; +import { ConfigService } from "../config/config.service"; +import { FilamentManagerService, FilamentSpool, FilamentSpoolList } from "../plugin-service/filament-manager.service"; +import { PrinterService, PrinterStatusAPI } from "../printer.service"; @Component({ - selector: 'app-filament', - templateUrl: './filament.component.html', - styleUrls: ['./filament.component.scss'], + selector: "app-filament", + templateUrl: "./filament.component.html", + styleUrls: ["./filament.component.scss"], }) export class FilamentComponent implements OnInit { - private selectedSpool: FilamentSpool; - private currentSpool: FilamentSpool; - private totalPages = 5; - - public page: number; - private timeout: number; - private timeout2: number; - - public filamentSpools: FilamentSpoolList; - public isLoadingSpools = true; - - public hotendTarget: number; - public hotendTemperature: number; - public automaticHeatingStartSeconds: number; - public isHeating: boolean; - - private feedSpeedSlow = false; - - public purgeAmount: number; - - public constructor( - private router: Router, - private configService: ConfigService, - private filamentManagerService: FilamentManagerService, - private printerService: PrinterService, - ) {} - - public ngOnInit(): void { - if (this.configService.isFilamentManagerEnabled()) { - this.setPage(0); - } else { - this.setPage(1); - } - this.hotendTarget = this.configService.getDefaultHotendTemperature(); - this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { - this.hotendTemperature = printerStatus.nozzle.current; - }); + private selectedSpool: FilamentSpool; + private currentSpool: FilamentSpool; + private totalPages = 5; + + public page: number; + private timeout: number; + private timeout2: number; + + public filamentSpools: FilamentSpoolList; + public isLoadingSpools = true; + + public hotendTarget: number; + public hotendTemperature: number; + public automaticHeatingStartSeconds: number; + public isHeating: boolean; + + private feedSpeedSlow = false; + + public purgeAmount: number; + + public constructor( + private router: Router, + private configService: ConfigService, + private filamentManagerService: FilamentManagerService, + private printerService: PrinterService + ) {} + + public ngOnInit(): void { + if (this.configService.isFilamentManagerEnabled()) { + this.setPage(0); + } else { + this.setPage(1); } - - public increasePage(): void { - if (this.page < this.totalPages) { - this.setPage(this.page + 1); - } else if (this.page === this.totalPages) { - this.router.navigate(['/main-screen']); - } - } - - // PAGINATION - - public decreasePage(): void { - if (this.page === 0) { - this.router.navigate(['/main-screen']); - } else if (this.page === 1 && this.configService.isFilamentManagerEnabled()) { - this.setPage(0); - } else if (this.page === 1) { - this.router.navigate(['/main-screen']); - } else if (this.page === 2 || this.page === 3) { - this.setPage(1); - } else if (this.page === 4 || this.page === 5) { - this.setPage(3); - } - } - - private setPage(page: number): void { - clearTimeout(this.timeout); - clearTimeout(this.timeout2); - if (this.page === 4) { - this.feedSpeedSlow = false; - } - if (page === 0) { - this.selectedSpool = null; - this.getSpools(); - } else if (page === 1) { - this.isHeating = false; - this.automaticHeatingStartSeconds = 6; - this.automaticHeatingStartTimer(); - } else if (page === 2) { - if (this.getFeedLength() === 0) { - this.setPage(3); - return; - } else { - this.unloadSpool(); - } - } else if (page === 3) { - if (this.configService.useM600()) { - this.initiateM600FilamentChange(); - } else { - this.disableExtruderStepper(); - } - } else if (page === 4) { - if (this.getFeedLength() === 0) { - this.setPage(5); - return; - } else { - this.loadSpool(); - } - } else if (page === 5) { - this.purgeAmount = this.configService.useM600() ? 0 : this.configService.getPurgeDistance(); - this.purgeFilament(this.purgeAmount); - } - this.page = page; - if (this.page > 0) { - setTimeout((): void => { - document.getElementById('progressBar').style.width = this.page * (20 / this.totalPages) + 'vw'; - }, 200); - } - } - - // FILAMENT MANAGEMENT - - private getSpools(): void { - this.isLoadingSpools = true; - this.filamentManagerService - .getSpoolList() - .then((spools: FilamentSpoolList): void => { - this.filamentSpools = spools; - }) - .catch((): void => { - this.filamentSpools = null; - }) - .finally((): void => { - this.filamentManagerService - .getCurrentSpool() - .then((spool: FilamentSpool): void => { - this.currentSpool = spool; - }) - .catch((): void => { - this.currentSpool = null; - }) - .finally((): void => { - this.isLoadingSpools = false; - }); - }); - } - - public getSpoolWeightLeft(weight: number, used: number): number { - return Math.floor(weight - used); + this.hotendTarget = this.configService.getDefaultHotendTemperature(); + this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { + this.hotendTemperature = printerStatus.nozzle.current; + }); + } + + public increasePage(): void { + if (this.page < this.totalPages) { + this.setPage(this.page + 1); + } else if (this.page === this.totalPages) { + this.router.navigate(["/main-screen"]); } - - public getSpoolTemperatureOffset(): string { - return `${ - this.selectedSpool.temp_offset === 0 ? '±' : this.selectedSpool.temp_offset > 0 ? '+' : '-' - }${Math.abs(this.selectedSpool.temp_offset)}`; + } + + // PAGINATION + + public decreasePage(): void { + if (this.page === 0) { + this.router.navigate(["/main-screen"]); + } else if (this.page === 1 && this.configService.isFilamentManagerEnabled()) { + this.setPage(0); + } else if (this.page === 1) { + this.router.navigate(["/main-screen"]); + } else if (this.page === 2 || this.page === 3) { + this.setPage(1); + } else if (this.page === 4 || this.page === 5) { + this.setPage(3); } + } - public getCurrentSpoolColor(): string { - if (this.currentSpool) { - return this.currentSpool.color; - } else { - return '#44bd32'; - } + private setPage(page: number): void { + clearTimeout(this.timeout); + clearTimeout(this.timeout2); + if (this.page === 4) { + this.feedSpeedSlow = false; } - - public getSelectedSpoolColor(): string { - if (this.selectedSpool) { - return this.selectedSpool.color; - } else { - return '#44bd32'; - } + if (page === 0) { + this.selectedSpool = null; + this.getSpools(); + } else if (page === 1) { + this.isHeating = false; + this.automaticHeatingStartSeconds = 6; + this.automaticHeatingStartTimer(); + } else if (page === 2) { + if (this.getFeedLength() === 0) { + this.setPage(3); + return; + } else { + this.unloadSpool(); + } + } else if (page === 3) { + if (this.configService.useM600()) { + this.initiateM600FilamentChange(); + } else { + this.disableExtruderStepper(); + } + } else if (page === 4) { + if (this.getFeedLength() === 0) { + this.setPage(5); + return; + } else { + this.loadSpool(); + } + } else if (page === 5) { + this.purgeAmount = this.configService.useM600() ? 0 : this.configService.getPurgeDistance(); + this.purgeFilament(this.purgeAmount); } - - private getFeedLength(): number { - return this.configService.useM600() ? 0 : this.configService.getFeedLength(); + this.page = page; + if (this.page > 0) { + setTimeout((): void => { + document.getElementById("progressBar").style.width = this.page * (20 / this.totalPages) + "vw"; + }, 200); } - - public getFeedSpeed(): number { - if (this.feedSpeedSlow) { - return this.configService.getFeedSpeedSlow(); - } else { - return this.configService.getFeedSpeed(); - } + } + + // FILAMENT MANAGEMENT + + private getSpools(): void { + this.isLoadingSpools = true; + this.filamentManagerService + .getSpoolList() + .then((spools: FilamentSpoolList): void => { + this.filamentSpools = spools; + }) + .catch((): void => { + this.filamentSpools = null; + }) + .finally((): void => { + this.filamentManagerService + .getCurrentSpool() + .then((spool: FilamentSpool): void => { + this.currentSpool = spool; + }) + .catch((): void => { + this.currentSpool = null; + }) + .finally((): void => { + this.isLoadingSpools = false; + }); + }); + } + + public getSpoolWeightLeft(weight: number, used: number): number { + return Math.floor(weight - used); + } + + public getSpoolTemperatureOffset(): string { + return `${this.selectedSpool.temp_offset === 0 ? "±" : this.selectedSpool.temp_offset > 0 ? "+" : "-"}${Math.abs( + this.selectedSpool.temp_offset + )}`; + } + + public getCurrentSpoolColor(): string { + if (this.currentSpool) { + return this.currentSpool.color; + } else { + return "#44bd32"; } + } - public setSpool(spool: FilamentSpool): void { - this.selectedSpool = spool; - this.hotendTarget = this.hotendTarget + spool.temp_offset; - this.increasePage(); + public getSelectedSpoolColor(): string { + if (this.selectedSpool) { + return this.selectedSpool.color; + } else { + return "#44bd32"; } + } - private unloadSpool(): void { - this.printerService.extrude(this.getFeedLength() * -1, this.configService.getFeedSpeed()); - setTimeout((): void => { - const unloadingProgressBar = document.getElementById('filamentUnloadBar'); - unloadingProgressBar.style.backgroundColor = this.getCurrentSpoolColor(); - const unloadTime = this.getFeedLength() / this.configService.getFeedSpeed() + 0.5; - unloadingProgressBar.style.transition = 'width ' + unloadTime + 's ease-in'; - setTimeout((): void => { - unloadingProgressBar.style.width = '0vw'; - this.timeout = setTimeout((): void => { - this.increasePage(); - }, unloadTime * 1000 + 500); - }, 200); - }, 0); - } + private getFeedLength(): number { + return this.configService.useM600() ? 0 : this.configService.getFeedLength(); + } - private loadSpool(): void { - const loadTimeFast = (this.getFeedLength() * 0.75) / this.configService.getFeedSpeed(); - const loadTimeSlow = (this.getFeedLength() * 0.17) / this.configService.getFeedSpeedSlow(); - const loadTime = loadTimeFast + loadTimeSlow + 0.5; - this.printerService.extrude(this.getFeedLength() * 0.75, this.configService.getFeedSpeed()); - setTimeout((): void => { - const loadingProgressBar = document.getElementById('filamentLoadBar'); - loadingProgressBar.style.backgroundColor = this.getSelectedSpoolColor(); - - loadingProgressBar.style.transition = 'width ' + loadTime + 's ease-in'; - setTimeout((): void => { - loadingProgressBar.style.width = '50vw'; - this.timeout = setTimeout((): void => { - this.printerService.extrude(this.getFeedLength() * 0.17, this.configService.getFeedSpeedSlow()); - this.feedSpeedSlow = true; - this.timeout2 = setTimeout((): void => { - this.increasePage(); - }, loadTimeSlow * 1000 + 400); - }, loadTimeFast * 1000 + 200); - }, 200); - }, 0); + public getFeedSpeed(): number { + if (this.feedSpeedSlow) { + return this.configService.getFeedSpeedSlow(); + } else { + return this.configService.getFeedSpeed(); } - - public setSpoolSelection(): void { - this.printerService.setTemperatureHotend(0); - if (this.selectedSpool) { - this.filamentManagerService.setCurrentSpool(this.selectedSpool).finally(this.increasePage.bind(this)); - } else { + } + + public setSpool(spool: FilamentSpool): void { + this.selectedSpool = spool; + this.hotendTarget = this.hotendTarget + spool.temp_offset; + this.increasePage(); + } + + private unloadSpool(): void { + this.printerService.extrude(this.getFeedLength() * -1, this.configService.getFeedSpeed()); + setTimeout((): void => { + const unloadingProgressBar = document.getElementById("filamentUnloadBar"); + unloadingProgressBar.style.backgroundColor = this.getCurrentSpoolColor(); + const unloadTime = this.getFeedLength() / this.configService.getFeedSpeed() + 0.5; + unloadingProgressBar.style.transition = "width " + unloadTime + "s ease-in"; + setTimeout((): void => { + unloadingProgressBar.style.width = "0vw"; + this.timeout = setTimeout((): void => { + this.increasePage(); + }, unloadTime * 1000 + 500); + }, 200); + }, 0); + } + + private loadSpool(): void { + const loadTimeFast = (this.getFeedLength() * 0.75) / this.configService.getFeedSpeed(); + const loadTimeSlow = (this.getFeedLength() * 0.17) / this.configService.getFeedSpeedSlow(); + const loadTime = loadTimeFast + loadTimeSlow + 0.5; + this.printerService.extrude(this.getFeedLength() * 0.75, this.configService.getFeedSpeed()); + setTimeout((): void => { + const loadingProgressBar = document.getElementById("filamentLoadBar"); + loadingProgressBar.style.backgroundColor = this.getSelectedSpoolColor(); + + loadingProgressBar.style.transition = "width " + loadTime + "s ease-in"; + setTimeout((): void => { + loadingProgressBar.style.width = "50vw"; + this.timeout = setTimeout((): void => { + this.printerService.extrude(this.getFeedLength() * 0.17, this.configService.getFeedSpeedSlow()); + this.feedSpeedSlow = true; + this.timeout2 = setTimeout((): void => { this.increasePage(); - } + }, loadTimeSlow * 1000 + 400); + }, loadTimeFast * 1000 + 200); + }, 200); + }, 0); + } + + public setSpoolSelection(): void { + this.printerService.setTemperatureHotend(0); + if (this.selectedSpool) { + this.filamentManagerService.setCurrentSpool(this.selectedSpool).finally(this.increasePage.bind(this)); + } else { + this.increasePage(); + } + } + + public stopExtruderMovement(): void { + this.printerService.stopMotors(); + clearTimeout(this.timeout); + clearTimeout(this.timeout2); + + let bar: HTMLElement; + const wrapper = (document.getElementsByClassName( + "filament__progress-bar-wrapper-wide" + // eslint-disable-next-line @typescript-eslint/no-explicit-any + )[0] as any) as HTMLElement; + + if (document.getElementById("filamentLoadBar")) { + bar = document.getElementById("filamentLoadBar"); + } else { + bar = document.getElementById("filamentUnloadBar"); } - public stopExtruderMovement(): void { - this.printerService.stopMotors(); - clearTimeout(this.timeout); - clearTimeout(this.timeout2); + bar.style.width = Math.floor(bar.getBoundingClientRect().width) + "px"; + wrapper.style.borderColor = "#c23616"; + } - let bar: HTMLElement; - const wrapper = (document.getElementsByClassName( - 'filament__progress-bar-wrapper-wide', - // eslint-disable-next-line @typescript-eslint/no-explicit-any - )[0] as any) as HTMLElement; + private disableExtruderStepper(): void { + this.printerService.executeGCode("M18 E "); + } - if (document.getElementById('filamentLoadBar')) { - bar = document.getElementById('filamentLoadBar'); - } else { - bar = document.getElementById('filamentUnloadBar'); - } + private initiateM600FilamentChange(): void { + this.printerService.executeGCode("M600"); + } - bar.style.width = Math.floor(bar.getBoundingClientRect().width) + 'px'; - wrapper.style.borderColor = '#c23616'; - } + // NOZZLE HEATING - private disableExtruderStepper(): void { - this.printerService.executeGCode('M18 E '); + public changeHotendTarget(value: number): void { + this.hotendTarget = this.hotendTarget + value; + if (this.hotendTarget < 0) { + this.hotendTarget = 0; } - - private initiateM600FilamentChange(): void { - this.printerService.executeGCode('M600'); + if (this.hotendTarget > 999) { + this.hotendTarget = 999; } - - // NOZZLE HEATING - - public changeHotendTarget(value: number): void { - this.hotendTarget = this.hotendTarget + value; - if (this.hotendTarget < 0) { - this.hotendTarget = 0; - } - if (this.hotendTarget > 999) { - this.hotendTarget = 999; - } - if (!this.isHeating) { - this.automaticHeatingStartSeconds = 5; - } else { - this.setNozzleTemperature(); - } + if (!this.isHeating) { + this.automaticHeatingStartSeconds = 5; + } else { + this.setNozzleTemperature(); } - - private automaticHeatingStartTimer(): void { - this.automaticHeatingStartSeconds--; - if (this.automaticHeatingStartSeconds === 0) { - this.setNozzleTemperature(); - } else { - this.timeout = setTimeout(this.automaticHeatingStartTimer.bind(this), 1000); - } + } + + private automaticHeatingStartTimer(): void { + this.automaticHeatingStartSeconds--; + if (this.automaticHeatingStartSeconds === 0) { + this.setNozzleTemperature(); + } else { + this.timeout = setTimeout(this.automaticHeatingStartTimer.bind(this), 1000); } + } - public setNozzleTemperature(): void { - if (this.page === 1) { - this.isHeating = true; - this.printerService.setTemperatureHotend(this.hotendTarget); - if (this.timeout) { - clearTimeout(this.timeout); - } - if (this.timeout2) { - clearTimeout(this.timeout2); - } - this.timeout2 = setTimeout(this.checkTemperature.bind(this), 1500); - } + public setNozzleTemperature(): void { + if (this.page === 1) { + this.isHeating = true; + this.printerService.setTemperatureHotend(this.hotendTarget); + if (this.timeout) { + clearTimeout(this.timeout); + } + if (this.timeout2) { + clearTimeout(this.timeout2); + } + this.timeout2 = setTimeout(this.checkTemperature.bind(this), 1500); } + } - private checkTemperature(): void { - if (this.hotendTemperature >= this.hotendTarget) { - this.increasePage(); - } else { - this.timeout2 = setTimeout(this.checkTemperature.bind(this), 1500); - } + private checkTemperature(): void { + if (this.hotendTemperature >= this.hotendTarget) { + this.increasePage(); + } else { + this.timeout2 = setTimeout(this.checkTemperature.bind(this), 1500); } + } - public increasePurgeAmount(length: number): void { - this.purgeAmount += length; - this.purgeFilament(length); - } + public increasePurgeAmount(length: number): void { + this.purgeAmount += length; + this.purgeFilament(length); + } - public purgeFilament(length: number): void { - this.printerService.extrude(length, this.configService.getFeedSpeedSlow()); - } + public purgeFilament(length: number): void { + this.printerService.extrude(length, this.configService.getFeedSpeedSlow()); + } } diff --git a/src/app/files.service.ts b/src/app/files.service.ts index 98d2d47203..46ef6da0ff 100644 --- a/src/app/files.service.ts +++ b/src/app/files.service.ts @@ -1,276 +1,265 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import _ from 'lodash'; -import { Subscription } from 'rxjs'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import _ from "lodash"; +import { Subscription } from "rxjs"; -import { AppService } from './app.service'; -import { ConfigService } from './config/config.service'; -import { NotificationService } from './notification/notification.service'; -import { OctoprintFilesAPI, OctoprintFolderAPI, OctoprintFolderContentAPI } from './octoprint-api/filesAPI'; +import { AppService } from "./app.service"; +import { ConfigService } from "./config/config.service"; +import { NotificationService } from "./notification/notification.service"; +import { OctoprintFilesAPI, OctoprintFolderAPI, OctoprintFolderContentAPI } from "./octoprint-api/filesAPI"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class FilesService { - private httpGETRequest: Subscription; - private httpPOSTRequest: Subscription; - private httpDELETERequest: Subscription; + private httpGETRequest: Subscription; + private httpPOSTRequest: Subscription; + private httpDELETERequest: Subscription; - public constructor( - private configService: ConfigService, - private http: HttpClient, - private notificationService: NotificationService, - private service: AppService, - ) {} + public constructor( + private configService: ConfigService, + private http: HttpClient, + private notificationService: NotificationService, + private service: AppService + ) {} - public getFolder(folderPath: string = '/'): Promise<(File | Folder)[]> { - return new Promise((resolve, reject): void => { - folderPath = folderPath === '/' ? '' : folderPath; - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); + public getFolder(folderPath = "/"): Promise<(File | Folder)[]> { + return new Promise((resolve, reject): void => { + folderPath = folderPath === "/" ? "" : folderPath; + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get(this.configService.getURL("files" + folderPath), this.configService.getHTTPHeaders()) + .subscribe( + (data: OctoprintFolderAPI & OctoprintFolderContentAPI): void => { + if ("children" in data) { + data.files = data.children; + delete data.children; } - this.httpGETRequest = this.http - .get(this.configService.getURL('files' + folderPath), this.configService.getHTTPHeaders()) - .subscribe( - (data: OctoprintFolderAPI & OctoprintFolderContentAPI): void => { - if ('children' in data) { - data.files = data.children; - delete data.children; - } - const folder: (File | Folder)[] = []; - let localCount = 0; - let sdCardCount = 0; - data.files.forEach((fileOrFolder): void => { - if (fileOrFolder.type === 'folder') { - if (folderPath === '') { - if (fileOrFolder.origin == 'local') { - localCount += fileOrFolder.children.length; - } else { - sdCardCount += fileOrFolder.children.length; - } - } + const folder: (File | Folder)[] = []; + let localCount = 0; + let sdCardCount = 0; + data.files.forEach((fileOrFolder): void => { + if (fileOrFolder.type === "folder") { + if (folderPath === "") { + if (fileOrFolder.origin == "local") { + localCount += fileOrFolder.children.length; + } else { + sdCardCount += fileOrFolder.children.length; + } + } - folder.push(({ - type: 'folder', - path: '/' + fileOrFolder.origin + '/' + fileOrFolder.path, - name: fileOrFolder.name, - // TODO: Think of a way to retrieve number of children - files: fileOrFolder.children ? fileOrFolder.children.length : '-', - } as unknown) as Folder); - } else if (fileOrFolder.typePath.includes('gcode')) { - let filamentLength = 0; - if (fileOrFolder.gcodeAnalysis) { - _.forEach(fileOrFolder.gcodeAnalysis.filament, (tool): void => { - filamentLength += tool.length; - }); - var estimatedPrintTime = this.service.convertSecondsToHours( - fileOrFolder.gcodeAnalysis.estimatedPrintTime, - ); - } + folder.push(({ + type: "folder", + path: "/" + fileOrFolder.origin + "/" + fileOrFolder.path, + name: fileOrFolder.name, + // TODO: Think of a way to retrieve number of children + files: fileOrFolder.children ? fileOrFolder.children.length : "-", + } as unknown) as Folder); + } else if (fileOrFolder.typePath.includes("gcode")) { + let filamentLength = 0; + if (fileOrFolder.gcodeAnalysis) { + _.forEach(fileOrFolder.gcodeAnalysis.filament, (tool): void => { + filamentLength += tool.length; + }); + } - if (folderPath === '') { - if (fileOrFolder.origin == 'local') { - localCount += 1; - } else { - sdCardCount += 1; - } - } + if (folderPath === "") { + if (fileOrFolder.origin == "local") { + localCount += 1; + } else { + sdCardCount += 1; + } + } - folder.push(({ - type: 'file', - path: '/' + fileOrFolder.origin + '/' + fileOrFolder.path, - name: fileOrFolder.name, - date: fileOrFolder.date, - size: this.service.convertByteToMegabyte(fileOrFolder.size), - ...(fileOrFolder.gcodeAnalysis - ? { - printTime: estimatedPrintTime, - filamentWeight: this.service.convertFilamentLengthToAmount( - filamentLength, - ), - } - : {}), - } as unknown) as File); - } - }); - data = null; + folder.push(({ + type: "file", + path: "/" + fileOrFolder.origin + "/" + fileOrFolder.path, + name: fileOrFolder.name, + date: fileOrFolder.date, + size: this.service.convertByteToMegabyte(fileOrFolder.size), + ...(fileOrFolder.gcodeAnalysis + ? { + printTime: this.service.convertSecondsToHours(fileOrFolder.gcodeAnalysis.estimatedPrintTime), + filamentWeight: this.service.convertFilamentLengthToAmount(filamentLength), + } + : {}), + } as unknown) as File); + } + }); + data = null; - if (folderPath === '') { - if (localCount > 0 && sdCardCount > 0) { - folder.length = 0; - folder.push(({ - type: 'folder', - path: '/local', - name: 'local', - files: localCount, - } as unknown) as Folder); - folder.push(({ - type: 'folder', - path: '/sdcard', - name: 'sdcard', - files: sdCardCount, - } as unknown) as Folder); - } - } - - resolve(folder); - }, - (error: HttpErrorResponse): void => { - if (error.status === 404) { - this.notificationService.setError("Can't find specified folder!", error.message); - if (folderPath !== '/') { - this.getFolder(folderPath.substring(0, folderPath.lastIndexOf('/'))); - } else { - reject(); - } - } else { - this.notificationService.setError("Can't retrieve folder!", error.message); - reject(); - } - }, - ); - }); - } + if (folderPath === "") { + if (localCount > 0 && sdCardCount > 0) { + folder.length = 0; + folder.push(({ + type: "folder", + path: "/local", + name: "local", + files: localCount, + } as unknown) as Folder); + folder.push(({ + type: "folder", + path: "/sdcard", + name: "sdcard", + files: sdCardCount, + } as unknown) as Folder); + } + } - public getFile(filePath: string): Promise { - return new Promise((resolve, reject): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); + resolve(folder); + }, + (error: HttpErrorResponse): void => { + if (error.status === 404) { + this.notificationService.setError("Can't find specified folder!", error.message); + if (folderPath !== "/") { + this.getFolder(folderPath.substring(0, folderPath.lastIndexOf("/"))); + } else { + reject(); + } + } else { + this.notificationService.setError("Can't retrieve folder!", error.message); + reject(); } - this.httpGETRequest = this.http - .get(this.configService.getURL('files' + filePath), this.configService.getHTTPHeaders()) - .subscribe( - (data: OctoprintFilesAPI): void => { - let filamentLength = 0; - if (data.gcodeAnalysis) { - _.forEach(data.gcodeAnalysis.filament, (tool): void => { - filamentLength += tool.length; - }); - } - const file = ({ - type: 'file', - path: '/' + data.origin + '/' + data.path, - name: data.name, - size: this.service.convertByteToMegabyte(data.size), - ...(data.gcodeAnalysis - ? { - date: this.service.convertDateToString(new Date(data.date * 1000)), - printTime: this.service.convertSecondsToHours( - data.gcodeAnalysis.estimatedPrintTime, - ), - filamentWeight: this.service.convertFilamentLengthToAmount(filamentLength), - } - : {}), - thumbnail: data.thumbnail - ? this.configService - .getURL(data.thumbnail) - .replace('/api/', '/') - : 'assets/object.svg', - } as unknown) as File; - resolve(file); - }, - (error: HttpErrorResponse): void => { - if (error.status === 404) { - this.notificationService.setError("Can't find specified file!", error.message); - reject(); - } else { - this.notificationService.setError("Can't retrieve folder!", error.message); - reject(); - } - }, - ); - }); - } + } + ); + }); + } - public getThumbnail(filePath: string): Promise { - return new Promise((resolve, reject): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); + public getFile(filePath: string): Promise { + return new Promise((resolve, reject): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get(this.configService.getURL("files" + filePath), this.configService.getHTTPHeaders()) + .subscribe( + (data: OctoprintFilesAPI): void => { + let filamentLength = 0; + if (data.gcodeAnalysis) { + _.forEach(data.gcodeAnalysis.filament, (tool): void => { + filamentLength += tool.length; + }); } - this.httpGETRequest = this.http - .get(this.configService.getURL('files' + filePath), this.configService.getHTTPHeaders()) - .subscribe( - (data: OctoprintFilesAPI): void => { - let thumbnail = data.thumbnail - ? this.configService - .getURL(data.thumbnail) - .replace('/api/', '/') - : 'assets/object.svg'; - resolve(thumbnail); - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't load thumbnail!", error.message); - reject(); - }, - ); - }); - } + const file = ({ + type: "file", + path: "/" + data.origin + "/" + data.path, + name: data.name, + size: this.service.convertByteToMegabyte(data.size), + ...(data.gcodeAnalysis + ? { + date: this.service.convertDateToString(new Date(data.date * 1000)), + printTime: this.service.convertSecondsToHours(data.gcodeAnalysis.estimatedPrintTime), + filamentWeight: this.service.convertFilamentLengthToAmount(filamentLength), + } + : {}), + thumbnail: data.thumbnail + ? this.configService.getURL(data.thumbnail).replace("/api/", "/") + : "assets/object.svg", + } as unknown) as File; + resolve(file); + }, + (error: HttpErrorResponse): void => { + if (error.status === 404) { + this.notificationService.setError("Can't find specified file!", error.message); + reject(); + } else { + this.notificationService.setError("Can't retrieve folder!", error.message); + reject(); + } + } + ); + }); + } - public loadFile(filePath: string): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const loadFileBody = { - command: 'select', - print: false, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('files' + filePath), loadFileBody, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't load the file!", error.message); - }, - ); - } + public getThumbnail(filePath: string): Promise { + return new Promise((resolve, reject): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get(this.configService.getURL("files" + filePath), this.configService.getHTTPHeaders()) + .subscribe( + (data: OctoprintFilesAPI): void => { + const thumbnail = data.thumbnail + ? this.configService.getURL(data.thumbnail).replace("/api/", "/") + : "assets/object.svg"; + resolve(thumbnail); + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't load thumbnail!", error.message); + reject(); + } + ); + }); + } - public printFile(filePath: string): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const printFileBody = { - command: 'select', - print: true, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('files' + filePath), printFileBody, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't start print!", error.message); - }, - ); + public loadFile(filePath: string): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + const loadFileBody = { + command: "select", + print: false, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("files" + filePath), loadFileBody, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't load the file!", error.message); + } + ); + } - public deleteFile(filePath: string): void { - if (this.httpDELETERequest) { - this.httpDELETERequest.unsubscribe(); + public printFile(filePath: string): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); + } + const printFileBody = { + command: "select", + print: true, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("files" + filePath), printFileBody, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't start print!", error.message); } - this.httpDELETERequest = this.http - .delete(this.configService.getURL('files' + filePath), this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't delete file!", error.message); - }, - ); + ); + } + + public deleteFile(filePath: string): void { + if (this.httpDELETERequest) { + this.httpDELETERequest.unsubscribe(); } + this.httpDELETERequest = this.http + .delete(this.configService.getURL("files" + filePath), this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't delete file!", error.message); + } + ); + } } export interface Folder { - type: string; - path: string; - name: string; - files?: number; + type: string; + path: string; + name: string; + files?: number; } export interface File { - type: string; - path: string; - name: string; - size?: string; - printTime?: string; - filamentWeight?: number; - date?: string; - thumbnail?: string; + type: string; + path: string; + name: string; + size?: string; + printTime?: string; + filamentWeight?: number; + date?: string; + thumbnail?: string; } diff --git a/src/app/files/files.component.ts b/src/app/files/files.component.ts index de6d17d36f..db526e9f51 100644 --- a/src/app/files/files.component.ts +++ b/src/app/files/files.component.ts @@ -1,184 +1,184 @@ -import { Component } from '@angular/core'; -import { Router } from '@angular/router'; -import { NgxSpinnerService } from 'ngx-spinner'; +import { Component } from "@angular/core"; +import { Router } from "@angular/router"; +import { NgxSpinnerService } from "ngx-spinner"; -import { AppService } from '../app.service'; -import { ConfigService } from '../config/config.service'; -import { File, FilesService, Folder } from '../files.service'; -import { JobService } from '../job.service'; +import { AppService } from "../app.service"; +import { ConfigService } from "../config/config.service"; +import { File, FilesService, Folder } from "../files.service"; +import { JobService } from "../job.service"; @Component({ - selector: 'app-files', - templateUrl: './files.component.html', - styleUrls: ['./files.component.scss'], + selector: "app-files", + templateUrl: "./files.component.html", + styleUrls: ["./files.component.scss"], }) export class FilesComponent { - public currentFolder: string; - public folderContent: (File | Folder)[]; - public fileDetail: File; - public sortingAttribute: 'name' | 'date' | 'size'; - public sortingOrder: 'asc' | 'dsc'; - public showSorting: boolean = false; - public homeFolder: string = '/'; + public currentFolder: string; + public folderContent: (File | Folder)[]; + public fileDetail: File; + public sortingAttribute: "name" | "date" | "size"; + public sortingOrder: "asc" | "dsc"; + public showSorting = false; + public homeFolder = "/"; - public constructor( - private filesService: FilesService, - private spinner: NgxSpinnerService, - private service: AppService, - private router: Router, - private jobService: JobService, - private configService: ConfigService, - ) { - this.showLoader(); - this.folderContent = []; - this.currentFolder = '/'; - this.sortingAttribute = this.configService.getDefaultSortingAttribute(); - this.sortingOrder = this.configService.getDefaultSortingOrder(); - this.openFolder(this.currentFolder); - } + public constructor( + private filesService: FilesService, + private spinner: NgxSpinnerService, + private service: AppService, + private router: Router, + private jobService: JobService, + private configService: ConfigService + ) { + this.showLoader(); + this.folderContent = []; + this.currentFolder = "/"; + this.sortingAttribute = this.configService.getDefaultSortingAttribute(); + this.sortingOrder = this.configService.getDefaultSortingOrder(); + this.openFolder(this.currentFolder); + } - public openDetails(filePath: string): void { - this.filesService - .getFile(filePath) - .then((data): void => { - this.fileDetail = data; - }) - .catch(({}): void => { - this.fileDetail = ({ name: 'error' } as unknown) as File; - }); - const fileDOMElement = document.getElementById('fileDetailView'); - fileDOMElement.style.display = 'block'; - setTimeout((): void => { - fileDOMElement.style.opacity = '1'; - }, 50); - } + public openDetails(filePath: string): void { + this.filesService + .getFile(filePath) + .then((data): void => { + this.fileDetail = data; + }) + .catch((): void => { + this.fileDetail = ({ name: "error" } as unknown) as File; + }); + const fileDOMElement = document.getElementById("fileDetailView"); + fileDOMElement.style.display = "block"; + setTimeout((): void => { + fileDOMElement.style.opacity = "1"; + }, 50); + } - public openFolder(folderPath: string): void { - setTimeout((): void => { - this.showLoader(); - this.folderContent = []; - this.filesService - .getFolder(folderPath) - .then((data): void => { - this.folderContent = data; - if (folderPath === '/' && !(data[0].name === 'local' && data[1].name == 'sdcard')) { - this.currentFolder = data[0].path.startsWith('/local') ? '/local' : '/sdcard'; - this.homeFolder = this.currentFolder; - } else { - this.currentFolder = folderPath; - } - this.sortFolder(this.sortingAttribute, this.sortingOrder); - this.spinner.hide(); - }) - .catch((): void => { - this.folderContent = null; - this.currentFolder = folderPath; - this.spinner.hide(); - }); - }, 300); - } + public openFolder(folderPath: string): void { + setTimeout((): void => { + this.showLoader(); + this.folderContent = []; + this.filesService + .getFolder(folderPath) + .then((data): void => { + this.folderContent = data; + if (folderPath === "/" && !(data[0].name === "local" && data[1].name == "sdcard")) { + this.currentFolder = data[0].path.startsWith("/local") ? "/local" : "/sdcard"; + this.homeFolder = this.currentFolder; + } else { + this.currentFolder = folderPath; + } + this.sortFolder(this.sortingAttribute, this.sortingOrder); + this.spinner.hide(); + }) + .catch((): void => { + this.folderContent = null; + this.currentFolder = folderPath; + this.spinner.hide(); + }); + }, 300); + } - public sortFolder(by: 'name' | 'date' | 'size' = 'name', order: 'asc' | 'dsc' = 'asc'): void { - switch (by) { - case 'name': { - this.folderContent.sort((a, b): number => - a.type === b.type - ? (order === 'asc' ? a.name > b.name : a.name < b.name) - ? 1 - : -1 - : a.type === 'folder' - ? -1 - : 1, - ); - break; - } - case 'date': { - this.sortFolder('name', order); - this.folderContent.sort((a, b): number => { - if (a.type === b.type && a.type === 'file') { - const aFile = (a as unknown) as File; - const bFile = (b as unknown) as File; - return (order === 'asc' ? aFile.date > bFile.date : aFile.date < bFile.date) ? 1 : -1; - } else { - return a.type === 'folder' ? -1 : 1; - } - }); - break; - } - case 'size': { - this.sortFolder('name', order); - this.folderContent.sort((a, b): number => { - if (a.type === b.type && (a as File).type) { - const aFile = (a as unknown) as File; - const bFile = (b as unknown) as File; - return (order === 'asc' ? aFile.size > bFile.size : aFile.size < bFile.size) ? 1 : -1; - } else { - return 1; - } - }); - break; - } - } + public sortFolder(by: "name" | "date" | "size" = "name", order: "asc" | "dsc" = "asc"): void { + switch (by) { + case "name": { + this.folderContent.sort((a, b): number => + a.type === b.type + ? (order === "asc" ? a.name > b.name : a.name < b.name) + ? 1 + : -1 + : a.type === "folder" + ? -1 + : 1 + ); + break; + } + case "date": { + this.sortFolder("name", order); + this.folderContent.sort((a, b): number => { + if (a.type === b.type && a.type === "file") { + const aFile = (a as unknown) as File; + const bFile = (b as unknown) as File; + return (order === "asc" ? aFile.date > bFile.date : aFile.date < bFile.date) ? 1 : -1; + } else { + return a.type === "folder" ? -1 : 1; + } + }); + break; + } + case "size": { + this.sortFolder("name", order); + this.folderContent.sort((a, b): number => { + if (a.type === b.type && (a as File).type) { + const aFile = (a as unknown) as File; + const bFile = (b as unknown) as File; + return (order === "asc" ? aFile.size > bFile.size : aFile.size < bFile.size) ? 1 : -1; + } else { + return 1; + } + }); + break; + } } + } - public closeDetails(): void { - const fileDOMElement = document.getElementById('fileDetailView'); - fileDOMElement.style.opacity = '0'; - setTimeout((): void => { - fileDOMElement.style.display = 'none'; - this.fileDetail = null; - }, 500); - } + public closeDetails(): void { + const fileDOMElement = document.getElementById("fileDetailView"); + fileDOMElement.style.opacity = "0"; + setTimeout((): void => { + fileDOMElement.style.display = "none"; + this.fileDetail = null; + }, 500); + } - public openSorting(): void { - this.showSorting = true; - setTimeout((): void => { - const sortingDOMElement = document.getElementById('sortingView'); - sortingDOMElement.style.opacity = '1'; - }, 50); - } + public openSorting(): void { + this.showSorting = true; + setTimeout((): void => { + const sortingDOMElement = document.getElementById("sortingView"); + sortingDOMElement.style.opacity = "1"; + }, 50); + } - public closeSorting(): void { - const sortingDOMElement = document.getElementById('sortingView'); - sortingDOMElement.style.opacity = '0'; - this.sortFolder(this.sortingAttribute, this.sortingOrder); - setTimeout((): void => { - sortingDOMElement.style.display = 'none'; - this.showSorting = false; - }, 500); - } + public closeSorting(): void { + const sortingDOMElement = document.getElementById("sortingView"); + sortingDOMElement.style.opacity = "0"; + this.sortFolder(this.sortingAttribute, this.sortingOrder); + setTimeout((): void => { + sortingDOMElement.style.display = "none"; + this.showSorting = false; + }, 500); + } - public loadFile(filePath: string): void { - setTimeout((): void => { - this.filesService.loadFile(filePath); - this.service.setLoadedFile(true); - this.jobService.deleteJobInformation(); - this.router.navigate(['/main-screen']); - }, 300); - } + public loadFile(filePath: string): void { + setTimeout((): void => { + this.filesService.loadFile(filePath); + this.service.setLoadedFile(true); + this.jobService.deleteJobInformation(); + this.router.navigate(["/main-screen"]); + }, 300); + } - public printFile(filePath: string): void { - setTimeout((): void => { - this.filesService.printFile(filePath); - this.router.navigate(['/main-screen']); - }, 300); - } + public printFile(filePath: string): void { + setTimeout((): void => { + this.filesService.printFile(filePath); + this.router.navigate(["/main-screen"]); + }, 300); + } - public deleteFile(filePath: string): void { - setTimeout((): void => { - this.filesService.deleteFile(filePath); - this.closeDetails(); - this.openFolder(this.currentFolder); - }, 300); - } + public deleteFile(filePath: string): void { + setTimeout((): void => { + this.filesService.deleteFile(filePath); + this.closeDetails(); + this.openFolder(this.currentFolder); + }, 300); + } - private showLoader(): void { - this.spinner.show(undefined, { - bdColor: '#353b48', - color: '#f5f6fa', - size: 'medium', - type: 'pacman', - fullScreen: false, - }); - } + private showLoader(): void { + this.spinner.show(undefined, { + bdColor: "#353b48", + color: "#f5f6fa", + size: "medium", + type: "pacman", + fullScreen: false, + }); + } } diff --git a/src/app/job-status/job-status.component.ts b/src/app/job-status/job-status.component.ts index 60a543d424..84e451a274 100644 --- a/src/app/job-status/job-status.component.ts +++ b/src/app/job-status/job-status.component.ts @@ -1,70 +1,70 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Subscription } from "rxjs"; -import { AppService } from '../app.service'; -import { ConfigService } from '../config/config.service'; -import { Job, JobService } from '../job.service'; -import { NotificationService } from '../notification/notification.service'; +import { AppService } from "../app.service"; +import { ConfigService } from "../config/config.service"; +import { Job, JobService } from "../job.service"; +import { NotificationService } from "../notification/notification.service"; @Component({ - selector: 'app-job-status', - templateUrl: './job-status.component.html', - styleUrls: ['./job-status.component.scss'], + selector: "app-job-status", + templateUrl: "./job-status.component.html", + styleUrls: ["./job-status.component.scss"], }) export class JobStatusComponent implements OnInit, OnDestroy { - private subscriptions: Subscription = new Subscription(); - public job: Job; + private subscriptions: Subscription = new Subscription(); + public job: Job; - public constructor( - private jobService: JobService, - private service: AppService, - private notificationService: NotificationService, - private configService: ConfigService, - ) {} + public constructor( + private jobService: JobService, + private service: AppService, + private notificationService: NotificationService, + private configService: ConfigService + ) {} - public ngOnInit(): void { - this.subscriptions.add(this.jobService.getObservable().subscribe((job: Job): Job => (this.job = job))); - } + public ngOnInit(): void { + this.subscriptions.add(this.jobService.getObservable().subscribe((job: Job): Job => (this.job = job))); + } - public ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } + public ngOnDestroy(): void { + this.subscriptions.unsubscribe(); + } - public isFileLoaded(): boolean { - return this.service.getLoadedFile(); - } + public isFileLoaded(): boolean { + return this.service.getLoadedFile(); + } - public isPreheatEnabled(): boolean { - return this.configService.isPreheatPluginEnabled(); - } + public isPreheatEnabled(): boolean { + return this.configService.isPreheatPluginEnabled(); + } - public preheat(): void { - this.jobService.preheat(); - } + public preheat(): void { + this.jobService.preheat(); + } - public preheatDisabled(): void { - this.notificationService.setWarning( - 'Preheat Plugin is not enabled!', - 'Please make sure to install and enable the Preheat Plugin to use this functionality.', - ); - } + public preheatDisabled(): void { + this.notificationService.setWarning( + "Preheat Plugin is not enabled!", + "Please make sure to install and enable the Preheat Plugin to use this functionality." + ); + } - public discardLoadedFile(): void { - this.service.setLoadedFile(false); - } + public discardLoadedFile(): void { + this.service.setLoadedFile(false); + } - public startJob(): void { - this.jobService.startJob(); - setTimeout((): void => { - this.service.setLoadedFile(false); - }, 5000); - } + public startJob(): void { + this.jobService.startJob(); + setTimeout((): void => { + this.service.setLoadedFile(false); + }, 5000); + } - public isPrinting(): boolean { - return this.jobService.isPrinting(); - } + public isPrinting(): boolean { + return this.jobService.isPrinting(); + } - public showPreview(): boolean { - return this.jobService.showPreviewWhilePrinting(); - } + public showPreview(): boolean { + return this.jobService.showPreviewWhilePrinting(); + } } diff --git a/src/app/job.service.ts b/src/app/job.service.ts index e9f123d3c0..b083bca5a8 100644 --- a/src/app/job.service.ts +++ b/src/app/job.service.ts @@ -1,273 +1,268 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Observable, Observer, Subscription, timer } from 'rxjs'; -import { shareReplay } from 'rxjs/operators'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Observable, Observer, Subscription, timer } from "rxjs"; +import { shareReplay } from "rxjs/operators"; -import { AppService } from './app.service'; -import { ConfigService } from './config/config.service'; -import { FilesService } from './files.service'; -import { NotificationService } from './notification/notification.service'; -import { JobCommand, OctoprintFilament, OctoprintJobAPI } from './octoprint-api/jobAPI'; +import { AppService } from "./app.service"; +import { ConfigService } from "./config/config.service"; +import { FilesService } from "./files.service"; +import { NotificationService } from "./notification/notification.service"; +import { JobCommand, OctoprintFilament, OctoprintJobAPI } from "./octoprint-api/jobAPI"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class JobService { - private httpGETRequest: Subscription; - private httpPOSTRequest: Subscription; - private observable: Observable; - private observer: Observer; - private printing = false; - private previewWhilePrinting = false; + private httpGETRequest: Subscription; + private httpPOSTRequest: Subscription; + private observable: Observable; + private observer: Observer; + private printing = false; + private previewWhilePrinting = false; - public constructor( - private configService: ConfigService, - private http: HttpClient, - private notificationService: NotificationService, - private service: AppService, - private fileService: FilesService, - ) { - this.previewWhilePrinting = this.configService.showThumbnailByDefault(); - this.observable = new Observable((observer: Observer): void => { - this.observer = observer; - timer(750, this.configService.getAPIPollingInterval()).subscribe((): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); + public constructor( + private configService: ConfigService, + private http: HttpClient, + private notificationService: NotificationService, + private service: AppService, + private fileService: FilesService + ) { + this.previewWhilePrinting = this.configService.showThumbnailByDefault(); + this.observable = new Observable((observer: Observer): void => { + this.observer = observer; + timer(750, this.configService.getAPIPollingInterval()).subscribe((): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get(this.configService.getURL("job"), this.configService.getHTTPHeaders()) + .subscribe( + async (data: OctoprintJobAPI): Promise => { + let job: Job = null; + if (data.job && data.job.file.name) { + this.printing = ["Printing", "Pausing", "Paused", "Cancelling", "Printing from SD"].includes( + data.state + ); + try { + job = { + status: data.state, + filename: data.job.file.display.replace(".gcode", "").replace(".ufp", ""), + thumbnail: await this.fileService.getThumbnail( + "/" + data.job.file.origin + "/" + data.job.file.path + ), + progress: Math.round((data.progress.filepos / data.job.file.size) * 100), + ...(data.job.filament !== null + ? { + filamentAmount: this.service.convertFilamentLengthToAmount( + this.getTotalAmountOfFilament(data.job.filament) + ), + } + : {}), + ...(data.progress.printTimeLeft !== null + ? { + timeLeft: { + value: this.service.convertSecondsToHours(data.progress.printTimeLeft), + unit: "h", + }, + } + : {}), + timePrinted: { + value: this.service.convertSecondsToHours(data.progress.printTime), + unit: "h", + }, + ...(data.job.estimatedPrintTime !== null + ? { + estimatedPrintTime: { + value: this.service.convertSecondsToHours(data.job.estimatedPrintTime), + unit: "h", + }, + estimatedEndTime: this.calculateEndTime(data.job.estimatedPrintTime), + } + : {}), + }; + } catch (error) { + this.notificationService.setError("Can't retrieve Job Status", error); } - this.httpGETRequest = this.http - .get(this.configService.getURL('job'), this.configService.getHTTPHeaders()) - .subscribe( - async (data: OctoprintJobAPI): Promise => { - let job: Job = null; - if (data.job && data.job.file.name) { - this.printing = [ - 'Printing', - 'Pausing', - 'Paused', - 'Cancelling', - 'Printing from SD', - ].includes(data.state); - try { - job = { - status: data.state, - filename: data.job.file.display.replace('.gcode', '').replace('.ufp', ''), - thumbnail: await this.fileService.getThumbnail( - '/' + data.job.file.origin + '/' + data.job.file.path, - ), - progress: Math.round((data.progress.filepos / data.job.file.size) * 100), - ...(data.job.filament !== null - ? { - filamentAmount: this.service.convertFilamentLengthToAmount( - this.getTotalAmountOfFilament(data.job.filament), - ), - } - : {}), - ...(data.progress.printTimeLeft !== null - ? { - timeLeft: { - value: this.service.convertSecondsToHours( - data.progress.printTimeLeft, - ), - unit: 'h', - }, - } - : {}), - timePrinted: { - value: this.service.convertSecondsToHours(data.progress.printTime), - unit: 'h', - }, - ...(data.job.estimatedPrintTime !== null - ? { - estimatedPrintTime: { - value: this.service.convertSecondsToHours( - data.job.estimatedPrintTime, - ), - unit: 'h', - }, - estimatedEndTime: this.calculateEndTime(data.job.estimatedPrintTime), - } - : {}), - }; - } catch (error) { - this.notificationService.setError("Can't retrieve Job Status", error); - } - } else { - this.printing = false; - } - observer.next(job); - }, - (error: HttpErrorResponse): void => { - this.printing = false; - this.notificationService.setError("Can't retrieve jobs!", error.message); - }, - ); - }); - }).pipe(shareReplay(1)); - this.observable.subscribe(); - } - - private getTotalAmountOfFilament(filamentAmount: OctoprintFilament): number { - let filamentLength = 0; - for (const property in filamentAmount) { - if (filamentAmount.hasOwnProperty(property) && filamentAmount[property].hasOwnProperty('length')) { - filamentLength += filamentAmount[property].length; + } else { + this.printing = false; + } + observer.next(job); + }, + (error: HttpErrorResponse): void => { + this.printing = false; + this.notificationService.setError("Can't retrieve jobs!", error.message); } - } - return filamentLength; - } + ); + }); + }).pipe(shareReplay(1)); + this.observable.subscribe(); + } - public deleteJobInformation(): void { - this.observer.next(null); + private getTotalAmountOfFilament(filamentAmount: OctoprintFilament): number { + let filamentLength = 0; + for (const property in filamentAmount) { + if ( + Object.prototype.hasOwnProperty.call(filamentAmount, "property") && + Object.prototype.hasOwnProperty.call(filamentAmount[property], "length") + ) { + filamentLength += filamentAmount[property].length; + } } + return filamentLength; + } - public getObservable(): Observable { - return this.observable; - } + public deleteJobInformation(): void { + this.observer.next(null); + } - public isPrinting(): boolean { - return this.printing; - } + public getObservable(): Observable { + return this.observable; + } - public togglePreviewWhilePrinting(): void { - this.previewWhilePrinting = !this.previewWhilePrinting; - } + public isPrinting(): boolean { + return this.printing; + } - public showPreviewWhilePrinting(): boolean { - return this.previewWhilePrinting; - } + public togglePreviewWhilePrinting(): void { + this.previewWhilePrinting = !this.previewWhilePrinting; + } - public cancelJob(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const cancelPayload: JobCommand = { - command: 'cancel', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('job'), cancelPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - if (error.status === 409) { - this.notificationService.setError( - "Can't cancel Job!", - 'There is no running job, that could be cancelled (409)', - ); - } else { - this.notificationService.setError("Can't cancel Job!", error.message); - } - }, - ); - } + public showPreviewWhilePrinting(): boolean { + return this.previewWhilePrinting; + } - public pauseJob(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const pausePayload: JobCommand = { - command: 'pause', - action: 'pause', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('job'), pausePayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - if (error.status === 409) { - this.notificationService.setError( - "Can't pause Job!", - 'There is no running job, that could be paused (409)', - ); - } else { - this.notificationService.setError("Can't pause Job!", error.message); - } - }, - ); + public cancelJob(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } - - public resumeJob(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const pausePayload: JobCommand = { - command: 'pause', - action: 'resume', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('job'), pausePayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - if (error.status === 409) { - this.notificationService.setError( - "Can't resume Job!", - 'There is no paused job, that could be resumed (409)', - ); - } else { - this.notificationService.setError("Can't resume Job!", error.message); - } - }, + const cancelPayload: JobCommand = { + command: "cancel", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("job"), cancelPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + if (error.status === 409) { + this.notificationService.setError( + "Can't cancel Job!", + "There is no running job, that could be cancelled (409)" ); - } - - public startJob(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); + } else { + this.notificationService.setError("Can't cancel Job!", error.message); + } } - const pausePayload: JobCommand = { - command: 'start', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('job'), pausePayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - if (error.status === 409) { - this.notificationService.setError("Can't start Job!", 'There is already a job running (409)'); - } else { - this.notificationService.setError("Can't start Job!", error.message); - } - }, - ); - } + ); + } - public preheat(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); + public pauseJob(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); + } + const pausePayload: JobCommand = { + command: "pause", + action: "pause", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("job"), pausePayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + if (error.status === 409) { + this.notificationService.setError( + "Can't pause Job!", + "There is no running job, that could be paused (409)" + ); + } else { + this.notificationService.setError("Can't pause Job!", error.message); + } } - const preheatPayload: JobCommand = { - command: 'preheat', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('plugin/preheat'), preheatPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't preheat printer!", error.message); - }, + ); + } + + public resumeJob(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); + } + const pausePayload: JobCommand = { + command: "pause", + action: "resume", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("job"), pausePayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + if (error.status === 409) { + this.notificationService.setError( + "Can't resume Job!", + "There is no paused job, that could be resumed (409)" ); + } else { + this.notificationService.setError("Can't resume Job!", error.message); + } + } + ); + } + + public startJob(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + const pausePayload: JobCommand = { + command: "start", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("job"), pausePayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + if (error.status === 409) { + this.notificationService.setError("Can't start Job!", "There is already a job running (409)"); + } else { + this.notificationService.setError("Can't start Job!", error.message); + } + } + ); + } - private calculateEndTime(duration: number): string { - const date = new Date(); - date.setSeconds(date.getSeconds() + duration); - return `${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}`; + public preheat(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + const preheatPayload: JobCommand = { + command: "preheat", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("plugin/preheat"), preheatPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't preheat printer!", error.message); + } + ); + } + + private calculateEndTime(duration: number): string { + const date = new Date(); + date.setSeconds(date.getSeconds() + duration); + return `${("0" + date.getHours()).slice(-2)}:${("0" + date.getMinutes()).slice(-2)}`; + } } interface Duration { - value: string; - unit: string; + value: string; + unit: string; } export interface Job { - status: string; - filename: string; - thumbnail: string | undefined; - progress: number; - filamentAmount?: number; - timeLeft?: Duration; - timePrinted: Duration; - estimatedPrintTime?: Duration; - estimatedEndTime?: string; + status: string; + filename: string; + thumbnail: string | undefined; + progress: number; + filamentAmount?: number; + timeLeft?: Duration; + timePrinted: Duration; + estimatedPrintTime?: Duration; + estimatedEndTime?: string; } diff --git a/src/app/layer-progress/layer-progress.component.ts b/src/app/layer-progress/layer-progress.component.ts index 7c0e2f7798..bc412764ad 100644 --- a/src/app/layer-progress/layer-progress.component.ts +++ b/src/app/layer-progress/layer-progress.component.ts @@ -1,41 +1,39 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Subscription } from "rxjs"; -import { DisplayLayerProgressAPI, LayerProgressService } from '../plugin-service/layer-progress.service'; +import { DisplayLayerProgressAPI, LayerProgressService } from "../plugin-service/layer-progress.service"; @Component({ - selector: 'app-layer-progress', - templateUrl: './layer-progress.component.html', - styleUrls: ['./layer-progress.component.scss'], + selector: "app-layer-progress", + templateUrl: "./layer-progress.component.html", + styleUrls: ["./layer-progress.component.scss"], }) export class LayerProgressComponent implements OnInit, OnDestroy { - private subscriptions: Subscription = new Subscription(); - public layerProgress: LayerProgress; + private subscriptions: Subscription = new Subscription(); + public layerProgress: LayerProgress; - public constructor(private displayLayerProgressService: LayerProgressService) { - this.layerProgress = { - current: 0, - total: 0, - }; - } + public constructor(private displayLayerProgressService: LayerProgressService) { + this.layerProgress = { + current: 0, + total: 0, + }; + } - public ngOnInit(): void { - this.subscriptions.add( - this.displayLayerProgressService - .getObservable() - .subscribe((layerProgress: DisplayLayerProgressAPI): void => { - this.layerProgress.current = layerProgress.current; - this.layerProgress.total = layerProgress.total; - }), - ); - } + public ngOnInit(): void { + this.subscriptions.add( + this.displayLayerProgressService.getObservable().subscribe((layerProgress: DisplayLayerProgressAPI): void => { + this.layerProgress.current = layerProgress.current; + this.layerProgress.total = layerProgress.total; + }) + ); + } - public ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } + public ngOnDestroy(): void { + this.subscriptions.unsubscribe(); + } } export interface LayerProgress { - current: number; - total: number; + current: number; + total: number; } diff --git a/src/app/main-menu/main-menu.component.ts b/src/app/main-menu/main-menu.component.ts index 1155a79364..546c54f106 100644 --- a/src/app/main-menu/main-menu.component.ts +++ b/src/app/main-menu/main-menu.component.ts @@ -1,22 +1,20 @@ -import { Component } from '@angular/core'; +import { Component } from "@angular/core"; @Component({ - selector: 'app-main-menu', - templateUrl: './main-menu.component.html', - styleUrls: ['./main-menu.component.scss'], + selector: "app-main-menu", + templateUrl: "./main-menu.component.html", + styleUrls: ["./main-menu.component.scss"], }) export class MainMenuComponent { - public settings = false; + public settings = false; - public constructor() {} + public showSettings(): void { + this.settings = true; + } - public showSettings(): void { - this.settings = true; - } - - public hideSettings(): void { - setTimeout((): void => { - this.settings = false; - }, 600); - } + public hideSettings(): void { + setTimeout((): void => { + this.settings = false; + }, 600); + } } diff --git a/src/app/main-screen/main-screen.component.ts b/src/app/main-screen/main-screen.component.ts index e9b196ead4..520960fcda 100644 --- a/src/app/main-screen/main-screen.component.ts +++ b/src/app/main-screen/main-screen.component.ts @@ -1,23 +1,23 @@ -import { Component } from '@angular/core'; +import { Component } from "@angular/core"; -import { AppService } from '../app.service'; -import { JobService } from '../job.service'; +import { AppService } from "../app.service"; +import { JobService } from "../job.service"; @Component({ - selector: 'app-main-screen', - templateUrl: './main-screen.component.html', - styleUrls: ['./main-screen.component.scss'], + selector: "app-main-screen", + templateUrl: "./main-screen.component.html", + styleUrls: ["./main-screen.component.scss"], }) export class MainScreenComponent { - public printing = false; + public printing = false; - public constructor(private jobService: JobService, private service: AppService) {} + public constructor(private jobService: JobService, private service: AppService) {} - public isPrinting(): boolean { - return this.jobService.isPrinting(); - } + public isPrinting(): boolean { + return this.jobService.isPrinting(); + } - public isFileLoaded(): boolean { - return this.service.getLoadedFile(); - } + public isFileLoaded(): boolean { + return this.service.getLoadedFile(); + } } diff --git a/src/app/main-screen/no-touch/main-screen-no-touch.component.ts b/src/app/main-screen/no-touch/main-screen-no-touch.component.ts index 50a3ded451..1e31861687 100644 --- a/src/app/main-screen/no-touch/main-screen-no-touch.component.ts +++ b/src/app/main-screen/no-touch/main-screen-no-touch.component.ts @@ -1,10 +1,8 @@ -import { Component } from '@angular/core'; +import { Component } from "@angular/core"; @Component({ - selector: 'app-main-screen-no-touch', - templateUrl: './main-screen-no-touch.component.html', - styleUrls: ['./main-screen-no-touch.component.scss'], + selector: "app-main-screen-no-touch", + templateUrl: "./main-screen-no-touch.component.html", + styleUrls: ["./main-screen-no-touch.component.scss"], }) -export class MainScreenNoTouchComponent { - public constructor() {} -} +export class MainScreenNoTouchComponent {} diff --git a/src/app/notification/notification.component.ts b/src/app/notification/notification.component.ts index 25f8506fa9..b7338f2fbe 100644 --- a/src/app/notification/notification.component.ts +++ b/src/app/notification/notification.component.ts @@ -1,41 +1,39 @@ -import { Component, OnDestroy } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy } from "@angular/core"; +import { Subscription } from "rxjs"; -import { Notification, NotificationService } from './notification.service'; +import { Notification, NotificationService } from "./notification.service"; @Component({ - selector: 'app-notification', - templateUrl: './notification.component.html', - styleUrls: ['./notification.component.scss'], + selector: "app-notification", + templateUrl: "./notification.component.html", + styleUrls: ["./notification.component.scss"], }) export class NotificationComponent implements OnDestroy { - private subscriptions: Subscription = new Subscription(); + private subscriptions: Subscription = new Subscription(); - public notification: Notification = { - heading: '', - text: '', - type: '', - }; - public show = false; + public notification: Notification = { + heading: "", + text: "", + type: "", + }; + public show = false; - public constructor(private notificationService: NotificationService) { - this.subscriptions.add( - this.notificationService - .getObservable() - .subscribe((message: Notification): void => this.setNotification(message)), - ); - } + public constructor(private notificationService: NotificationService) { + this.subscriptions.add( + this.notificationService.getObservable().subscribe((message: Notification): void => this.setNotification(message)) + ); + } - public hideNotification(): void { - this.show = false; - } + public hideNotification(): void { + this.show = false; + } - public setNotification(notification: Notification): void { - this.notification = notification; - this.show = true; - } + public setNotification(notification: Notification): void { + this.notification = notification; + this.show = true; + } - public ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } + public ngOnDestroy(): void { + this.subscriptions.unsubscribe(); + } } diff --git a/src/app/notification/notification.service.ts b/src/app/notification/notification.service.ts index 1b8fd480c8..74563860f1 100644 --- a/src/app/notification/notification.service.ts +++ b/src/app/notification/notification.service.ts @@ -1,62 +1,62 @@ -import { Injectable } from '@angular/core'; -import { Observable, Observer } from 'rxjs'; -import { shareReplay } from 'rxjs/operators'; +import { Injectable } from "@angular/core"; +import { Observable, Observer } from "rxjs"; +import { shareReplay } from "rxjs/operators"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class NotificationService { - private observable: Observable; - private observer: Observer; - private hideNotifications = false; - private bootGrace = true; - - public constructor() { - this.observable = new Observable((observer: Observer): void => { - this.observer = observer; - setTimeout((): void => { - this.bootGrace = false; - }, 30000); - }).pipe(shareReplay(1)); - } - - public enableNotifications(): void { - console.clear(); - this.hideNotifications = false; - } - - public disableNotifications(): void { - console.clear(); - this.hideNotifications = true; - } - - public setError(heading: string, text: string): void { - if ((!this.hideNotifications && !this.bootGrace) || (this.bootGrace && !text.endsWith('0 Unknown Error'))) { - this.observer.next({ heading, text, type: 'error' }); - } - } - - public setWarning(heading: string, text: string): void { - if (!this.hideNotifications) { - this.observer.next({ heading, text, type: 'warn' }); - } - } - - public setUpdate(heading: string, text: string): void { - this.observer.next({ heading, text, type: 'update' }); - } - - public getObservable(): Observable { - return this.observable; - } - - public getBootGrace(): boolean { - return this.bootGrace; - } + private observable: Observable; + private observer: Observer; + private hideNotifications = false; + private bootGrace = true; + + public constructor() { + this.observable = new Observable((observer: Observer): void => { + this.observer = observer; + setTimeout((): void => { + this.bootGrace = false; + }, 30000); + }).pipe(shareReplay(1)); + } + + public enableNotifications(): void { + console.clear(); + this.hideNotifications = false; + } + + public disableNotifications(): void { + console.clear(); + this.hideNotifications = true; + } + + public setError(heading: string, text: string): void { + if ((!this.hideNotifications && !this.bootGrace) || (this.bootGrace && !text.endsWith("0 Unknown Error"))) { + this.observer.next({ heading, text, type: "error" }); + } + } + + public setWarning(heading: string, text: string): void { + if (!this.hideNotifications) { + this.observer.next({ heading, text, type: "warn" }); + } + } + + public setUpdate(heading: string, text: string): void { + this.observer.next({ heading, text, type: "update" }); + } + + public getObservable(): Observable { + return this.observable; + } + + public getBootGrace(): boolean { + return this.bootGrace; + } } export interface Notification { - heading: string; - text: string; - type: string; + heading: string; + text: string; + type: string; } diff --git a/src/app/octoprint-api/connectionAPI.ts b/src/app/octoprint-api/connectionAPI.ts index 29ff90d83d..604055a571 100644 --- a/src/app/octoprint-api/connectionAPI.ts +++ b/src/app/octoprint-api/connectionAPI.ts @@ -1,21 +1,21 @@ export interface OctoprintConnectionAPI { - current: OctoprintConnectionCurrentAPI; - options: OctoprintConnectionOptionsAPI; + current: OctoprintConnectionCurrentAPI; + options: OctoprintConnectionOptionsAPI; } interface OctoprintConnectionCurrentAPI { - state: string; - port: string; - baudrate: number; - printerProfile: string; + state: string; + port: string; + baudrate: number; + printerProfile: string; } interface OctoprintConnectionOptionsAPI { - ports: string[]; - baudrates: number[]; - printerProfiles: object[]; - portPreference: string; - baudratePreference: string; - printerProfilePreference: string; - autoconnect: boolean; + ports: string[]; + baudrates: number[]; + printerProfiles: Record; + portPreference: string; + baudratePreference: string; + printerProfilePreference: string; + autoconnect: boolean; } diff --git a/src/app/octoprint-api/filesAPI.ts b/src/app/octoprint-api/filesAPI.ts index 0dbcc31424..3516d8b386 100644 --- a/src/app/octoprint-api/filesAPI.ts +++ b/src/app/octoprint-api/filesAPI.ts @@ -1,76 +1,76 @@ -import { OctoprintFilament } from './jobAPI'; +import { OctoprintFilament } from "./jobAPI"; export interface OctoprintFilesAPI { - date: number; - display: string; - gcodeAnalysis?: OctoprintGCodeAnalysis; - hash: string; - name: string; - origin: string; - path: string; - prints: OctoprintPrints; - refs: OctoprintRefs; - size: number; - statistics?: object; - type: string; - typePath: [string]; - thumbnail?: string; + date: number; + display: string; + gcodeAnalysis?: OctoprintGCodeAnalysis; + hash: string; + name: string; + origin: string; + path: string; + prints: OctoprintPrints; + refs: OctoprintRefs; + size: number; + statistics?: Record; + type: string; + typePath: [string]; + thumbnail?: string; } export interface OctoprintFolderAPI { - files: [OctoprintFilesAPI & OctoprintFolderContentAPI]; - free: number; - total: number; + files: [OctoprintFilesAPI & OctoprintFolderContentAPI]; + free: number; + total: number; } export interface OctoprintFolderContentAPI { - children: [OctoprintFilesAPI & OctoprintFolderContentAPI]; - display: string; - name: string; - origin: string; - path: string; - refs: OctoprintRefs; - type: string; - typePath: [string]; + children: [OctoprintFilesAPI & OctoprintFolderContentAPI]; + display: string; + name: string; + origin: string; + path: string; + refs: OctoprintRefs; + type: string; + typePath: [string]; } interface OctoprintGCodeAnalysis { - analysisFirstFilamentPrintTime: number; - analysisLastFilamentPrintTime: number; - analysisPending: boolean; - analysisPrintTime: number; - compensatedPrintTime: number; - dimensions: { - depth: number; - height: number; - width: number; - }; - estimatedPrintTime: number; - filament: OctoprintFilament; - firstFilament: number; - lastFilament: number; - printingArea: { - maxX: number; - maxY: number; - maxZ: number; - minX: number; - minY: number; - minZ: number; - }; - progress: [[number, number]]; + analysisFirstFilamentPrintTime: number; + analysisLastFilamentPrintTime: number; + analysisPending: boolean; + analysisPrintTime: number; + compensatedPrintTime: number; + dimensions: { + depth: number; + height: number; + width: number; + }; + estimatedPrintTime: number; + filament: OctoprintFilament; + firstFilament: number; + lastFilament: number; + printingArea: { + maxX: number; + maxY: number; + maxZ: number; + minX: number; + minY: number; + minZ: number; + }; + progress: [[number, number]]; } interface OctoprintPrints { - failure: number; - success: number; - last: { - date: number; - printTime: number; - success: boolean; - }; + failure: number; + success: number; + last: { + date: number; + printTime: number; + success: boolean; + }; } interface OctoprintRefs { - download?: string; - resource: string; + download?: string; + resource: string; } diff --git a/src/app/octoprint-api/jobAPI.ts b/src/app/octoprint-api/jobAPI.ts index 633b643eeb..6a41af2325 100644 --- a/src/app/octoprint-api/jobAPI.ts +++ b/src/app/octoprint-api/jobAPI.ts @@ -1,49 +1,49 @@ export interface OctoprintJobAPI { - job: OctoprintJob; - progress: OctoprintProgress; - state: string; + job: OctoprintJob; + progress: OctoprintProgress; + state: string; } interface OctoprintJob { - file: OctoprintFile; - estimatedPrintTime: number; - filament: OctoprintFilament; + file: OctoprintFile; + estimatedPrintTime: number; + filament: OctoprintFilament; } interface OctoprintFile { - name: string; - origin: string; - display: string; - path?: string; - type?: string; - typePath?: string; - size: number; - date: number; + name: string; + origin: string; + display: string; + path?: string; + type?: string; + typePath?: string; + size: number; + date: number; } export interface OctoprintFilament { - tool0?: OctoprintFilamentValues; - tool1?: OctoprintFilamentValues; - tool2?: OctoprintFilamentValues; - tool3?: OctoprintFilamentValues; - tool4?: OctoprintFilamentValues; - tool5?: OctoprintFilamentValues; - [key: string]: OctoprintFilamentValues; + tool0?: OctoprintFilamentValues; + tool1?: OctoprintFilamentValues; + tool2?: OctoprintFilamentValues; + tool3?: OctoprintFilamentValues; + tool4?: OctoprintFilamentValues; + tool5?: OctoprintFilamentValues; + [key: string]: OctoprintFilamentValues; } interface OctoprintFilamentValues { - length: number; - volume: number; + length: number; + volume: number; } interface OctoprintProgress { - completion: number; - filepos: number; - printTime: number; - printTimeLeft: number; + completion: number; + filepos: number; + printTime: number; + printTimeLeft: number; } export interface JobCommand { - command: string; - action?: string; + command: string; + action?: string; } diff --git a/src/app/octoprint-api/layerProgressAPI.ts b/src/app/octoprint-api/layerProgressAPI.ts index f30df7764f..52dc584d78 100644 --- a/src/app/octoprint-api/layerProgressAPI.ts +++ b/src/app/octoprint-api/layerProgressAPI.ts @@ -1,17 +1,17 @@ export interface OctoprintLayerProgressAPI { - layer: OctoprintLayer; - height: OctoprintHeight; - fanSpeed: string; - feedrate: string; + layer: OctoprintLayer; + height: OctoprintHeight; + fanSpeed: string; + feedrate: string; } interface OctoprintLayer { - total: string; - current: string; + total: string; + current: string; } interface OctoprintHeight { - total: string; - totalWithExtrusion: string; - current: string; + total: string; + totalWithExtrusion: string; + current: string; } diff --git a/src/app/octoprint-api/printerStatusAPI.ts b/src/app/octoprint-api/printerStatusAPI.ts index 10501e3313..baaab294f0 100644 --- a/src/app/octoprint-api/printerStatusAPI.ts +++ b/src/app/octoprint-api/printerStatusAPI.ts @@ -1,43 +1,43 @@ export interface OctoprintPrinterStatusAPI { - temperature: OctoprintTemperature; - sd: OctoprintSD; - state: OctoprintPrinterState; + temperature: OctoprintTemperature; + sd: OctoprintSD; + state: OctoprintPrinterState; } interface OctoprintTemperature { - tool0?: OctoprintTemperatureData; - tool1?: OctoprintTemperatureData; - tool2?: OctoprintTemperatureData; - tool3?: OctoprintTemperatureData; - tool4?: OctoprintTemperatureData; - tool5?: OctoprintTemperatureData; - bed?: OctoprintTemperatureData; - [key: string]: OctoprintTemperatureData; + tool0?: OctoprintTemperatureData; + tool1?: OctoprintTemperatureData; + tool2?: OctoprintTemperatureData; + tool3?: OctoprintTemperatureData; + tool4?: OctoprintTemperatureData; + tool5?: OctoprintTemperatureData; + bed?: OctoprintTemperatureData; + [key: string]: OctoprintTemperatureData; } interface OctoprintTemperatureData { - actual: number; - target: number; - offset: number; + actual: number; + target: number; + offset: number; } interface OctoprintSD { - ready: boolean; + ready: boolean; } interface OctoprintPrinterState { - text: string; - flags: OctoprintPrinterStateFlags; + text: string; + flags: OctoprintPrinterStateFlags; } interface OctoprintPrinterStateFlags { - operational: boolean; - paused: boolean; - printing: boolean; - pausing: boolean; - cancelling: boolean; - sdReady: boolean; - error: boolean; - ready: boolean; - closedOrError: boolean; + operational: boolean; + paused: boolean; + printing: boolean; + pausing: boolean; + cancelling: boolean; + sdReady: boolean; + error: boolean; + ready: boolean; + closedOrError: boolean; } diff --git a/src/app/octoprint.service.ts b/src/app/octoprint.service.ts index e820f4f7dc..3ab4cc62f1 100644 --- a/src/app/octoprint.service.ts +++ b/src/app/octoprint.service.ts @@ -1,58 +1,54 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Subscription } from "rxjs"; -import { ConfigService } from './config/config.service'; -import { NotificationService } from './notification/notification.service'; +import { ConfigService } from "./config/config.service"; +import { NotificationService } from "./notification/notification.service"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class OctoprintService { - private httpPOSTRequest: Subscription; + private httpPOSTRequest: Subscription; - public constructor( - private http: HttpClient, - private configService: ConfigService, - private notificationService: NotificationService, - ) {} + public constructor( + private http: HttpClient, + private configService: ConfigService, + private notificationService: NotificationService + ) {} - public disconnectPrinter(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const disconnectPayload: DisconnectCommand = { - command: 'disconnect', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('connection'), disconnectPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't disconnect from Printer!", error.message); - }, - ); + public disconnectPrinter(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } - - public sendSystemCommand(command: string): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); + const disconnectPayload: DisconnectCommand = { + command: "disconnect", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("connection"), disconnectPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't disconnect from Printer!", error.message); } - this.httpPOSTRequest = this.http - .post( - this.configService.getURL(`system/commands/core/${command}`), - null, - this.configService.getHTTPHeaders(), - ) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError(`Can't execute ${command} command!`, error.message); - }, - ); + ); + } + + public sendSystemCommand(command: string): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + this.httpPOSTRequest = this.http + .post(this.configService.getURL(`system/commands/core/${command}`), null, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError(`Can't execute ${command} command!`, error.message); + } + ); + } } interface DisconnectCommand { - command: string; + command: string; } diff --git a/src/app/plugin-service/enclosure.service.ts b/src/app/plugin-service/enclosure.service.ts index c912ea9000..90c74e19de 100644 --- a/src/app/plugin-service/enclosure.service.ts +++ b/src/app/plugin-service/enclosure.service.ts @@ -1,85 +1,82 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Observable, Observer, Subscription, timer } from 'rxjs'; -import { shareReplay } from 'rxjs/operators'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Observable, Observer, Subscription, timer } from "rxjs"; +import { shareReplay } from "rxjs/operators"; -import { TemperatureReading } from '../bottom-bar/bottom-bar.component'; -import { ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; +import { TemperatureReading } from "../bottom-bar/bottom-bar.component"; +import { ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class EnclosureService { - private httpGETRequest: Subscription; - private observable: Observable; - private initialRequest = true; + private httpGETRequest: Subscription; + private observable: Observable; + private initialRequest = true; - public constructor( - private http: HttpClient, - private configService: ConfigService, - private notificationService: NotificationService, - ) { - this.observable = new Observable((observer: Observer): void => { - timer(2500, 15000).subscribe((): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); - } - this.httpGETRequest = this.http - .get( - this.configService - .getURL('plugin/enclosure/inputs/' + this.configService.getAmbientTemperatureSensorName()) - .replace('/api', ''), - this.configService.getHTTPHeaders(), - ) - .subscribe( - (data: EnclosurePluginAPI): void => { - this.initialRequest = false; - observer.next(({ - temperature: data.temp_sensor_temp, - humidity: data.temp_sensor_humidity, - unit: data.use_fahrenheit ? '°F' : '°C', - } as unknown) as TemperatureReading); - }, - (error: HttpErrorResponse): void => { - if (this.initialRequest && error.status === 500) { - this.initialRequest = false; - } else { - this.notificationService.setError( - "Can't retrieve enclosure temperature!", - error.message, - ); - } - }, - ); - }); - }).pipe(shareReplay(1)); - } + public constructor( + private http: HttpClient, + private configService: ConfigService, + private notificationService: NotificationService + ) { + this.observable = new Observable((observer: Observer): void => { + timer(2500, 15000).subscribe((): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get( + this.configService + .getURL("plugin/enclosure/inputs/" + this.configService.getAmbientTemperatureSensorName()) + .replace("/api", ""), + this.configService.getHTTPHeaders() + ) + .subscribe( + (data: EnclosurePluginAPI): void => { + this.initialRequest = false; + observer.next(({ + temperature: data.temp_sensor_temp, + humidity: data.temp_sensor_humidity, + unit: data.use_fahrenheit ? "°F" : "°C", + } as unknown) as TemperatureReading); + }, + (error: HttpErrorResponse): void => { + if (this.initialRequest && error.status === 500) { + this.initialRequest = false; + } else { + this.notificationService.setError("Can't retrieve enclosure temperature!", error.message); + } + } + ); + }); + }).pipe(shareReplay(1)); + } - public getObservable(): Observable { - return this.observable; - } + public getObservable(): Observable { + return this.observable; + } } interface EnclosurePluginAPI { - /* eslint-disable camelcase */ - controlled_io: string; - temp_sensor_address: string; - temp_sensor_navbar: boolean; - temp_sensor_temp: number; - printer_action: string; - filament_sensor_enabled: boolean; - controlled_io_set_value: number; - temp_sensor_type: string; - temp_sensor_humidity: number; - filament_sensor_timeout: number; - edge: string; - ds18b20_serial: string; - action_type: string; - input_pull_resistor: string; - input_type: string; - label: string; - index_id: number; - use_fahrenheit: boolean; - gpio_pin: string; + /* eslint-disable camelcase */ + controlled_io: string; + temp_sensor_address: string; + temp_sensor_navbar: boolean; + temp_sensor_temp: number; + printer_action: string; + filament_sensor_enabled: boolean; + controlled_io_set_value: number; + temp_sensor_type: string; + temp_sensor_humidity: number; + filament_sensor_timeout: number; + edge: string; + ds18b20_serial: string; + action_type: string; + input_pull_resistor: string; + input_type: string; + label: string; + index_id: number; + use_fahrenheit: boolean; + gpio_pin: string; } diff --git a/src/app/plugin-service/filament-manager.service.ts b/src/app/plugin-service/filament-manager.service.ts index 20dd32b94c..93658a8dbe 100644 --- a/src/app/plugin-service/filament-manager.service.ts +++ b/src/app/plugin-service/filament-manager.service.ts @@ -1,172 +1,172 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Subscription } from "rxjs"; -import { ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; +import { ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; const colorRegexp = /\((.*)\)$/g; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class FilamentManagerService { - private httpGETRequest: Subscription; - private httpPOSTRequest: Subscription; + private httpGETRequest: Subscription; + private httpPOSTRequest: Subscription; - public constructor( - private configService: ConfigService, - private notificationService: NotificationService, - private http: HttpClient, - ) {} + public constructor( + private configService: ConfigService, + private notificationService: NotificationService, + private http: HttpClient + ) {} - public getSpoolList(): Promise { - return new Promise((resolve, reject): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); - } - this.httpGETRequest = this.http - .get( - this.configService.getURL('plugin/filamentmanager/spools').replace('/api', ''), - this.configService.getHTTPHeaders(), - ) - .subscribe( - (spools: FilamentSpoolList): void => { - spools.spools.forEach((spool): void => { - let match = colorRegexp.exec(spool.name); - if (match) { - spool.color = match[1]; - spool.displayName = `${spool.profile.vendor} - ${spool.name.replace(match[0], '')}`; - } else { - spool.color = '#f5f6fa'; - spool.displayName = `${spool.profile.vendor} - ${spool.name}`; - } - colorRegexp.lastIndex = 0; - }); - resolve(spools); - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't load filament spools!", error.message); - reject(); - }, - ); - }); - } + public getSpoolList(): Promise { + return new Promise((resolve, reject): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get( + this.configService.getURL("plugin/filamentmanager/spools").replace("/api", ""), + this.configService.getHTTPHeaders() + ) + .subscribe( + (spools: FilamentSpoolList): void => { + spools.spools.forEach((spool): void => { + const match = colorRegexp.exec(spool.name); + if (match) { + spool.color = match[1]; + spool.displayName = `${spool.profile.vendor} - ${spool.name.replace(match[0], "")}`; + } else { + spool.color = "#f5f6fa"; + spool.displayName = `${spool.profile.vendor} - ${spool.name}`; + } + colorRegexp.lastIndex = 0; + }); + resolve(spools); + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't load filament spools!", error.message); + reject(); + } + ); + }); + } - public getCurrentSpool(): Promise { - return new Promise((resolve, reject): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); + public getCurrentSpool(): Promise { + return new Promise((resolve, reject): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get( + this.configService.getURL("plugin/filamentmanager/selections").replace("/api", ""), + this.configService.getHTTPHeaders() + ) + .subscribe( + (selections: FilamentSelections): void => { + if (selections.selections.length > 0) { + const match = colorRegexp.exec(selections.selections[0].spool.name); + if (match) { + selections.selections[0].spool.color = match[1]; + selections.selections[0].spool.displayName = `${ + selections.selections[0].spool.profile.vendor + } - ${selections.selections[0].spool.name.replace(match[0], "")}`; + } else { + selections.selections[0].spool.color = "#f5f6fa"; + selections.selections[0].spool.displayName = `${selections.selections[0].spool.profile.vendor} - ${selections.selections[0].spool.name}`; + } + colorRegexp.lastIndex = 0; + resolve(selections.selections[0].spool); } - this.httpGETRequest = this.http - .get( - this.configService.getURL('plugin/filamentmanager/selections').replace('/api', ''), - this.configService.getHTTPHeaders(), - ) - .subscribe( - (selections: FilamentSelections): void => { - if (selections.selections.length > 0) { - let match = colorRegexp.exec(selections.selections[0].spool.name); - if (match) { - selections.selections[0].spool.color = match[1]; - selections.selections[0].spool.displayName = `${ - selections.selections[0].spool.profile.vendor - } - ${selections.selections[0].spool.name.replace(match[0], '')}`; - } else { - selections.selections[0].spool.color = '#f5f6fa'; - selections.selections[0].spool.displayName = `${selections.selections[0].spool.profile.vendor} - ${selections.selections[0].spool.name}`; - } - colorRegexp.lastIndex = 0; - resolve(selections.selections[0].spool); - } - resolve(null); - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't load filament spools!", error.message); - reject(); - }, - ); - }); - } + resolve(null); + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't load filament spools!", error.message); + reject(); + } + ); + }); + } - public setCurrentSpool(spool: FilamentSpool): Promise { - return new Promise((resolve, reject): void => { - let setSpoolBody: FilamentSelectionPatch = { - selection: { - tool: 0, - spool: spool, - }, - }; - this.httpPOSTRequest = this.http - .patch( - this.configService.getURL('plugin/filamentmanager/selections/0').replace('/api', ''), - setSpoolBody, - this.configService.getHTTPHeaders(), - ) - .subscribe( - (selection: FilamentSelectionConfirm): void => { - if (selection.selection.spool.id === spool.id) { - resolve(); - } else { - this.notificationService.setError( - `Spool IDs didn't match`, - `Can't change spool. Please change spool manually in the OctoPrint UI.`, - ); - reject(); - } - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't set new spool!", error.message); - reject(); - }, - ); - }); - } + public setCurrentSpool(spool: FilamentSpool): Promise { + return new Promise((resolve, reject): void => { + const setSpoolBody: FilamentSelectionPatch = { + selection: { + tool: 0, + spool: spool, + }, + }; + this.httpPOSTRequest = this.http + .patch( + this.configService.getURL("plugin/filamentmanager/selections/0").replace("/api", ""), + setSpoolBody, + this.configService.getHTTPHeaders() + ) + .subscribe( + (selection: FilamentSelectionConfirm): void => { + if (selection.selection.spool.id === spool.id) { + resolve(); + } else { + this.notificationService.setError( + `Spool IDs didn't match`, + `Can't change spool. Please change spool manually in the OctoPrint UI.` + ); + reject(); + } + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't set new spool!", error.message); + reject(); + } + ); + }); + } } export interface FilamentSpoolList { - spools: FilamentSpool[]; + spools: FilamentSpool[]; } export interface FilamentSelections { - selections: FilamentSelection[]; + selections: FilamentSelection[]; } interface FilamentSelectionPatch { - selection: { - tool: number; - spool: FilamentSpool; - }; + selection: { + tool: number; + spool: FilamentSpool; + }; } interface FilamentSelectionConfirm { - selection: FilamentSelection; + selection: FilamentSelection; } interface FilamentSelection { - // eslint-disable-next-line camelcase - client_id: string; - spool: FilamentSpool; - tool: number; + // eslint-disable-next-line camelcase + client_id: string; + spool: FilamentSpool; + tool: number; } export interface FilamentSpool { - /* eslint-disable camelcase */ - cost: number; - id: number; - name: string; - displayName?: string; - color?: string; - profile: FilamentProfile; - temp_offset: number; - used: number; - weight: number; + /* eslint-disable camelcase */ + cost: number; + id: number; + name: string; + displayName?: string; + color?: string; + profile: FilamentProfile; + temp_offset: number; + used: number; + weight: number; } interface FilamentProfile { - density: number; - diameter: number; - id: number; - material: string; - vendor: string; + density: number; + diameter: number; + id: number; + material: string; + vendor: string; } diff --git a/src/app/plugin-service/layer-progress.service.ts b/src/app/plugin-service/layer-progress.service.ts index f99a6de079..bed300beaf 100644 --- a/src/app/plugin-service/layer-progress.service.ts +++ b/src/app/plugin-service/layer-progress.service.ts @@ -1,62 +1,57 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Observable, Observer, Subscription, timer } from 'rxjs'; -import { shareReplay } from 'rxjs/operators'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Observable, Observer, Subscription, timer } from "rxjs"; +import { shareReplay } from "rxjs/operators"; -import { ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; -import { OctoprintLayerProgressAPI } from '../octoprint-api/layerProgressAPI'; +import { ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; +import { OctoprintLayerProgressAPI } from "../octoprint-api/layerProgressAPI"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class LayerProgressService { - private httpGETRequest: Subscription; - private observable: Observable; + private httpGETRequest: Subscription; + private observable: Observable; - public constructor( - private configService: ConfigService, - private notificationService: NotificationService, - private http: HttpClient, - ) { - this.observable = new Observable((observer: Observer): void => { - timer(1000, this.configService.getAPIPollingInterval()).subscribe((): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); - } - this.httpGETRequest = this.http - .get( - this.configService.getURL('plugin/DisplayLayerProgress/values').replace('/api', ''), - this.configService.getHTTPHeaders(), - ) - .subscribe( - (data: OctoprintLayerProgressAPI): void => { - observer.next({ - current: data.layer.current === '-' ? 0 : Number(data.layer.current), - total: data.layer.total === '-' ? 0 : Number(data.layer.total), - fanSpeed: - data.fanSpeed === '-' - ? 0 - : data.fanSpeed === 'Off' - ? 0 - : data.fanSpeed.replace('%', ''), - }); - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't retrieve layer progress!", error.message); - }, - ); - }); - }).pipe(shareReplay(1)); - } + public constructor( + private configService: ConfigService, + private notificationService: NotificationService, + private http: HttpClient + ) { + this.observable = new Observable((observer: Observer): void => { + timer(1000, this.configService.getAPIPollingInterval()).subscribe((): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get( + this.configService.getURL("plugin/DisplayLayerProgress/values").replace("/api", ""), + this.configService.getHTTPHeaders() + ) + .subscribe( + (data: OctoprintLayerProgressAPI): void => { + observer.next({ + current: data.layer.current === "-" ? 0 : Number(data.layer.current), + total: data.layer.total === "-" ? 0 : Number(data.layer.total), + fanSpeed: data.fanSpeed === "-" ? 0 : data.fanSpeed === "Off" ? 0 : data.fanSpeed.replace("%", ""), + }); + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't retrieve layer progress!", error.message); + } + ); + }); + }).pipe(shareReplay(1)); + } - public getObservable(): Observable { - return this.observable; - } + public getObservable(): Observable { + return this.observable; + } } export interface DisplayLayerProgressAPI { - current: number; - total: number; - fanSpeed: number | string; + current: number; + total: number; + fanSpeed: number | string; } diff --git a/src/app/plugin-service/psu-control.service.ts b/src/app/plugin-service/psu-control.service.ts index b7d1eeea8b..0c543ff34c 100644 --- a/src/app/plugin-service/psu-control.service.ts +++ b/src/app/plugin-service/psu-control.service.ts @@ -1,54 +1,54 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Subscription } from "rxjs"; -import { ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; -import { JobCommand } from '../octoprint-api/jobAPI'; +import { ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; +import { JobCommand } from "../octoprint-api/jobAPI"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class PsuControlService { - private httpPOSTRequest: Subscription; + private httpPOSTRequest: Subscription; - public constructor( - private configService: ConfigService, - private notificationService: NotificationService, - private http: HttpClient, - ) {} + public constructor( + private configService: ConfigService, + private notificationService: NotificationService, + private http: HttpClient + ) {} - public changePSUState(on: boolean): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); - } - const psuPayload: JobCommand = { - command: on ? 'turnPSUOn' : 'turnPSUOff', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('plugin/psucontrol'), psuPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't control PSU!", error.message); - }, - ); + public changePSUState(on: boolean): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } - - public togglePSU(): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); + const psuPayload: JobCommand = { + command: on ? "turnPSUOn" : "turnPSUOff", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("plugin/psucontrol"), psuPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't control PSU!", error.message); } - const psuPayload: JobCommand = { - command: 'togglePSU', - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('plugin/psucontrol'), psuPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't control PSU!", error.message); - }, - ); + ); + } + + public togglePSU(): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + const psuPayload: JobCommand = { + command: "togglePSU", + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("plugin/psucontrol"), psuPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't control PSU!", error.message); + } + ); + } } diff --git a/src/app/print-control/print-control.component.ts b/src/app/print-control/print-control.component.ts index c52437f44d..ee306d7e17 100644 --- a/src/app/print-control/print-control.component.ts +++ b/src/app/print-control/print-control.component.ts @@ -1,180 +1,180 @@ -import { Component } from '@angular/core'; -import { take } from 'rxjs/operators'; +import { Component } from "@angular/core"; +import { take } from "rxjs/operators"; -import { JobService } from '../job.service'; -import { PrinterService, PrinterStatusAPI } from '../printer.service'; +import { JobService } from "../job.service"; +import { PrinterService, PrinterStatusAPI } from "../printer.service"; @Component({ - selector: 'app-print-control', - templateUrl: './print-control.component.html', - styleUrls: ['./print-control.component.scss'], + selector: "app-print-control", + templateUrl: "./print-control.component.html", + styleUrls: ["./print-control.component.scss"], }) export class PrintControlComponent { - public showControls = false; - public controlView = ControlView; - public view = ControlView.MAIN; - - public temperatureHotend: number; - public temperatureHeatbed: number; - public feedrate: number; - public flowrate: number; - - public constructor(private jobService: JobService, private printerService: PrinterService) { + public showControls = false; + public controlView = ControlView; + public view = ControlView.MAIN; + + public temperatureHotend: number; + public temperatureHeatbed: number; + public feedrate: number; + public flowrate: number; + + public constructor(private jobService: JobService, private printerService: PrinterService) { + this.temperatureHotend = 0; + this.temperatureHeatbed = 0; + this.flowrate = 100; + this.feedrate = 100; + } + + public isClickOnPreview(event: MouseEvent): boolean { + const previewSwitchMin = window.innerWidth * 0.08; + const previewSwitchMax = window.innerWidth * 0.25; + + return ( + previewSwitchMin < event.clientX && + event.clientX < previewSwitchMax && + previewSwitchMin < event.clientY && + event.clientY < previewSwitchMax + ); + } + + public cancel(event: MouseEvent): void { + if (this.showControls) { + this.stopPropagation(event); + this.view = ControlView.CANCEL; + } + } + + public pause(event: MouseEvent): void { + if (this.showControls) { + this.stopPropagation(event); + this.jobService.pauseJob(); + this.view = ControlView.PAUSE; + } + } + + public adjust(event: MouseEvent): void { + if (this.showControls) { + this.view = ControlView.ADJUST; + this.stopPropagation(event); + } + } + + public stopPropagation(event: MouseEvent): void { + if (this.showControls) { + event.stopPropagation(); + } + } + + public showControlOverlay(event?: MouseEvent): void { + if (!this.isClickOnPreview(event) && !this.showControls) { + this.stopPropagation(event); + this.loadData(); + this.view = ControlView.MAIN; + this.showControls = true; + } else { + this.jobService.togglePreviewWhilePrinting(); + } + } + + public hideControlOverlay(event: MouseEvent): void { + this.stopPropagation(event); + this.showControls = false; + } + + public cancelPrint(event: MouseEvent): void { + if (this.showControls && this.view === ControlView.CANCEL) { + this.jobService.cancelJob(); + this.hideControlOverlay(event); + } + } + + public resume(event: MouseEvent): void { + if (this.showControls && this.view === ControlView.PAUSE) { + this.jobService.resumeJob(); + this.hideControlOverlay(event); + } + } + + public backToControlScreen(event: MouseEvent): void { + if (this.showControls) { + this.view = ControlView.MAIN; + this.stopPropagation(event); + } + } + + private loadData(): void { + this.printerService + .getObservable() + .pipe(take(1)) + .subscribe((printerStatus: PrinterStatusAPI): void => { + this.temperatureHotend = printerStatus.nozzle.set; + this.temperatureHeatbed = printerStatus.heatbed.set; + }); + } + + public changeTemperatureHotend(value: number): void { + if (this.showControls) { + this.temperatureHotend += value; + if (this.temperatureHotend < 0) { this.temperatureHotend = 0; - this.temperatureHeatbed = 0; - this.flowrate = 100; - this.feedrate = 100; - } - - public isClickOnPreview(event: MouseEvent): boolean { - const previewSwitchMin = window.innerWidth * 0.08; - const previewSwitchMax = window.innerWidth * 0.25; - - return ( - previewSwitchMin < event.clientX && - event.clientX < previewSwitchMax && - previewSwitchMin < event.clientY && - event.clientY < previewSwitchMax - ); - } - - public cancel(event: MouseEvent): void { - if (this.showControls) { - this.stopPropagation(event); - this.view = ControlView.CANCEL; - } - } - - public pause(event: MouseEvent): void { - if (this.showControls) { - this.stopPropagation(event); - this.jobService.pauseJob(); - this.view = ControlView.PAUSE; - } - } - - public adjust(event: MouseEvent): void { - if (this.showControls) { - this.view = ControlView.ADJUST; - this.stopPropagation(event); - } - } - - public stopPropagation(event: MouseEvent): void { - if (this.showControls) { - event.stopPropagation(); - } - } - - public showControlOverlay(event?: MouseEvent): void { - if (!this.isClickOnPreview(event) && !this.showControls) { - this.stopPropagation(event); - this.loadData(); - this.view = ControlView.MAIN; - this.showControls = true; - } else { - this.jobService.togglePreviewWhilePrinting(); - } - } - - public hideControlOverlay(event: MouseEvent): void { - this.stopPropagation(event); - this.showControls = false; + } + if (this.temperatureHotend > 999) { + this.temperatureHotend = 999; + } } + } - public cancelPrint(event: MouseEvent): void { - if (this.showControls && this.view === ControlView.CANCEL) { - this.jobService.cancelJob(); - this.hideControlOverlay(event); - } - } - - public resume(event: MouseEvent): void { - if (this.showControls && this.view === ControlView.PAUSE) { - this.jobService.resumeJob(); - this.hideControlOverlay(event); - } - } - - public backToControlScreen(event: MouseEvent): void { - if (this.showControls) { - this.view = ControlView.MAIN; - this.stopPropagation(event); - } - } - - private loadData(): void { - this.printerService - .getObservable() - .pipe(take(1)) - .subscribe((printerStatus: PrinterStatusAPI): void => { - this.temperatureHotend = printerStatus.nozzle.set; - this.temperatureHeatbed = printerStatus.heatbed.set; - }); - } - - public changeTemperatureHotend(value: number): void { - if (this.showControls) { - this.temperatureHotend += value; - if (this.temperatureHotend < 0) { - this.temperatureHotend = 0; - } - if (this.temperatureHotend > 999) { - this.temperatureHotend = 999; - } - } - } - - public changeTemperatureHeatbed(value: number): void { - if (this.showControls) { - this.temperatureHeatbed += value; - if (this.temperatureHeatbed < 0) { - this.temperatureHeatbed = 0; - } - if (this.temperatureHeatbed > 999) { - this.temperatureHeatbed = 999; - } - } - } - - public changeFeedrate(value: number): void { - if (this.showControls) { - this.feedrate += value; - if (this.feedrate < 50) { - this.feedrate = 50; - } - if (this.feedrate > 200) { - this.feedrate = 200; - } - } - } - - public changeFlowrate(value: number): void { - if (this.showControls) { - this.flowrate += value; - if (this.flowrate < 75) { - this.flowrate = 75; - } - if (this.flowrate > 125) { - this.flowrate = 125; - } - } - } - - public setAdjustParameters(event: MouseEvent): void { - if (this.showControls) { - this.printerService.setTemperatureHotend(this.temperatureHotend); - this.printerService.setTemperatureHeatbed(this.temperatureHeatbed); - this.printerService.setFeedrate(this.feedrate); - this.printerService.setFlowrate(this.flowrate); - this.hideControlOverlay(event); - } - } + public changeTemperatureHeatbed(value: number): void { + if (this.showControls) { + this.temperatureHeatbed += value; + if (this.temperatureHeatbed < 0) { + this.temperatureHeatbed = 0; + } + if (this.temperatureHeatbed > 999) { + this.temperatureHeatbed = 999; + } + } + } + + public changeFeedrate(value: number): void { + if (this.showControls) { + this.feedrate += value; + if (this.feedrate < 50) { + this.feedrate = 50; + } + if (this.feedrate > 200) { + this.feedrate = 200; + } + } + } + + public changeFlowrate(value: number): void { + if (this.showControls) { + this.flowrate += value; + if (this.flowrate < 75) { + this.flowrate = 75; + } + if (this.flowrate > 125) { + this.flowrate = 125; + } + } + } + + public setAdjustParameters(event: MouseEvent): void { + if (this.showControls) { + this.printerService.setTemperatureHotend(this.temperatureHotend); + this.printerService.setTemperatureHeatbed(this.temperatureHeatbed); + this.printerService.setFeedrate(this.feedrate); + this.printerService.setFlowrate(this.flowrate); + this.hideControlOverlay(event); + } + } } enum ControlView { - MAIN, - CANCEL, - PAUSE, - ADJUST, + MAIN, + CANCEL, + PAUSE, + ADJUST, } diff --git a/src/app/printer-status/printer-status.component.ts b/src/app/printer-status/printer-status.component.ts index cdb7c6173d..d2a69696ef 100644 --- a/src/app/printer-status/printer-status.component.ts +++ b/src/app/printer-status/printer-status.component.ts @@ -1,185 +1,183 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { Subscription } from "rxjs"; -import { ConfigService } from '../config/config.service'; -import { DisplayLayerProgressAPI, LayerProgressService } from '../plugin-service/layer-progress.service'; -import { PrinterService, PrinterStatusAPI, PrinterValue } from '../printer.service'; +import { ConfigService } from "../config/config.service"; +import { DisplayLayerProgressAPI, LayerProgressService } from "../plugin-service/layer-progress.service"; +import { PrinterService, PrinterStatusAPI, PrinterValue } from "../printer.service"; @Component({ - selector: 'app-printer-status', - templateUrl: './printer-status.component.html', - styleUrls: ['./printer-status.component.scss'], + selector: "app-printer-status", + templateUrl: "./printer-status.component.html", + styleUrls: ["./printer-status.component.scss"], }) export class PrinterStatusComponent implements OnInit, OnDestroy { - private subscriptions: Subscription = new Subscription(); - public printerStatus: PrinterStatus; - public status: string; - public QuickControlView = QuickControlView; - public view = QuickControlView.NONE; - public hotendTarget: number; - public heatbedTarget: number; - public fanTarget: number; - - public constructor( - private printerService: PrinterService, - private displayLayerProgressService: LayerProgressService, - private configService: ConfigService, - ) { - this.printerStatus = { - nozzle: { - current: 0, - set: 0, - }, - heatbed: { - current: 0, - set: 0, - }, - fan: 0, - }; - this.status = 'connecting'; - this.hotendTarget = this.configService.getDefaultHotendTemperature(); - this.heatbedTarget = this.configService.getDefaultHeatbedTemperature(); - this.fanTarget = this.configService.getDefaultFanSpeed(); - } - - public ngOnInit(): void { - this.subscriptions.add( - this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { - this.printerStatus.nozzle = printerStatus.nozzle; - this.printerStatus.heatbed = printerStatus.heatbed; - this.status = printerStatus.status; - }), - ); - - this.subscriptions.add( - this.displayLayerProgressService - .getObservable() - .subscribe((layerProgress: DisplayLayerProgressAPI): void => { - this.printerStatus.fan = layerProgress.fanSpeed; - }), - ); - } - - public ngOnDestroy(): void { - this.subscriptions.unsubscribe(); - } - - public showQuickControlHotend(): void { - this.view = QuickControlView.HOTEND; - this.showQuickControl(); - } - - public showQuickControlHeatbed(): void { - this.view = QuickControlView.HEATBED; - this.showQuickControl(); - } - - public showQuickControlFan(): void { - this.view = QuickControlView.FAN; - this.showQuickControl(); - } - - private showQuickControl(): void { - setTimeout((): void => { - const controlViewDOM = document.getElementById('quickControl'); - controlViewDOM.style.opacity = '1'; - }, 50); - } - - public hideQuickControl(): void { - const controlViewDOM = document.getElementById('quickControl'); - controlViewDOM.style.opacity = '0'; - setTimeout((): void => { - this.view = QuickControlView.NONE; - }, 500); - } - - public quickControlChangeValue(value: number): void { - switch (this.view) { - case QuickControlView.HOTEND: - this.changeTemperatureHotend(value); - break; - case QuickControlView.HEATBED: - this.changeTemperatureHeatbed(value); - break; - case QuickControlView.FAN: - this.changeSpeedFan(value); - break; - } - } - - public quickControlSetValue(): void { - switch (this.view) { - case QuickControlView.HOTEND: - this.setTemperatureHotend(); - break; - case QuickControlView.HEATBED: - this.setTemperatureHeatbed(); - break; - case QuickControlView.FAN: - this.setFanSpeed(); - break; - } - } - - private changeTemperatureHotend(value: number): void { - this.hotendTarget += value; - if (this.hotendTarget < -999) { - this.hotendTarget = this.configService.getDefaultHotendTemperature(); - } else if (this.hotendTarget < 0) { - this.hotendTarget = 0; - } else if (this.hotendTarget > 999) { - this.hotendTarget = 999; - } - } - - private changeTemperatureHeatbed(value: number): void { - this.heatbedTarget += value; - if (this.heatbedTarget < -999) { - this.heatbedTarget = this.configService.getDefaultHeatbedTemperature(); - } else if (this.heatbedTarget < 0) { - this.heatbedTarget = 0; - } else if (this.heatbedTarget > 999) { - this.heatbedTarget = 999; - } - } - - private changeSpeedFan(value: number): void { - this.fanTarget += value; - if (this.fanTarget < -999) { - this.fanTarget = this.configService.getDefaultFanSpeed(); - } else if (this.fanTarget < 0) { - this.fanTarget = 0; - } else if (this.fanTarget > 100) { - this.fanTarget = 100; - } - } - - private setTemperatureHotend(): void { - this.printerService.setTemperatureHotend(this.hotendTarget); - this.hideQuickControl(); - } - - private setTemperatureHeatbed(): void { - this.printerService.setTemperatureHeatbed(this.heatbedTarget); - this.hideQuickControl(); - } - - private setFanSpeed(): void { - this.printerService.setFanSpeed(this.fanTarget); - this.hideQuickControl(); - } + private subscriptions: Subscription = new Subscription(); + public printerStatus: PrinterStatus; + public status: string; + public QuickControlView = QuickControlView; + public view = QuickControlView.NONE; + public hotendTarget: number; + public heatbedTarget: number; + public fanTarget: number; + + public constructor( + private printerService: PrinterService, + private displayLayerProgressService: LayerProgressService, + private configService: ConfigService + ) { + this.printerStatus = { + nozzle: { + current: 0, + set: 0, + }, + heatbed: { + current: 0, + set: 0, + }, + fan: 0, + }; + this.status = "connecting"; + this.hotendTarget = this.configService.getDefaultHotendTemperature(); + this.heatbedTarget = this.configService.getDefaultHeatbedTemperature(); + this.fanTarget = this.configService.getDefaultFanSpeed(); + } + + public ngOnInit(): void { + this.subscriptions.add( + this.printerService.getObservable().subscribe((printerStatus: PrinterStatusAPI): void => { + this.printerStatus.nozzle = printerStatus.nozzle; + this.printerStatus.heatbed = printerStatus.heatbed; + this.status = printerStatus.status; + }) + ); + + this.subscriptions.add( + this.displayLayerProgressService.getObservable().subscribe((layerProgress: DisplayLayerProgressAPI): void => { + this.printerStatus.fan = layerProgress.fanSpeed; + }) + ); + } + + public ngOnDestroy(): void { + this.subscriptions.unsubscribe(); + } + + public showQuickControlHotend(): void { + this.view = QuickControlView.HOTEND; + this.showQuickControl(); + } + + public showQuickControlHeatbed(): void { + this.view = QuickControlView.HEATBED; + this.showQuickControl(); + } + + public showQuickControlFan(): void { + this.view = QuickControlView.FAN; + this.showQuickControl(); + } + + private showQuickControl(): void { + setTimeout((): void => { + const controlViewDOM = document.getElementById("quickControl"); + controlViewDOM.style.opacity = "1"; + }, 50); + } + + public hideQuickControl(): void { + const controlViewDOM = document.getElementById("quickControl"); + controlViewDOM.style.opacity = "0"; + setTimeout((): void => { + this.view = QuickControlView.NONE; + }, 500); + } + + public quickControlChangeValue(value: number): void { + switch (this.view) { + case QuickControlView.HOTEND: + this.changeTemperatureHotend(value); + break; + case QuickControlView.HEATBED: + this.changeTemperatureHeatbed(value); + break; + case QuickControlView.FAN: + this.changeSpeedFan(value); + break; + } + } + + public quickControlSetValue(): void { + switch (this.view) { + case QuickControlView.HOTEND: + this.setTemperatureHotend(); + break; + case QuickControlView.HEATBED: + this.setTemperatureHeatbed(); + break; + case QuickControlView.FAN: + this.setFanSpeed(); + break; + } + } + + private changeTemperatureHotend(value: number): void { + this.hotendTarget += value; + if (this.hotendTarget < -999) { + this.hotendTarget = this.configService.getDefaultHotendTemperature(); + } else if (this.hotendTarget < 0) { + this.hotendTarget = 0; + } else if (this.hotendTarget > 999) { + this.hotendTarget = 999; + } + } + + private changeTemperatureHeatbed(value: number): void { + this.heatbedTarget += value; + if (this.heatbedTarget < -999) { + this.heatbedTarget = this.configService.getDefaultHeatbedTemperature(); + } else if (this.heatbedTarget < 0) { + this.heatbedTarget = 0; + } else if (this.heatbedTarget > 999) { + this.heatbedTarget = 999; + } + } + + private changeSpeedFan(value: number): void { + this.fanTarget += value; + if (this.fanTarget < -999) { + this.fanTarget = this.configService.getDefaultFanSpeed(); + } else if (this.fanTarget < 0) { + this.fanTarget = 0; + } else if (this.fanTarget > 100) { + this.fanTarget = 100; + } + } + + private setTemperatureHotend(): void { + this.printerService.setTemperatureHotend(this.hotendTarget); + this.hideQuickControl(); + } + + private setTemperatureHeatbed(): void { + this.printerService.setTemperatureHeatbed(this.heatbedTarget); + this.hideQuickControl(); + } + + private setFanSpeed(): void { + this.printerService.setFanSpeed(this.fanTarget); + this.hideQuickControl(); + } } export interface PrinterStatus { - nozzle: PrinterValue; - heatbed: PrinterValue; - fan: number | string; + nozzle: PrinterValue; + heatbed: PrinterValue; + fan: number | string; } enum QuickControlView { - NONE, - HOTEND, - HEATBED, - FAN, + NONE, + HOTEND, + HEATBED, + FAN, } diff --git a/src/app/printer.service.ts b/src/app/printer.service.ts index 59b9f99c93..8b8e692434 100644 --- a/src/app/printer.service.ts +++ b/src/app/printer.service.ts @@ -1,315 +1,304 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; -import { Observable, Observer, Subscription, timer } from 'rxjs'; -import { shareReplay } from 'rxjs/operators'; +import { HttpClient, HttpErrorResponse } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { Router } from "@angular/router"; +import { Observable, Observer, Subscription, timer } from "rxjs"; +import { shareReplay } from "rxjs/operators"; -import { ConfigService } from './config/config.service'; -import { NotificationService } from './notification/notification.service'; -import { OctoprintConnectionAPI } from './octoprint-api/connectionAPI'; -import { OctoprintPrinterStatusAPI } from './octoprint-api/printerStatusAPI'; +import { ConfigService } from "./config/config.service"; +import { NotificationService } from "./notification/notification.service"; +import { OctoprintConnectionAPI } from "./octoprint-api/connectionAPI"; +import { OctoprintPrinterStatusAPI } from "./octoprint-api/printerStatusAPI"; @Injectable({ - providedIn: 'root', + providedIn: "root", }) export class PrinterService { - private httpGETRequest: Subscription; - private httpPOSTRequest: Subscription; - private observable: Observable; + private httpGETRequest: Subscription; + private httpPOSTRequest: Subscription; + private observable: Observable; - public constructor( - private http: HttpClient, - private configService: ConfigService, - private notificationService: NotificationService, - private router: Router, - ) { - this.observable = new Observable((observer: Observer): void => { - timer(500, this.configService.getAPIPollingInterval()).subscribe((): void => { - if (this.httpGETRequest) { - this.httpGETRequest.unsubscribe(); - } - this.httpGETRequest = this.http - .get(this.configService.getURL('printer'), this.configService.getHTTPHeaders()) - .subscribe( - (data: OctoprintPrinterStatusAPI): void => { - const printerStatus: PrinterStatusAPI = { - status: data.state.text.toLowerCase(), - nozzle: { - current: Math.round(data.temperature.tool0.actual), - set: Math.round(data.temperature.tool0.target), - }, - heatbed: { - current: data.temperature.bed ? Math.round(data.temperature.bed.actual) : 0, - set: data.temperature.bed ? Math.round(data.temperature.bed.target) : 0, - }, - }; - observer.next(printerStatus); - }, - (error: HttpErrorResponse): void => { - if (error.status === 409) { - this.isPrinterOffline().then((printerOffline): void => { - if (printerOffline) { - this.router.navigate(['/standby']); - this.notificationService.disableNotifications(); - } else { - this.notificationService.setError( - "Can't retrieve printer status!", - error.message, - ); - } - }); - } else if (error.status === 0 && this.notificationService.getBootGrace()) { - const printerStatus: PrinterStatusAPI = { - status: `connecting ...`, - nozzle: { - current: 0, - set: 0, - }, - heatbed: { - current: 0, - set: 0, - }, - }; - observer.next(printerStatus); - } else { - const printerStatus: PrinterStatusAPI = { - status: `error (${error.status})`, - nozzle: { - current: 0, - set: 0, - }, - heatbed: { - current: 0, - set: 0, - }, - }; - observer.next(printerStatus); - this.notificationService.setError("Can't retrieve printer status!", error.message); - } - }, - ); - }); - }).pipe(shareReplay(1)); - } - - public getObservable(): Observable { - return this.observable; - } + public constructor( + private http: HttpClient, + private configService: ConfigService, + private notificationService: NotificationService, + private router: Router + ) { + this.observable = new Observable((observer: Observer): void => { + timer(500, this.configService.getAPIPollingInterval()).subscribe((): void => { + if (this.httpGETRequest) { + this.httpGETRequest.unsubscribe(); + } + this.httpGETRequest = this.http + .get(this.configService.getURL("printer"), this.configService.getHTTPHeaders()) + .subscribe( + (data: OctoprintPrinterStatusAPI): void => { + const printerStatus: PrinterStatusAPI = { + status: data.state.text.toLowerCase(), + nozzle: { + current: Math.round(data.temperature.tool0.actual), + set: Math.round(data.temperature.tool0.target), + }, + heatbed: { + current: data.temperature.bed ? Math.round(data.temperature.bed.actual) : 0, + set: data.temperature.bed ? Math.round(data.temperature.bed.target) : 0, + }, + }; + observer.next(printerStatus); + }, + (error: HttpErrorResponse): void => { + if (error.status === 409) { + this.isPrinterOffline().then((printerOffline): void => { + if (printerOffline) { + this.router.navigate(["/standby"]); + this.notificationService.disableNotifications(); + } else { + this.notificationService.setError("Can't retrieve printer status!", error.message); + } + }); + } else if (error.status === 0 && this.notificationService.getBootGrace()) { + const printerStatus: PrinterStatusAPI = { + status: `connecting ...`, + nozzle: { + current: 0, + set: 0, + }, + heatbed: { + current: 0, + set: 0, + }, + }; + observer.next(printerStatus); + } else { + const printerStatus: PrinterStatusAPI = { + status: `error (${error.status})`, + nozzle: { + current: 0, + set: 0, + }, + heatbed: { + current: 0, + set: 0, + }, + }; + observer.next(printerStatus); + this.notificationService.setError("Can't retrieve printer status!", error.message); + } + } + ); + }); + }).pipe(shareReplay(1)); + } - public stopMotors(): void { - this.executeGCode('M410'); - } + public getObservable(): Observable { + return this.observable; + } - public jog(x: number, y: number, z: number): void { - const jogPayload: JogCommand = { - command: 'jog', - x, - y, - z, - speed: z !== 0 ? this.configService.getZSpeed() * 60 : this.configService.getXYSpeed() * 60, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('printer/printhead'), jogPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't move Printhead!", error.message); - }, - ); - } + public stopMotors(): void { + this.executeGCode("M410"); + } - public extrude(amount: number, speed: number): void { - let multiplier = 1; - let toBeExtruded: number; - if (amount < 0) { - multiplier = -1; - toBeExtruded = amount * -1; - } else { - toBeExtruded = amount; + public jog(x: number, y: number, z: number): void { + const jogPayload: JogCommand = { + command: "jog", + x, + y, + z, + speed: z !== 0 ? this.configService.getZSpeed() * 60 : this.configService.getXYSpeed() * 60, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/printhead"), jogPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't move Printhead!", error.message); } + ); + } - while (toBeExtruded > 0) { - if (toBeExtruded >= 100) { - toBeExtruded -= 100; - this.moveExtruder(100 * multiplier, speed); - } else { - this.moveExtruder(toBeExtruded * multiplier, speed); - toBeExtruded = 0; - } - } + public extrude(amount: number, speed: number): void { + let multiplier = 1; + let toBeExtruded: number; + if (amount < 0) { + multiplier = -1; + toBeExtruded = amount * -1; + } else { + toBeExtruded = amount; } - private moveExtruder(amount: number, speed: number): void { - const extrudePayload: ExtrudeCommand = { - command: 'extrude', - amount, - speed: speed * 60, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('printer/tool'), extrudePayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't extrude Filament!", error.message); - }, - ); + while (toBeExtruded > 0) { + if (toBeExtruded >= 100) { + toBeExtruded -= 100; + this.moveExtruder(100 * multiplier, speed); + } else { + this.moveExtruder(toBeExtruded * multiplier, speed); + toBeExtruded = 0; + } } + } - public executeGCode(gCode: string): void { - if (this.httpPOSTRequest) { - this.httpPOSTRequest.unsubscribe(); + private moveExtruder(amount: number, speed: number): void { + const extrudePayload: ExtrudeCommand = { + command: "extrude", + amount, + speed: speed * 60, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/tool"), extrudePayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't extrude Filament!", error.message); } - const gCodePayload: GCodeCommand = { - commands: gCode.split('; '), - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('printer/command'), gCodePayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't send GCode!", error.message); - }, - ); - } + ); + } - public setTemperatureHotend(temperature: number): void { - const temperatureHotendCommand: TemperatureHotendCommand = { - command: 'target', - targets: { - tool0: temperature, - }, - }; - this.httpPOSTRequest = this.http - .post( - this.configService.getURL('printer/tool'), - temperatureHotendCommand, - this.configService.getHTTPHeaders(), - ) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't set Hotend Temperature!", error.message); - }, - ); - } - - public setTemperatureHeatbed(temperature: number): void { - const temperatureHeatbedCommand: TemperatureHeatbedCommand = { - command: 'target', - target: temperature, - }; - this.httpPOSTRequest = this.http - .post( - this.configService.getURL('printer/bed'), - temperatureHeatbedCommand, - this.configService.getHTTPHeaders(), - ) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't set Heatbed Temperature!", error.message); - }, - ); + public executeGCode(gCode: string): void { + if (this.httpPOSTRequest) { + this.httpPOSTRequest.unsubscribe(); } + const gCodePayload: GCodeCommand = { + commands: gCode.split("; "), + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/command"), gCodePayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't send GCode!", error.message); + } + ); + } - public setFeedrate(feedrate: number): void { - if (feedrate === 100) { - return; + public setTemperatureHotend(temperature: number): void { + const temperatureHotendCommand: TemperatureHotendCommand = { + command: "target", + targets: { + tool0: temperature, + }, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/tool"), temperatureHotendCommand, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't set Hotend Temperature!", error.message); } - const feedrateCommand: FeedrateCommand = { - command: 'feedrate', - factor: feedrate, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('printer/printhead'), feedrateCommand, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't set Feedrate!", error.message); - }, - ); - } + ); + } - public setFlowrate(flowrate: number): void { - if (flowrate === 100) { - return; + public setTemperatureHeatbed(temperature: number): void { + const temperatureHeatbedCommand: TemperatureHeatbedCommand = { + command: "target", + target: temperature, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/bed"), temperatureHeatbedCommand, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't set Heatbed Temperature!", error.message); } - const flowrateCommand: FeedrateCommand = { - command: 'flowrate', - factor: flowrate, - }; - this.httpPOSTRequest = this.http - .post(this.configService.getURL('printer/tool'), flowrateCommand, this.configService.getHTTPHeaders()) - .subscribe( - (): void => null, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't set Flowrate!", error.message); - }, - ); - } + ); + } - public setFanSpeed(percentage: number): void { - this.executeGCode('M106 S' + Math.round((percentage / 100) * 255)); + public setFeedrate(feedrate: number): void { + if (feedrate === 100) { + return; } + const feedrateCommand: FeedrateCommand = { + command: "feedrate", + factor: feedrate, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/printhead"), feedrateCommand, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't set Feedrate!", error.message); + } + ); + } - public isPrinterOffline(): Promise { - return new Promise((resolve): void => { - this.http.get(this.configService.getURL('connection'), this.configService.getHTTPHeaders()).subscribe( - (data: OctoprintConnectionAPI): void => { - resolve(data.current.state === 'Closed' || data.current.state.includes('Error:')); - }, - (error: HttpErrorResponse): void => { - this.notificationService.setError("Can't retrieve connection state!", error.message); - resolve(false); - }, - ); - }); + public setFlowrate(flowrate: number): void { + if (flowrate === 100) { + return; } + const flowrateCommand: FeedrateCommand = { + command: "flowrate", + factor: flowrate, + }; + this.httpPOSTRequest = this.http + .post(this.configService.getURL("printer/tool"), flowrateCommand, this.configService.getHTTPHeaders()) + .subscribe( + (): void => null, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't set Flowrate!", error.message); + } + ); + } + + public setFanSpeed(percentage: number): void { + this.executeGCode("M106 S" + Math.round((percentage / 100) * 255)); + } + + public isPrinterOffline(): Promise { + return new Promise((resolve): void => { + this.http.get(this.configService.getURL("connection"), this.configService.getHTTPHeaders()).subscribe( + (data: OctoprintConnectionAPI): void => { + resolve(data.current.state === "Closed" || data.current.state.includes("Error:")); + }, + (error: HttpErrorResponse): void => { + this.notificationService.setError("Can't retrieve connection state!", error.message); + resolve(false); + } + ); + }); + } } export interface PrinterStatusAPI { - status: string; - nozzle: PrinterValue; - heatbed: PrinterValue; + status: string; + nozzle: PrinterValue; + heatbed: PrinterValue; } export interface PrinterValue { - current: number; - set: number; + current: number; + set: number; } interface JogCommand { - command: 'jog'; - x: number; - y: number; - z: number; - speed: number; + command: "jog"; + x: number; + y: number; + z: number; + speed: number; } interface ExtrudeCommand { - command: 'extrude'; - amount: number; - speed: number; + command: "extrude"; + amount: number; + speed: number; } interface GCodeCommand { - commands: string[]; + commands: string[]; } interface FeedrateCommand { - command: string; - factor: number; + command: string; + factor: number; } interface TemperatureHotendCommand { - command: string; - targets: { - tool0: number; - tool1?: number; - }; + command: string; + targets: { + tool0: number; + tool1?: number; + }; } interface TemperatureHeatbedCommand { - command: string; - target: number; + command: string; + target: number; } diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts index a1c76d1dc2..b2a3618798 100644 --- a/src/app/settings/settings.component.ts +++ b/src/app/settings/settings.component.ts @@ -1,117 +1,117 @@ -import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'; +import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from "@angular/core"; -import { AppService } from '../app.service'; -import { Config, ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; +import { AppService } from "../app.service"; +import { Config, ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; @Component({ - selector: 'app-settings', - templateUrl: './settings.component.html', - styleUrls: ['./settings.component.scss'], + selector: "app-settings", + templateUrl: "./settings.component.html", + styleUrls: ["./settings.component.scss"], }) export class SettingsComponent implements OnInit { - @Output() private closeFunction = new EventEmitter(); - @ViewChild('settingsMain') private settingsMain: ElementRef; - @ViewChild('settingsGeneral') private settingsGeneral: ElementRef; - @ViewChild('settingsOctoDash') private settingsOctoDash: ElementRef; - @ViewChild('settingsPlugins') private settingsPlugins: ElementRef; - @ViewChild('settingsCredits') private settingsCredits: ElementRef; + @Output() private closeFunction = new EventEmitter(); + @ViewChild("settingsMain") private settingsMain: ElementRef; + @ViewChild("settingsGeneral") private settingsGeneral: ElementRef; + @ViewChild("settingsOctoDash") private settingsOctoDash: ElementRef; + @ViewChild("settingsPlugins") private settingsPlugins: ElementRef; + @ViewChild("settingsCredits") private settingsCredits: ElementRef; - public fadeOutAnimation = false; - public config: Config; - public customActionsPosition = [ - 'Top Left', - 'Top Right', - 'Middle Left', - 'Middle Right', - 'Bottom Left', - 'Bottom Right', - ]; - public version: string; - private overwriteNoSave = false; - private pages = []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - private ipc: any; + public fadeOutAnimation = false; + public config: Config; + public customActionsPosition = [ + "Top Left", + "Top Right", + "Middle Left", + "Middle Right", + "Bottom Left", + "Bottom Right", + ]; + public version: string; + private overwriteNoSave = false; + private pages = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private ipc: any; - public constructor( - private configService: ConfigService, - private notificationService: NotificationService, - private service: AppService, - ) { - this.config = this.configService.getCurrentConfig(); - this.config = this.configService.revertConfigForInput(this.config); - this.getVersion(); - if (window.require) { - try { - this.ipc = window.require('electron').ipcRenderer; - } catch (e) { - this.notificationService.setError( - "Can't connect to backend", - "Please open an issue for GitHub as this shouldn't happen.", - ); - } - } + public constructor( + private configService: ConfigService, + private notificationService: NotificationService, + private service: AppService + ) { + this.config = this.configService.getCurrentConfig(); + this.config = this.configService.revertConfigForInput(this.config); + this.getVersion(); + if (window.require) { + try { + this.ipc = window.require("electron").ipcRenderer; + } catch (e) { + this.notificationService.setError( + "Can't connect to backend", + "Please open an issue for GitHub as this shouldn't happen." + ); + } } + } - private getVersion(): void { - this.version = this.service.getVersion(); - if (this.version === undefined) { - setTimeout(this.getVersion.bind(this), 3500); - } + private getVersion(): void { + this.version = this.service.getVersion(); + if (this.version === undefined) { + setTimeout(this.getVersion.bind(this), 3500); } + } - public ngOnInit(): void { - setTimeout((): void => { - this.pages = [ - this.settingsMain.nativeElement, - this.settingsGeneral.nativeElement, - this.settingsOctoDash.nativeElement, - this.settingsPlugins.nativeElement, - this.settingsCredits.nativeElement, - ]; - }, 400); - } + public ngOnInit(): void { + setTimeout((): void => { + this.pages = [ + this.settingsMain.nativeElement, + this.settingsGeneral.nativeElement, + this.settingsOctoDash.nativeElement, + this.settingsPlugins.nativeElement, + this.settingsCredits.nativeElement, + ]; + }, 400); + } - public hideSettings(): void { - if ( - this.configService.isEqualToCurrentConfig(this.configService.createConfigFromInput(this.config)) || - this.overwriteNoSave - ) { - this.fadeOutAnimation = true; - this.closeFunction.emit(); - setTimeout((): void => { - this.fadeOutAnimation = false; - }, 800); - } else { - this.notificationService.setWarning( - 'Configuration not saved!', - "You haven't saved your config yet, so your changes will not be applied. Click close again if you want to discard your changes!", - ); - this.overwriteNoSave = true; - } + public hideSettings(): void { + if ( + this.configService.isEqualToCurrentConfig(this.configService.createConfigFromInput(this.config)) || + this.overwriteNoSave + ) { + this.fadeOutAnimation = true; + this.closeFunction.emit(); + setTimeout((): void => { + this.fadeOutAnimation = false; + }, 800); + } else { + this.notificationService.setWarning( + "Configuration not saved!", + "You haven't saved your config yet, so your changes will not be applied. Click close again if you want to discard your changes!" + ); + this.overwriteNoSave = true; } + } - public changePage(page: number, current: number, direction: 'forward' | 'backward'): void { - this.pages[current].classList.add('settings__content-slideout-' + direction); - this.pages[page].classList.remove('settings__content-inactive'); - this.pages[page].classList.add('settings__content-slidein-' + direction); + public changePage(page: number, current: number, direction: "forward" | "backward"): void { + this.pages[current].classList.add("settings__content-slideout-" + direction); + this.pages[page].classList.remove("settings__content-inactive"); + this.pages[page].classList.add("settings__content-slidein-" + direction); - setTimeout((): void => { - this.pages[current].classList.add('settings__content-inactive'); - this.pages[current].classList.remove('settings__content-slideout-' + direction); - this.pages[page].classList.remove('settings__content-slidein-' + direction); - }, 470); - } + setTimeout((): void => { + this.pages[current].classList.add("settings__content-inactive"); + this.pages[current].classList.remove("settings__content-slideout-" + direction); + this.pages[page].classList.remove("settings__content-slidein-" + direction); + }, 470); + } - public updateConfig(): void { - const config = this.configService.createConfigFromInput(this.config); - if (!this.configService.validateGiven(config)) { - this.notificationService.setError('Config is invalid!', this.configService.getErrors().toString()); - } - this.configService.saveConfig(config); - this.overwriteNoSave = true; - this.hideSettings(); - this.configService.updateConfig(); - this.ipc.send('reload', ''); + public updateConfig(): void { + const config = this.configService.createConfigFromInput(this.config); + if (!this.configService.validateGiven(config)) { + this.notificationService.setError("Config is invalid!", this.configService.getErrors().toString()); } + this.configService.saveConfig(config); + this.overwriteNoSave = true; + this.hideSettings(); + this.configService.updateConfig(); + this.ipc.send("reload", ""); + } } diff --git a/src/app/standby/standby.component.ts b/src/app/standby/standby.component.ts index 1409236f6c..0b1cf5f1f2 100644 --- a/src/app/standby/standby.component.ts +++ b/src/app/standby/standby.component.ts @@ -1,132 +1,132 @@ -import { HttpClient } from '@angular/common/http'; -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router } from '@angular/router'; +import { HttpClient } from "@angular/common/http"; +import { Component, OnInit } from "@angular/core"; +import { Router } from "@angular/router"; -import { AppService } from '../app.service'; -import { ConfigService } from '../config/config.service'; -import { NotificationService } from '../notification/notification.service'; -import { OctoprintConnectionAPI } from '../octoprint-api/connectionAPI'; -import { PsuControlService } from '../plugin-service/psu-control.service'; +import { AppService } from "../app.service"; +import { ConfigService } from "../config/config.service"; +import { NotificationService } from "../notification/notification.service"; +import { OctoprintConnectionAPI } from "../octoprint-api/connectionAPI"; +import { PsuControlService } from "../plugin-service/psu-control.service"; @Component({ - selector: 'app-standby', - templateUrl: './standby.component.html', - styleUrls: ['./standby.component.scss'], + selector: "app-standby", + templateUrl: "./standby.component.html", + styleUrls: ["./standby.component.scss"], }) export class StandbyComponent implements OnInit { - public connecting = false; - public error = ''; - private connectionRetries = 3; - private displaySleepTimeout: number; + public connecting = false; + public error = ""; + private connectionRetries = 3; + private displaySleepTimeout: number; - public constructor( - private configService: ConfigService, - private http: HttpClient, - private router: Router, - private service: AppService, - private notificationService: NotificationService, - private psuControlService: PsuControlService, - ) {} + public constructor( + private configService: ConfigService, + private http: HttpClient, + private router: Router, + private service: AppService, + private notificationService: NotificationService, + private psuControlService: PsuControlService + ) {} - public ngOnInit(): void { - if (this.configService.getAutomaticScreenSleep()) { - this.displaySleepTimeout = setTimeout(this.service.turnDisplayOff.bind(this.service), 300000); - } + public ngOnInit(): void { + if (this.configService.getAutomaticScreenSleep()) { + this.displaySleepTimeout = setTimeout(this.service.turnDisplayOff.bind(this.service), 300000); } + } - public reconnect(): void { - this.connecting = true; - if (this.configService.turnOnPSUWhenExitingSleep()) { - this.psuControlService.changePSUState(true); - setTimeout(this.checkConnection.bind(this), 5000); - } else { - this.checkConnection(); - } + public reconnect(): void { + this.connecting = true; + if (this.configService.turnOnPSUWhenExitingSleep()) { + this.psuControlService.changePSUState(true); + setTimeout(this.checkConnection.bind(this), 5000); + } else { + this.checkConnection(); } + } - private connectToPrinter(): void { - this.http - .post(this.configService.getURL('connection'), connectPayload, this.configService.getHTTPHeaders()) - .subscribe( - (): void => { - setTimeout(this.checkConnection.bind(this), 5000); - }, - (): void => { - this.setConnectionError(); - }, - ); - } - - private checkConnection(): void { - this.http.get(this.configService.getURL('connection'), this.configService.getHTTPHeaders()).subscribe( - (data: OctoprintConnectionAPI): void => { - if (data.current.state === 'Closed') { - if (this.connectionRetries <= 0) { - this.connectionRetries = 3; - this.setConnectionError(); - } else { - this.connectionRetries--; - setTimeout(this.connectToPrinter.bind(this), 500); - } - } else if (data.current.state.includes('Error')) { - if (this.connectionRetries <= 1) { - this.connectionRetries = 3; - this.setConnectionError(); - } else { - this.connectionRetries--; - setTimeout(this.connectToPrinter.bind(this), 500); - } - } else if (data.current.state === 'Connecting') { - if (this.connectionRetries < 0) { - this.connectionRetries = 3; - this.setConnectionError(); - } else { - this.connectionRetries--; - setTimeout(this.checkConnection.bind(this), 5000); - } - } else { - this.disableStandby(); - } - }, - (): void => { - this.connecting = false; - this.error = - "There is something really wrong, OctoDash can't get a response from OctoPrint. Please check your setup!"; - }, - ); - } + private connectToPrinter(): void { + this.http + .post(this.configService.getURL("connection"), connectPayload, this.configService.getHTTPHeaders()) + .subscribe( + (): void => { + setTimeout(this.checkConnection.bind(this), 5000); + }, + (): void => { + this.setConnectionError(); + } + ); + } - private setConnectionError(): void { + private checkConnection(): void { + this.http.get(this.configService.getURL("connection"), this.configService.getHTTPHeaders()).subscribe( + (data: OctoprintConnectionAPI): void => { + if (data.current.state === "Closed") { + if (this.connectionRetries <= 0) { + this.connectionRetries = 3; + this.setConnectionError(); + } else { + this.connectionRetries--; + setTimeout(this.connectToPrinter.bind(this), 500); + } + } else if (data.current.state.includes("Error")) { + if (this.connectionRetries <= 1) { + this.connectionRetries = 3; + this.setConnectionError(); + } else { + this.connectionRetries--; + setTimeout(this.connectToPrinter.bind(this), 500); + } + } else if (data.current.state === "Connecting") { + if (this.connectionRetries < 0) { + this.connectionRetries = 3; + this.setConnectionError(); + } else { + this.connectionRetries--; + setTimeout(this.checkConnection.bind(this), 5000); + } + } else { + this.disableStandby(); + } + }, + (): void => { this.connecting = false; this.error = - "OctoPrint can't connect to your printer. Please make sure that the connection works, then come back and try again."; - } + "There is something really wrong, OctoDash can't get a response from OctoPrint. Please check your setup!"; + } + ); + } - private disableStandby(): void { - if (this.configService.getAutomaticScreenSleep()) { - if (this.displaySleepTimeout) { - clearTimeout(this.displaySleepTimeout); - } - this.service.turnDisplayOn(); - } - setTimeout((): void => { - this.connecting = false; - this.notificationService.enableNotifications(); - this.router.navigate(['/main-screen']); - }, 1000); + private setConnectionError(): void { + this.connecting = false; + this.error = + "OctoPrint can't connect to your printer. Please make sure that the connection works, then come back and try again."; + } + + private disableStandby(): void { + if (this.configService.getAutomaticScreenSleep()) { + if (this.displaySleepTimeout) { + clearTimeout(this.displaySleepTimeout); + } + this.service.turnDisplayOn(); } + setTimeout((): void => { + this.connecting = false; + this.notificationService.enableNotifications(); + this.router.navigate(["/main-screen"]); + }, 1000); + } } const connectPayload: ConnectCommand = { - command: 'connect', - save: false, + command: "connect", + save: false, }; interface ConnectCommand { - command: string; - port?: string; - baudrate?: number; - printerProfile?: string; - save?: boolean; - autoconnect?: boolean; + command: string; + port?: string; + baudrate?: number; + printerProfile?: string; + save?: boolean; + autoconnect?: boolean; } diff --git a/src/app/url.pipe.ts b/src/app/url.pipe.ts index 9c9bf004d0..d607e58fdf 100644 --- a/src/app/url.pipe.ts +++ b/src/app/url.pipe.ts @@ -1,11 +1,11 @@ -import { Pipe, PipeTransform } from '@angular/core'; -import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { Pipe, PipeTransform } from "@angular/core"; +import { DomSanitizer, SafeResourceUrl } from "@angular/platform-browser"; -@Pipe({ name: 'url' }) +@Pipe({ name: "url" }) export class URLSafePipe implements PipeTransform { - public constructor(private sanitizer: DomSanitizer) {} + public constructor(private sanitizer: DomSanitizer) {} - public transform(url): SafeResourceUrl { - return this.sanitizer.bypassSecurityTrustResourceUrl(url); - } + public transform(url: string): SafeResourceUrl { + return this.sanitizer.bypassSecurityTrustResourceUrl(url); + } } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 99ea51f2ea..73269f2d3e 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ export const environment = { - production: true, - config: 'assets/config.json', + production: true, + config: "assets/config.json", }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 7aa6e6e8aa..5039a307f0 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,8 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false, - config: 'assets/config.testing.json', + production: false, + config: "assets/config.testing.json", }; /* diff --git a/src/main.ts b/src/main.ts index 7d55186e7b..aded854ae1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,13 +1,13 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { enableProdMode } from "@angular/core"; +import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import { AppModule } from "./app/app.module"; +import { environment } from "./environments/environment"; if (environment.production) { - enableProdMode(); + enableProdMode(); } platformBrowserDynamic() - .bootstrapModule(AppModule) - .catch((err): void => console.error(err)); + .bootstrapModule(AppModule) + .catch((err): void => console.error(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts index 2f258e56c6..2b7fe10e38 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -55,7 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. +import "zone.js/dist/zone"; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS