mirror of
https://github.com/pldubouilh/gossa
synced 2025-12-06 08:22:32 +01:00
keybinding move elements
This commit is contained in:
parent
bb44f2d852
commit
55678337b9
3 changed files with 56 additions and 36 deletions
45
Makefile
45
Makefile
|
|
@ -3,6 +3,28 @@ build:
|
|||
go build gossa.go
|
||||
rm gossa.go
|
||||
|
||||
embed:
|
||||
echo "embedding css and js into binary"
|
||||
cp main.go gossa.go
|
||||
perl -pe 's/css_will_be_here/`cat style.css`/ge' -i gossa.go
|
||||
perl -pe 's/js_will_be_here/`cat script.js`/ge' -i gossa.go
|
||||
|
||||
run:
|
||||
make build
|
||||
./gossa fixture
|
||||
|
||||
ci:
|
||||
go fmt
|
||||
go vet
|
||||
timeout 5 make run &
|
||||
sleep 1 && go test
|
||||
|
||||
ci-watch:
|
||||
ls main.go script.js main_test.go | entr -rc make ci
|
||||
|
||||
watch:
|
||||
ls main.go script.js | entr -rc make run
|
||||
|
||||
build-all:
|
||||
make embed
|
||||
env GOOS=linux GOARCH=amd64 go build gossa.go
|
||||
|
|
@ -25,26 +47,3 @@ clean:
|
|||
-rm gossa-linux-arm64
|
||||
-rm gossa-mac
|
||||
-rm gossa-windows.exe
|
||||
|
||||
embed:
|
||||
echo "embedding css and js into binary"
|
||||
cp main.go gossa.go
|
||||
perl -pe 's/css_will_be_here/`cat style.css`/ge' -i gossa.go
|
||||
perl -pe 's/js_will_be_here/`cat script.js`/ge' -i gossa.go
|
||||
|
||||
ci:
|
||||
go fmt
|
||||
go vet
|
||||
timeout 5 go run main.go fixture &
|
||||
sleep 1 && go test
|
||||
|
||||
ci-watch:
|
||||
ls main.go script.js main_test.go | entr -rc make ci
|
||||
|
||||
watch:
|
||||
ls main.go script.js | entr -rc make run
|
||||
|
||||
run:
|
||||
make embed
|
||||
go run gossa.go fixture
|
||||
rm gossa.go
|
||||
|
|
|
|||
11
readme.md
11
readme.md
|
|
@ -8,19 +8,20 @@ gossa
|
|||
🎶 A fast and simple webserver for your files. It's dependency-free and with under 250 lines for the server code, easily code-reviewable.
|
||||
|
||||
### features
|
||||
* upload files and folders with drag-and-drop
|
||||
* browse throughout files/directories
|
||||
* upload files and folders with drag-and-drop
|
||||
* create new folders
|
||||
* move files to different directories with drag-and-drop and keyboard
|
||||
* browse throughout pictures with a full-screen carousel
|
||||
* simple keyboard navigation/shortcuts
|
||||
* fast ; fills my 80MB/s AC wifi link
|
||||
|
||||
### run
|
||||
```sh
|
||||
# run
|
||||
go run main.go fixture
|
||||
# run on test fixture folder
|
||||
make run
|
||||
|
||||
# build embedding the js/css in the binary
|
||||
# build
|
||||
make
|
||||
./gossa --help
|
||||
|
||||
|
|
@ -32,6 +33,8 @@ make ci
|
|||
* Arrows/Enter browse throughout the files/directories and pictures
|
||||
* Ctrl/Meta + C copy selected path to clipboard
|
||||
* Ctrl/Meta + D create a new directory
|
||||
* Ctrl/Meta + X cut selected path
|
||||
* Ctrl/Meta + V paste paths previously selected with the above shortcut to directory
|
||||
* \<any letter\> search on first letters in filename
|
||||
|
||||
### built blobs
|
||||
|
|
|
|||
36
script.js
36
script.js
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-env browser */
|
||||
/* global allA */
|
||||
/* eslint-disable no-multi-str */
|
||||
|
||||
function cancelDefault (e) {
|
||||
|
|
@ -9,10 +8,6 @@ function cancelDefault (e) {
|
|||
|
||||
// RPC
|
||||
function rpcFs (call, args, cb) {
|
||||
// Prefix path with pwd if not absolute
|
||||
const decodedPath = decodeURI(location.pathname)
|
||||
args = args.map(a => a.startsWith('/') ? a : decodedPath + a)
|
||||
|
||||
console.log('RPC', call, args)
|
||||
const xhr = new window.XMLHttpRequest()
|
||||
xhr.open('POST', location.origin + '/rpc')
|
||||
|
|
@ -21,8 +16,10 @@ function rpcFs (call, args, cb) {
|
|||
xhr.onload = cb
|
||||
}
|
||||
|
||||
const prependPath = (a) => a.startsWith('/') ? a : decodeURI(location.pathname) + a
|
||||
|
||||
// RPC Handlers
|
||||
const mkdirCall = (path, cb) => rpcFs('mkdirp', [path], cb)
|
||||
const mkdirCall = (path, cb) => rpcFs('mkdirp', [prependPath(path)], cb)
|
||||
|
||||
const mvCall = (path1, path2, cb) => rpcFs('mv', [path1, path2], cb)
|
||||
|
||||
|
|
@ -178,9 +175,9 @@ document.ondrop = (e) => {
|
|||
const t = e.target.classList.contains('fav') ? e.target : getLink(e)
|
||||
if (!t || !t.innerText.endsWith('/')) return
|
||||
e.dataTransfer.items[0].getAsString(s => {
|
||||
const root = decodeURI(s.replace(location.href, ''))
|
||||
const root = decodeURIComponent(s.replace(location.href, ''))
|
||||
const dest = t.innerText + root
|
||||
mvCall(root, dest, refresh)
|
||||
mvCall(prependPath(root), prependPath(dest), refresh)
|
||||
})
|
||||
} else {
|
||||
Array.from(e.dataTransfer.items).forEach(pushEntry)
|
||||
|
|
@ -360,6 +357,18 @@ function setCursorToClosestTyped () {
|
|||
restoreCursorPos()
|
||||
}
|
||||
|
||||
let cuts = []
|
||||
|
||||
function onPaste () {
|
||||
if (!cuts.length) { return refresh() }
|
||||
const root = cuts.pop()
|
||||
const pwd = decodeURIComponent(location.pathname)
|
||||
const isFolderDest = getASelected().innerText.endsWith('/')
|
||||
const filename = root.split('/').pop()
|
||||
const dest = isFolderDest ? pwd + getASelected().innerText : pwd
|
||||
mvCall(root, dest + filename, onPaste)
|
||||
}
|
||||
|
||||
// Kb handler
|
||||
document.body.addEventListener('keydown', e => {
|
||||
switch (e.code) {
|
||||
|
|
@ -373,7 +382,6 @@ document.body.addEventListener('keydown', e => {
|
|||
return picsNav(false) || moveArrow(false)
|
||||
|
||||
case 'Enter':
|
||||
case 'Space':
|
||||
case 'ArrowRight':
|
||||
e.preventDefault()
|
||||
return picsOn(true) || picsNav(true) || getASelected().click()
|
||||
|
|
@ -399,6 +407,16 @@ document.body.addEventListener('keydown', e => {
|
|||
case 'KeyC':
|
||||
e.preventDefault()
|
||||
return isPicMode() || cpPath()
|
||||
|
||||
case 'KeyX':
|
||||
e.preventDefault()
|
||||
const x = decodeURIComponent(getASelected().href).replace(location.origin, '')
|
||||
cuts.push(prependPath(x))
|
||||
return false
|
||||
|
||||
case 'KeyV':
|
||||
e.preventDefault()
|
||||
return onPaste()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue