- error express sever is offline
- difference between loading & no torrents active in dashboard
- animation when clicking refresh
This commit is contained in:
WDaan 2019-04-26 11:15:28 +02:00
parent 2215c8c636
commit 3f35340c0d
9 changed files with 80 additions and 55 deletions

6
.dockerignore Normal file
View file

@ -0,0 +1,6 @@
nodemodules
src
LICENSE.md
package-lock.json
package.json
README.md

View file

@ -6,7 +6,7 @@
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint", "lint": "vue-cli-service lint",
"start" : "nodemon server.js" "start" : "nodemon server/server.js"
}, },
"dependencies": { "dependencies": {
"apexcharts": "^3.6.5", "apexcharts": "^3.6.5",

View file

@ -1,8 +1,8 @@
{ {
"qbit_user": "admin", "qbit_user": "admin",
"qbit_pass": "adminadmin", "qbit_pass": "adminadmin",
"qbit_host": "https://qbit.mydomain.com", "qbit_host": "https://qbittorrent.mydomain.com",
"web_user": "username", "web_user": "username",
"web_pass": " password", "web_pass": " password",
"web_host": "https://vuetr.mydomain.me" "web_host": "https://vuetorrent.mydomain.com"
} }

View file

@ -18,7 +18,7 @@ const upload = multer({
const app = express(); const app = express();
app.use(express.json()); app.use(express.json());
app.use(express.static('./src/dist')); app.use(express.static('dist'));
app.use(function(req, res, next) { app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Origin', '*');
@ -119,7 +119,7 @@ app.delete('/upload', upload.single('file'), (req, res) => {
return res.send('deleted file'); return res.send('deleted file');
}); });
app.listen(3000, () => console.log(`Server listening on port 3000!`)); app.listen(3009, () => console.log(`Server listening on port 3009!`));
//clear the tmp directory on every boot //clear the tmp directory on every boot
const directory = path.resolve(__dirname + '/tmp'); const directory = path.resolve(__dirname + '/tmp');

View file

@ -3,9 +3,7 @@
<!--title--> <!--title-->
<v-toolbar flat app> <v-toolbar flat app>
<v-toolbar-side-icon @click="drawer = !drawer" class="grey--text"></v-toolbar-side-icon> <v-toolbar-side-icon @click="drawer = !drawer" class="grey--text"></v-toolbar-side-icon>
<v-toolbar-title <v-toolbar-title :class="['grey--text', {'subheading ml-0': $vuetify.breakpoint.smAndDown}]">
:class="['grey--text', {'subheading ml-0': $vuetify.breakpoint.smAndDown}]"
>
<span class="font-weight-light">Vue</span> <span class="font-weight-light">Vue</span>
<span>Torrent</span> <span>Torrent</span>
</v-toolbar-title> </v-toolbar-title>
@ -22,7 +20,7 @@
<v-btn small fab flat class="mr-0 ml-0" @click="pauseTorrents"> <v-btn small fab flat class="mr-0 ml-0" @click="pauseTorrents">
<v-icon color="grey">pause</v-icon> <v-icon color="grey">pause</v-icon>
</v-btn> </v-btn>
<v-btn small fab flat class="mr-0 ml-0" @click="REFRESH_TORRENTS"> <v-btn small fab flat class="mr-0 ml-0" @click="refreshTorrents">
<v-icon color="grey">autorenew</v-icon> <v-icon color="grey">autorenew</v-icon>
</v-btn> </v-btn>
</v-toolbar> </v-toolbar>
@ -187,6 +185,10 @@ export default {
removeTorrents() { removeTorrents() {
this.$store.dispatch("REMOVE_TORRENTS"); this.$store.dispatch("REMOVE_TORRENTS");
}, },
refreshTorrents() {
this.$store.state.init_torrents = false;
this.$store.dispatch("REFRESH_TORRENTS");
},
closeSnackbar() { closeSnackbar() {
this.$store.state.snackbar = false; this.$store.state.snackbar = false;
} }

View file

@ -1,8 +1,8 @@
{ {
"qbit_user": "admin", "qbit_user": "admin",
"qbit_pass": "adminadmin", "qbit_pass": "adminadmin",
"qbit_host": "https://qbit.mydomain.com", "qbit_host": "https://qbittorrent.mydomain.com",
"web_user": "username", "web_user": "username",
"web_pass": " password", "web_pass": " password",
"web_host": "https://vuetr.mydomain.me" "web_host": "https://vuetorrent.mydomain.com"
} }

View file

@ -1,6 +1,6 @@
const axios = require('axios'); const axios = require('axios');
const info = require('./config/config.json'); const info = require('../config/config.json');
class Qbit { class Qbit {
constructor() { constructor() {
@ -45,13 +45,17 @@ class Qbit {
} }
async remove_torrents(torrents) { async remove_torrents(torrents) {
let res = await this._axios.post('/remove', torrents); let res = await this._axios.post('/remove', torrents)
return res.data; return res.data;
} }
async login(credentials) { async login(credentials) {
let res = await this._axios.post('/login', credentials); let timeout = false;
return res.data; let res = await this._axios.post('/login', credentials).catch(error => {
if (error.code === 'ECONNABORTED') timeout = true;
else throw error;
});
return timeout ? 'timeout' : res.data;
} }
} }

View file

@ -18,6 +18,7 @@ export default new Vuex.Store({
upload_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], upload_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
download_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], download_data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
torrents: [], torrents: [],
init_torrents : false,
selected_torrents: [], selected_torrents: [],
network_error: false, network_error: false,
snackbar_error: false, snackbar_error: false,
@ -40,7 +41,8 @@ export default new Vuex.Store({
state.error_msg = 'Lost connection with server, reload page'; state.error_msg = 'Lost connection with server, reload page';
state.snackbar_error = true; state.snackbar_error = true;
}); });
state.torrents = torrents.map(a => ({...a})); state.torrents = torrents.map(a => ({ ...a }));
state.init_torrents = true;
}, },
REFRESH_SESSION_STATS: async state => { REFRESH_SESSION_STATS: async state => {
let _stats = await qbit.get_sessions_stats(); let _stats = await qbit.get_sessions_stats();
@ -122,38 +124,47 @@ export default new Vuex.Store({
}, },
LOGIN: async (state, payload) => { LOGIN: async (state, payload) => {
let res = await qbit.login(payload); let res = await qbit.login(payload);
switch (res) { if (res == 'timeout') {
case 'No such user': state.loading = false;
state.snackbar_error = true; state.snackbar_error = true;
state.error_msg = 'No such user!'; state.error_msg = 'Express server timed out!';
setTimeout(() => { setTimeout(() => {
state.snackbar_error = false; state.snackbar_error = false;
}, 4000); }, 4000);
break; } else {
case 'Wrong password!': switch (res) {
state.snackbar_error = true; case 'No such user':
state.error_msg = 'Wrong password!'; state.snackbar_error = true;
setTimeout(() => { state.error_msg = 'No such user!';
state.snackbar_error = false; setTimeout(() => {
}, 4000); state.snackbar_error = false;
break; }, 4000);
case 'SUCCES': break;
state.snackbar = true; case 'Wrong password!':
state.succes_msg = 'Succesfully logged in!'; state.snackbar_error = true;
state.authenticated = true; state.error_msg = 'Wrong password!';
setTimeout(() => { setTimeout(() => {
state.snackbar = false; state.snackbar_error = false;
}, 4000); }, 4000);
break; break;
default: case 'SUCCES':
state.snackbar_error = true; state.snackbar = true;
state.error_msg = 'Something went wrong'; state.succes_msg = 'Succesfully logged in!';
setTimeout(() => { state.authenticated = true;
state.snackbar_error = false; setTimeout(() => {
}, 4000); state.snackbar = false;
break; }, 4000);
break;
default:
state.snackbar_error = true;
state.error_msg = 'Something went wrong';
setTimeout(() => {
state.snackbar_error = false;
}, 4000);
break;
}
state.loading = false;
} }
state.loading = false;
} }
}, },
actions: { actions: {

View file

@ -16,8 +16,15 @@
@keyup.enter.native="sortBy" @keyup.enter.native="sortBy"
></v-text-field> ></v-text-field>
</v-flex> </v-flex>
<v-container v-if="!init_torrents" fill-height>
<div v-if="torrents.length >= 1"> <div style="margin: 150px auto;">
<v-progress-circular :size="100" indeterminate color="green_accent"></v-progress-circular>
</div>
</v-container>
<div v-if="torrents.length === 0 && init_torrents" class="mt-5 text-xs-center">
<p class="grey--text">No active Torrents!</p>
</div>
<div v-else>
<v-card <v-card
ripple ripple
flat flat
@ -108,11 +115,6 @@
<v-divider></v-divider> <v-divider></v-divider>
</v-card> </v-card>
</div> </div>
<v-container v-else fill-height>
<div style="margin: 150px auto;">
<v-progress-circular :size="100" indeterminate color="green_accent"></v-progress-circular>
</div>
</v-container>
</v-container> </v-container>
</div> </div>
</template> </template>
@ -127,7 +129,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapState(["torrents"]) ...mapState(["torrents", "init_torrents"])
}, },
methods: { methods: {
...mapMutations(["SORT_TORRENTS"]), ...mapMutations(["SORT_TORRENTS"]),