Skip to content

Commit

Permalink
Merge pull request #15 from help-14/dev
Browse files Browse the repository at this point in the history
Refactor code + runt task in background
  • Loading branch information
Nhan Phan authored Mar 22, 2023
2 parents b977845 + b3441ae commit e2ffabe
Show file tree
Hide file tree
Showing 18 changed files with 709 additions and 143 deletions.
113 changes: 113 additions & 0 deletions assets/components/explorer-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
export class ExplorerItem extends HTMLElement {
constructor() {
super()
}

connectedCallback() {
document.addEventListener("alpine:initialized", () => {
Alpine.initTree(this.shadowRoot)
})
this.render()
}

render() {
this.attachShadow({ mode: "open" })

const wrapper = document.createElement("div")
wrapper.setAttribute("class", "col-xl-3 col-sm-6 d-grid mt-2 mb-2")
wrapper.setAttribute('x-transition', '')

const button = wrapper.appendChild(document.createElement("button"))
button.id = 'btn'
button.setAttribute("class", "btn btn-light selectable")
button.setAttribute("type", 'button')
button.addEventListener("dblclick", () => {
if (this.isDirectory())
goto(this.getUrl())
else
preview(this.getUrl())
})
//button.setAttribute("x-on:dblclick", "if(file.directory){goto(file.path)} else {preview(file)}")

const content = button.appendChild(document.createElement("div"))
content.setAttribute("class", "row p-1 d-flex")

const icon = content.appendChild(document.createElement("div"))
icon.id = 'icon'
icon.setAttribute("class", "col-3 align-middle fs-2 align-self-center")
icon.setAttribute("x-text", "$t(directory ? 'files.icons.folder' : 'files.icons.file')")
this.updateDirectory(icon)

const text = content.appendChild(document.createElement("div"))
text.id = 'text'
text.setAttribute("class", "col-8 fs-6 text-start text-wrap text-break align-middle align-self-center")
this.updateText(text)

this.shadowRoot.append(wrapper);
}

attributeChangedCallback(name, oldValue, newValue) {
console.log(name, oldValue, newValue)
return
// switch (name) {
// case "text":
// this.updateText()
// break
// case "directory":
// this.updateDirectory()
// break
// case "selected":
// this.updateSelected()
// break
// case "url":
// break
// }
}

getText() {
return this.getAttribute('text')
}

setText(val) {
this.setAttribute('text', val)
}

updateText(element) {
(element ?? document.querySelector('#text')).innerHTML = this.getText()
}

getUrl() {
return this.getAttribute('url')
}

isDirectory() {
return this.getAttribute('directory') === 'true'
}

setDirectory(val) {
this.setAttribute('directory', val)
}

updateDirectory(element) {
(element ?? document.querySelector('#icon')).innerHTML = AlpineI18n.t(this.isDirectory() ? 'files.icons.folder' : 'files.icons.file')
}

isSelected() {
return this.getAttribute('selected') === 'true'
}

setSelected(val) {
this.setAttribute('selected', val)
}

updateSelected(element) {
const button = element ?? this.querySelector('#btn')
if (this.isSelected()) {
button.classList.remove('btn-light')
button.classList.add('btn-primary')
} else {
button.classList.add('btn-light')
button.classList.remove('btn-primary')
}
}
}
6 changes: 6 additions & 0 deletions assets/components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

import { ExplorerItem } from "./explorer-item.js";

export function InitComponents() {
customElements.define("explorer-item", ExplorerItem);
}
61 changes: 61 additions & 0 deletions assets/css/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,65 @@
body {
opacity: 0;
transition: opacity 0.2s;
}

.jiggle {
animation: jiggling 0.3s infinite ease-in;
animation-direction: alternate;
}

@keyframes jiggling {
from {
transform: rotate(0deg);
}

to {
transform: rotate(30deg);
}
}

/* Indicator */

.lds-facebook {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}

.lds-facebook div {
display: inline-block;
position: absolute;
left: 8px;
width: 16px;
background: #fff;
animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
}

.lds-facebook div:nth-child(1) {
left: 8px;
animation-delay: -0.24s;
}

.lds-facebook div:nth-child(2) {
left: 32px;
animation-delay: -0.12s;
}

.lds-facebook div:nth-child(3) {
left: 56px;
animation-delay: 0;
}

