mirror of
https://github.com/jiojciojsioe3/a3cjroijsiojiorj.git
synced 2024-12-23 01:36:14 +08:00
Add folder dropping, fix rate limits
- Add folder drag and drop support - Do expodential retrying if rate limited, allowing upload of very large drive folders - Do not import deleted files - Move the upload buttons to their own line - Notify when no TJA files have been found - Add more translations
This commit is contained in:
parent
180ec58adb
commit
5094b0bc70
@ -108,6 +108,14 @@ kbd{
|
||||
.left-buttons .taibtn{
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
.center-buttons{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 1.5em 0;
|
||||
}
|
||||
.center-buttons .taibtn{
|
||||
margin: 0 0.2em;
|
||||
}
|
||||
.diag-txt textarea,
|
||||
.diag-txt iframe{
|
||||
width: 100%;
|
||||
@ -217,7 +225,8 @@ kbd{
|
||||
z-index: 1;
|
||||
}
|
||||
#settings-gamepad,
|
||||
#settings-latency{
|
||||
#settings-latency,
|
||||
#customsongs-error{
|
||||
display: none;
|
||||
}
|
||||
#settings-gamepad .view{
|
||||
@ -289,7 +298,8 @@ kbd{
|
||||
.latency-buttons span:active{
|
||||
background-color: #946013;
|
||||
}
|
||||
.left-buttons .taibtn{
|
||||
.left-buttons .taibtn,
|
||||
.center-buttons .taibtn{
|
||||
z-index: 1;
|
||||
}
|
||||
.accountpass-form,
|
||||
@ -403,3 +413,19 @@ kbd{
|
||||
font-size: 1em;
|
||||
padding: 0.2em;
|
||||
}
|
||||
#customsongs-error .view,
|
||||
#dropzone .view{
|
||||
width: 600px;
|
||||
}
|
||||
#dropzone{
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s;
|
||||
}
|
||||
#dropzone .view-content{
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
#dropzone.dragover{
|
||||
opacity: 1;
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ class RemoteFile{
|
||||
}
|
||||
}
|
||||
class LocalFile{
|
||||
constructor(file){
|
||||
constructor(file, path){
|
||||
this.file = file
|
||||
this.path = file.webkitRelativePath
|
||||
this.path = path || file.webkitRelativePath
|
||||
this.url = this.path
|
||||
this.name = file.name
|
||||
}
|
||||
|
@ -165,7 +165,6 @@ class AutoScore {
|
||||
GetMaxCombo() {
|
||||
var combo = 0;
|
||||
for (var circle of this.circles) {
|
||||
//alert(this.IsCommonCircle(circle));
|
||||
if (this.IsCommonCircle(circle) && (!circle.branch || circle.branch.name === "master")) {
|
||||
combo++;
|
||||
}
|
||||
|
@ -252,8 +252,8 @@ class Controller{
|
||||
}))
|
||||
}
|
||||
if(songObj.lyricsFile){
|
||||
promises.push(songObj.lyricsFile.read().then(event => {
|
||||
songObj.lyricsData = event.target.result
|
||||
promises.push(songObj.lyricsFile.read().then(result => {
|
||||
songObj.lyricsData = result
|
||||
}, () => Promise.resolve()), songObj.lyricsFile.path)
|
||||
}
|
||||
Promise.all(promises).then(resolve)
|
||||
|
@ -6,6 +6,7 @@ class CustomSongs{
|
||||
this.getElement("view-outer").classList.add("touch-enabled")
|
||||
}
|
||||
this.locked = false
|
||||
this.mode = "main"
|
||||
|
||||
var tutorialTitle = this.getElement("view-title")
|
||||
this.setAltText(tutorialTitle, strings.customSongs.title)
|
||||
@ -40,21 +41,55 @@ class CustomSongs{
|
||||
|
||||
this.endButton = this.getElement("view-end-button")
|
||||
this.setAltText(this.endButton, strings.session.cancel)
|
||||
pageEvents.add(this.endButton, ["mousedown", "touchstart"], this.onEnd.bind(this))
|
||||
pageEvents.add(this.endButton, ["mousedown", "touchstart"], event => this.onEnd(event, true))
|
||||
this.items.push(this.endButton)
|
||||
this.selected = this.items.length - 1
|
||||
|
||||
this.loaderDiv = document.createElement("div")
|
||||
this.loaderDiv.innerHTML = assets.pages["loadsong"]
|
||||
var loadingText = this.loaderDiv.querySelector("#loading-text")
|
||||
loadingText.appendChild(document.createTextNode(strings.loading))
|
||||
loadingText.setAttribute("alt", strings.loading)
|
||||
this.setAltText(loadingText, strings.loading)
|
||||
|
||||
if(DataTransferItem.prototype.webkitGetAsEntry){
|
||||
this.dropzone = document.getElementById("dropzone")
|
||||
var dropContent = this.dropzone.getElementsByClassName("view-content")[0]
|
||||
dropContent.innerText = strings.customSongs.dropzone
|
||||
this.dragging = false
|
||||
pageEvents.add(document, "dragover", event => {
|
||||
event.preventDefault()
|
||||
if(!this.locked){
|
||||
event.dataTransfer.dropEffect = "copy"
|
||||
this.dropzone.classList.add("dragover")
|
||||
this.dragging = true
|
||||
}else{
|
||||
event.dataTransfer.dropEffect = "none"
|
||||
}
|
||||
})
|
||||
pageEvents.add(document, "dragleave", () => {
|
||||
this.dropzone.classList.remove("dragover")
|
||||
this.dragging = false
|
||||
})
|
||||
pageEvents.add(document, "drop", this.filesDropped.bind(this))
|
||||
}
|
||||
|
||||
this.errorDiv = document.getElementById("customsongs-error")
|
||||
pageEvents.add(this.errorDiv, ["mousedown", "touchstart"], event => {
|
||||
if(event.target === event.currentTarget){
|
||||
this.hideError()
|
||||
}
|
||||
})
|
||||
var errorTitle = this.errorDiv.getElementsByClassName("view-title")[0]
|
||||
this.setAltText(errorTitle, strings.customSongs.importError)
|
||||
this.errorContent = this.errorDiv.getElementsByClassName("view-content")[0]
|
||||
this.errorEnd = this.errorDiv.getElementsByClassName("view-end-button")[0]
|
||||
this.setAltText(this.errorEnd, strings.tutorial.ok)
|
||||
pageEvents.add(this.errorEnd, ["mousedown", "touchstart"], () => this.hideError(true))
|
||||
|
||||
this.keyboard = new Keyboard({
|
||||
confirm: ["enter", "space", "don_l", "don_r"],
|
||||
previous: ["left", "up", "ka_l"],
|
||||
next: ["right", "down", "ka_r"],
|
||||
back: ["escape"]
|
||||
backEsc: ["escape"]
|
||||
}, this.keyPressed.bind(this))
|
||||
this.gamepad = new Gamepad({
|
||||
confirmPad: ["b", "ls", "rs"],
|
||||
@ -73,9 +108,17 @@ class CustomSongs{
|
||||
element.setAttribute("alt", text)
|
||||
}
|
||||
localFolder(){
|
||||
if(this.locked){
|
||||
if(event){
|
||||
if(event.type === "touchstart"){
|
||||
event.preventDefault()
|
||||
}else if(event.which !== 1){
|
||||
return
|
||||
}
|
||||
}
|
||||
if(this.locked || this.mode !== "main"){
|
||||
return
|
||||
}
|
||||
this.changeSelected(this.linkLocalFolder)
|
||||
this.browse.click()
|
||||
}
|
||||
browseChange(event){
|
||||
@ -83,6 +126,47 @@ class CustomSongs{
|
||||
for(var i = 0; i < event.target.files.length; i++){
|
||||
files.push(new LocalFile(event.target.files[i]))
|
||||
}
|
||||
this.importLocal(files)
|
||||
}
|
||||
filesDropped(event){
|
||||
event.preventDefault()
|
||||
this.dropzone.classList.remove("dragover")
|
||||
this.dragging = false
|
||||
if(this.locked){
|
||||
return
|
||||
}
|
||||
var files = []
|
||||
var walk = (entry, path="") => {
|
||||
return new Promise(resolve => {
|
||||
if(entry.isFile){
|
||||
entry.file(file => {
|
||||
files.push(new LocalFile(file, path + file.name))
|
||||
return resolve()
|
||||
}, resolve)
|
||||
}else if(entry.isDirectory){
|
||||
var dirReader = entry.createReader()
|
||||
dirReader.readEntries(entries => {
|
||||
var dirPromises = []
|
||||
for(var i = 0; i < entries.length; i++){
|
||||
dirPromises.push(walk(entries[i], path + entry.name + "/"))
|
||||
}
|
||||
return Promise.all(dirPromises).then(resolve)
|
||||
}, resolve)
|
||||
}else{
|
||||
return resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
var dropPromises = []
|
||||
for(var i = 0; i < event.dataTransfer.items.length; i++){
|
||||
var entry = event.dataTransfer.items[i].webkitGetAsEntry()
|
||||
if(entry){
|
||||
dropPromises.push(walk(entry))
|
||||
}
|
||||
}
|
||||
Promise.all(dropPromises).then(() => this.importLocal(files))
|
||||
}
|
||||
importLocal(files){
|
||||
if(!files.length){
|
||||
return
|
||||
}
|
||||
@ -94,15 +178,25 @@ class CustomSongs{
|
||||
this.browse.parentNode.reset()
|
||||
this.locked = false
|
||||
this.loading(false)
|
||||
if(e !== "cancel"){
|
||||
if(e === "nosongs"){
|
||||
this.showError(strings.customSongs.noSongs)
|
||||
}else if(e !== "cancel"){
|
||||
return Promise.reject(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
gdriveFolder(){
|
||||
if(this.locked){
|
||||
gdriveFolder(event){
|
||||
if(event){
|
||||
if(event.type === "touchstart"){
|
||||
event.preventDefault()
|
||||
}else if(event.which !== 1){
|
||||
return
|
||||
}
|
||||
}
|
||||
if(this.locked || this.mode !== "main"){
|
||||
return
|
||||
}
|
||||
this.changeSelected(this.linkGdriveFolder)
|
||||
this.locked = true
|
||||
this.loading(true)
|
||||
var importSongs = new ImportSongs(true)
|
||||
@ -117,13 +211,17 @@ class CustomSongs{
|
||||
return gpicker.browse(locked => {
|
||||
this.locked = locked
|
||||
this.loading(locked)
|
||||
}, error => {
|
||||
this.showError(error)
|
||||
})
|
||||
}).then(files => importSongs.load(files))
|
||||
.then(this.songsLoaded.bind(this))
|
||||
.catch(e => {
|
||||
this.locked = false
|
||||
this.loading(false)
|
||||
if(e !== "cancel"){
|
||||
if(e === "nosongs"){
|
||||
this.showError(strings.customSongs.noSongs)
|
||||
}else if(e !== "cancel"){
|
||||
return Promise.reject(e)
|
||||
}
|
||||
})
|
||||
@ -154,32 +252,48 @@ class CustomSongs{
|
||||
return
|
||||
}
|
||||
var selected = this.items[this.selected]
|
||||
if(name === "confirm" || name === "confirmPad"){
|
||||
if(selected === this.endButton){
|
||||
this.onEnd()
|
||||
}else if(name !== "confirmPad"){
|
||||
if(selected === this.linkLocalFolder){
|
||||
assets.sounds["se_don"].play()
|
||||
this.localFolder()
|
||||
}else if(selected === this.linkGdriveFolder){
|
||||
assets.sounds["se_don"].play()
|
||||
this.gdriveFolder()
|
||||
if(this.mode === "main"){
|
||||
if(name === "confirm" || name === "confirmPad"){
|
||||
if(selected === this.endButton){
|
||||
this.onEnd(null, true)
|
||||
}else if(name !== "confirmPad"){
|
||||
if(selected === this.linkLocalFolder){
|
||||
assets.sounds["se_don"].play()
|
||||
this.localFolder()
|
||||
}else if(selected === this.linkGdriveFolder){
|
||||
assets.sounds["se_don"].play()
|
||||
this.gdriveFolder()
|
||||
}
|
||||
}
|
||||
}else if(name === "previous" || name === "next"){
|
||||
selected.classList.remove("selected")
|
||||
this.selected = this.mod(this.items.length, this.selected + (name === "next" ? 1 : -1))
|
||||
this.items[this.selected].classList.add("selected")
|
||||
assets.sounds["se_ka"].play()
|
||||
}else if(name === "back" || name === "backEsc"){
|
||||
if(!this.dragging || name !== "backEsc"){
|
||||
this.onEnd()
|
||||
}
|
||||
}
|
||||
}else if(name === "previous" || name === "next"){
|
||||
}else if(this.mode === "error"){
|
||||
if(name === "confirm" || name === "confirmPad" || name === "back" || name === "backEsc"){
|
||||
this.hideError(name === "confirm" || name === "confirmPad")
|
||||
}
|
||||
}
|
||||
}
|
||||
changeSelected(button){
|
||||
var selected = this.items[this.selected]
|
||||
if(selected !== button){
|
||||
selected.classList.remove("selected")
|
||||
this.selected = this.mod(this.items.length, this.selected + (name === "next" ? 1 : -1))
|
||||
this.selected = this.items.findIndex(item => item === button)
|
||||
this.items[this.selected].classList.add("selected")
|
||||
assets.sounds["se_ka"].play()
|
||||
}else if(name === "back"){
|
||||
this.onEnd()
|
||||
}
|
||||
}
|
||||
mod(length, index){
|
||||
return ((index % length) + length) % length
|
||||
}
|
||||
onEnd(event){
|
||||
if(this.locked){
|
||||
onEnd(event, confirm){
|
||||
if(this.locked || this.mode !== "main"){
|
||||
return
|
||||
}
|
||||
var touched = false
|
||||
@ -190,13 +304,32 @@ class CustomSongs{
|
||||
}else if(event.which !== 1){
|
||||
return
|
||||
}
|
||||
}else{
|
||||
touched = this.touchEnabled
|
||||
}
|
||||
this.clean()
|
||||
assets.sounds["se_don"].play()
|
||||
assets.sounds[confirm ? "se_don" : "se_cancel"].play()
|
||||
setTimeout(() => {
|
||||
new SongSelect("customSongs", false, touched)
|
||||
}, 500)
|
||||
}
|
||||
showError(text){
|
||||
if(this.mode === "error"){
|
||||
return
|
||||
}
|
||||
this.mode = "error"
|
||||
this.errorContent.innerText = text
|
||||
this.errorDiv.style.display = "flex"
|
||||
assets.sounds["se_pause"].play()
|
||||
}
|
||||
hideError(confirm){
|
||||
if(this.mode !== "error"){
|
||||
return
|
||||
}
|
||||
this.mode = "main"
|
||||
this.errorDiv.style.display = ""
|
||||
assets.sounds[confirm ? "se_don" : "se_cancel"].play()
|
||||
}
|
||||
clean(){
|
||||
this.keyboard.clean()
|
||||
this.gamepad.clean()
|
||||
@ -208,11 +341,20 @@ class CustomSongs{
|
||||
pageEvents.remove(this.linkGdriveFolder, ["mousedown", "touchstart"])
|
||||
}
|
||||
pageEvents.remove(this.endButton, ["mousedown", "touchstart"])
|
||||
pageEvents.remove(this.errorDiv, ["mousedown", "touchstart"])
|
||||
pageEvents.remove(this.errorEnd, ["mousedown", "touchstart"])
|
||||
if(DataTransferItem.prototype.webkitGetAsEntry){
|
||||
pageEvents.remove(document, ["dragover", "dragleave", "drop"])
|
||||
delete this.dropzone
|
||||
}
|
||||
delete this.browse
|
||||
delete this.linkLocalFolder
|
||||
delete this.linkGdriveFolder
|
||||
delete this.endButton
|
||||
delete this.items
|
||||
delete this.loaderDiv
|
||||
delete this.errorDiv
|
||||
delete this.errorContent
|
||||
delete this.errorEnd
|
||||
}
|
||||
}
|
||||
|
@ -9,15 +9,17 @@ class Gpicker{
|
||||
this.resolveQueue = []
|
||||
this.queueActive = false
|
||||
}
|
||||
browse(lockedCallback){
|
||||
browse(lockedCallback, errorCallback){
|
||||
return this.loadApi()
|
||||
.then(() => this.getToken(lockedCallback))
|
||||
.then(() => this.getToken(lockedCallback, errorCallback))
|
||||
.then(() => new Promise((resolve, reject) => {
|
||||
this.displayPicker(data => {
|
||||
if(data.action === "picked"){
|
||||
var file = data.docs[0]
|
||||
var folders = []
|
||||
var rateLimit = -1
|
||||
var lastBatch = 0
|
||||
var walk = (files, output=[]) => {
|
||||
var batch = null
|
||||
for(var i = 0; i < files.length; i++){
|
||||
var path = files[i].path ? files[i].path + "/" : ""
|
||||
var list = files[i].list
|
||||
@ -27,14 +29,9 @@ class Gpicker{
|
||||
for(var j = 0; j < list.length; j++){
|
||||
var file = list[j]
|
||||
if(file.mimeType === this.folder){
|
||||
if(!batch){
|
||||
batch = gapi.client.newBatch()
|
||||
}
|
||||
batch.add(gapi.client.drive.files.list({
|
||||
q: "'" + file.id + "' in parents",
|
||||
orderBy: "name_natural"
|
||||
}), {
|
||||
id: path + file.name
|
||||
folders.push({
|
||||
path: path + file.name,
|
||||
id: file.id
|
||||
})
|
||||
}else{
|
||||
output.push(new GdriveFile({
|
||||
@ -45,14 +42,64 @@ class Gpicker{
|
||||
}
|
||||
}
|
||||
}
|
||||
if(batch){
|
||||
return this.queue()
|
||||
.then(() => batch.then(responses => {
|
||||
var files = []
|
||||
for(var path in responses.result){
|
||||
files.push({path: path, list: responses.result[path].result.files})
|
||||
var batchList = []
|
||||
for(var i = 0; i < folders.length && batchList.length < 100; i++){
|
||||
if(!folders[i].listed){
|
||||
folders[i].pos = i
|
||||
folders[i].listed = true
|
||||
batchList.push(folders[i])
|
||||
}
|
||||
}
|
||||
if(batchList.length){
|
||||
var batch = gapi.client.newBatch()
|
||||
batchList.forEach(folder => {
|
||||
var req = {
|
||||
q: "'" + folder.id + "' in parents and trashed = false",
|
||||
orderBy: "name_natural"
|
||||
}
|
||||
if(folder.pageToken){
|
||||
req.pageToken = folder.pageToken
|
||||
}
|
||||
batch.add(gapi.client.drive.files.list(req), {id: folder.pos})
|
||||
})
|
||||
if(lastBatch + batchList.length > 100){
|
||||
var waitPromise = this.sleep(1000)
|
||||
}else{
|
||||
var waitPromise = Promise.resolve()
|
||||
}
|
||||
return waitPromise.then(() => this.queue()).then(() => batch.then(responses => {
|
||||
var files = []
|
||||
var rateLimited = false
|
||||
for(var i in responses.result){
|
||||
var result = responses.result[i].result
|
||||
if(result.error){
|
||||
if(result.error.errors[0].domain !== "usageLimits"){
|
||||
console.warn(result)
|
||||
}else if(!rateLimited){
|
||||
rateLimited = true
|
||||
rateLimit++
|
||||
folders.push({
|
||||
path: folders[i].path,
|
||||
id: folders[i].id,
|
||||
pageToken: folders[i].pageToken
|
||||
})
|
||||
}
|
||||
}else{
|
||||
if(result.nextPageToken){
|
||||
folders.push({
|
||||
path: folders[i].path,
|
||||
id: folders[i].id,
|
||||
pageToken: result.nextPageToken
|
||||
})
|
||||
}
|
||||
files.push({path: folders[i].path, list: result.files})
|
||||
}
|
||||
}
|
||||
if(rateLimited){
|
||||
return this.sleep(Math.pow(2, rateLimit) * 1000).then(() => walk(files, output))
|
||||
}else{
|
||||
return walk(files, output)
|
||||
}
|
||||
return walk(files, output)
|
||||
}))
|
||||
}else{
|
||||
return output
|
||||
@ -84,7 +131,7 @@ class Gpicker{
|
||||
gapi.client.load("drive", "v3").then(resolve, reject)
|
||||
))
|
||||
}
|
||||
getToken(lockedCallback=()=>{}){
|
||||
getToken(lockedCallback=()=>{}, errorCallback=()=>{}){
|
||||
if(this.oauthToken){
|
||||
return Promise.resolve()
|
||||
}
|
||||
@ -97,7 +144,7 @@ class Gpicker{
|
||||
this.auth = gapi.auth2.getAuthInstance()
|
||||
}, e => {
|
||||
if(e.details){
|
||||
alert(strings.gpicker.authError.replace("%s", e.details))
|
||||
errorCallback(strings.gpicker.authError.replace("%s", e.details))
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
@ -132,6 +179,7 @@ class Gpicker{
|
||||
.setDeveloperKey(this.apiKey)
|
||||
.setAppId(this.projectNumber)
|
||||
.setOAuthToken(this.oauthToken)
|
||||
.setLocale(strings.gpicker.locale)
|
||||
.hideTitleBar()
|
||||
.addView(new picker.DocsView("folders")
|
||||
.setLabel(strings.gpicker.myDrive)
|
||||
@ -184,6 +232,9 @@ class Gpicker{
|
||||
})
|
||||
)
|
||||
}
|
||||
sleep(time){
|
||||
return new Promise(resolve => setTimeout(resolve, time))
|
||||
}
|
||||
queue(){
|
||||
return new Promise(resolve => {
|
||||
this.resolveQueue.push(resolve)
|
||||
|
@ -417,10 +417,13 @@
|
||||
}
|
||||
}))
|
||||
image.id = name
|
||||
image.src = URL.createObjectURL(file.blob())
|
||||
promises.push(file.blob().then(blob => {
|
||||
image.src = URL.createObjectURL(blob)
|
||||
}))
|
||||
loader.assetsDiv.appendChild(image)
|
||||
var oldImage = assets.image[id]
|
||||
if(oldImage && oldImage.parentNode){
|
||||
URL.revokeObjectURL(oldImage.src)
|
||||
oldImage.parentNode.removeChild(oldImage)
|
||||
}
|
||||
assets.image[id] = image
|
||||
@ -543,7 +546,7 @@
|
||||
}else if(Object.keys(this.assetFiles).length){
|
||||
return Promise.resolve()
|
||||
}else{
|
||||
return Promise.reject("cancel")
|
||||
return Promise.reject("nosongs")
|
||||
}
|
||||
this.clean()
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ class SongSelect{
|
||||
})
|
||||
}
|
||||
}else if(this.state.locked !== 1 || fromP2){
|
||||
if(this.songs[this.selectedSong].courses && (this.state.locked === 0 || fromP2)){
|
||||
if(this.songs[this.selectedSong].courses && !this.songs[this.selectedSong].unloaded && (this.state.locked === 0 || fromP2)){
|
||||
this.state.moveMS = ms
|
||||
}else{
|
||||
this.state.moveMS = ms - this.songSelecting.speed * this.songSelecting.resize
|
||||
@ -2222,7 +2222,7 @@ class SongSelect{
|
||||
]
|
||||
this.draw.layeredText({
|
||||
ctx: ctx,
|
||||
text: strings.ok,
|
||||
text: strings.tutorial.ok,
|
||||
x: _x,
|
||||
y: _y + 18,
|
||||
width: _w,
|
||||
|
@ -1060,7 +1060,11 @@ var translations = {
|
||||
},
|
||||
customSongs: {
|
||||
title: {
|
||||
ja: "カスタム曲リスト",
|
||||
en: "Custom Song List",
|
||||
cn: "自定义歌曲列表",
|
||||
tw: "自定義歌曲列表",
|
||||
ko: "맞춤 노래 목록"
|
||||
},
|
||||
default: {
|
||||
ja: "デフォルト曲リスト",
|
||||
@ -1075,21 +1079,61 @@ var translations = {
|
||||
]
|
||||
},
|
||||
localFolder: {
|
||||
en: "Local Folder..."
|
||||
ja: "ローカルフォルダ...",
|
||||
en: "Local Folder...",
|
||||
cn: "本地文件夹...",
|
||||
tw: "本地文件夾...",
|
||||
ko: "로컬 폴더..."
|
||||
},
|
||||
gdriveFolder: {
|
||||
en: "Google Drive..."
|
||||
ja: "Google ドライブ...",
|
||||
en: "Google Drive...",
|
||||
cn: "Google云端硬盘...",
|
||||
tw: "Google雲端硬碟...",
|
||||
ko: "구글 드라이브..."
|
||||
},
|
||||
dropzone: {
|
||||
ja: "ここにファイルをドロップ",
|
||||
en: "Drop files here",
|
||||
cn: "将文件拖至此处",
|
||||
tw: "將文件拖至此處",
|
||||
ko: "파일을 여기에 드롭"
|
||||
},
|
||||
importError: {
|
||||
en: "Import Error"
|
||||
},
|
||||
noSongs: {
|
||||
en: "No Taiko chart files have been found in the provided folder."
|
||||
}
|
||||
},
|
||||
gpicker: {
|
||||
locale: {
|
||||
ja: "ja",
|
||||
en: "en-GB",
|
||||
cn: "zh-CN",
|
||||
tw: "zh-TW",
|
||||
ko: "ko"
|
||||
},
|
||||
myDrive: {
|
||||
en: "My Drive"
|
||||
ja: "マイドライブ",
|
||||
en: "My Drive",
|
||||
cn: "我的云端硬盘",
|
||||
tw: "我的雲端硬碟",
|
||||
ko: "내 드라이브"
|
||||
},
|
||||
starred: {
|
||||
en: "Starred"
|
||||
ja: "スター付き",
|
||||
en: "Starred",
|
||||
cn: "已加星标",
|
||||
tw: "已加星號",
|
||||
ko: "중요 문서함"
|
||||
},
|
||||
sharedWithMe: {
|
||||
en: "Shared with me"
|
||||
ja: "共有アイテム",
|
||||
en: "Shared with me",
|
||||
cn: "与我共享",
|
||||
tw: "與我共用",
|
||||
ko: "공유 문서함"
|
||||
},
|
||||
authError: {
|
||||
en: "Auth error: %s"
|
||||
|
@ -175,7 +175,9 @@ class ViewAssets{
|
||||
})
|
||||
}
|
||||
clean(){
|
||||
this.don.clean()
|
||||
if(this.don){
|
||||
this.don.clean()
|
||||
}
|
||||
delete this.ctx
|
||||
delete this.don
|
||||
delete this.fire
|
||||
|
@ -1,12 +1,24 @@
|
||||
<div class="view-outer">
|
||||
<div class="view">
|
||||
<div class="view drag-bg">
|
||||
<div class="view-title stroke-sub"></div>
|
||||
<div class="view-content"></div>
|
||||
<div class="left-buttons">
|
||||
<div class="center-buttons">
|
||||
<div id="link-localfolder" class="taibtn stroke-sub link-btn"></div>
|
||||
<div id="link-gdrivefolder" class="taibtn stroke-sub link-btn"></div>
|
||||
</div>
|
||||
<div class="view-end-button taibtn stroke-sub selected"></div>
|
||||
<div class="view-outer shadow-outer" id="dropzone">
|
||||
<div class="view">
|
||||
<div class="view-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view-outer shadow-outer" id="customsongs-error">
|
||||
<div class="view">
|
||||
<div class="view-title stroke-sub"></div>
|
||||
<div class="view-content"></div>
|
||||
<div class="view-end-button taibtn stroke-sub selected"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form><input id="browse" type="file" webkitdirectory multiple></form>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user