From 5007646ff06b6fe4c4f1cb1820712df9f5210eda Mon Sep 17 00:00:00 2001 From: Stefan Dej Date: Tue, 19 Sep 2023 20:01:07 +0200 Subject: [PATCH 1/6] feat: add warning for outdated browsers (#1537) --- package-lock.json | 11 ++++++ package.json | 1 + src/locales/de.json | 4 ++ src/locales/en.json | 4 ++ src/store/gui/notifications/getters.ts | 52 +++++++++++++++++++++++++- src/store/variables.ts | 1 + 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 85359b3e2..ac924769e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "axios": "^0.27.0", "codemirror": "^6.0.1", "core-js": "^3.16.0", + "detect-browser": "^5.3.0", "echarts": "^5.2.2", "echarts-gl": "^2.0.8", "hls.js": "^1.3.3", @@ -4991,6 +4992,11 @@ "node": ">=0.4.0" } }, + "node_modules/detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -14179,6 +14185,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", diff --git a/package.json b/package.json index 5e74e7920..346a98df3 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "axios": "^0.27.0", "codemirror": "^6.0.1", "core-js": "^3.16.0", + "detect-browser": "^5.3.0", "echarts": "^5.2.2", "echarts-gl": "^2.0.8", "hls.js": "^1.3.3", diff --git a/src/locales/de.json b/src/locales/de.json index 6d7d1b593..d4da31f9e 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -1,6 +1,10 @@ { "App": { "Notifications": { + "BrowserWarnings": { + "Headline": "Veralteter Browser", + "Description": "Die verwendete {name} Version ({version}) ist veraltet und wird nicht vollständig unterstützt. Mainsail benötigt die Version {minVersion} oder höher." + }, "DependencyDescription": "Die momentane {name} Version unterstützt nicht alle Funktionen von Mainsail. Aktualisiere {name} mindestens auf Version {neededVersion}.", "DependencyName": "Abhängigkeit: {name}", "DismissAll": "Alles verwerfen", diff --git a/src/locales/en.json b/src/locales/en.json index 704471f03..9612e5638 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,6 +1,10 @@ { "App": { "Notifications": { + "BrowserWarnings": { + "Headline": "Outdated Browser", + "Description": "{name} is outdated and not fully supported. The current version is {version}, but Mainsail requires version {minVersion} or higher." + }, "DependencyDescription": "The current {name} version does not support all features of Mainsail. Update {name} to at least {neededVersion}.", "DependencyName": "Dependency: {name}", "DismissAll": "Dismiss all", diff --git a/src/store/gui/notifications/getters.ts b/src/store/gui/notifications/getters.ts index de456430d..a4072f186 100644 --- a/src/store/gui/notifications/getters.ts +++ b/src/store/gui/notifications/getters.ts @@ -5,6 +5,9 @@ import i18n from '@/plugins/i18n.js' import { RootStateDependency } from '@/store/types' import { sha256 } from 'js-sha256' import { PrinterStateKlipperConfigWarning } from '@/store/printer/types' +import { detect } from 'detect-browser' +import semver from 'semver' +import { minBrowserVersions } from '@/store/variables' export const getters: GetterTree = { getNotifications: (state, getters) => { @@ -22,12 +25,15 @@ export const getters: GetterTree = { // moonraker warnings notifications = notifications.concat(getters['getNotificationsMoonrakerWarnings']) - // moonraker failed compontents + // moonraker failed components notifications = notifications.concat(getters['getNotificationsMoonrakerFailedComponents']) // klipper warnings notifications = notifications.concat(getters['getNotificationsKlipperWarnings']) + // browser warnings + notifications = notifications.concat(getters['getNotificationsBrowserWarnings']) + const mapType = { normal: 2, high: 1, @@ -270,6 +276,50 @@ export const getters: GetterTree = { return notifications }, + getNotificationsBrowserWarnings: (state, getters, rootState) => { + const notifications: GuiNotificationStateEntry[] = [] + + const browser = detect() + const date = rootState.server.system_boot_at ?? new Date() + + // stop here, because no browser detected + if (browser === null) return notifications + + // output browser information to console + window.console.debug(`Browser: ${browser.name} ${browser.version}, OS: ${browser.os}`) + + // find browser requirement + const minBrowserVersion = minBrowserVersions.find( + (entry) => entry.name.toLowerCase() === browser.name.toLowerCase() + ) + + // stop here, because no browser requirement found + if (minBrowserVersion === undefined) return notifications + + if ( + semver.valid(browser.version) && + semver.valid(minBrowserVersion.version) && + semver.gt(minBrowserVersion.version, browser.version ?? '0.0.0') + ) { + notifications.push({ + id: `browserWarning/${minBrowserVersion.name}/${minBrowserVersion.version}`, + priority: 'critical', + title: i18n.t('App.Notifications.BrowserWarnings.Headline').toString(), + description: i18n + .t('App.Notifications.BrowserWarnings.Description', { + name: minBrowserVersion.name, + version: browser.version, + minVersion: minBrowserVersion.version, + }) + .toString(), + date, + dismissed: false, + } as GuiNotificationStateEntry) + } + + return notifications + }, + getDismiss: (state, getters, rootState) => { const currentTime = new Date() const systemBootAt = rootState.server.system_boot_at ?? new Date() diff --git a/src/store/variables.ts b/src/store/variables.ts index d2a847be4..df540bde7 100644 --- a/src/store/variables.ts +++ b/src/store/variables.ts @@ -3,6 +3,7 @@ export const defaultPrimaryColor = '#2196f3' export const minKlipperVersion = 'v0.11.0-97' export const minMoonrakerVersion = 'v0.8.0-38' +export const minBrowserVersions = [{ name: 'safari', version: '16.5.2' }] export const colorArray = ['#F44336', '#8e379d', '#03DAC5', '#3F51B5', '#ffde03', '#009688', '#E91E63'] From 9a2328ba69e6ec9eb3102b88d7261d5a73889a3c Mon Sep 17 00:00:00 2001 From: Stefan Dej Date: Tue, 19 Sep 2023 20:03:14 +0200 Subject: [PATCH 2/6] feat: automatic selection of the gcode offset save gcode (#1531) --- .../ToolheadControls/ZoffsetControl.vue | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/components/panels/ToolheadControls/ZoffsetControl.vue b/src/components/panels/ToolheadControls/ZoffsetControl.vue index 2eae278c1..52f974cae 100644 --- a/src/components/panels/ToolheadControls/ZoffsetControl.vue +++ b/src/components/panels/ToolheadControls/ZoffsetControl.vue @@ -27,11 +27,7 @@ {{ $t('Panels.ZoffsetPanel.Clear') }} {{ mdiContentSave }} {{ $t('Panels.ZoffsetPanel.Save') }} - - - - - - {{ mdiElectricSwitch }} - {{ $t('Panels.ZoffsetPanel.ToEndstop') }} - - - - - {{ mdiElevator }} - {{ $t('Panels.ZoffsetPanel.ToProbe') }} - - - - @@ -123,7 +94,7 @@ @@ -160,12 +131,9 @@ import Responsive from '@/components/ui/Responsive.vue' import { mdiBroom, - mdiElectricSwitch, - mdiElevator, mdiContentSave, mdiArrowCollapseDown, mdiInformation, - mdiMenuDown, mdiArrowExpandUp, mdiLayersOutline, } from '@mdi/js' @@ -174,16 +142,13 @@ import { }) export default class ZoffsetControl extends Mixins(BaseMixin) { mdiBroom = mdiBroom - mdiElectricSwitch = mdiElectricSwitch - mdiElevator = mdiElevator mdiContentSave = mdiContentSave mdiArrowCollapseDown = mdiArrowCollapseDown mdiInformation = mdiInformation - mdiMenuDown = mdiMenuDown mdiArrowExpandUp = mdiArrowExpandUp mdiLayersOutline = mdiLayersOutline - private saveOffsetDialog = false + saveOffsetDialog = false get homing_origin() { return this.$store.state.printer?.gcode_move?.homing_origin ?? [] @@ -198,13 +163,37 @@ export default class ZoffsetControl extends Mixins(BaseMixin) { } get homed_axis() { - return this.$store.state.printer.toolhead.homed_axes ?? '' + return this.$store.state.printer.toolhead?.homed_axes ?? '' } get helplist() { return this.$store.state.printer.helplist ?? [] } + get settings() { + return this.$store.state.printer.configfile?.settings ?? {} + } + + get kinematics() { + return this.settings.printer?.kinematics ?? 'cartesian' + } + + get stepper_name() { + if (this.kinematics === 'delta') return 'stepper_a' + + return 'stepper_z' + } + + get endstop_pin() { + const stepperConfig = this.settings[this.stepper_name] ?? {} + + return stepperConfig?.endstop_pin + } + + get isEndstopProbe() { + return this.endstop_pin.search('probe:z_virtual_endstop') !== -1 + } + get existZOffsetApplyProbe() { return this.helplist.findIndex((gcode: CommandHelp) => gcode.commandLow === 'z_offset_apply_probe') !== -1 } @@ -217,6 +206,17 @@ export default class ZoffsetControl extends Mixins(BaseMixin) { return this.$store.state.printer?.gcode_move?.homing_origin[2].toFixed(3) } + get showSaveButton() { + // hide button when offset is 0 + if (this.z_gcode_offset === 0) return false + + // show button when z endstop is probe and probe gcode exists + if (this.isEndstopProbe && this.existZOffsetApplyProbe) return true + + // show button when z endstop is endstop and endstop gcode exists + return !this.isEndstopProbe && this.existZOffsetApplyEndstop + } + sendBabyStepDown(offset: number): void { const gcode = `SET_GCODE_OFFSET Z_ADJUST=-${offset} ${this.homed_axis === 'xyz' ? 'MOVE=1' : ''}` this.$store.dispatch('server/addEvent', { message: gcode, type: 'command' }) @@ -236,12 +236,12 @@ export default class ZoffsetControl extends Mixins(BaseMixin) { } saveZOffset(): void { - if (this.existZOffsetApplyProbe && !this.existZOffsetApplyEndstop) { + if (this.isEndstopProbe && this.existZOffsetApplyProbe) { this.saveZOffsetToProbe() + return } - if (!this.existZOffsetApplyProbe && this.existZOffsetApplyEndstop) { - this.saveZOffsetToEndstop() - } + + this.saveZOffsetToEndstop() } saveZOffsetToEndstop(): void { From a0ad7e84ab454407d39010157b10e76eff3366c7 Mon Sep 17 00:00:00 2001 From: Stefan Dej Date: Tue, 19 Sep 2023 20:04:22 +0200 Subject: [PATCH 3/6] feat: hide Moonraker power devices with a `_` as first char (#1545) --- src/components/TheTopCornerMenu.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/TheTopCornerMenu.vue b/src/components/TheTopCornerMenu.vue index 97241b626..0690a4439 100644 --- a/src/components/TheTopCornerMenu.vue +++ b/src/components/TheTopCornerMenu.vue @@ -238,7 +238,9 @@ export default class TheTopCornerMenu extends Mixins(BaseMixin) { } get powerDevices() { - return this.$store.getters['server/power/getDevices'] + const devices = this.$store.getters['server/power/getDevices'] ?? [] + + return devices.filter((device: ServerPowerStateDevice) => !device.device.startsWith('_')) } get service_states() { From 09c25266422ba295c5b2a397df81c7a3b9f0d6a4 Mon Sep 17 00:00:00 2001 From: Stefan Dej Date: Tue, 19 Sep 2023 20:04:36 +0200 Subject: [PATCH 4/6] feat: add option to block autoscroll in console (#1519) --- src/components/panels/MiniconsolePanel.vue | 58 +++++++++++++++------- src/locales/en.json | 2 + src/pages/Console.vue | 58 +++++++++++++++------- src/store/gui/console/index.ts | 1 + src/store/gui/console/types.ts | 1 + 5 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/components/panels/MiniconsolePanel.vue b/src/components/panels/MiniconsolePanel.vue index 16a947f2d..93daad7a3 100644 --- a/src/components/panels/MiniconsolePanel.vue +++ b/src/components/panels/MiniconsolePanel.vue @@ -1,13 +1,3 @@ - -