const component_search_folders = {
emits: ['play_audio', 'set_token'],
data() {
return {
search_foldernames: "",
folders: [],
folder: {},
offset: 0,
limit: 10,
folder_offset: 0,
folder_limit: 10,
files_in_folder: [],
playing_audio_file: {},
}
},
template: `
{{ offset }}~{{ offset + folders.length }}
| Folder Name |
Action |
| {{ folder.foldername }} |
|
{{ folder_offset }}~{{ folder_offset + files_in_folder.length }}
| Filename |
Folder Name |
Size |
Action |
`,
mounted() {
if (this.$route.query.folder_id) {
this.folder.id = parseInt(this.$route.query.folder_id)
this.folder.foldername = this.$route.query.foldername
this.get_files_in_folder()
}
},
methods: {
folder_last_page() {
this.folder_offset = this.folder_offset - this.folder_limit
if (this.folder_offset < 0) {
this.folder_offset = 0
return
}
this.get_files_in_folder()
},
folder_next_page() {
this.folder_offset = this.folder_offset + this.folder_limit
this.get_files_in_folder()
},
view_folder(folder) {
this.folder = folder
this.get_files_in_folder()
},
get_files_in_folder() {
axios.post('/api/v1/get_files_in_folder', {
folder_id: this.folder.id,
limit: this.folder_limit,
offset: this.folder_offset,
}).then((response) => {
var files = response.data.files
for (var key in files) {
files[key].foldername = this.folder.foldername
}
this.files_in_folder = files
})
},
last_page() {
this.offset = this.offset - this.limit
if (this.offset < 0) {
this.offset = 0
return
}
this.search_folders()
},
next_page() {
this.offset = this.offset + this.limit
this.search_folders()
},
first_search_folders() {
this.offset = 0
this.search_folders()
},
search_folders() {
axios.post('/api/v1/search_folders', {
foldername: this.search_foldernames,
limit: this.limit,
offset: this.offset,
}).then((response) => {
this.folders = response.data.folders
})
},
},
}
const component_token = {
progs: ['token'],
emits: ['set_token'],
data() {
return {
token_tmp: "",
}
},
template: `
`,
methods: {
emit_set_token() {
this.$emit('set_token', this.token_tmp)
},
},
}
const component_manage= {
props: ['token'],
emits: ['set_token'],
data() {
return {
}
},
template: `
关于本站
本站是 MSW Project 的一个应用,希望以个人之力分享被隐藏在历史中的音乐。
自己是V家厨,喜欢的p主包括 wonder-k, buzzG, *luna 等,但却因为种种原因淹没在主流音乐APP的曲库中。本站的初衷是为了让那些知名度低的 VOCALOID / ACG / 东方曲,能够被更多有缘人听到,同时有一个跨平台的工具,能够在低网速的条件下享受硬盘中的无损音乐。
`,
}
const component_manage_database = {
props: ['token'],
data() {
return {
root: "",
pattern: [".flac", ".mp3"],
pattern_tmp: "",
s: "",
}
},
template: `
`,
methods: {
add_pattern() {
this.pattern.push(this.pattern_tmp)
this.pattern_tmp = ""
},
reset_database() {
axios.post('/api/v1/reset', {
token: this.token,
}).then((response) => {
this.s = response.data.status
}).catch((err) => {
this.s = err.response.data.status
})
},
update_database() {
this.s = "Updating..."
axios.post('/api/v1/walk', {
token: this.token,
root: this.root,
pattern: this.pattern,
}).then((response) => {
this.s = response.data.status
}).catch((err) => {
this.s = err.response.data.status
})
}
},
}
const component_file_dialog = {
props: ['file', 'show_dialog'],
emits: ['play_audio', 'close_dialog'],
template: `
`,
data() {
return {
download_loaded: 0,
disabled: false,
}
},
methods: {
emit_close_dialog() {
this.$emit('close_dialog')
},
emit_stream_audio() {
this.file.play_back_type = 'stream',
this.$emit("play_audio", this.file)
this.emit_close_dialog()
},
emit_play_audio() {
console.log("pressed button")
this.file.play_back_type = 'raw'
this.$emit("play_audio", this.file)
this.emit_close_dialog()
},
download_file(file) {
this.disabled = true
axios({
url: '/api/v1/get_file',
method: 'POST',
responseType: 'blob', // important
data: {
id: file.id,
},
onDownloadProgress: ProgressEvent => {
this.download_loaded = ProgressEvent.loaded
}
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', file.filename);
document.body.appendChild(link);
link.click();
this.download_loaded = 0
this.disabled = false
this.emit_close_dialog()
})
},
},
computed: {
computed_download_status() {
if (this.download_loaded === 0) {
return 'Download'
} else {
return Math.round(this.download_loaded / this.file.filesize * 100) + '%'
}
},
},
}
const component_file = {
props: ['file'],
emits: ['play_audio'],
template: `
{{ file.filename }} |
{{ file.foldername }} |
{{ computed_readable_size }} |
|
`,
data() {
return {
download_loaded: 0,
disabled: false,
show_dialog: false,
}
},
methods: {
show_folder() {
this.$router.push({
path: '/search_folders',
query: {
folder_id: this.file.folder_id,
foldername: this.file.foldername,
}
})
},
close_dialog() {
this.show_dialog = false
},
dialog() {
this.show_dialog = this.show_dialog ? false : true
},
},
computed: {
computed_readable_size() {
let filesize = this.file.filesize
if (filesize < 1024) {
return filesize
}
if (filesize < 1024 * 1024) {
return Math.round(filesize / 1024) + 'K'
}
if (filesize < 1024 * 1024 * 1024) {
return Math.round(filesize / 1024 / 1024) + 'M'
}
if (filesize < 1024 * 1024 * 1024 * 1024) {
return Math.round(filesize / 1024 / 1024 / 1024) + 'G'
}
},
},
}
const component_audio_player = {
data() {
return {
loop: true,
ffmpeg_config: {},
}
},
props: ["file"],
template: `
`,
methods: {
set_ffmpeg_config(ffmpeg_config) {
this.ffmpeg_config = ffmpeg_config
},
},
computed: {
computed_playing_audio_file_url() {
if (this.file.play_back_type === 'raw') {
return '/api/v1/get_file_direct?id=' + this.file.id
} else if (this.file.play_back_type === 'stream') {
return '/api/v1/get_file_stream?id=' + this.file.id + '&config=' + this.ffmpeg_config.name
}
},
computed_show() {
return this.file.id ? true : false
},
},
}
const component_search_files = {
emits: ['play_audio'],
template: `
`,
data() {
return {
search_filenames: '',
files: [],
offset: 0,
limit: 10,
playing_audio_file: {},
}
},
methods: {
first_search_files() {
this.offset = 0
this.search_files()
},
search_files() {
axios.post('/api/v1/search_files', {
filename: this.search_filenames,
limit: this.limit,
offset: this.offset,
}).then((response) => {
this.files = response.data.files
})
},
last_page() {
this.offset = this.offset - this.limit
if (this.offset < 0) {
this.offset = 0
return
}
this.search_files()
},
next_page() {
this.offset = this.offset + this.limit
this.search_files()
},
},
}
const component_get_random_files = {
emits: ['play_audio', 'set_token'],
data() {
return {
files: [],
}
},
template: `
| Filename |
Folder Name |
Size |
Action |
`,
mounted() {
this.get_random_files()
},
methods: {
get_random_files() {
axios.get('/api/v1/get_random_files'
).then(response => {
this.files = response.data.files;
})
}
},
}
const component_stream_config = {
emits: ['set_ffmpeg_config'],
data() {
return {
ffmpeg_config_list: [],
selected_ffmpeg_config: {},
}
},
template: `
`,
mounted() {
axios.get('/api/v1/get_ffmpeg_config_list',
).then(response => {
var ffmpeg_configs = response.data.ffmpeg_configs
var tmp_list = []
for (var key in ffmpeg_configs) {
tmp_list.push(ffmpeg_configs[key])
}
tmp_list.sort()
this.ffmpeg_config_list = tmp_list
this.selected_ffmpeg_config = this.ffmpeg_config_list[0]
}).catch(err => {
this.ffmpeg_config_list = [{name: 'No avaliable config'}]
this.selected_ffmpeg_config = this.ffmpeg_config_list[0]
})
},
watch: {
selected_ffmpeg_config(n, o) {
this.$emit('set_ffmpeg_config', this.selected_ffmpeg_config)
},
},
}
const routes = [
{ path: '/', component: component_get_random_files},
{ path: '/search_files', component: component_search_files},
{ path: '/search_folders', component: component_search_folders},
{ path: '/manage', component: component_manage},
]
const router = VueRouter.createRouter({
history: VueRouter.createWebHashHistory(),
routes,
})
const app = Vue.createApp({
data() {
return {
playing_audio_file: {},
token: "default token",
}
},
methods: {
set_token(token) {
this.token = token
},
play_audio(file) {
console.log(file)
this.playing_audio_file = file
},
},
})
app.component('component-search-folders', component_search_folders)
app.component('component-manage', component_manage)
app.component('component-file', component_file)
app.component('component-audio-player', component_audio_player)
app.component('component-search-files', component_search_files)
app.component('component-get-random-files', component_get_random_files)
app.component('component-file-dialog', component_file_dialog)
app.component('component-token', component_token)
app.component('component-stream-config', component_stream_config)
app.component('component-manage-database', component_manage_database)
app.use(router)
app.mount('#app')