diff --git a/src/api/subscriber.js b/src/api/subscriber.js
index 713448d3..d29ae39c 100644
--- a/src/api/subscriber.js
+++ b/src/api/subscriber.js
@@ -7,6 +7,7 @@ import {
import {
getList,
get,
+ getAsBlob,
patchAdd,
patchReplace,
patchRemove,
@@ -14,9 +15,11 @@ import {
patchAddFull
} from './common'
+
import {
assignNumbers
} from './user'
+
export function getPreferences (id) {
return new Promise((resolve, reject) => {
Vue.http.get('api/subscriberpreferences/' + id).then((result) => {
@@ -616,3 +619,9 @@ export async function getSubscriberRegistrations (options) {
})
return list
}
+
+export async function getRecordingStream (fileId) {
+ return await getAsBlob({
+ path: 'api/callrecordingfiles/' + fileId
+ })
+}
diff --git a/src/pages/CscPageCallRecording.vue b/src/pages/CscPageCallRecording.vue
index c4a63ca8..4c958fb9 100644
--- a/src/pages/CscPageCallRecording.vue
+++ b/src/pages/CscPageCallRecording.vue
@@ -86,16 +86,6 @@
:icon="isRowExpanded(props.row.id) ? 'expand_less' : 'expand_more'"
@click="updateCollapseArray(props.row.id)"
/>
-
{{ col.value }}
-
+
+
@@ -170,13 +169,14 @@ import { mapGetters } from 'vuex'
import { mapWaitingActions } from 'vue-wait'
import { saveAs } from 'file-saver'
import { showGlobalError, showToast } from 'src/helpers/ui'
-import CscConfirmationDialog from 'components/CscConfirmationDialog'
+import CscAudioPlayer from 'components/CscAudioPlayer'
import CscPageSticky from 'components/CscPageSticky'
import CscCallRecordingFilters from 'components/pages/CallRecording/CscCallRecordingFilters'
+import CscRemoveDialog from 'components/CscRemoveDialog'
export default {
name: 'CscCallBlocking',
components: {
- CscConfirmationDialog,
+ CscAudioPlayer,
CscPageSticky,
CscCallRecordingFilters
},
@@ -272,7 +272,8 @@ export default {
fetchRecordings: 'csc-call-recordings',
fetchStreams: 'csc-call-recordings',
deleteRecording: 'csc-call-recordings',
- downloadRecording: 'csc-call-recordings'
+ downloadRecording: 'csc-call-recordings',
+ playStreamFile: 'csc-call-recordings'
}),
async fetchPaginatedRecordings (props) {
const { page, rowsPerPage, sortBy, descending } = props.pagination
@@ -301,7 +302,14 @@ export default {
this.showFilters = false
},
confirmRowDeletion (rowId) {
- this.$refs['confirmDelete-' + rowId].open()
+ this.$q.dialog({
+ component: CscRemoveDialog,
+ parent: this,
+ title: this.$t('Delete recording'),
+ message: this.$t('You are about to delete recording #{id}', { id: rowId })
+ }).onOk(() => {
+ this.deleteRecord(rowId)
+ })
},
async deleteRecord (rowId) {
try {
@@ -319,12 +327,17 @@ export default {
const rowStatus = this.rowStatus.filter(row => row.id === id)[0] || null
return rowStatus && rowStatus.expanded
},
- updateCollapseArray (id) {
+ async updateCollapseArray (id) {
const recording = this.recordings.filter(rec => rec.id === id)[0]
const rowStatus = this.rowStatus.filter(row => row.id === id)[0]
rowStatus.expanded = !rowStatus.expanded
if (rowStatus.expanded && recording.files.length === 0) {
- this.fetchStreams(id)
+ this.$wait.start('loading-stream-' + id)
+ try {
+ await this.fetchStreams(id)
+ } finally {
+ this.$wait.end('loading-stream-' + id)
+ }
}
},
async saveFile (fileId) {
@@ -348,4 +361,12 @@ export default {
font-size 15px
.table-td-no-padding
padding 0px !important // needed to override .q-table td
+.table-td-action-cont
+ min-width 140px
+ .player-btns
+ bottom 9px
+ left 8px
+ .download-btn
+ height 30px
+
diff --git a/src/store/call-recordings.js b/src/store/call-recordings.js
index 04009426..350e842b 100644
--- a/src/store/call-recordings.js
+++ b/src/store/call-recordings.js
@@ -1,5 +1,5 @@
import Vue from 'vue'
-import { getRecordings, getRecordingStreams, downloadRecordingStream } from '../api/subscriber'
+import { getRecordings, getRecordingStreams, downloadRecordingStream, getRecordingStream } from '../api/subscriber'
export default {
namespaced: true,
state: {
@@ -15,6 +15,11 @@ export default {
},
mutations: {
callRecordings (state, res) {
+ (state.recordings || []).forEach(r => {
+ (r?.files || []).forEach(s => {
+ if (s.url) URL.revokeObjectURL(s.url)
+ })
+ })
state.recordings = res
},
callRecordingStreams (state, data) {
@@ -33,6 +38,10 @@ export default {
},
async fetchStreams (context, recId) {
const streams = await getRecordingStreams(recId)
+ await Promise.all(streams.map(async stream => {
+ const blob = await getRecordingStream(stream.id)
+ stream.url = blob
+ }))
context.commit('callRecordingStreams', {
recId: recId,
streams: streams