@keyframes lds-facebook {
0% {
top: 8px;
height: 64px;
}

50%,
100% {
top: 24px;
height: 32px;
}
}
17 changes: 3 additions & 14 deletions assets/js/mountain/alpine.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ function startInstance() {
return {
files: [],
breadcrumbs: [],
tasks: [],
path: '',
emptyFolder: false,
opsToolbar: false,
Expand All @@ -14,19 +15,7 @@ function startInstance() {
getStartUrl, goto, modalGoTo, showOps, select, clickMode,
download, upload, modalOpened, generateCompressName, preview,
showSearch, showDeleteModal, showRenameModal, showOpsModal,
createFolder, createFile, deleteSelected, renameSelected, copyOrMove, compressSelected
createFolder, createFile, deleteSelected, renameSelected, copyOrMove, compressSelected,
showTasks
}
}

// AlpineJS i18n
document.addEventListener('alpine-i18n:ready', async function () {
const en = await get('/assets/languages/en.json')
let selected = document.querySelector('#language')?.value
if (!selected || selected.length !== 2) {
window.AlpineI18n.create('en', en);
} else {
const choosen = await get(`/assets/languages/${selected}.json`)
window.AlpineI18n.create(selected, { ...en, ...choosen });
window.AlpineI18n.fallbackLocale = 'en';
}
});
40 changes: 16 additions & 24 deletions assets/js/mountain/explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function goto(path) {
ds.removeSelectables(ds.getSelectables(), true)
ds.stop()
}
get(`/api/get?path=${utf8_to_b64(path)}`)
doGetFilesFromPath(path)
.then(data => {
this.emptyFolder = data.length === 0
this.files = sort(data.map(a => {
Expand Down Expand Up @@ -188,17 +188,12 @@ function createFile() {
if (!newFileName || !newFileContent) return

if (newFileName.value.trim().length <= 0) {
showToast($AlpineI18n.t('toast.error.fileNameEmpty'))
showToast(AlpineI18n.t('toast.error.fileNameEmpty'))
return
}

enabled('#newFileModal button[type="submit"]', false)
post(`/api/create`, {
path: this.path,
name: newFileName.value.trim(),
directory: false,
content: newFileContent.value.trim()
})
doCreateFile(this.path, newFileName.value.trim(), newFileContent.value.trim())
.then(data => {
this.goto(currentPath)
newFileName.value = ''
Expand All @@ -213,17 +208,12 @@ function createFolder() {
if (!newFolderInput) return
const text = newFolderInput.value
if (text.length <= 0) {
showToast($AlpineI18n.t('toast.error.folderNameEmpty'))
showToast(AlpineI18n.t('toast.error.folderNameEmpty'))
return
}

enabled('#newFolderModal button[type="submit"]', false)
post(`/api/create`, {
path: this.path,
name: text,
directory: true,
content: ''
})
doCreateFolder(this.path, text)
.then(data => {
this.goto(currentPath)
newFolderInput.value = ''
Expand All @@ -235,7 +225,7 @@ function createFolder() {
async function deleteSelected() {
const selected = this.files.filter(f => f.selected).map(f => f.path)
hideModal()
await post(`/api/delete`, selected)
await doDeleteFiles(selected)
this.goto(currentPath)
}

Expand All @@ -253,7 +243,7 @@ function renameSelected() {
})

enabled('#renameModal button[type="submit"]', false)
post(`/api/rename`, data)
doRenameFiles(data)
.then(data => {
this.goto(currentPath)
hideModal()
Expand All @@ -267,12 +257,10 @@ function compressSelected() {
return
const name = document.querySelector('#compressFileName')?.value ?? new Date().getTime()
const type = document.querySelector('#compressTypeSelect')?.value ?? 'zip'
post(`/api/compress`, {
name,
path: this.path,
type: type,
files: selected.map(f => f.path)
}).then(() => this.goto(this.path)).finally(() => hideModal())

doCompressFiles(name, this.path, type, selected.map(f => f.path))
.then(() => this.goto(this.path))
.finally(() => hideModal())
}

function copyOrMove(ops) {
Expand All @@ -290,7 +278,11 @@ function copyOrMove(ops) {
})

enabled('#destinationModal button[type="submit"]', false)
post(`/api/${ops}`, data)
(ops === 'copy'
? doCopyFiles(data)
: ops === 'move'
? doMoveFiles(data)
: {})
.then(data => {
this.goto(currentPath)
hideModal()
Expand Down
39 changes: 21 additions & 18 deletions assets/js/mountain/modals.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,23 @@ function updateUploadToast() {
}

function modalGoTo(path = '/') {
get(`/api/get?directory=true&path=${utf8_to_b64(path)}`)
.then(data => {
this.modalSelectFolder.files = sort(data, this.config.sort)
this.modalSelectFolder.path = path

let breadcrumbs = []
let splitted = path.split('/')
for (let i = 1; i < splitted.length; i++) {
const name = splitted[i]
if (name.length === 0) continue

breadcrumbs.push({
name: splitted[i],
path: splitted.slice(0, i + 1).join('/')
})
}
this.modalSelectFolder.breadcrumbs = breadcrumbs
})
goGetDirectoriesFromPath(path).then(data => {
this.modalSelectFolder.files = sort(data, this.config.sort)
this.modalSelectFolder.path = path

let breadcrumbs = []
let splitted = path.split('/')
for (let i = 1; i < splitted.length; i++) {
const name = splitted[i]
if (name.length === 0) continue

breadcrumbs.push({
name: splitted[i],
path: splitted.slice(0, i + 1).join('/')
})
}
this.modalSelectFolder.breadcrumbs = breadcrumbs
})
}

function preview(file) {
Expand Down Expand Up @@ -151,4 +150,8 @@ function showOpsModal(ops) {
function showSearch() {
if (!modalOpened())
document.querySelector('#searchBox')?.focus()
}

function showTasks() {
doGetIoTasks().then(data => { this.tasks = data })
}
Loading

0 comments on commit e2ffabe

Please sign in to comment.