Skip to content

Commit

Permalink
Many changes in one commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Matěj Jehlička committed May 13, 2021
1 parent 5e090d4 commit 83b01f8
Show file tree
Hide file tree
Showing 6 changed files with 663 additions and 20 deletions.
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11"
"optimize-css-assets-webpack-plugin": "^5.0.4",
"terser-webpack-plugin": "^5.1.1",
"vue": "^2.6.11",
"vue-qrcode-reader": "^2.3.18",
"vuex": "^3.4.0",
"webpack": "^5.28.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
Expand Down
257 changes: 251 additions & 6 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,218 @@
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<h1>Tracker configuration</h1>
<div v-if="error" v-html="error" style="background-color: red; color: white"></div>
<a href="#" @click="showConfig = !showConfig" class="clear-console">
<div v-if="showConfig">Hide configuration</div>
<div v-else>Show configuration</div>
</a>
<div v-if="showConfig">
<div>Upload configuration file and restart tracker.</div>
<div>File is upload immediately after select!</div>
<br/>
<input type="file" ref="fileupload" accept="application/json" @change="onFileChange">
<div>
<button v-if="selectedFile" @click="clear">Clear selection</button>
</div>
<br/>
<div>
<label for="apnhost">APN host</label>
<input id="apnhost" v-model="apnHost" placeholder="apn host">
<label for="apnuser">APN username</label>
<input id="apnuser" v-model="apnUser" placeholder="apn user">
<label for="apnpass">APN password</label>
<input id="apnpass" v-model="apnPass" placeholder="apn pass">
</div>
<br/>
<button @click="sendForm">Update config</button>
<hr/>
</div>

<div v-if="moving" style="color: green"> Tracker is moving</div>
<div v-else style="color: red"> Tracker is not moving</div>
<div v-if="position">Position: {{ position.latitude }}, {{ position.longitude }}</div>
<div v-if="position">Speed: {{ position.speed }} kph</div>
<div v-if="message">Last known state: <b>{{ message.state }}</b></div>
<h2>Log</h2>
<div class="console">
<div class="console-text">
{{ log }}
</div>
<a href="#" @click="clearLog" class="clear-console">Clear</a>
</div>

</div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
components: {},
data() {
return {
showQrReader: false,
message: "",
host: window.location.hostname,
// host: "192.168.88.53",
log: "Welcome\n",
mqttLog: "Welcome\n",
selectedFile: false,
position: null,
moving: false,
apnHost: "",
apnUser: "",
apnPass: "",
showConfig: true,
error: ""
}
},
created: function () {
this.initWs()
},
computed: {
ws: {
get: function () {
return this.$store.getters.ws
},
set: function (value) {
this.$store.commit('initWs', value)
}
},
connected: {
get: function () {
return this.$store.getters.connected
},
set: function (value) {
this.$store.commit('setConnected', value)
}
}
},
methods: {
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
this.readFile(files[0]);
},
readFile(file) {
this.selectedFile = true
let reader = new FileReader();
reader.onload = e => {
console.log(e.target.result);
const json = JSON.parse(e.target.result)
this.addMessageToLog("Configuration file \"" + file.name + "\" loaded")
if (json.information) {
this.addMessageToLog(json.information)
}
const message = {
type: "file",
msg: json.information,
username: json.username,
password: json.password,
token: json.token,
vehicleId: json.vehicleId,
mqttHost: json.mqttHost,
mqttPort: json.mqttPort,
mqttUsername: json.mqttUsername,
mqttPassword: json.mqttPassword,
mqttTopic: json.mqttTopic
}
console.log(JSON.stringify(message))
this.ws.send(JSON.stringify(message))
};
reader.readAsText(file);
},
sendForm() {
this.error = ""
if (this.apnHost.length > 20) this.error = `apn host is too long <br/>` + this.error
if (this.apnUser.length > 20) this.error = `apn username is too long <br/>` + this.error
if (this.apnPass.length > 20) this.error = `apn password is too long <br/>` + this.error
const message = {
type: "form",
apnHost: this.apnHost,
apnUser: this.apnUser,
apnPass: this.apnPass,
}
console.log(JSON.stringify(message))
this.ws.send(JSON.stringify(message))
},
addMessageToLog(msg) {
if (msg.includes("MQTT state") || msg.includes("Modem is not")) this.mqttLog = new Date().toLocaleString() + '> ' + msg + '\n' + this.mqttLog
this.log = new Date().toLocaleString() + '> ' + msg + '\n' + this.log
},
clear() {
this.$refs.fileupload.value = null;
this.selectedFile = false;
},
clearLog() {
this.log = ""
},
initWs: function () {
let hostname = this.host
console.log("Connecting to ws://" + hostname + "/ws")
this.ws = new WebSocket("ws://" + hostname + "/ws")
this.ws.onopen = () => {
this.connected = true
};
this.ws.onerror = (err) => {
this.connected = false;
console.log("WS error: " + JSON.stringify(err));
this.restartConnection()
};
this.ws.onmessage = (data) => {
this.message = JSON.parse(data.data);
this.position = {
latitude: this.message.latitude,
longitude: this.message.longitude,
speed: this.message.speed
}
this.moving = this.message.isMoving
if (this.message.new) {
this.addMessageToLog(this.message.state)
}
};
this.ws.onclose = () => {
if (this.connected) {
console.log("Connection closed, restarting");
this.restartConnection()
} else {
console.log("Connection closed")
}
};
window.addEventListener('beforeunload', () => {
console.log("Closing the page")
if (this.ws != null && this.ws.readyState === 1) {
this.disconnect()
}
}, false)
},
restartConnection: function () {
setTimeout(() => {
this.initWs()
}, 1000)
},
disconnect: function () {
console.log("Closing connection")
this.connected = false
if (this.ws != null)
this.ws.close()
},
}
}
</script>

<style>
label {
display: block;
text-align: center;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
Expand All @@ -25,4 +221,53 @@ export default {
color: #2c3e50;
margin-top: 60px;
}
.console {
width: 400px;
height: 255px;
margin: 20px 0 20px;
font-family: Arial, sans-serif;
font-size: 12px;
display: inline-block;
vertical-align: top;
position: relative;
background: #eee;
border: 1px dotted #333;
transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
}
.console-text {
text-align: left;
position: absolute;
top: 0;
left: 0;
width: 380px;
height: 205px;
padding: 25px 10px;
overflow: auto;
overflow-x: hidden;
white-space: pre;
}
.clear-console {
position: absolute;
top: 0;
right: 0;
text-decoration: none;
color: #666;
padding: 5px 10px;
background: #ccc;
}
.clear-console:hover {
color: #222;
}
</style>
4 changes: 3 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
render: h => h(App),
store,
render: h => h(App)
}).$mount('#app')
27 changes: 27 additions & 0 deletions src/store/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
state: {
connected: false,
ws: null,
},
getters: {
ws: function (state) {
return state.ws
},
connected: function (state) {
return state.connected
},
},
mutations: {
initWs(state, ws) {
state.ws = ws
},
setConnected(state, connected) {
state.connected = connected
},
}
})
29 changes: 29 additions & 0 deletions vue.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const path = require('path');
const webpack = require('webpack');

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
configureWebpack: config => {
config.optimization = {
runtimeChunk: 'single',
minimizer: [
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: ['default', {discardComments: {removeAll: true}}],
}
}),
]
};
config.output = {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: 'js/[hash:5].js',
chunkFilename: 'js/[id].[hash:5].js'
};
config.plugins.concat([
new webpack.optimize.AggressiveMergingPlugin(),
]);

}
}
Loading

0 comments on commit 83b01f8

Please sign in to comment.