Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Connect to Moonraker via subdirectory/path #1836

Merged
merged 14 commits into from
Apr 27, 2024
Merged
3 changes: 3 additions & 0 deletions .env.development.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ VUE_APP_HOSTNAME=printer.local
# port from the moonraker instance
VUE_APP_PORT=7125

# route_prefix from the moonraker instance
VUE_APP_PATH="/"

# reconnect interval in ms
VUE_APP_RECONNECT_INTERVAL=5000

Expand Down
1 change: 1 addition & 0 deletions public/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"defaultTheme": "dark",
"hostname": null,
"port": null,
"path": null,
"instancesDB": "moonraker",
"instances": []
}
8 changes: 7 additions & 1 deletion src/components/TheConnectingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,14 @@ export default class TheConnectingDialog extends Mixins(BaseMixin, ThemeMixin) {
return this.$store.state.socket.port
}

get path() {
return this.$store.state.socket.path
}

get formatHostname() {
return parseInt(this.port) !== 80 && this.port !== '' ? this.hostname + ':' + this.port : this.hostname
return parseInt(this.port) !== 80 && this.port !== ''
? this.hostname + ':' + this.port + this.path
: this.hostname + this.path
}

get isConnecting() {
Expand Down
92 changes: 76 additions & 16 deletions src/components/TheSelectPrinterDialog.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<style scoped></style>

<template>
<v-dialog v-model="showDialog" persistent :width="400">
<panel
Expand Down Expand Up @@ -34,7 +32,7 @@
</template>
<template v-if="isConnecting || (isConnected && !guiIsReady)">
<v-card-text>
<v-progress-linear color="primary" indeterminate></v-progress-linear>
<v-progress-linear color="primary" indeterminate />
</v-card-text>
</template>
<template v-else-if="connectingFailed">
Expand Down Expand Up @@ -70,7 +68,7 @@
required
outlined
hide-details="auto"
dense></v-text-field>
dense />
</v-col>
<v-col class="col-4">
<v-text-field
Expand All @@ -80,12 +78,30 @@
hide-details="auto"
required
outlined
dense></v-text-field>
dense />
</v-col>
</v-row>
<v-row v-if="showOptionalSettings">
<v-col class="col-12">
<v-text-field
v-model="dialogAddPrinter.path"
:rules="[(v) => !v || v.startsWith('/') || 'Path must start with /']"
:label="$t('SelectPrinterDialog.Path')"
hide-details="auto"
outlined
dense />
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-checkbox
v-model="showOptionalSettings"
class="ml-2"
:on-icon="mdiShowOptional"
:off-icon="mdiHideOptional"
:true-value="false"
:false-value="true" />
<v-spacer />
<v-btn color="primary" text class="middle" type="submit" :disabled="!addPrinterValid">
{{ $t('SelectPrinterDialog.AddPrinter') }}
</v-btn>
Expand All @@ -108,7 +124,7 @@
required
outlined
dense
hide-details="auto"></v-text-field>
hide-details="auto" />
</v-col>
<v-col class="col-4">
<v-text-field
Expand All @@ -118,15 +134,33 @@
required
outlined
dense
hide-details="auto"></v-text-field>
hide-details="auto" />
</v-col>
</v-row>
<v-row v-if="showOptionalSettings">
<v-col class="col-12">
<v-text-field
v-model="dialogEditPrinter.path"
:rules="[(v) => !v || v.startsWith('/') || 'Path must start with /']"
:label="$t('SelectPrinterDialog.Path')"
hide-details="auto"
outlined
dense />
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn color="red" icon tile class="minwidth-0 rounded" @click="delPrinter">
<v-icon small>{{ mdiDelete }}</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-checkbox
v-model="showOptionalSettings"
class="ml-2"
:on-icon="mdiShowOptional"
:off-icon="mdiHideOptional"
:true-value="false"
:false-value="true" />
<v-spacer />
<v-btn color="primary" text type="submit" :disabled="!editPrinterValid">
{{ $t('SelectPrinterDialog.UpdatePrinter') }}
</v-btn>
Expand All @@ -149,7 +183,7 @@
indeterminate
color="primary"
size="24"
width="2.5"></v-progress-circular>
width="2.5" />
<v-icon
v-if="!printer.socket.isConnecting"
:color="printer.socket.isConnected ? 'green' : 'red'">
Expand Down Expand Up @@ -225,6 +259,8 @@ import {
mdiCloseThick,
mdiConnection,
mdiDelete,
mdiCog,
mdiCogOff,
mdiPencil,
mdiSync,
} from '@mdi/js'
Expand All @@ -233,19 +269,22 @@ import {
components: { Panel },
})
export default class TheSelectPrinterDialog extends Mixins(BaseMixin) {
private addPrinterValid = false
private dialogAddPrinter = {
addPrinterValid = false
dialogAddPrinter = {
bool: false,
hostname: '',
port: 7125,
path: '/',
}
private editPrinterValid = false
private dialogEditPrinter = {
editPrinterValid = false
dialogEditPrinter = {
bool: false,
id: '',
hostname: '',
port: 0,
path: '/',
}
showOptionalSettings = false

/**
* Icons
Expand All @@ -257,6 +296,8 @@ export default class TheSelectPrinterDialog extends Mixins(BaseMixin) {
mdiPencil = mdiPencil
mdiCheckboxMarkedCircle = mdiCheckboxMarkedCircle
mdiCancel = mdiCancel
mdiShowOptional = mdiCog
mdiHideOptional = mdiCogOff

get printers() {
return this.$store.getters['gui/remoteprinters/getRemoteprinters'] ?? []
Expand All @@ -282,8 +323,12 @@ export default class TheSelectPrinterDialog extends Mixins(BaseMixin) {
return this.$store.state.socket.port
}

get path() {
return this.$store.state.socket.path
}

get formatHostname() {
return parseInt(this.port) !== 80 && this.port !== '' ? this.hostname + ':' + this.port : this.hostname
return this.hostname + (this.port !== '' ? ':' + this.port : '') + (this.path !== '' ? this.path : '')
}

get isConnected() {
Expand Down Expand Up @@ -345,24 +390,29 @@ export default class TheSelectPrinterDialog extends Mixins(BaseMixin) {
const values = {
hostname: this.dialogAddPrinter.hostname,
port: this.dialogAddPrinter.port,
path: this.dialogAddPrinter.path,
}
this.$store.dispatch('gui/remoteprinters/store', { values })

this.dialogAddPrinter.hostname = ''
this.dialogAddPrinter.bool = false
this.dialogAddPrinter.path = '/'
}

editPrinter(printer: GuiRemoteprintersStatePrinter) {
this.dialogEditPrinter.hostname = printer.hostname
this.dialogEditPrinter.port = printer.port
this.dialogEditPrinter.id = printer.id ?? ''
this.dialogEditPrinter.path = printer.path ?? '/'
this.dialogEditPrinter.bool = true
}

updatePrinter() {
const values = {
hostname: this.dialogEditPrinter.hostname,
port: this.dialogEditPrinter.port,
path: this.dialogEditPrinter.path,
id: this.dialogEditPrinter.id,
}
this.$store.dispatch('gui/remoteprinters/update', {
id: this.dialogEditPrinter.id,
Expand All @@ -381,8 +431,18 @@ export default class TheSelectPrinterDialog extends Mixins(BaseMixin) {
this.$store.dispatch('socket/setData', {
hostname: printer.socket.hostname,
port: printer.socket.port,
path: printer.socket.path,
})
this.$socket.setUrl(this.protocol + '://' + printer.socket.hostname + ':' + printer.socket.port + '/websocket')
const normPath = printer.socket.path.replaceAll(/(^\/*)|(\/*$)/g, '')
const url =
this.protocol +
'://' +
printer.socket.hostname +
':' +
printer.socket.port +
(normPath.length > 0 ? `/${normPath}` : '') +
'/websocket'
this.$socket.setUrl(url)
this.$socket.connect()
}

Expand Down
28 changes: 22 additions & 6 deletions src/components/settings/SettingsRemotePrintersTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{ $t('Settings.RemotePrintersTab.UseConfigJson') }}
</v-alert>
<div v-for="(printer, index) in printers" :key="printer.id">
<v-divider v-if="index" class="my-2"></v-divider>
<v-divider v-if="index" class="my-2" />
<settings-row
:title="formatPrinterName(printer)"
:loading="printer.socket.isConnecting"
Expand Down Expand Up @@ -54,17 +54,26 @@
hide-details="auto"
required
dense
outlined></v-text-field>
outlined />
</settings-row>
<v-divider class="my-2"></v-divider>
<v-divider class="my-2" />
<settings-row :title="$t('Settings.RemotePrintersTab.Port')">
<v-text-field
v-model="form.port"
:rules="[(v) => !!v || 'Port is required']"
hide-details="auto"
required
dense
outlined></v-text-field>
outlined />
</settings-row>
<v-divider class="my-2" />
<settings-row :title="$t('Settings.RemotePrintersTab.Path')">
<v-text-field
v-model="form.path"
:rules="[(v) => !v || v.startsWith('/') || 'Path must start with /']"
hide-details="auto"
outlined
dense />
</settings-row>
</v-card-text>
<v-card-actions class="d-flex justify-end">
Expand All @@ -91,6 +100,7 @@ interface printerForm {
bool: boolean
hostname: string
port: number
path: string | null
id: string | null
namespace: string | null
}
Expand All @@ -105,10 +115,11 @@ export default class SettingsRemotePrintersTab extends Mixins(BaseMixin) {
mdiDelete = mdiDelete
mdiAlertOutline = mdiAlertOutline

private form: printerForm = {
form: printerForm = {
bool: false,
hostname: '',
port: 7125,
path: '/',
id: null,
namespace: null,
}
Expand All @@ -126,12 +137,13 @@ export default class SettingsRemotePrintersTab extends Mixins(BaseMixin) {
}

formatPrinterName(printer: GuiRemoteprintersStatePrinter) {
return printer.hostname + (printer.port !== 80 ? ':' + printer.port : '')
return printer.hostname + (printer.port !== 80 ? ':' + printer.port : '') + (printer.path ?? '')
}

createPrinter() {
this.form.hostname = ''
this.form.port = 7125
this.form.path = '/'
this.form.id = null
this.form.namespace = null
this.form.bool = true
Expand All @@ -141,6 +153,7 @@ export default class SettingsRemotePrintersTab extends Mixins(BaseMixin) {
const printer = {
hostname: this.form.hostname,
port: this.form.port,
path: this.form.path,
}

this.$store.dispatch('gui/remoteprinters/store', { values: printer })
Expand All @@ -155,20 +168,23 @@ export default class SettingsRemotePrintersTab extends Mixins(BaseMixin) {
this.form.id = printer.id ?? null
this.form.hostname = printer.hostname
this.form.port = printer.port
this.form.path = printer.path ?? '/'
this.form.bool = true
}

updatePrinter() {
const values = {
hostname: this.form.hostname,
port: this.form.port,
path: this.form.path,
}

this.$store.dispatch('gui/remoteprinters/update', { id: this.form.id, values })

this.form.id = null
this.form.hostname = ''
this.form.port = 7125
this.form.path = '/'
this.form.bool = false
}

Expand Down
2 changes: 2 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,7 @@
"HostnameInvalid": "invalid Hostname/IP",
"HostnameIp": "Hostname/IP",
"HostnameRequired": "Hostname is required",
"Path": "Path",
"Port": "Port",
"PortRequired": "Port is required",
"RememberToAdd": "Please remember to add '{cors}' in moonraker.conf within 'cors_domains'.",
Expand Down Expand Up @@ -1062,6 +1063,7 @@
"AddPrinter": "Add Printer",
"EditPrinter": "Edit Printer",
"Hostname": "Hostname",
"Path": "Path",
"Port": "Port",
"RemotePrinters": "Printers",
"UpdatePrinter": "Update Printer",
Expand Down
1 change: 1 addition & 0 deletions src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,6 @@ export const actions: ActionTree<RootState, RootState> = {

if (payload.hostname) commit('socket/setData', { hostname: payload.hostname })
if (payload.port) commit('socket/setData', { port: parseInt(payload.port.toString()) })
if (payload.path) commit('socket/setData', { route_prefix: payload.path })
},
}
1 change: 1 addition & 0 deletions src/store/farm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const farm: Module<FarmState, RootState> = {
commit(payload.id + '/setSocketData', {
hostname: payload.values.hostname,
port: payload.values.port,
path: payload.values.path,
isConnecting: true,
})
dispatch(payload.id + '/reconnect')
Expand Down
Loading
Loading