diff --git a/vueapp/common/upload.service.js b/vueapp/common/upload.service.js index e85cb891b..6543f0f01 100644 --- a/vueapp/common/upload.service.js +++ b/vueapp/common/upload.service.js @@ -92,6 +92,10 @@ class UploadService { return str; } + networkError(onError) { + onError('Beim Hochladen der Datei ist ein Fehler aufgetreten. Stellen Sie sicher, dass eine Verbindung zum Opencast Server besteht und probieren Sie es erneut.'); + } + async getMediaPackage() { return axios({ method: 'GET', @@ -183,6 +187,7 @@ class UploadService { this.fixFilenames(files); let onProgress = options.uploadProgress; let uploadDone = options.uploadDone; + let onError = options.onError; let obj = this; return files.reduce(function(promise, file) { @@ -193,15 +198,19 @@ class UploadService { data.append('overwriteExisting', file.overwriteExisting); data.append('track', file.file); - return obj.addTrack(data, "/" + episode_id + "/track", file, onProgress); + return obj.addTrack(data, "/" + episode_id + "/track", file, onProgress, onError); }); }, Promise.resolve()) .then(() => { uploadDone(); - }) + }).catch(function (error) { + if (error.code === 'ERR_NETWORK') { + obj.networkError(onError) + } + }); } - addTrack(data, url_path, track, onProgress) { + addTrack(data, url_path, track, onProgress, onError) { var fnOnProgress = function (event) { onProgress(track, event.loaded, event.total); }; @@ -278,6 +287,7 @@ class UploadService { let obj = this; let onProgress = options.uploadProgress; let uploadDone = options.uploadDone; + let onError = options.onError; return this.getMediaPackage() .then(function ({ data }) { @@ -307,7 +317,11 @@ class UploadService { /* Catch XML parse error. On Error Resume Next ;-) */ } return ingest; - }) + }).catch(function (error) { + if (error.code === 'ERR_NETWORK') { + obj.networkError(onError); + } + }); } cancel() { diff --git a/vueapp/components/Videos/Actions/CaptionUpload.vue b/vueapp/components/Videos/Actions/CaptionUpload.vue index 511df549e..58fb70eeb 100644 --- a/vueapp/components/Videos/Actions/CaptionUpload.vue +++ b/vueapp/components/Videos/Actions/CaptionUpload.vue @@ -238,6 +238,9 @@ export default { text: this.$gettext('Die Datei wurde erfolgreich hochgeladen.') }); view.$emit('done'); + }, + onError: (response) => { + this.$store.dispatch('errorCommit', response); } } ); diff --git a/vueapp/components/Videos/VideoUpload.vue b/vueapp/components/Videos/VideoUpload.vue index 1ccc66136..6c3adf74e 100644 --- a/vueapp/components/Videos/VideoUpload.vue +++ b/vueapp/components/Videos/VideoUpload.vue @@ -439,6 +439,9 @@ export default { this.$store.dispatch('setVideosReload', true); }); + }, + onError: (response) => { + this.$store.dispatch('errorCommit', response); } }); }, diff --git a/vueapp/components/Videos/VideosTable.vue b/vueapp/components/Videos/VideosTable.vue index b665049f5..24c1c1d3e 100644 --- a/vueapp/components/Videos/VideosTable.vue +++ b/vueapp/components/Videos/VideosTable.vue @@ -225,7 +225,8 @@ export default { 'playlist', 'course_config', 'isLTIAuthenticated', - 'simple_config_list' + 'simple_config_list', + 'errors' ]), numberOfColumns() { @@ -490,6 +491,44 @@ export default { getPlaylistLink(token) { return window.STUDIP.URLHelper.getURL('plugins.php/opencast/contents/index#/contents/playlists/' + token + '/edit', {}, ['cid']) }, + + checkLTIPeriodically() { + let view = this; + + this.$store.dispatch('simpleConfigListRead').then(() => { + + const error_msg = this.$gettext('Es ist ein Verbindungsfehler zum Opencast Server aufgetreten. Bitte wenden Sie sich bei auftretenden Problemen an den Support oder versuchen Sie es zu einem späteren Zeitpunkt erneut.'); + const server_ids = Object.keys(view.simple_config_list['server']); + + // periodically check, if lti is authenticated + view.interval = setInterval(async () => { + // Create an array of promises for checking each server in parallel + const promises = server_ids.map(async (id) => { + await view.$store.dispatch('checkLTIAuthentication', view.simple_config_list['server'][id]); + // Remove server from list, if authenticated + if (view.isLTIAuthenticated[id]) { + server_ids.splice(server_ids.indexOf(id), 1); + } + }); + // Wait for all checks to finish + await Promise.all(promises); + + if (server_ids.length === 0) { + view.$store.dispatch('errorRemove', error_msg); + clearInterval(view.interval); + } else { + if (!view.errors.find((e) => e === error_msg)) { + view.$store.dispatch('errorCommit', error_msg); + } + } + + view.interval_counter++; + if (view.interval_counter > 10) { + clearInterval(view.interval); + } + }, 2000); + }); + } }, async mounted() { @@ -516,25 +555,7 @@ export default { } }) - // periodically check, if lti is authenticated - let view = this; - - this.$store.dispatch('simpleConfigListRead').then(() => { - view.interval = setInterval(() => { - for (let id in view.simple_config_list['server']) { - if (!view.isLTIAuthenticated[id]) { - view.$store.dispatch('checkLTIAuthentication', view.simple_config_list['server'][id]); - } - } - - view.interval_counter++; - - // prevent spamming of oc server - if (view.interval_counter > 10) { - clearInterval(view.interval); - } - }, 2000); - }); + this.checkLTIPeriodically(); }, watch: { diff --git a/vueapp/store/error.module.js b/vueapp/store/error.module.js index 1d190a6b4..99ede8d28 100644 --- a/vueapp/store/error.module.js +++ b/vueapp/store/error.module.js @@ -13,6 +13,10 @@ const actions = { context.commit('errorsAdd', error); }, + errorRemove(context, error) { + context.commit('errorsRemove', error); + }, + errorClear(context) { context.commit('errorsClear'); } @@ -23,6 +27,13 @@ const mutations = { state.errors.push(data); }, + errorsRemove(state, data) { + let idx = state.errors.indexOf(data); + if (idx !== -1) { + state.errors.splice(idx, 1); + } + }, + errorsClear(state) { state.errors = []; } diff --git a/vueapp/store/opencast.module.js b/vueapp/store/opencast.module.js index 2f480fffb..70e0e2013 100644 --- a/vueapp/store/opencast.module.js +++ b/vueapp/store/opencast.module.js @@ -133,18 +133,20 @@ const actions = { return ApiService.put('courses/' + data.cid + '/upload/' + data.upload); }, - checkLTIAuthentication({ commit }, server) + async checkLTIAuthentication({ commit }, server) { - axios({ - method: 'GET', - url: server.name + "/lti/info.json", - crossDomain: true, - withCredentials: true, - headers: { - "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" - } - }).then((response) => { - if (response.status == 200) { + try { + const response = await axios({ + method: 'GET', + url: server.name + "/lti/info.json", + crossDomain: true, + withCredentials: true, + headers: { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + } + }); + + if (response.status === 200) { commit('setLTIStatus', { server: server.id, authenticated: true @@ -155,7 +157,12 @@ const actions = { authenticated: false }); } - }); + } catch (error) { + commit('setLTIStatus', { + server: server.id, + authenticated: false + }); + } } }