openvk/Web/Presenters/templates/Audio/Upload.xml
2024-12-13 16:43:34 +03:00

233 lines
9.4 KiB
XML

{extends "../@layout.xml"}
{block title}
{_upload_audio}
{/block}
{block header}
{if !$playlist}
{if !is_null($group)}
<a href="{$group->getURL()}">{$group->getCanonicalName()}</a>
»
<a href="/audios-{$group->getId()}">{_audios}</a>
{else}
<a href="{$thisUser->getURL()}">{$thisUser->getCanonicalName()}</a>
»
<a href="/audios{$thisUser->getId()}">{_audios}</a>
{/if}
{else}
<a href="{$owner->getURL()}">{$owner->getCanonicalName()}</a>
»
<a href="/playlists{$owner->getRealId()}">{_playlists}</a>
»
<a href="/playlist{$playlist->getPrettyId()}">{_playlist}</a>
{/if}
»
{_upload_audio}
{/block}
{block content}
<div class="container_gray" style="border: 0;margin-top: -10px;">
<div id="upload_container">
<div id="firstStep">
<h4>{_select_audio}</h4><br/>
<b><a href="javascript:void(0)">{_limits}</a></b>
<ul>
<li>{tr("audio_requirements", 1, 30, 25)}</li>
<li>{tr("audio_requirements_2")}</li>
</ul>
<div id="audio_upload">
<input id="audio_input" multiple type="file" name="blob" accept="audio/*" style="display:none" />
<input value="{_upload_button}" class="button" type="button" onclick="document.querySelector('#audio_input').click()">
</div><br/>
<span>{_you_can_also_add_audio_using} <b><a href="/search?section=audios">{_search_audio_inst}</a></b>.<span>
</div>
<div id="lastStep" style="display:none;">
<div id="lastStepContainers"></div>
<div id="lastStepButtons" style="text-align: center;margin-top: 10px;">
<input class="button" type="button" id="uploadMusic" value="{_upload_button}">
<input class="button" type="button" id="backToUpload" onclick="document.querySelector('#audio_input').click()" value="{_select_another_file}">
</div>
</div>
</div>
</div>
<script type="module" n:syntax='off'>
import * as id3 from "/assets/packages/static/openvk/js/node_modules/id3js/lib/id3.js";
window.__audio_upload_page = new class {
files_list = []
hideFirstPage() {
u('#firstStep').attr('style', 'display:none')
u('#lastStep').attr('style', 'display:block')
}
showFirstPage() {
u('#firstStep').attr('style', 'display:block')
u('#lastStep').attr('style', 'display:none')
}
async detectTags(blob) {
const return_params = {
performer: '',
name: '',
genre: '',
lyrics: '',
explicit: 0,
unlisted: 0,
}
function fallback() {
console.info('Tags not found, setting default values.')
return_params.name = remove_file_format(blob.name)
return_params.genre = 'Other'
return_params.performer = tr('track_unknown')
}
let tags = null
try {
tags = await id3.fromFile(blob)
} catch(e) {
console.error(e)
}
console.log(tags)
if(tags != null) {
console.log("ID" + tags.kind + " detected, setting values...")
if(tags.title) {
return_params.name = tags.title
} else {
return_params.name = remove_file_format(blob.name)
}
if(tags.artist) {
return_params.performer = tags.artist
} else {
return_params.performer = tr('track_unknown')
// todo: split performer and title from filename
}
if(tags.genre != null) {
if(tags.genre.split(', ').length > 1) {
const genres = tags.genre.split(', ')
genres.forEach(genre => {
if(window.openvk.audio_genres[genre]) {
return_params.genre = genre;
}
})
} else {
if(window.openvk.audio_genres.indexOf(tags.genre) != -1) {
return_params.genre = tags.genre
} else {
console.warn("Unknown genre: " + tags.genre)
return_params.genre = 'Other'
}
}
} else {
return_params.genre = 'Other'
}
if(tags.comments != null)
return_params.lyrics = tags.comments
} else {
fallback()
}
return return_params
}
async appendFile(appender)
{
appender.info = await this.detectTags(appender.file)
const audio_index = this.files_list.push(appender) - 1
this.appendAudioFrame(audio_index)
}
appendAudioFrame(audio_index) {
const audio_element = this.files_list[audio_index]
if(!audio_element) {
return
}
const template = u(`
<div class='upload_container_element' data-index="${audio_index}">
<div class='upload_container_name'>
<span>${ovk_proc_strtr(escapeHtml(audio_element.file.name), 63)}</span>
<div id="small_remove_button"></div>
</div>
<table cellspacing="7" cellpadding="0" border="0" align="center">
<tbody>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('performer')}:</span></td>
<td><input value='${escapeHtml(audio_element.info.performer)}' name="performer" type="text" autocomplete="off" maxlength="80" /></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('audio_name')}:</span></td>
<td><input type="text" value='${escapeHtml(audio_element.info.name)}' name="name" autocomplete="off" maxlength="80" /></td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('genre')}:</span></td>
<td>
<select name="genre"></select>
</td>
</tr>
<tr>
<td width="120" valign="top"><span class="nobold">${tr('lyrics')}:</span></td>
<td><textarea name="lyrics" style="resize: vertical;max-height: 300px;">${escapeHtml(audio_element.info.lyrics)}</textarea></td>
</tr>
<tr>
<td width="120" valign="top"></td>
<td>
<label style='display:block'><input type="checkbox" name="explicit">${tr('audios_explicit')}</label>
<label><input type="checkbox" name="unlisted">${tr('audios_unlisted')}</label>
</td>
</tr>
</tbody>
</table>
</div>
`)
window.openvk.audio_genres.forEach(genre => {
template.find('select').append(`
<option ${genre == audio_element.info.genre ? 'selected': ''} value='${genre}'>${genre}</option>
`)
})
u('#lastStep #lastStepContainers').append(template)
}
}
u(`#audio_upload input`).on('change', (e) => {
const files = e.target.files
if(files.length <= 0) {
return
}
Array.from(files).forEach(async file => {
let has_duplicates = false
const appender = {
'file': file
}
if(!file.type.startsWith('audio/')) {
makeError(tr('only_audios_accepted', escapeHtml(file.name)))
return
}
window.__audio_upload_page.files_list.forEach(el => {
if(el && file.name == el.file.name) {
has_duplicates = true
}
})
if(!has_duplicates) {
window.__audio_upload_page.appendFile(appender)
}
})
window.__audio_upload_page.hideFirstPage()
})
</script>
{/block}