Compare commits
8 Commits
4382b57e9e
...
70a163c4aa
Author | SHA1 | Date | |
---|---|---|---|
70a163c4aa | |||
71dc0c519b | |||
00750280df | |||
1e93568f9b | |||
ccc24b93ad | |||
b496ce2ab2 | |||
313be711a9 | |||
bea6859457 |
@ -3,7 +3,9 @@ package finder
|
||||
import (
|
||||
"net/http"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -34,6 +36,78 @@ func (f *FinderApplication) Render(isMobile bool) gin.H {
|
||||
return gin.H{}
|
||||
}
|
||||
|
||||
func (f *FinderApplication) RenderContextMenu(context string, data string) gin.H {
|
||||
islands := [][]wde.ContexMenuRow{} //FIXME
|
||||
switch context {
|
||||
case "FileTileView":
|
||||
islands = [][]wde.ContexMenuRow{
|
||||
{
|
||||
{
|
||||
Label: "Get Info",
|
||||
Action: strings.Join([]string{"getInfo"}[:], ","),
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
Label: "New Directory",
|
||||
Action: strings.Join([]string{"newDir"}[:], ","),
|
||||
},
|
||||
},
|
||||
}
|
||||
case "directory":
|
||||
islands = [][]wde.ContexMenuRow{
|
||||
{
|
||||
{
|
||||
Label: "Test",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
{
|
||||
Label: "Delete",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
Label: "Get Info",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
islands = [][]wde.ContexMenuRow{
|
||||
{
|
||||
{
|
||||
Label: "temp Menu 1",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
{
|
||||
Label: "temp Menu 2",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
{
|
||||
Label: "temp Menu 3",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
{
|
||||
Label: "temp Menu 4",
|
||||
Action: strings.Join([]string{""}[:], ","),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
islands = append(islands, []wde.ContexMenuRow{
|
||||
{
|
||||
Label: "Delete File",
|
||||
Action: strings.Join([]string{"deleteFile"}[:], ";"),
|
||||
},
|
||||
})
|
||||
|
||||
return gin.H{
|
||||
"Islands": islands,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
||||
routes.GET("render", func(ctx *gin.Context) {
|
||||
isMobileParam := ctx.Query("isMobile")
|
||||
@ -61,7 +135,11 @@ func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
||||
}
|
||||
ctx.HTML(http.StatusOK, "finder/desktop.tmpl", gin.H{})
|
||||
})
|
||||
|
||||
routes.GET("contextMenu", func(ctx *gin.Context) {
|
||||
ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", gin.H{})
|
||||
context := ctx.Query("context")
|
||||
data := ctx.Query("data")
|
||||
ginH := f.RenderContextMenu(context, data)
|
||||
ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", ginH)
|
||||
})
|
||||
}
|
||||
|
32
main.go
32
main.go
@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -82,37 +81,6 @@ func main() {
|
||||
appsStorage.Apps["img-viewer"] = &imgViewerApp
|
||||
appsStorage.Apps["blog-viewer"] = blogViewerApp
|
||||
|
||||
router.POST("/upload", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
return
|
||||
}
|
||||
// single file
|
||||
file, _ := ctx.FormFile("file")
|
||||
if file == nil {
|
||||
ctx.String(http.StatusBadRequest, "file is nil")
|
||||
}
|
||||
// generateMins := c.Param("generateMins")
|
||||
// log.Println(file.Filename)
|
||||
|
||||
// Upload the file to specific dst.
|
||||
dst := "./test-img/" + file.Filename
|
||||
ctx.SaveUploadedFile(file, dst)
|
||||
|
||||
err := webfs.UploadFile(dst, path)
|
||||
if err != nil {
|
||||
ctx.String(http.StatusInternalServerError, "TODO") //TODO
|
||||
return
|
||||
}
|
||||
|
||||
// webFsCollection.CreateMiniatures("./test-img/", file.Filename)
|
||||
|
||||
// webfs.CreateFile(&img, "/home/user/")
|
||||
|
||||
ctx.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
|
||||
})
|
||||
|
||||
system := router.Group("system")
|
||||
{
|
||||
libsGroup := system.Group("libs")
|
||||
|
@ -31,7 +31,9 @@ class Finder{
|
||||
|
||||
this.fileView = new FileView(newWindow.querySelector(".FileTileView"),
|
||||
(event) =>{ this.Open(event, false) },
|
||||
(event) =>{ this.RightClick(event) })
|
||||
(event) =>{ this.RightClick(event) },
|
||||
(event) =>{ this.FileUploading(event) },
|
||||
)
|
||||
this.OpenDir(this.path)
|
||||
|
||||
newWindow.querySelector("#BackButton").addEventListener('click', () =>{
|
||||
@ -47,6 +49,7 @@ class Finder{
|
||||
if (!WebDesktopEnvironment.isMobile){
|
||||
// let scrollBar = new WdeScrollBar(newWindow.children[1].children[1], newWindow.children[1].children[0])// TODO to querry selector
|
||||
// console.log(newWindow.querySelector("#closeWindowButton"))
|
||||
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
@ -59,6 +62,32 @@ class Finder{
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DataTransferItemList} filesList
|
||||
*/
|
||||
|
||||
FileUploading(filesList){
|
||||
let formData = new FormData()
|
||||
// console.log(filesList)
|
||||
for (let i = 0; i < filesList.length; i++) {
|
||||
const element = filesList[i];
|
||||
formData.append("file", element.getAsFile())
|
||||
console.log(formData)
|
||||
}
|
||||
// console.log(formData)
|
||||
// formData.append("photo", photo);
|
||||
fetch('/fs/upload/?' + new URLSearchParams({
|
||||
path: '/home/user/',
|
||||
}),
|
||||
{
|
||||
method: "POST",
|
||||
body: formData
|
||||
})
|
||||
.catch((error) => {
|
||||
WebDesktopEnvironment.Alert(error);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
*/
|
||||
@ -128,6 +157,17 @@ class Finder{
|
||||
case "blog-page":
|
||||
WebDesktopEnvironment.Open("blog-viewer", [this.path + "/" + fileName])
|
||||
break
|
||||
case "deleteFile":
|
||||
fetch(`/fs/delete` + new URLSearchParams({
|
||||
path: "/home/user/" + fileName //FIXME
|
||||
}))
|
||||
.then((response) => {
|
||||
console.log(response.status)
|
||||
})
|
||||
.catch((error) => {
|
||||
WebDesktopEnvironment.Alert(error);
|
||||
})
|
||||
break
|
||||
// case "app":
|
||||
// //TODO get real id
|
||||
// WebDesktopEnvironment.Open("personal-properties", [])
|
||||
@ -143,16 +183,19 @@ class Finder{
|
||||
}
|
||||
|
||||
RightClick(event){
|
||||
// console.log(event)
|
||||
// console.log()
|
||||
if (event.target.className="FileTileView" ||event.target.getAttribute('filetype') != ""){
|
||||
this.CreateContextMenu(event.target, [event.clientY, event.clientX])
|
||||
}
|
||||
this.CreateContextMenu(event.target, [event.clientY, event.clientX])
|
||||
}
|
||||
|
||||
CreateContextMenu(target, pos){
|
||||
let context = ""
|
||||
if (target.classList.contains("FileTileView"))
|
||||
{
|
||||
context = "FileTileView"
|
||||
|
||||
}
|
||||
fetch(`${window.location.origin}/application/${this.appId}/contextMenu?` + new URLSearchParams({
|
||||
kek: "kek"
|
||||
context: context
|
||||
|
||||
}))
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
@ -161,21 +204,25 @@ class Finder{
|
||||
overlay.style.position = 'absolute'
|
||||
overlay.style.width = "100%"
|
||||
overlay.style.height = "100%"
|
||||
|
||||
let menu = document.createElement("div")
|
||||
menu.setAttribute('class', 'ContextMenu WindowFrameShadow')
|
||||
menu.style.position = 'absolute';
|
||||
// menu.style.backgroundColor = '#000000';
|
||||
menu.style.top = pos[0] + "px";
|
||||
menu.style.left = pos[1] + "px";
|
||||
|
||||
menu.innerHTML = html
|
||||
menu.children[0].lastElementChild.remove() //FIXME Can't ommit rendering of horLine in end of menu on backend
|
||||
|
||||
overlay.appendChild(menu)
|
||||
document.body.appendChild(overlay)
|
||||
|
||||
overlay.addEventListener('click',(event) => {
|
||||
if (event.target.className == "Row"){ //TODO add uuid id to rows to more accurate checks??
|
||||
// console.log("aaaa")
|
||||
if (event.target.classList.contains("Row")){ //TODO add uuid id to rows to more accurate checks??
|
||||
switch (event.target.children[0].getAttribute("action")) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
overlay.remove()
|
||||
})
|
||||
@ -186,24 +233,6 @@ class Finder{
|
||||
})
|
||||
.catch((error) => {
|
||||
WebDesktopEnvironment.Alert(error);
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @param {path} string
|
||||
// */
|
||||
// renderFileView(path){
|
||||
// fetch(`${window.location.origin}/fs/list?` + new URLSearchParams({
|
||||
// path: path,
|
||||
// }))
|
||||
// .then((response) => response.text())
|
||||
// .then((html) => {
|
||||
// this.fileView.innerHTML = html
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// WebDesktopEnvironment.Alert(error);
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ class FileView{
|
||||
* @param {Function} doubleClickCallback
|
||||
* @param {Function} rightClickCallback
|
||||
*/
|
||||
constructor(fileViewElem, doubleClickCallback, rightClickCallback){
|
||||
constructor(fileViewElem, doubleClickCallback, rightClickCallback, fileUploadCallback){
|
||||
//TODO check all params
|
||||
this.parentElem = fileViewElem
|
||||
|
||||
@ -18,8 +18,7 @@ class FileView{
|
||||
}
|
||||
if (event.detail === 1){
|
||||
this.DeselectAll()
|
||||
this.selected.push(event.target)
|
||||
event.target.classList.add("Selected")
|
||||
this.Select([event.target])
|
||||
} else if (event.detail === 2) {
|
||||
doubleClickCallback(event)
|
||||
}
|
||||
@ -27,8 +26,40 @@ class FileView{
|
||||
|
||||
fileViewElem.addEventListener('contextmenu', (event) => {
|
||||
event.preventDefault();
|
||||
if (event.target.classList.contains("Tile")){
|
||||
this.DeselectAll()
|
||||
this.Select([event.target])
|
||||
}
|
||||
this.Select([event.target])
|
||||
rightClickCallback(event)
|
||||
})
|
||||
|
||||
if (fileUploadCallback !== undefined) {
|
||||
fileViewElem.addEventListener('dragenter', function(event) {
|
||||
// console.log("start")
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragover', function(event) {
|
||||
event.preventDefault();
|
||||
// console.log("over")
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener("drop", (event) => {
|
||||
event.preventDefault();
|
||||
// console.log(event.dataTransfer.items[0])
|
||||
fileUploadCallback(event.dataTransfer.items)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[]Element} elements
|
||||
*/
|
||||
Select(elements){
|
||||
elements.forEach(element => {
|
||||
this.selected.push(element)
|
||||
element.classList.add("Selected")
|
||||
});
|
||||
}
|
||||
|
||||
DeselectAll(){
|
||||
|
@ -4,8 +4,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// console.log(window.screen.width)
|
||||
wde = new WebDesktopEnvironment
|
||||
if (!WebDesktopEnvironment.isMobile){
|
||||
// WebDesktopEnvironment.Open("finder", ["/home/user"])
|
||||
WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"])
|
||||
WebDesktopEnvironment.Open("finder", ["/home/user"])
|
||||
// WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"])
|
||||
// WebDesktopEnvironment.Open("personal-properties", ["kek"])
|
||||
} else {
|
||||
WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"])
|
||||
|
@ -60,6 +60,10 @@
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.AdjectiveHorizontalLine:last-child {
|
||||
height: 0%;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
.WindowFrame .TitleBar {
|
||||
|
@ -1,28 +1,12 @@
|
||||
{{ define "wde-widgets/context-menu.tmpl" }}
|
||||
<!-- <div class="ContextMenu WindowFrameShadow"> -->
|
||||
<div class="MenuContent ConvexElement">
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Open</div>
|
||||
</div>
|
||||
<div class="Row" actionType="" action="">
|
||||
<div class="Lable NoClick">Test</div>
|
||||
</div>
|
||||
<div class="AdjectiveHorizontalLine"></div>
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Lol kek</div>
|
||||
</div>
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Delete this file</div>
|
||||
</div>
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Save to computer</div>
|
||||
</div>
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Pizda</div>
|
||||
</div>
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick">Azaza</div>
|
||||
</div>
|
||||
{{ range $island := .Islands }}
|
||||
{{ range $row := $island }}
|
||||
<div class="Row">
|
||||
<div class="Lable NoClick" action="{{$row.Action}}">{{ $row.Label }}</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="AdjectiveHorizontalLine"></div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
{{ end }}
|
10
wde/contextmenu.go
Normal file
10
wde/contextmenu.go
Normal file
@ -0,0 +1,10 @@
|
||||
package wde
|
||||
|
||||
type ContexMenuIsland struct {
|
||||
Rows []ContexMenuRow
|
||||
}
|
||||
|
||||
type ContexMenuRow struct {
|
||||
Label string
|
||||
Action string
|
||||
}
|
@ -44,6 +44,35 @@ func (fs *WebFileSystem) UploadFile(realFilepath string, path string) error {
|
||||
return errors.New("this filetype not allowed")
|
||||
}
|
||||
|
||||
}
|
||||
func (fs *WebFileSystem) UploadBinaryFile(file []byte, fileName string, path string) error {
|
||||
extension := fs.GetExtension(fileName)
|
||||
switch extension {
|
||||
case "jpg":
|
||||
fallthrough
|
||||
case "jpeg":
|
||||
newFile := WebFSFile{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: fileName,
|
||||
Type: "jpeg",
|
||||
Data: file,
|
||||
Icon: "",
|
||||
}
|
||||
err := fs.CreateFile(&newFile, path)
|
||||
return err
|
||||
case "png":
|
||||
newFile := WebFSFile{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: fileName,
|
||||
Type: "png",
|
||||
Data: file,
|
||||
}
|
||||
err := fs.CreateFile(&newFile, path)
|
||||
return err
|
||||
default:
|
||||
return errors.New("this filetype not allowed")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// func (fs *WebFileSystem) CreateMiniatures(parentDir string, file string) error {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -175,6 +176,44 @@ func (fs *WebFileSystem) GetParentPath(path string) string {
|
||||
}
|
||||
|
||||
func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
||||
route.POST("/upload", func(ctx *gin.Context) { //TODO To PUT request
|
||||
// fileName := ctx.Query("fileName")
|
||||
// if fileName == "" {
|
||||
// ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
// return
|
||||
// }
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
return
|
||||
}
|
||||
// single file
|
||||
file, _ := ctx.FormFile("file")
|
||||
if file == nil {
|
||||
ctx.String(http.StatusBadRequest, "file is nil")
|
||||
return
|
||||
}
|
||||
// generateMins := c.Param("generateMins")
|
||||
// log.Println(file.Filename)
|
||||
|
||||
// Upload the file to specific dst.
|
||||
dst := "./test-img/" + file.Filename
|
||||
ctx.SaveUploadedFile(file, dst)
|
||||
|
||||
//TODO: Not Save to disk
|
||||
err := fs.UploadFile(dst, path)
|
||||
if err != nil {
|
||||
ctx.String(http.StatusInternalServerError, "TODO") //TODO
|
||||
return
|
||||
}
|
||||
|
||||
// webFsCollection.CreateMiniatures("./test-img/", file.Filename)
|
||||
|
||||
// webfs.CreateFile(&img, "/home/user/")
|
||||
|
||||
ctx.Status(http.StatusCreated)
|
||||
})
|
||||
|
||||
route.GET("writeFile", func(ctx *gin.Context) {
|
||||
parentPath := ctx.Query("parentPath")
|
||||
if parentPath == "" {
|
||||
@ -242,6 +281,74 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
||||
|
||||
ctx.JSON(http.StatusOK, &file)
|
||||
})
|
||||
|
||||
route.GET("validate", func(ctx *gin.Context) {
|
||||
err := fs.Validate()
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusOK)
|
||||
})
|
||||
}
|
||||
|
||||
func (fs *WebFileSystem) Validate() error {
|
||||
filter := primitive.D{
|
||||
{
|
||||
Key: "type",
|
||||
Value: "directory",
|
||||
},
|
||||
}
|
||||
cur, err := fs.webfsCollection.Find(context.Background(), filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cur.Close(context.Background())
|
||||
|
||||
directories := []*WebFSFile{}
|
||||
|
||||
for cur.Next(context.Background()) {
|
||||
dir := &WebFSFile{}
|
||||
|
||||
err = cur.Decode(dir)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return err
|
||||
}
|
||||
directories = append(directories, dir)
|
||||
}
|
||||
|
||||
for _, d := range directories {
|
||||
fs.validateDir(d)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fs *WebFileSystem) validateDir(dir *WebFSFile) error {
|
||||
kek := dir.Data.(primitive.D).Map()["children"].(primitive.A)
|
||||
_ = kek
|
||||
|
||||
children := []primitive.ObjectID{}
|
||||
counter := 0
|
||||
for _, v := range kek {
|
||||
_, err := fs.ReadByObjectID(v.(primitive.ObjectID))
|
||||
if err != nil {
|
||||
counter++
|
||||
} else {
|
||||
children = append(children, v.(primitive.ObjectID))
|
||||
}
|
||||
}
|
||||
if counter > 0 {
|
||||
println(dir.Name + " broken iDs: " + strconv.Itoa(counter))
|
||||
_, err := fs.webfsCollection.UpdateByID(context.Background(), dir.MongoId, bson.M{"$set": bson.M{"data.children": children}})
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type WebFSFile struct {
|
||||
|
Loading…
Reference in New Issue
Block a user