perf(vite): chunk webcams, locales and large libraries (#1578)
This commit is contained in:
parent
817efba0d8
commit
32122348b3
1284
package-lock.json
generated
1284
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@ -34,8 +34,6 @@
|
||||
"@jaames/iro": "^5.5.2",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@sindarius/gcodeviewer": "^3.2.2",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/overlayscrollbars": "^1.12.1",
|
||||
"@uiw/codemirror-theme-vscode": "^4.19.11",
|
||||
"axios": "^0.27.0",
|
||||
"codemirror": "^6.0.1",
|
||||
@ -45,12 +43,12 @@
|
||||
"echarts-gl": "^2.0.8",
|
||||
"hls.js": "^1.3.3",
|
||||
"jmuxer": "^2.0.5",
|
||||
"js-sha256": "^0.9.0",
|
||||
"js-sha256": "^0.10.0",
|
||||
"lodash.kebabcase": "^4.1.1",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"overlayscrollbars": "^1.13.1",
|
||||
"overlayscrollbars-vue": "^0.2.2",
|
||||
"regenerator-runtime": "^0.13.9",
|
||||
"regenerator-runtime": "^0.14.0",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"semver": "^7.5.2",
|
||||
"typed_janus_js": "^1.0.14",
|
||||
@ -76,8 +74,10 @@
|
||||
"@types/jmuxer": "^2.0.3",
|
||||
"@types/lodash.kebabcase": "^4.1.6",
|
||||
"@types/lodash.throttle": "^4.1.6",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/overlayscrollbars": "^1.12.1",
|
||||
"@types/semver": "^7.3.8",
|
||||
"@types/uuid": "^8.3.1",
|
||||
"@types/uuid": "^9.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
||||
"@typescript-eslint/parser": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
@ -87,13 +87,15 @@
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-jsonc": "^2.2.1",
|
||||
"eslint-plugin-vue": "^9.0.0",
|
||||
"postcss": "^8.4.31",
|
||||
"postcss-nesting": "^12.0.1",
|
||||
"prettier": "^3.0.0",
|
||||
"sass": "~1.32",
|
||||
"start-server-and-test": "^1.14.0",
|
||||
"start-server-and-test": "^2.0.0",
|
||||
"typescript": "^4.5.5",
|
||||
"unplugin-vue-components": "^0.22.12",
|
||||
"vite": "^3.2.7",
|
||||
"vite-plugin-checker": "^0.5.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-checker": "^0.6.0",
|
||||
"vite-plugin-package-version": "^1.0.2",
|
||||
"vite-plugin-pwa": "^0.16.4",
|
||||
"vite-plugin-vue2": "^2.0.1",
|
||||
|
13
src/App.vue
13
src/App.vue
@ -40,6 +40,7 @@ import TheUploadSnackbar from '@/components/TheUploadSnackbar.vue'
|
||||
import TheManualProbeDialog from '@/components/dialogs/TheManualProbeDialog.vue'
|
||||
import TheBedScrewsDialog from '@/components/dialogs/TheBedScrewsDialog.vue'
|
||||
import TheScrewsTiltAdjustDialog from '@/components/dialogs/TheScrewsTiltAdjustDialog.vue'
|
||||
import { setAndLoadLocale } from './plugins/i18n'
|
||||
|
||||
Component.registerHooks(['metaInfo'])
|
||||
|
||||
@ -162,8 +163,8 @@ export default class App extends Mixins(BaseMixin) {
|
||||
}
|
||||
|
||||
@Watch('language')
|
||||
languageChanged(newVal: string): void {
|
||||
this.$i18n.locale = newVal
|
||||
async languageChanged(newVal: string): Promise<void> {
|
||||
await setAndLoadLocale(newVal)
|
||||
}
|
||||
|
||||
@Watch('customStylesheet')
|
||||
@ -310,10 +311,10 @@ export default class App extends Mixins(BaseMixin) {
|
||||
<style>
|
||||
@import './assets/styles/fonts.css';
|
||||
@import './assets/styles/toastr.css';
|
||||
@import './assets/styles/page.scss';
|
||||
@import './assets/styles/sidebar.scss';
|
||||
@import './assets/styles/utils.scss';
|
||||
@import './assets/styles/updateManager.scss';
|
||||
@import './assets/styles/page.css';
|
||||
@import './assets/styles/sidebar.css';
|
||||
@import './assets/styles/utils.css';
|
||||
@import './assets/styles/updateManager.css';
|
||||
|
||||
:root {
|
||||
--app-height: 100%;
|
||||
|
@ -1,12 +1,3 @@
|
||||
@mixin no-select {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.user-select-none {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
@ -124,7 +124,7 @@ export default class CommandHelpModal extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.command-help-content {
|
||||
overflow-x: hidden;
|
||||
|
||||
|
@ -341,7 +341,7 @@ export default class TheEditor extends Mixins(BaseMixin) {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
::v-deep .ͼ1 .cm-panel.cm-search *:focus:not(.focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div :class="'consoleTable ' + (isMini ? 'mini' : '')">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style scoped lang="scss">
|
||||
<style scoped>
|
||||
.consoleTableRow {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-size: 0.95em;
|
||||
|
@ -173,4 +173,4 @@ export default class TheBedScrewsDialog extends Mixins(BaseMixin, ControlMixin)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
@ -181,7 +181,7 @@ export default class TheManualProbeDialog extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.v-btn-toggle {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ export default class ExtruderControlPanel extends Mixins(BaseMixin, ExtruderMixi
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
._btn-group {
|
||||
border-radius: 4px;
|
||||
display: inline-flex;
|
||||
|
@ -49,14 +49,13 @@ export default class ExtruderControlPanel extends Mixins(BaseMixin, ControlMixin
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
._btn-group {
|
||||
border-radius: 4px;
|
||||
display: inline-flex;
|
||||
flex-wrap: nowrap;
|
||||
max-width: 100%;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
|
||||
.v-btn {
|
||||
border-radius: 0;
|
||||
|
@ -116,7 +116,7 @@ export default class GitCommitsList extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.groupedCommits {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ export default class GitCommitsListDayCommit extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
li.commit {
|
||||
border-color: rgb(48, 54, 61);
|
||||
border-style: solid;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<panel
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div v-if="['printing', 'paused'].includes(printer_state) && printing_objects.length">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
svg {
|
||||
//background: rgba(200, 200, 200);
|
||||
border: 2px solid #888;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ export default class StatusPanelJobqueue extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.filesJobqueue {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ export default class StatusPanelJobqueueEntry extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.filesJobqueue {
|
||||
position: relative;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<v-card-text class="pa-0">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
||||
<template>
|
||||
<v-card-text class="pa-0">
|
||||
|
@ -223,7 +223,7 @@ export default class StatusPanelPrintstatusThumbnail extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.statusPanel-big-thumbnail {
|
||||
transition: height 0.25s ease-out;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ export default class StatusPanel extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
._border-radius {
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
|
@ -155,7 +155,7 @@ export default class TemperaturePanelList extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.temperature-panel-table th,
|
||||
.temperature-panel-table ::v-deep td {
|
||||
padding-top: 5px !important;
|
||||
|
@ -273,7 +273,7 @@ export default class TemperaturePanelListItem extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
::v-deep .v-icon._no-focus-style:focus::after {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ export default class TemperaturePanelListItemNevermore extends Mixins(BaseMixin)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
::v-deep .v-icon._no-focus-style:focus::after {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ export default class TemperaturePanelPresets extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
._preset-title {
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.btnHomeAxis {
|
||||
width: 36px;
|
||||
min-width: 36px !important;
|
||||
|
@ -706,7 +706,7 @@ export default class CircleControl extends Mixins(BaseMixin, ControlMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
svg {
|
||||
max-height: 350px;
|
||||
min-height: 275px;
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.btnMinWidthAuto {
|
||||
min-width: auto !important;
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ export default class ZoffsetControl extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.v-btn-toggle {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -82,6 +82,25 @@ export default class SettingsGeneralTab extends Mixins(BaseMixin, SettingsGenera
|
||||
mdiHelpCircle = mdiHelpCircle
|
||||
mdiCloseThick = mdiCloseThick
|
||||
|
||||
availableLanguages: { text: string; value: string }[] = []
|
||||
|
||||
async created() {
|
||||
const locales = import.meta.glob<string>('../../locales/*.json', { import: 'title' })
|
||||
const languages: { text: string; value: string }[] = []
|
||||
|
||||
for (const file in locales) {
|
||||
const langKey = file.slice(file.lastIndexOf('.') - 2, file.lastIndexOf('.'))
|
||||
const title = await locales[file]()
|
||||
|
||||
languages.push({
|
||||
text: title,
|
||||
value: langKey,
|
||||
})
|
||||
}
|
||||
|
||||
this.availableLanguages = languages
|
||||
}
|
||||
|
||||
get printerName() {
|
||||
return this.$store.state.gui.general.printername
|
||||
}
|
||||
@ -98,22 +117,6 @@ export default class SettingsGeneralTab extends Mixins(BaseMixin, SettingsGenera
|
||||
this.$store.dispatch('gui/saveSetting', { name: 'general.language', value: newVal })
|
||||
}
|
||||
|
||||
get availableLanguages() {
|
||||
const locales = import.meta.glob('../../locales/*.json', { eager: true }) as { [key: string]: any }
|
||||
const languages: { text: string; value: string }[] = []
|
||||
|
||||
Object.keys(locales).map((file: string) => {
|
||||
const langKey = file.slice(file.lastIndexOf('.') - 2, file.lastIndexOf('.'))
|
||||
|
||||
languages.push({
|
||||
text: locales[file].title,
|
||||
value: langKey,
|
||||
})
|
||||
})
|
||||
|
||||
return languages
|
||||
}
|
||||
|
||||
get dateFormat() {
|
||||
return this.$store.state.gui.general.dateFormat
|
||||
}
|
||||
|
@ -78,4 +78,4 @@ export default class SettingsMiscellaneousTab extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
@ -233,4 +233,4 @@ export default class SettingsMiscellaneousTabLightGroups extends Mixins(BaseMixi
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
@ -464,4 +464,4 @@ export default class SettingsMiscellaneousTabLightPresets extends Mixins(BaseMix
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
@ -322,7 +322,7 @@ export default class WebcamForm extends Mixins(BaseMixin, WebcamMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
::v-deep ._transition svg {
|
||||
transition: transform 500ms;
|
||||
}
|
||||
|
@ -70,4 +70,4 @@ export default class WebcamListEntry extends Mixins(BaseMixin, WebcamMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style scoped></style>
|
||||
|
@ -83,7 +83,7 @@ export default class Panel extends Mixins(BaseMixin) {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.expanded header.v-toolbar {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
@ -107,7 +107,7 @@ export default class Panel extends Mixins(BaseMixin) {
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
<style>
|
||||
.v-card.panel .v-toolbar__content {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
.btn-collapsible > * {
|
||||
will-change: transform;
|
||||
transition: transform 500ms;
|
||||
|
@ -1,31 +1,31 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="service === 'mjpegstreamer'">
|
||||
<mjpegstreamer :cam-settings="webcam" :show-fps="showFps" :printer-url="printerUrl" />
|
||||
<mjpegstreamer-async :cam-settings="webcam" :show-fps="showFps" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'mjpegstreamer-adaptive'">
|
||||
<mjpegstreamer-adaptive :cam-settings="webcam" :show-fps="showFps" :printer-url="printerUrl" />
|
||||
<mjpegstreamer-adaptive-async :cam-settings="webcam" :show-fps="showFps" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'uv4l-mjpeg'">
|
||||
<uv4l-mjpeg :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<uv4l-mjpeg-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'ipstream'">
|
||||
<ipstreamer :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<ipstreamer-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'hlsstream'">
|
||||
<hlsstreamer :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<hlsstreamer-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'jmuxer-stream'">
|
||||
<j-muxer-stream :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<j-muxer-stream-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'webrtc-camerastreamer'">
|
||||
<webrtc-camera-streamer :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<webrtc-camera-streamer-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'webrtc-janus'">
|
||||
<janus-streamer :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<janus-streamer-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else-if="service === 'webrtc-mediamtx'">
|
||||
<webrtc-media-m-t-x :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
<webrtc-media-m-t-x-async :cam-settings="webcam" :printer-url="printerUrl" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<p class="text-center py-3 font-italic">{{ $t('Panels.WebcamPanel.UnknownWebcamService') }}</p>
|
||||
@ -38,18 +38,19 @@ import Component from 'vue-class-component'
|
||||
import { Mixins, Prop } from 'vue-property-decorator'
|
||||
import BaseMixin from '@/components/mixins/base'
|
||||
import { GuiWebcamStateWebcam } from '@/store/gui/webcams/types'
|
||||
import { DynamicCamLoader } from '@/components/webcams/streamers/DynamicCamLoader'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
Hlsstreamer: () => import('@/components/webcams/Hlsstreamer.vue'),
|
||||
Ipstreamer: () => import('@/components/webcams/Ipstreamer.vue'),
|
||||
JanusStreamer: () => import('@/components/webcams/JanusStreamer.vue'),
|
||||
JMuxerStream: () => import('@/components/webcams/JMuxerStream.vue'),
|
||||
Mjpegstreamer: () => import('@/components/webcams/Mjpegstreamer.vue'),
|
||||
MjpegstreamerAdaptive: () => import('@/components/webcams/MjpegstreamerAdaptive.vue'),
|
||||
Uv4lMjpeg: () => import('@/components/webcams/Uv4lMjpeg.vue'),
|
||||
WebrtcCameraStreamer: () => import('@/components/webcams/WebrtcCameraStreamer.vue'),
|
||||
WebrtcMediaMTX: () => import('@/components/webcams/WebrtcMediaMTX.vue'),
|
||||
HlsstreamerAsync: DynamicCamLoader('Hlsstreamer'),
|
||||
IpstreamerAsync: DynamicCamLoader('Ipstreamer'),
|
||||
JanusStreamerAsync: DynamicCamLoader('JanusStreamer'),
|
||||
JMuxerStreamAsync: DynamicCamLoader('JMuxerStream'),
|
||||
MjpegstreamerAsync: DynamicCamLoader('Mjpegstreamer'),
|
||||
MjpegstreamerAdaptiveAsync: DynamicCamLoader('MjpegstreamerAdaptive'),
|
||||
Uv4lMjpegAsync: DynamicCamLoader('Uv4lMjpeg'),
|
||||
WebrtcCameraStreamerAsync: DynamicCamLoader('WebrtcCameraStreamer'),
|
||||
WebrtcMediaMTXAsync: DynamicCamLoader('WebrtcMediaMTX'),
|
||||
},
|
||||
})
|
||||
export default class WebcamWrapperItem extends Mixins(BaseMixin) {
|
||||
|
39
src/components/webcams/streamers/DynamicCamLoader.ts
Normal file
39
src/components/webcams/streamers/DynamicCamLoader.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
type StreamerTypes =
|
||||
| 'Hlsstreamer'
|
||||
| 'Ipstreamer'
|
||||
| 'JanusStreamer'
|
||||
| 'JMuxerStream'
|
||||
| 'Mjpegstreamer'
|
||||
| 'MjpegstreamerAdaptive'
|
||||
| 'Uv4lMjpeg'
|
||||
| 'WebrtcCameraStreamer'
|
||||
| 'WebrtcMediaMTX'
|
||||
|
||||
function getDynamicCamImport(componentName: StreamerTypes) {
|
||||
// split each webcam streamer into its own chunk
|
||||
switch (componentName) {
|
||||
case 'Hlsstreamer':
|
||||
return () => import('@/components/webcams/streamers/Hlsstreamer.vue')
|
||||
case 'Ipstreamer':
|
||||
return () => import('@/components/webcams/streamers/Ipstreamer.vue')
|
||||
case 'JanusStreamer':
|
||||
return () => import('@/components/webcams/streamers/JanusStreamer.vue')
|
||||
case 'JMuxerStream':
|
||||
return () => import('@/components/webcams/streamers/JMuxerStream.vue')
|
||||
case 'Mjpegstreamer':
|
||||
return () => import('@/components/webcams/streamers/Mjpegstreamer.vue')
|
||||
case 'MjpegstreamerAdaptive':
|
||||
return () => import('@/components/webcams/streamers/MjpegstreamerAdaptive.vue')
|
||||
case 'Uv4lMjpeg':
|
||||
return () => import('@/components/webcams/streamers/Uv4lMjpeg.vue')
|
||||
case 'WebrtcCameraStreamer':
|
||||
return () => import('@/components/webcams/streamers/WebrtcCameraStreamer.vue')
|
||||
case 'WebrtcMediaMTX':
|
||||
return () => import('@/components/webcams/streamers/WebrtcMediaMTX.vue')
|
||||
}
|
||||
}
|
||||
|
||||
export const DynamicCamLoader = (componentName: StreamerTypes) =>
|
||||
Vue.component(componentName, getDynamicCamImport(componentName))
|
86
src/main.ts
86
src/main.ts
@ -1,41 +1,53 @@
|
||||
import 'core-js/stable' // polyfills for older browsers
|
||||
import 'regenerator-runtime' // async polyfill used by the gcodeviewer
|
||||
import 'resize-observer-polyfill' // polyfill needed by the responsive class detection
|
||||
|
||||
import Vue from 'vue'
|
||||
import App from '@/App.vue'
|
||||
import vuetify from '@/plugins/vuetify'
|
||||
import i18n from '@/plugins/i18n'
|
||||
import i18n, { setAndLoadLocale } from '@/plugins/i18n'
|
||||
import store from '@/store'
|
||||
import router from '@/plugins/router'
|
||||
import { WebSocketPlugin } from '@/plugins/webSocketClient'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
// vue-observe-visibility
|
||||
import { ObserveVisibility } from 'vue-observe-visibility'
|
||||
Vue.directive('observe-visibility', ObserveVisibility)
|
||||
|
||||
//vue-meta
|
||||
import VueMeta from 'vue-meta'
|
||||
Vue.use(VueMeta)
|
||||
|
||||
//vue-load-image
|
||||
import VueLoadImage from 'vue-load-image'
|
||||
Vue.component('VueLoadImage', VueLoadImage)
|
||||
|
||||
//vue-toast-notifications
|
||||
import VueToast from 'vue-toast-notification'
|
||||
import 'vue-toast-notification/dist/theme-sugar.css'
|
||||
//overlayerscrollbars-vue
|
||||
import { OverlayScrollbarsPlugin } from 'overlayscrollbars-vue'
|
||||
import 'overlayscrollbars/css/OverlayScrollbars.css'
|
||||
// Directives
|
||||
import './directives/longpress'
|
||||
import './directives/responsive-class'
|
||||
|
||||
// Echarts
|
||||
import ECharts from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
|
||||
// import ECharts modules manually to reduce bundle size
|
||||
import { SVGRenderer } from 'echarts/renderers'
|
||||
import { BarChart, LineChart, PieChart } from 'echarts/charts'
|
||||
import { DatasetComponent, GridComponent, LegendComponent, TooltipComponent } from 'echarts/components'
|
||||
// vue-resize
|
||||
import 'vue-resize/dist/vue-resize.css'
|
||||
// @ts-ignore
|
||||
import VueResize from 'vue-resize'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.directive('observe-visibility', ObserveVisibility)
|
||||
|
||||
Vue.use(VueMeta)
|
||||
|
||||
Vue.component('VueLoadImage', VueLoadImage)
|
||||
|
||||
Vue.use(VueToast, {
|
||||
duration: 3000,
|
||||
})
|
||||
|
||||
//overlayerscrollbars-vue
|
||||
import { OverlayScrollbarsPlugin } from 'overlayscrollbars-vue'
|
||||
import 'overlayscrollbars/css/OverlayScrollbars.css'
|
||||
|
||||
const isSafari = navigator.userAgent.includes('Safari') && navigator.userAgent.search('Chrome') === -1
|
||||
const isTouch = 'ontouchstart' in window || (navigator.maxTouchPoints > 0 && navigator.maxTouchPoints !== 256)
|
||||
Vue.use(OverlayScrollbarsPlugin, {
|
||||
@ -46,41 +58,27 @@ Vue.use(OverlayScrollbarsPlugin, {
|
||||
},
|
||||
})
|
||||
|
||||
// Directives
|
||||
import './directives/longpress'
|
||||
import './directives/responsive-class'
|
||||
|
||||
// Echarts
|
||||
import ECharts from 'vue-echarts'
|
||||
import { use } from 'echarts/core'
|
||||
|
||||
// import ECharts modules manually to reduce bundle size
|
||||
import { SVGRenderer } from 'echarts/renderers'
|
||||
import { LineChart, BarChart, PieChart } from 'echarts/charts'
|
||||
import { GridComponent, LegendComponent, TooltipComponent, DatasetComponent } from 'echarts/components'
|
||||
|
||||
use([SVGRenderer, LineChart, BarChart, LegendComponent, PieChart, DatasetComponent, GridComponent, TooltipComponent])
|
||||
Vue.component('EChart', ECharts)
|
||||
|
||||
// vue-resize
|
||||
import 'vue-resize/dist/vue-resize.css'
|
||||
// @ts-ignore
|
||||
import VueResize from 'vue-resize'
|
||||
Vue.use(VueResize)
|
||||
|
||||
const initLoad = async () => {
|
||||
//load config.json
|
||||
await fetch('/config.json')
|
||||
.then((res) => res.json())
|
||||
.then(async (file) => {
|
||||
window.console.debug('Loaded config.json')
|
||||
try {
|
||||
//load config.json
|
||||
const res = await fetch('/config.json')
|
||||
const file = (await res.json()) as Record<string, unknown>
|
||||
|
||||
await store.dispatch('importConfigJson', file)
|
||||
if ('defaultLocale' in file) i18n.locale = file.defaultLocale
|
||||
})
|
||||
.catch(() => {
|
||||
window.console.error('config.json not found or cannot be decoded!')
|
||||
})
|
||||
window.console.debug('Loaded config.json')
|
||||
|
||||
await store.dispatch('importConfigJson', file)
|
||||
if ('defaultLocale' in file) {
|
||||
await setAndLoadLocale(file.defaultLocale as string)
|
||||
}
|
||||
} catch (e) {
|
||||
window.console.error('Failed to load config.json')
|
||||
window.console.error(e)
|
||||
}
|
||||
|
||||
const url = store.getters['socket/getWebsocketUrl']
|
||||
Vue.use(WebSocketPlugin, { url, store })
|
||||
|
@ -2,23 +2,21 @@ import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
Vue.use(VueI18n)
|
||||
|
||||
function loadLocaleMessages() {
|
||||
const locales = import.meta.globEager('../locales/*.json')
|
||||
const messages: any = {}
|
||||
import defaultLocale from '../locales/en.json'
|
||||
|
||||
for (const file in locales) {
|
||||
const langKey = file.slice(file.lastIndexOf('.') - 2, file.lastIndexOf('.'))
|
||||
const locale = (import.meta.env.VUE_APP_I18N_LOCALE as string) || 'en'
|
||||
|
||||
if (langKey && langKey.length > 1) {
|
||||
messages[langKey] = JSON.parse(JSON.stringify(locales[file]))
|
||||
}
|
||||
}
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
export default new VueI18n({
|
||||
locale: (import.meta.env.VUE_APP_I18N_LOCALE as string) || 'en',
|
||||
const i18n = new VueI18n({
|
||||
locale,
|
||||
fallbackLocale: (import.meta.env.VUE_APP_I18N_FALLBACK_LOCALE as string) || 'en',
|
||||
messages: loadLocaleMessages(),
|
||||
messages: { en: defaultLocale },
|
||||
})
|
||||
|
||||
export default i18n
|
||||
|
||||
export async function setAndLoadLocale(lang: string) {
|
||||
const locales = await import(`../locales/${lang}.json`)
|
||||
i18n.setLocaleMessage(lang, locales)
|
||||
i18n.locale = lang
|
||||
return locales
|
||||
}
|
||||
|
@ -76,17 +76,35 @@ export default defineConfig({
|
||||
resolvers: [VuetifyResolver()],
|
||||
}),
|
||||
],
|
||||
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
css: { charset: false },
|
||||
scss: {
|
||||
quietDeps: true,
|
||||
},
|
||||
postcss: {
|
||||
plugins: [require('postcss-nesting')()],
|
||||
},
|
||||
},
|
||||
|
||||
build: {
|
||||
target: 'safari12',
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: (id: string) => {
|
||||
if (id.includes('node_modules')) {
|
||||
// split codemirror into its own chunk
|
||||
if (id.includes('/codemirror/') || id.includes('/@codemirror/')) {
|
||||
return 'codemirror'
|
||||
}
|
||||
|
||||
// split these libs into their own chunks
|
||||
const chunkedLibs = ['vuetify', 'echarts', 'overlayscrollbars']
|
||||
for (const lib of chunkedLibs) {
|
||||
if (id.includes(`/node_modules/${lib}/`)) {
|
||||
return lib.replace('.js', '')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
envPrefix: 'VUE_',
|
||||
|
Loading…
x
Reference in New Issue
Block a user