work on sound list

This commit is contained in:
bkfox
2024-03-25 18:05:55 +01:00
parent f41cc3ce0c
commit 70a55607a5
17 changed files with 433 additions and 226 deletions

View File

@ -0,0 +1,110 @@
<template>
<div ref="list" class="a-select-file-list">
<form ref="form" class="flex-column" v-if="state == STATE.DEFAULT">
<slot name="form"></slot>
<div class="field is-horizontal">
<label class="label">{{ label }}</label>
<input type="file" ref="uploadFile" :name="fieldName" @change="onFileChange"/>
</div>
<div class="flex-row align-right" v-if="submitLabel">
<button type="button" class="button small" @click="submit">
{{ submitLabel }}
</button>
</div>
</form>
<div class="flex-column" v-else>
<slot name="preview" :fileUrl="fileUrl" :file="file" :loaded="loaded" :total="total"></slot>
<div class="flex-row">
<progress :max="total" :value="loaded"/>
<button type="button" class="button small square ml-2" @click="abort">
<span class="icon small">
<i class="fa fa-close"></i>
</span>
</button>
</div>
</div>
</div>
</template>
<script>
import {getCsrf} from "../model"
export default {
emit: ["fileChange", "load"],
props: {
url: { type: String },
fieldName: { type: String, default: "file" },
label: { type: String, default: "Select a file" },
submitLabel: { type: String, default: "Upload" },
},
data() {
return {
STATE: {
DEFAULT: 0,
UPLOADING: 1,
},
state: 0,
upload: {},
file: null,
fileUrl: null,
total: 0,
loaded: 0,
request: null,
}
},
methods: {
abort() {
this.request && this.request.abort()
},
onFileChange() {
const [file] = this.$refs.uploadFile.files
if(!file)
return
this._setUploadFile(file)
this.$emit("fileChange", {upload: this, file: this.file, fileUrl: this.fileUrl})
},
submit() {
const req = new XMLHttpRequest()
req.open("POST", this.url)
req.upload.addEventListener("progress", (e) => this.onUploadProgress(e))
req.addEventListener("load", (e) => this.onUploadDone(e))
req.addEventListener("abort", (e) => this.onUploadDone(e))
req.addEventListener("error", (e) => this.onUploadDone(e))
const formData = new FormData(this.$refs.form);
formData.append('csrfmiddlewaretoken', getCsrf())
req.send(formData)
this._resetUpload(this.STATE.UPLOADING, false, req)
},
onUploadProgress(event) {
this.loaded = event.loaded
this.total = event.total
},
onUploadDone(event) {
this.$emit("load", event)
this._resetUpload(this.STATE.DEFAULT, true)
},
_setUploadFile(file) {
this.file = file
this.fileURL = file && URL.createObjectURL(file)
},
_resetUpload(state, resetFile=false, request=null) {
this.state = state
this.loaded = 0
this.total = 0
this.request = request
if(resetFile)
this.file = null
}
},}
</script>

View File

@ -1,5 +1,29 @@
<template>
<div class="a-playlist-editor">
<a-modal ref="modal" :title="labels && labels.add_sound">
<template #default>
<a-file-upload ref="file-upload" :url="soundUploadUrl" :label="labels.select_file" submitLabel="" @load="uploadDone"
>
<template #preview="{upload}">
<slot name="upload-preview" :upload="upload"></slot>
</template>
<template #form>
<slot name="upload-form"></slot>
</template>
</a-file-upload>
</template>
<template #footer>
<button type="button" class="button"
@click.stop="$refs['file-upload'].submit()">
<span class="icon">
<i class="fa fa-upload"></i>
</span>
<span>{{ labels.submit }}</span>
</button>
</template>
</a-modal>
<a-rows :set="set" :columns="columns"
:labels="initData.fields" :allow-create="true" :orderable="true"
@move="listItemMove">
@ -21,7 +45,7 @@
<span class="icon"><i class="fa fa-rotate" /></span>
</button>
<button type="button" class="button square is-primary p-2"
@click="this.set.push(new this.set.model())"
@click="$refs.modal.open()"
:title="labels.add_sound"
:aria-label="labels.add_sound"
>
@ -38,16 +62,19 @@ import Model, {Set} from '../model'
// import AActionButton from './AActionButton'
import ARows from './ARows'
// import AModal from "./AModal"
import AModal from "./AModal"
import AFileUpload from "./AFileUpload"
export default {
components: {ARows},
components: {ARows, AModal, AFileUpload},
props: {
initData: Object,
dataPrefix: String,
labels: Object,
settingsUrl: String,
soundListUrl: String,
soundUploadUrl: String,
columns: {
type: Array,
default: () => ['name', "type", 'is_public', 'is_downloadable']
@ -89,6 +116,14 @@ export default {
// if(settings)
// this.settingsSaved(settings)
},
uploadDone(event) {
const req = event.target
if(req.status == 201) {
const item = JSON.parse(req.response)
this.set.push(item)
}
},
},

View File

@ -12,11 +12,12 @@ import ASoundItem from './ASoundItem'
import ASwitch from './ASwitch'
import AModal from "./AModal"
import AFileUpload from "./AFileUpload"
import ASelectFile from "./ASelectFile"
import AStatistics from './AStatistics'
import AStreamer from './AStreamer'
import ATracklistEditor from './ATracklistEditor'
import APlaylistEditor from './APlaylistEditor'
import ATrackListEditor from './ATrackListEditor'
import ASoundListEditor from './ASoundListEditor'
/**
* Core components
@ -31,10 +32,10 @@ export default base
export const admin = {
...base,
AStatistics, AStreamer, ATracklistEditor
AStatistics, AStreamer, ATrackListEditor
}
export const dashboard = {
...base,
AActionButton, ASelectFile, AModal, ATracklistEditor, APlaylistEditor
AActionButton, AFileUpload, ASelectFile, AModal, ATrackListEditor, ASoundListEditor
}