Changes new file upload target to "new document".
This commit is contained in:
parent
caa63fdc71
commit
07c8758182
6 changed files with 131 additions and 73 deletions
|
@ -95,3 +95,8 @@ enum class State(val code: Int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tuple for internal and external ID.
|
||||||
|
*/
|
||||||
|
data class IdPair(val id: Long, val extId: ExtId)
|
|
@ -10,8 +10,6 @@ import java.time.format.FormatStyle
|
||||||
|
|
||||||
class LimboController(val modifiers: TemplateModifiers, val repository: SqliteRepository) {
|
class LimboController(val modifiers: TemplateModifiers, val repository: SqliteRepository) {
|
||||||
|
|
||||||
private val dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT)
|
|
||||||
|
|
||||||
fun formLimbo(ctx: Context) {
|
fun formLimbo(ctx: Context) {
|
||||||
val session = ctx.requireSession()
|
val session = ctx.requireSession()
|
||||||
|
|
||||||
|
|
|
@ -12,24 +12,45 @@ class UploadController(val modifiers: TemplateModifiers, val repository: SqliteR
|
||||||
|
|
||||||
val accountid = session.id
|
val accountid = session.id
|
||||||
|
|
||||||
|
val target = ctx.queryParam("target")
|
||||||
|
|
||||||
val files = ctx.uploadedFiles()
|
val files = ctx.uploadedFiles()
|
||||||
|
|
||||||
files.forEach {
|
when (target) {
|
||||||
println("filename: " + it.filename())
|
"document" -> {
|
||||||
println("ext: " + it.extension())
|
val extIds = files.map {
|
||||||
println("contentType: " + it.contentType()) // mime
|
it.contentAndClose { content ->
|
||||||
println("size: " + it.size())
|
repository.addFileToLimbo(accountid, it.filename(), it.contentType(), it.size(), content).extId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.status(200)
|
||||||
|
ctx.json(
|
||||||
|
Result(
|
||||||
|
files = files.size,
|
||||||
|
redirect = "/document/new?${extIds.joinToString("&") { "file_id=$it" }}"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
it.contentAndClose { content ->
|
"limbo" -> {
|
||||||
repository.addFileToLimbo(accountid, it.filename(), it.contentType(), it.size(), content)
|
files.forEach {
|
||||||
|
it.contentAndClose { content ->
|
||||||
|
repository.addFileToLimbo(accountid, it.filename(), it.contentType(), it.size(), content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.status(200)
|
||||||
|
ctx.json(
|
||||||
|
Result(
|
||||||
|
files = files.size,
|
||||||
|
redirect = "/limbo"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.status(200)
|
|
||||||
ctx.json(Result(files = files.size))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Result(
|
data class Result(
|
||||||
val files: Int
|
val files: Int,
|
||||||
|
val redirect: String
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,16 +69,52 @@ class SqliteRepository(url: String) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addFileToLimbo(accountId: Long, filename: String, contentType: String?, size: Long, content: InputStream) {
|
fun addFileToLimbo(
|
||||||
database.databaseQueries.insertFileIntoLimbo(
|
accountId: Long,
|
||||||
account_id = accountId,
|
filename: String,
|
||||||
ext_id = ExtId.generate(),
|
contentType: String?,
|
||||||
filename = filename,
|
size: Long,
|
||||||
content_type = contentType,
|
content: InputStream
|
||||||
file_size = size,
|
): IdPair =
|
||||||
content = content.readAllBytes()
|
database.databaseQueries.transactionWithResult {
|
||||||
)
|
val extId = ExtId.generate()
|
||||||
}
|
database.databaseQueries.insertFileIntoLimbo(
|
||||||
|
account_id = accountId,
|
||||||
|
ext_id = extId,
|
||||||
|
filename = filename,
|
||||||
|
content_type = contentType,
|
||||||
|
file_size = size,
|
||||||
|
content = content.readAllBytes()
|
||||||
|
)
|
||||||
|
IdPair(
|
||||||
|
id = lastInsertedId(),
|
||||||
|
extId = extId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun addNewFileToDocument(
|
||||||
|
accountId: Long,
|
||||||
|
documentId: Long,
|
||||||
|
filename: String,
|
||||||
|
contentType: String?,
|
||||||
|
size: Long,
|
||||||
|
content: InputStream
|
||||||
|
) =
|
||||||
|
database.databaseQueries.transactionWithResult {
|
||||||
|
ExtId.generate().let { extId ->
|
||||||
|
database.databaseQueries.insertFileForDocument(
|
||||||
|
account_id = accountId,
|
||||||
|
document_id = documentId,
|
||||||
|
ext_id = extId,
|
||||||
|
filename = filename,
|
||||||
|
content_type = contentType,
|
||||||
|
file_size = size,
|
||||||
|
content = content.readAllBytes()
|
||||||
|
)
|
||||||
|
IdPair(id = lastInsertedId(), extId = extId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getLimboFileCount(accountId: Long, state: State = State.ACTIVE): Long {
|
fun getLimboFileCount(accountId: Long, state: State = State.ACTIVE): Long {
|
||||||
return database.databaseQueries.getLimboFileCount(account_id = accountId, state = state)
|
return database.databaseQueries.getLimboFileCount(account_id = accountId, state = state)
|
||||||
|
@ -273,4 +309,6 @@ class SqliteRepository(url: String) {
|
||||||
fun setFileState(accountId: Long, extId: ExtId, state: State) {
|
fun setFileState(accountId: Long, extId: ExtId, state: State) {
|
||||||
database.databaseQueries.setFileState(account_id = accountId, ext_id = extId, state = state)
|
database.databaseQueries.setFileState(account_id = accountId, ext_id = extId, state = state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun lastInsertedId() = database.databaseQueries.getLastInsertRowId().executeAsOne()
|
||||||
}
|
}
|
|
@ -60,6 +60,9 @@ CREATE INDEX file_state_IDX ON file (state);
|
||||||
CREATE UNIQUE INDEX file_ext_id_IDX ON file (ext_id);
|
CREATE UNIQUE INDEX file_ext_id_IDX ON file (ext_id);
|
||||||
|
|
||||||
---
|
---
|
||||||
|
insertFileForDocument:
|
||||||
|
INSERT INTO file (account_id, document_id, ext_id, filename, content_type, file_size, content) VALUES (?, ?,?,?,?,?,?);
|
||||||
|
|
||||||
insertFileIntoLimbo:
|
insertFileIntoLimbo:
|
||||||
INSERT INTO file (account_id, ext_id, filename, content_type, file_size, content) VALUES (?,?,?,?,?,?);
|
INSERT INTO file (account_id, ext_id, filename, content_type, file_size, content) VALUES (?,?,?,?,?,?);
|
||||||
|
|
||||||
|
|
|
@ -1,73 +1,66 @@
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
console.log("filemure ready")
|
|
||||||
const dropzone = document.querySelector('html');
|
const dropzone = document.querySelector('html');
|
||||||
|
|
||||||
let progressDialog = document.querySelector('#upload_progress_dialog')
|
let progressDialog = document.querySelector('#upload_progress_dialog')
|
||||||
let progressBar = document.querySelector('#upload_progress')
|
let progressBar = document.querySelector('#upload_progress')
|
||||||
|
|
||||||
// window.addEventListener
|
|
||||||
|
|
||||||
// Prevent default behavior for drag-over and drop
|
|
||||||
dropzone.addEventListener('dragover', (e) => {
|
dropzone.addEventListener('dragover', (e) => {
|
||||||
console.log("over")
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dropzone.classList.add('dragactive');
|
dropzone.classList.add('dragactive');
|
||||||
});
|
});
|
||||||
|
|
||||||
dropzone.addEventListener('dragleave', (e) => {
|
dropzone.addEventListener('dragleave', (e) => {
|
||||||
console.log("out")
|
|
||||||
dropzone.classList.remove('dragactive');
|
dropzone.classList.remove('dragactive');
|
||||||
});
|
});
|
||||||
|
|
||||||
dropzone.addEventListener('drop', (e) => {
|
dropzone.addEventListener('drop', (e) => {
|
||||||
console.log("drop")
|
e.preventDefault();
|
||||||
e.preventDefault();
|
dropzone.classList.remove('dragactive');
|
||||||
dropzone.classList.remove('dragactive');
|
|
||||||
|
|
||||||
// Handle dropped files
|
// Handle dropped files
|
||||||
const files = e.dataTransfer.files;
|
const files = e.dataTransfer.files;
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
console.log('Files dropped:', files);
|
console.log('Files dropped:', files);
|
||||||
|
|
||||||
// Process the files
|
for (const file of files) {
|
||||||
for (const file of files) {
|
// show progress dialog
|
||||||
progressDialog.showModal();
|
// warning: this way the progress dialog is shown for each file individually
|
||||||
console.log('File name:', file.name);
|
progressDialog.showModal();
|
||||||
console.log('File size:', file.size, 'bytes');
|
const formData = new FormData();
|
||||||
console.log('File type:', file.type);
|
formData.append('file', file);
|
||||||
|
|
||||||
const formData = new FormData();
|
const xhr = new XMLHttpRequest();
|
||||||
formData.append('file', file);
|
xhr.upload.addEventListener("progress", (event) => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
// console.log("upload progress:", event.loaded / event.total);
|
||||||
|
progressBar.value = 100.0 * event.loaded / event.total;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xhr.addEventListener("progress", (event) => {
|
||||||
|
if (event.lengthComputable) {
|
||||||
|
// console.log("download progress:", event.loaded / event.total);
|
||||||
|
progressBar.value = event.loaded / event.total;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
xhr.addEventListener("load", (event) => {
|
||||||
|
console.log(xhr.readyState, xhr.status)
|
||||||
|
progressDialog.close();
|
||||||
|
let res = JSON.parse(xhr.response);
|
||||||
|
window.location = res.redirect;
|
||||||
|
});
|
||||||
|
|
||||||
const xhr = new XMLHttpRequest();
|
xhr.addEventListener("error", event => {
|
||||||
xhr.upload.addEventListener("progress", (event) => {
|
progressDialog.close();
|
||||||
if (event.lengthComputable) {
|
alert("An error occurred.")
|
||||||
console.log("upload progress:", event.loaded / event.total);
|
});
|
||||||
progressBar.value = 100.0 * event.loaded / event.total;
|
xhr.addEventListener("abort", event => {
|
||||||
}
|
progressDialog.close();
|
||||||
});
|
alert("Upload has been cancelled.")
|
||||||
xhr.addEventListener("progress", (event) => {
|
});
|
||||||
if (event.lengthComputable) {
|
|
||||||
console.log("download progress:", event.loaded / event.total);
|
|
||||||
progressBar.value = event.loaded / event.total;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
xhr.addEventListener("loadend", () => {
|
|
||||||
console.log(xhr.readyState, xhr.status)
|
|
||||||
progressDialog.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
xhr.open('POST', '/upload', false);
|
xhr.open('POST', '/upload?target=document', false);
|
||||||
xhr.send(formData);
|
xhr.send(formData);
|
||||||
|
}
|
||||||
// fetch('/upload', {
|
|
||||||
// method: 'POST',
|
|
||||||
// body: formData,
|
|
||||||
// })
|
|
||||||
// .then(response => response.json())
|
|
||||||
// .then(data => console.log('Upload successful:', data))
|
|
||||||
// .catch(error => console.error('Upload failed:', error));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
Loading…
Reference in a new issue