Compare commits
17 Commits
5b03a465fc
...
5aaea9c1be
Author | SHA1 | Date | |
---|---|---|---|
5aaea9c1be | |||
55bb4c17fc | |||
b975dd958a | |||
0599e35a92 | |||
641e58984b | |||
4cb31d2e19 | |||
9ec954ceb3 | |||
5d160bddd9 | |||
9cc2dc5a42 | |||
56038cc284 | |||
f363ebbe10 | |||
2a5f0bb3f4 | |||
6a93f418d5 | |||
d2ea95a182 | |||
1b3f17777e | |||
8facac5d19 | |||
435e98dac0 |
@ -10,7 +10,7 @@ FROM golang:1.18-alpine
|
|||||||
WORKDIR /usr/app
|
WORKDIR /usr/app
|
||||||
COPY --from=build /usr/app/personalwebsite /usr/app/personalwebsite
|
COPY --from=build /usr/app/personalwebsite /usr/app/personalwebsite
|
||||||
COPY ./templates /usr/app/templates
|
COPY ./templates /usr/app/templates
|
||||||
COPY ./resources /usr/app/resources
|
COPY ./res /usr/app/res
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
|
28
apps/BlogWriter/blogwriter.go
Normal file
28
apps/BlogWriter/blogwriter.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package blogwriter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BlogWriterApplication struct {
|
||||||
|
fs *webfilesystem.WebFileSystem
|
||||||
|
appID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBlogWriterApp(webfs *webfilesystem.WebFileSystem) *BlogWriterApplication {
|
||||||
|
return &BlogWriterApplication{
|
||||||
|
fs: webfs,
|
||||||
|
appID: "BlogWriter",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *BlogWriterApplication) GetAppID() string {
|
||||||
|
return bw.appID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bw *BlogWriterApplication) PublicRoutes(routes *gin.RouterGroup) {}
|
||||||
|
func (bw *BlogWriterApplication) PrivateRoutes(routes *gin.RouterGroup) {
|
||||||
|
|
||||||
|
}
|
7
apps/appCtx/appContext.go
Normal file
7
apps/appCtx/appContext.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package appCtx
|
||||||
|
|
||||||
|
type AppContext struct {
|
||||||
|
IsMobile bool `json:"isMobile"`
|
||||||
|
BundlePath string `json:"bundlePath"`
|
||||||
|
RunPath string `json:"runPath"`
|
||||||
|
}
|
@ -2,5 +2,5 @@ package blogviewer
|
|||||||
|
|
||||||
type BlogFileData struct {
|
type BlogFileData struct {
|
||||||
Header string `bson:"header"`
|
Header string `bson:"header"`
|
||||||
Blocks []Block `bson:"blocks"`
|
Blocks []*Block `bson:"blocks"`
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package blogviewer
|
package blogviewer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"personalwebsite/apps"
|
"path"
|
||||||
|
"personalwebsite/apps/appCtx"
|
||||||
|
"personalwebsite/errormessage"
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -11,27 +14,65 @@ import (
|
|||||||
|
|
||||||
type BlogViewerApplication struct {
|
type BlogViewerApplication struct {
|
||||||
fs *webfilesystem.WebFileSystem
|
fs *webfilesystem.WebFileSystem
|
||||||
manifest apps.ApplicationManifest
|
appID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBlogViewerApp(webFs *webfilesystem.WebFileSystem) *BlogViewerApplication {
|
func NewBlogViewerApp(webFs *webfilesystem.WebFileSystem) *BlogViewerApplication {
|
||||||
return &BlogViewerApplication{
|
return &BlogViewerApplication{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: apps.ApplicationManifest{
|
appID: "BlogViewer",
|
||||||
AppId: "blog-viewer",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogViewerApplication) GetManifest() apps.ApplicationManifest {
|
func (b *BlogViewerApplication) GetAppID() string {
|
||||||
return b.manifest
|
return b.appID
|
||||||
}
|
}
|
||||||
|
func (b *BlogViewerApplication) PrivateRoutes(route *gin.RouterGroup) {
|
||||||
|
b.PublicRoutes(route)
|
||||||
|
|
||||||
func (b *BlogViewerApplication) GetId() string {
|
route.POST("edit", func(ctx *gin.Context) {
|
||||||
return b.manifest.AppId
|
filePath := ctx.Query("path")
|
||||||
|
if filePath == "" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
|
Message: "File path is empty",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
blogData := BlogFileData{}
|
||||||
|
err := ctx.BindJSON(&blogData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.Edit(filePath, blogData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
})
|
||||||
|
|
||||||
|
route.GET("read", func(ctx *gin.Context) {
|
||||||
|
filePath := ctx.Query("path")
|
||||||
|
if filePath == "" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
|
Message: "File path is empty",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
blogData, err := b.Read(filePath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, blogData)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
func (b *BlogViewerApplication) PublicRoutes(route *gin.RouterGroup) {
|
||||||
func (b *BlogViewerApplication) Route(route *gin.RouterGroup) {
|
|
||||||
route.GET("writeMockBlog", func(ctx *gin.Context) {
|
route.GET("writeMockBlog", func(ctx *gin.Context) {
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@ -46,22 +87,27 @@ func (b *BlogViewerApplication) Route(route *gin.RouterGroup) {
|
|||||||
ctx.JSON(http.StatusOK, "OK")
|
ctx.JSON(http.StatusOK, "OK")
|
||||||
})
|
})
|
||||||
|
|
||||||
route.GET("render", func(ctx *gin.Context) {
|
route.POST("render", func(ctx *gin.Context) {
|
||||||
isMobileParam := ctx.Query("isMobile")
|
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
ctx.JSON(http.StatusBadRequest, "no path provided")
|
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isMobile := isMobileParam == "true"
|
appCtx := appCtx.AppContext{}
|
||||||
ginH, err := b.Render(path, isMobile)
|
err := ctx.BindJSON(&appCtx)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ginH, err := b.Render(path, appCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(http.StatusInternalServerError, "TODO")
|
ctx.JSON(http.StatusInternalServerError, "TODO")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isMobile {
|
if appCtx.IsMobile {
|
||||||
ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH)
|
||||||
} else {
|
} else {
|
||||||
ctx.HTML(http.StatusOK, "blog-viewer/app.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "blog-viewer/app.tmpl", ginH)
|
||||||
@ -71,25 +117,17 @@ func (b *BlogViewerApplication) Route(route *gin.RouterGroup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogViewerApplication) WriteMock(path string) error {
|
func (b *BlogViewerApplication) WriteMock(path string) error {
|
||||||
blogFileHeader := webfilesystem.FileHeader{
|
blogFileHeader := webfilesystem.FileHeader{ //TODO to fs.CreateDirectory()
|
||||||
MongoId: primitive.NewObjectID(),
|
MongoId: primitive.NewObjectID(),
|
||||||
Name: "blog1.blog",
|
Name: "blog1.blog",
|
||||||
Type: "",
|
Type: "directory",
|
||||||
Icon: "",
|
Icon: "",
|
||||||
Data: [12]byte{},
|
Data: [12]byte{},
|
||||||
}
|
}
|
||||||
blogFileData := BlogFileData{
|
blogFileData := webfilesystem.DirectoryData{
|
||||||
Header: "OMG THIS IS BLOG",
|
MongoId: primitive.NewObjectID(),
|
||||||
Blocks: []Block{
|
Parent: [12]byte{},
|
||||||
{
|
Children: []primitive.ObjectID{},
|
||||||
Type: "plain-text",
|
|
||||||
Data: []string{
|
|
||||||
"Apoqiwepoqiwepo",
|
|
||||||
".,mas;dakls;d",
|
|
||||||
"q[poqwieqpipoi]",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData)
|
_, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData)
|
||||||
@ -97,16 +135,87 @@ func (b *BlogViewerApplication) WriteMock(path string) error {
|
|||||||
println(err.Error())
|
println(err.Error())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blogContentFileHeader := webfilesystem.FileHeader{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Name: ".content",
|
||||||
|
Type: "blog-content",
|
||||||
|
Icon: "",
|
||||||
|
Data: [12]byte{},
|
||||||
|
}
|
||||||
|
blogContentFileData := BlogFileData{
|
||||||
|
Header: "OMG THIS IS BLOG",
|
||||||
|
}
|
||||||
|
blogContentFileData.Blocks = append(blogContentFileData.Blocks, &Block{
|
||||||
|
Type: "plain-text",
|
||||||
|
Data: []string{
|
||||||
|
"Apoqiwepoqiwepo",
|
||||||
|
".,mas;dakls;d",
|
||||||
|
"q[poqwieqpipoi]",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, _, err = b.fs.Write("/home/user/blog1.blog/.content", &blogContentFileHeader, blogContentFileData)
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BlogViewerApplication) Render(filePath string, isMobile bool) (gin.H, error) {
|
func (b *BlogViewerApplication) Read(filePath string) (*BlogFileData, error) {
|
||||||
data := BlogFileData{}
|
fileData := BlogFileData{}
|
||||||
_, err := b.fs.Read(filePath, &data)
|
fileHeader, err := b.fs.Read(path.Join(filePath, ".content"), &fileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fileHeader.Type != "blog-content" {
|
||||||
|
return nil, errors.New("wrong file type")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &fileData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlogViewerApplication) Edit(filePath string, blogData BlogFileData) error {
|
||||||
|
contentPath := path.Join(filePath, ".content")
|
||||||
|
fileHeader, err := b.fs.Read(contentPath, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if fileHeader.Type != "blog-content" {
|
||||||
|
return errors.New("wrong file type")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = b.fs.Remove(contentPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fileHeader.MongoId = primitive.NewObjectID()
|
||||||
|
_, _, err = b.fs.Write(contentPath, fileHeader, blogData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BlogViewerApplication) Render(filePath string, appCtx appCtx.AppContext) (gin.H, error) {
|
||||||
|
data := &BlogFileData{}
|
||||||
|
_, err := b.fs.Read(path.Join(filePath, ".content"), &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, block := range data.Blocks {
|
||||||
|
if block.Type == "image" {
|
||||||
|
newData := []string{}
|
||||||
|
for _, image := range block.Data {
|
||||||
|
newData = append(newData, b.fs.RelativeToAbsolute(appCtx, image))
|
||||||
|
}
|
||||||
|
block.Data = newData
|
||||||
|
}
|
||||||
|
}
|
||||||
return gin.H{
|
return gin.H{
|
||||||
"header": data.Header,
|
"header": data.Header,
|
||||||
"blocks": data.Blocks,
|
"blocks": data.Blocks,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package finder
|
package finder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"personalwebsite/apps"
|
"personalwebsite/apps/appCtx"
|
||||||
"personalwebsite/wde"
|
"personalwebsite/wde"
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
@ -10,114 +10,55 @@ import (
|
|||||||
|
|
||||||
type FinderApplication struct {
|
type FinderApplication struct {
|
||||||
fs *webfilesystem.WebFileSystem
|
fs *webfilesystem.WebFileSystem
|
||||||
manifest apps.ApplicationManifest
|
appID string
|
||||||
|
// manifest apps.ApplicationManifest
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication {
|
func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication {
|
||||||
return &FinderApplication{
|
return &FinderApplication{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: apps.ApplicationManifest{
|
appID: "Finder",
|
||||||
AppId: "finder",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (f *FinderApplication) GetManifest() apps.ApplicationManifest {
|
|
||||||
return f.manifest
|
func (f *FinderApplication) GetAppID() string {
|
||||||
}
|
return f.appID
|
||||||
func (f *FinderApplication) GetId() string {
|
|
||||||
return f.manifest.AppId
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FinderApplication) Render(isMobile bool) gin.H {
|
func (f *FinderApplication) Render(appCtx appCtx.AppContext) gin.H {
|
||||||
return gin.H{}
|
return gin.H{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FinderApplication) RenderContextMenu(context string, filePath string, data string) gin.H {
|
func (f *FinderApplication) RenderPublicContextMenu(context string, filePath string, data string) gin.H {
|
||||||
islands := [][]wde.ContexMenuRow{}
|
islands := [][]wde.ContexMenuRow{}
|
||||||
islands = append(islands, []wde.ContexMenuRow{})
|
islands = append(islands, []wde.ContexMenuRow{})
|
||||||
|
|
||||||
if context == "FileTileView" {
|
//TODO: Links read as source files in props info
|
||||||
islands = append(islands, []wde.ContexMenuRow{
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
{Label: "Get Info", Action: "getInfo"},
|
{Label: "Get Info", Action: "getInfo"},
|
||||||
{Label: "New Directory", Action: "createDir"},
|
|
||||||
})
|
})
|
||||||
|
if context == "FileTileView" {
|
||||||
return gin.H{
|
return gin.H{
|
||||||
"Islands": islands,
|
"Islands": islands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch context {
|
switch context {
|
||||||
case "directory":
|
|
||||||
if f.fs.GetExtension(filePath) == "app" {
|
|
||||||
islands = append(islands, []wde.ContexMenuRow{
|
|
||||||
{Label: "Open as Directory", Action: "openAsDir"},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
islands = append(islands, []wde.ContexMenuRow{
|
|
||||||
{Label: "temp Menu 1", Action: ""},
|
|
||||||
{Label: "temp Menu 2", Action: ""},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
islands = append(islands, []wde.ContexMenuRow{
|
|
||||||
{Label: "Delete File", Action: "deleteFile"},
|
|
||||||
})
|
|
||||||
|
|
||||||
return gin.H{
|
return gin.H{
|
||||||
"Islands": islands,
|
"Islands": islands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FinderApplication) RenderProps(filePath string) (gin.H, error) {
|
func (f *FinderApplication) RenderProps(filePath string) (gin.H, error) {
|
||||||
// file, err := f.fs.NewReadDeprecated(filePath)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
fileHeader, err := f.fs.Read(filePath, nil)
|
fileHeader, err := f.fs.Read(filePath, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return gin.H{
|
return gin.H{
|
||||||
// "fileId": fileHeader.MongoId,
|
|
||||||
// "fileDataId": fileHeader.Data,
|
|
||||||
"file": fileHeader,
|
"file": fileHeader,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
|
||||||
// routes.GET("render", func(ctx *gin.Context) {
|
|
||||||
// isMobileParam := ctx.Query("isMobile")
|
|
||||||
// isMobile := isMobileParam == "true"
|
|
||||||
// admin := true
|
|
||||||
// if isMobile {
|
|
||||||
// ctx.HTML(http.StatusOK, "finder/mobile-app.tmpl", f.Render(isMobile))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if admin {
|
|
||||||
// ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(isMobile))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(isMobile))
|
|
||||||
|
|
||||||
// })
|
|
||||||
// routes.GET("renderMobileDesktop", func(ctx *gin.Context) {
|
|
||||||
// ctx.HTML(http.StatusOK, "finder/mobile-desktop.tmpl", gin.H{})
|
|
||||||
// })
|
|
||||||
// routes.GET("renderDesktop", func(ctx *gin.Context) {
|
|
||||||
// path := ctx.Query("path")
|
|
||||||
// if path == "" {
|
|
||||||
// ctx.JSON(http.StatusBadRequest, "no path provided")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// ctx.HTML(http.StatusOK, "finder/desktop.tmpl", gin.H{})
|
|
||||||
// })
|
|
||||||
|
|
||||||
// routes.GET("contextMenu", func(ctx *gin.Context) {
|
|
||||||
// context := ctx.Query("context")
|
|
||||||
// data := ctx.Query("data")
|
|
||||||
// ginH := f.RenderContextMenu(context, data)
|
|
||||||
// ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", ginH)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
@ -1,22 +1,61 @@
|
|||||||
package finder
|
package finder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"personalwebsite/apps"
|
"personalwebsite/apps/appCtx"
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/wde"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FinderAdminApp struct {
|
func (f *FinderApplication) RenderAdminWindow(appCtx appCtx.AppContext) gin.H {
|
||||||
fs *webfilesystem.WebFileSystem
|
|
||||||
manifest apps.ApplicationManifest
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFinderAdminApp(webfs *webfilesystem.WebFileSystem) FinderAdminApp {
|
return gin.H{}
|
||||||
return FinderAdminApp{
|
}
|
||||||
fs: webfs,
|
func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath string, data string) gin.H {
|
||||||
manifest: apps.ApplicationManifest{},
|
islands := [][]wde.ContexMenuRow{}
|
||||||
|
// islands = append(islands, []wde.ContexMenuRow{})
|
||||||
|
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "Get Info", Action: "getInfo"},
|
||||||
|
})
|
||||||
|
|
||||||
|
if context == "FileTileView" {
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "New Directory", Action: "createDir"},
|
||||||
|
})
|
||||||
|
return gin.H{
|
||||||
|
"Islands": islands,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "Create path link", Action: "createPathLink"},
|
||||||
|
})
|
||||||
|
|
||||||
|
switch context {
|
||||||
|
case "directory":
|
||||||
|
switch f.fs.GetExtension(filePath) {
|
||||||
|
case "app":
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "Open as Directory", Action: "openAsDir"},
|
||||||
|
})
|
||||||
|
case "blog":
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "Open as Directory", Action: "openAsDir"},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "temp Menu 1", Action: ""},
|
||||||
|
{Label: "temp Menu 2", Action: ""},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
islands = append(islands, []wde.ContexMenuRow{
|
||||||
|
{Label: "Delete File", Action: "deleteFile"},
|
||||||
|
})
|
||||||
|
|
||||||
|
return gin.H{
|
||||||
|
"Islands": islands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FinderAdminApp) RenderWindow() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -2,24 +2,23 @@ package finder
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"personalwebsite/apps/appCtx"
|
||||||
|
"personalwebsite/errormessage"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
func (f *FinderApplication) PublicRoutes(routes *gin.RouterGroup) {
|
||||||
routes.GET("render", func(ctx *gin.Context) {
|
routes.POST("render", func(ctx *gin.Context) {
|
||||||
isMobileParam := ctx.Query("isMobile")
|
appCtx := appCtx.AppContext{}
|
||||||
isMobile := isMobileParam == "true"
|
err := ctx.BindJSON(&appCtx)
|
||||||
admin := true
|
if err != nil {
|
||||||
if isMobile {
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
ctx.HTML(http.StatusOK, "finder/mobile-app.tmpl", f.Render(isMobile))
|
Message: "Error in decoding app bundle",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if admin {
|
ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(appCtx))
|
||||||
ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(isMobile))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(isMobile))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
routes.GET("renderMobileDesktop", func(ctx *gin.Context) {
|
routes.GET("renderMobileDesktop", func(ctx *gin.Context) {
|
||||||
@ -36,17 +35,58 @@ func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
|||||||
|
|
||||||
routes.GET("contextMenu", func(ctx *gin.Context) {
|
routes.GET("contextMenu", func(ctx *gin.Context) {
|
||||||
context := ctx.Query("context")
|
context := ctx.Query("context")
|
||||||
// if context == "" {
|
|
||||||
// ctx.Status(http.StatusBadRequest)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
filePath := ctx.Query("path")
|
filePath := ctx.Query("path")
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
ctx.Status(http.StatusBadRequest)
|
ctx.Status(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data := ctx.Query("data")
|
data := ctx.Query("data")
|
||||||
ginH := f.RenderContextMenu(context, filePath, data)
|
ginH := f.RenderPublicContextMenu(context, filePath, data)
|
||||||
|
ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", ginH)
|
||||||
|
})
|
||||||
|
|
||||||
|
routes.GET("renderProps", func(ctx *gin.Context) {
|
||||||
|
filePath := ctx.Query("path")
|
||||||
|
ginH, err := f.RenderProps(filePath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.HTML(http.StatusOK, "finder/props.tmpl", ginH)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FinderApplication) PrivateRoutes(routes *gin.RouterGroup) {
|
||||||
|
routes.POST("render", func(ctx *gin.Context) {
|
||||||
|
appCtx := appCtx.AppContext{}
|
||||||
|
err := ctx.BindJSON(&appCtx)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
|
Message: "Error in decoding app context",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(appCtx))
|
||||||
|
})
|
||||||
|
|
||||||
|
routes.GET("renderDesktop", func(ctx *gin.Context) {
|
||||||
|
path := ctx.Query("path")
|
||||||
|
if path == "" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.HTML(http.StatusOK, "finder/desktop.tmpl", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
routes.GET("contextMenu", func(ctx *gin.Context) {
|
||||||
|
context := ctx.Query("context")
|
||||||
|
filePath := ctx.Query("path")
|
||||||
|
if filePath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := ctx.Query("data")
|
||||||
|
ginH := f.RenderPrivateContextMenu(context, filePath, data)
|
||||||
ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "wde-widgets/context-menu.tmpl", ginH)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package imgviewer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
websiteapp "personalwebsite/apps"
|
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -10,20 +9,20 @@ import (
|
|||||||
|
|
||||||
type ImgViewerApp struct {
|
type ImgViewerApp struct {
|
||||||
fs *webfilesystem.WebFileSystem
|
fs *webfilesystem.WebFileSystem
|
||||||
manifest websiteapp.ApplicationManifest
|
appID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) ImgViewerApp {
|
func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) *ImgViewerApp {
|
||||||
newApp := ImgViewerApp{
|
newApp := ImgViewerApp{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: websiteapp.ApplicationManifest{
|
appID: "ImgViewer",
|
||||||
AppId: "img-viewer",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return newApp
|
return &newApp
|
||||||
}
|
}
|
||||||
|
func (p *ImgViewerApp) PrivateRoutes(route *gin.RouterGroup) {
|
||||||
func (p *ImgViewerApp) Route(route *gin.RouterGroup) {
|
p.PublicRoutes(route)
|
||||||
|
}
|
||||||
|
func (p *ImgViewerApp) PublicRoutes(route *gin.RouterGroup) {
|
||||||
route.GET("render", func(ctx *gin.Context) {
|
route.GET("render", func(ctx *gin.Context) {
|
||||||
isMobileParam := ctx.Query("isMobile")
|
isMobileParam := ctx.Query("isMobile")
|
||||||
isMobile := isMobileParam == "true"
|
isMobile := isMobileParam == "true"
|
||||||
@ -45,11 +44,8 @@ func (p *ImgViewerApp) Route(route *gin.RouterGroup) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ImgViewerApp) GetManifest() websiteapp.ApplicationManifest {
|
func (p *ImgViewerApp) GetAppID() string {
|
||||||
return p.manifest
|
return p.appID
|
||||||
}
|
|
||||||
func (p *ImgViewerApp) GetId() string {
|
|
||||||
return p.manifest.AppId
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ImgViewerApp) Render(filePath string, isMobile bool) (gin.H, error) {
|
func (p *ImgViewerApp) Render(filePath string, isMobile bool) (gin.H, error) {
|
||||||
|
@ -2,50 +2,47 @@ package personalprops
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
websiteapp "personalwebsite/apps"
|
"personalwebsite/apps/appCtx"
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//TODO Rename to AboutMe
|
||||||
type PersonalPropertiesApp struct {
|
type PersonalPropertiesApp struct {
|
||||||
fs *webfilesystem.WebFileSystem
|
fs *webfilesystem.WebFileSystem
|
||||||
manifest websiteapp.ApplicationManifest
|
appID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPersPropsApp(webFs *webfilesystem.WebFileSystem) PersonalPropertiesApp {
|
func NewPersPropsApp(webFs *webfilesystem.WebFileSystem) *PersonalPropertiesApp {
|
||||||
newApp := PersonalPropertiesApp{
|
newApp := PersonalPropertiesApp{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: websiteapp.ApplicationManifest{
|
appID: "AboutMe",
|
||||||
AppId: "personal-properties",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return newApp
|
return &newApp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PersonalPropertiesApp) Route(route *gin.RouterGroup) {
|
func (p *PersonalPropertiesApp) PublicRoutes(route *gin.RouterGroup) {
|
||||||
route.GET("writeMock", func(ctx *gin.Context) {
|
route.POST("render", func(ctx *gin.Context) {
|
||||||
err := p.WriteMock()
|
|
||||||
if err != nil {
|
|
||||||
ctx.Status(http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
ctx.Status(http.StatusOK)
|
|
||||||
})
|
|
||||||
route.GET("render", func(ctx *gin.Context) {
|
|
||||||
isMobileParam := ctx.Query("isMobile")
|
|
||||||
isMobile := isMobileParam == "true"
|
|
||||||
filePath := ctx.Query("path")
|
filePath := ctx.Query("path")
|
||||||
if filePath == "" {
|
if filePath == "" {
|
||||||
ctx.Status(http.StatusBadRequest)
|
ctx.Status(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ginH, err := p.Render(filePath)
|
appCtx := appCtx.AppContext{}
|
||||||
|
err := ctx.BindJSON(&appCtx)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ginH, err := p.Render(appCtx, filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(http.StatusInternalServerError, "TODO") //TODO
|
ctx.JSON(http.StatusInternalServerError, "TODO") //TODO
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if isMobile {
|
if appCtx.IsMobile {
|
||||||
ctx.HTML(http.StatusOK, "personal-properties/mobile-app.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "personal-properties/mobile-app.tmpl", ginH)
|
||||||
} else {
|
} else {
|
||||||
ctx.HTML(http.StatusOK, "personal-properties/app.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "personal-properties/app.tmpl", ginH)
|
||||||
@ -53,11 +50,20 @@ func (p *PersonalPropertiesApp) Route(route *gin.RouterGroup) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PersonalPropertiesApp) GetManifest() websiteapp.ApplicationManifest {
|
func (p *PersonalPropertiesApp) PrivateRoutes(router *gin.RouterGroup) {
|
||||||
return p.manifest
|
p.PublicRoutes(router)
|
||||||
|
router.GET("writeMock", func(ctx *gin.Context) {
|
||||||
|
err := p.WriteMock()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
func (p *PersonalPropertiesApp) GetId() string {
|
|
||||||
return p.manifest.AppId
|
func (p *PersonalPropertiesApp) GetAppID() string {
|
||||||
|
return p.appID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PersonalPropertiesApp) WriteMock() error {
|
func (p *PersonalPropertiesApp) WriteMock() error {
|
||||||
@ -101,13 +107,14 @@ func (p *PersonalPropertiesApp) WriteMock() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PersonalPropertiesApp) Render(filePath string) (gin.H, error) {
|
func (p *PersonalPropertiesApp) Render(appCtx appCtx.AppContext, filePath string) (gin.H, error) {
|
||||||
propsData := PropertiesFileData{}
|
propsData := PropertiesFileData{}
|
||||||
|
filePath = p.fs.RelativeToAbsolute(appCtx, filePath)
|
||||||
_, err := p.fs.Read(filePath, &propsData)
|
_, err := p.fs.Read(filePath, &propsData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
propsData.Header.IconPath = p.fs.RelativeToAbsolute(appCtx, propsData.Header.IconPath)
|
||||||
return gin.H{
|
return gin.H{
|
||||||
"headerProps": propsData.Header,
|
"headerProps": propsData.Header,
|
||||||
"allprops": propsData.Props,
|
"allprops": propsData.Props,
|
||||||
|
@ -12,9 +12,12 @@ import (
|
|||||||
//TODO to libs
|
//TODO to libs
|
||||||
type WebDEApplication interface {
|
type WebDEApplication interface {
|
||||||
// Render()
|
// Render()
|
||||||
GetManifest() ApplicationManifest
|
GetAppID() string
|
||||||
|
PublicRoutes(*gin.RouterGroup)
|
||||||
|
PrivateRoutes(*gin.RouterGroup)
|
||||||
|
// GetManifest() ApplicationManifest //TODO: Delete
|
||||||
// GEtHtml()
|
// GEtHtml()
|
||||||
GetId() string
|
// GetId() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApplicationManifest struct {
|
type ApplicationManifest struct {
|
||||||
@ -36,6 +39,25 @@ type ApplicationsStorage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (as *ApplicationsStorage) createApp(appName string, appId string, appPath string) error {
|
func (as *ApplicationsStorage) createApp(appName string, appId string, appPath string) error {
|
||||||
|
appBundleName := appName + ".app"
|
||||||
|
newAppBundleHeader := webfilesystem.FileHeader{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Name: appBundleName,
|
||||||
|
Type: "directory",
|
||||||
|
Icon: "",
|
||||||
|
Data: primitive.NewObjectID(),
|
||||||
|
}
|
||||||
|
newAppBundleData := webfilesystem.DirectoryData{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Parent: primitive.NewObjectID(),
|
||||||
|
Children: []primitive.ObjectID{},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := as.fs.Write(appPath+"/"+appBundleName, &newAppBundleHeader, &newAppBundleData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
newAppData := ApplicationManifest{
|
newAppData := ApplicationManifest{
|
||||||
AppId: appId,
|
AppId: appId,
|
||||||
Js: []string{},
|
Js: []string{},
|
||||||
@ -49,34 +71,27 @@ func (as *ApplicationsStorage) createApp(appName string, appId string, appPath s
|
|||||||
Icon: "",
|
Icon: "",
|
||||||
Data: primitive.NewObjectID(),
|
Data: primitive.NewObjectID(),
|
||||||
}
|
}
|
||||||
|
_, _, err = as.fs.Write(appPath+"/"+appBundleName+"/"+newAppFile.Name, &newAppFile, newAppData)
|
||||||
//TODO: Create folder for app, etc
|
|
||||||
_, _, err := as.fs.Write(appPath+"/"+newAppFile.Name, &newAppFile, newAppData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func NewApplicationsStorage() *ApplicationsStorage {
|
func (aStorage *ApplicationsStorage) PrivateRoute(route *gin.RouterGroup) {
|
||||||
// newStorage := ApplicationsStorage{}
|
|
||||||
|
|
||||||
// return &newStorage
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (aStorage *ApplicationsStorage) Route(route *gin.RouterGroup) {
|
|
||||||
route.GET("/get", func(ctx *gin.Context) {
|
route.GET("/get", func(ctx *gin.Context) {
|
||||||
appId := ctx.Query("appid")
|
appId := ctx.Query("appid")
|
||||||
if appId == "" {
|
if appId == "" {
|
||||||
ctx.Status(http.StatusBadRequest)
|
ctx.Status(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app, isExist := aStorage.Apps[appId]
|
// app, isExist := aStorage.Apps[appId]
|
||||||
if !isExist {
|
// if !isExist {
|
||||||
ctx.Status(http.StatusNoContent)
|
// ctx.Status(http.StatusNoContent)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
ctx.JSON(http.StatusOK, app.GetManifest())
|
// ctx.JSON(http.StatusOK, app.GetManifest())
|
||||||
|
ctx.String(http.StatusMovedPermanently, "Obsolete")
|
||||||
})
|
})
|
||||||
|
|
||||||
route.GET("/loadApp", func(ctx *gin.Context) {
|
route.GET("/loadApp", func(ctx *gin.Context) {
|
||||||
@ -120,7 +135,7 @@ func (aStorage *ApplicationsStorage) Route(route *gin.RouterGroup) {
|
|||||||
|
|
||||||
err := aStorage.createApp(appId, appName, appPath)
|
err := aStorage.createApp(appId, appName, appPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Status(http.StatusInternalServerError)
|
ctx.String(http.StatusInternalServerError, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Status(http.StatusOK)
|
ctx.Status(http.StatusOK)
|
||||||
|
5
errormessage/errormessage.go
Normal file
5
errormessage/errormessage.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package errormessage
|
||||||
|
|
||||||
|
type ErrorMessage struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
2
go.mod
2
go.mod
@ -21,6 +21,7 @@ require (
|
|||||||
github.com/bytedance/sonic v1.8.0 // indirect
|
github.com/bytedance/sonic v1.8.0 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
|
github.com/gin-contrib/cors v1.4.0
|
||||||
github.com/gin-contrib/location v0.0.2
|
github.com/gin-contrib/location v0.0.2
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
@ -39,6 +40,7 @@ require (
|
|||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||||
|
github.com/thinkerou/favicon v0.2.0
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||||
go.mongodb.org/mongo-driver v1.11.4
|
go.mongodb.org/mongo-driver v1.11.4
|
||||||
|
30
go.sum
30
go.sum
@ -4,27 +4,35 @@ github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
|
|||||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
|
github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g=
|
||||||
|
github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs=
|
||||||
github.com/gin-contrib/location v0.0.2 h1:QZKh1+K/LLR4KG/61eIO3b7MLuKi8tytQhV6texLgP4=
|
github.com/gin-contrib/location v0.0.2 h1:QZKh1+K/LLR4KG/61eIO3b7MLuKi8tytQhV6texLgP4=
|
||||||
github.com/gin-contrib/location v0.0.2/go.mod h1:NGoidiRlf0BlA/VKSVp+g3cuSMeTmip/63PhEjRhUAc=
|
github.com/gin-contrib/location v0.0.2/go.mod h1:NGoidiRlf0BlA/VKSVp+g3cuSMeTmip/63PhEjRhUAc=
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||||
|
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||||
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8=
|
||||||
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
|
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
|
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||||
|
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||||
|
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
|
||||||
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
@ -48,12 +56,16 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
|
|||||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
@ -67,11 +79,15 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6f
|
|||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
|
||||||
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@ -82,11 +98,15 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/thinkerou/favicon v0.2.0 h1:/qO//fFevzhx68pAAPjuiOwB2ykoKwLcZW9luMZ8PEU=
|
||||||
|
github.com/thinkerou/favicon v0.2.0/go.mod h1:PM31DMRkXDVi9/sGwb/a/evMB536N9VfVNC+Dtf4iDQ=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||||
|
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
|
github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU=
|
||||||
github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||||
@ -101,11 +121,13 @@ go.mongodb.org/mongo-driver v1.11.4 h1:4ayjakA013OdpGyL2K3ZqylTac/rMjrJOMZ1EHizX
|
|||||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
@ -115,12 +137,15 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||||
@ -128,13 +153,18 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
10
libs/cat.go
10
libs/cat.go
@ -38,7 +38,7 @@ func (c *Cat) Get(filePath string) (string, error) {
|
|||||||
return fileData.Data, nil
|
return fileData.Data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cat) Route(route *gin.RouterGroup) {
|
func (c *Cat) PublicRoutes(route *gin.RouterGroup) {
|
||||||
route.GET("get", func(ctx *gin.Context) {
|
route.GET("get", func(ctx *gin.Context) {
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@ -52,7 +52,13 @@ func (c *Cat) Route(route *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mode := ctx.Query("mode")
|
||||||
|
switch mode {
|
||||||
|
case "json":
|
||||||
|
ctx.JSON(http.StatusOK, data)
|
||||||
|
default:
|
||||||
ctx.String(http.StatusOK, "plaintext", data)
|
ctx.String(http.StatusOK, "plaintext", data)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ func NewImgLib(webfs *webfilesystem.WebFileSystem) *ImagLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *ImagLib) Route(route *gin.RouterGroup) {
|
func (l *ImagLib) PublicRoutes(route *gin.RouterGroup) {
|
||||||
route.GET("get", func(ctx *gin.Context) {
|
route.GET("get", func(ctx *gin.Context) {
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
@ -31,10 +31,6 @@ func (l *ImagLib) Route(route *gin.RouterGroup) {
|
|||||||
ctx.Status(http.StatusInternalServerError)
|
ctx.Status(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// _, err = l.fs.readFSDocs(fileId, &imgData)
|
|
||||||
// if err != nil {
|
|
||||||
// ctx.Status(http.StatusInternalServerError)
|
|
||||||
// }
|
|
||||||
|
|
||||||
ctx.Data(http.StatusOK, "image/jpeg", imgData.Bin)
|
ctx.Data(http.StatusOK, "image/jpeg", imgData.Bin)
|
||||||
})
|
})
|
||||||
|
205
main.go
205
main.go
@ -4,21 +4,18 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"personalwebsite/apps"
|
"personalwebsite/apps"
|
||||||
|
blogwriter "personalwebsite/apps/BlogWriter"
|
||||||
"personalwebsite/apps/blogviewer"
|
"personalwebsite/apps/blogviewer"
|
||||||
"personalwebsite/apps/finder"
|
"personalwebsite/apps/finder"
|
||||||
imgviewer "personalwebsite/apps/img-viewer"
|
imgviewer "personalwebsite/apps/img-viewer"
|
||||||
"personalwebsite/apps/personalprops"
|
"personalwebsite/apps/personalprops"
|
||||||
"personalwebsite/libs"
|
"personalwebsite/routes"
|
||||||
"personalwebsite/routewde"
|
|
||||||
"personalwebsite/wde"
|
"personalwebsite/wde"
|
||||||
"personalwebsite/webfilesystem"
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
"github.com/gin-contrib/location"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
@ -54,110 +51,130 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
router := gin.New()
|
|
||||||
router.Use(location.Default())
|
|
||||||
router.LoadHTMLGlob("templates/**/*")
|
|
||||||
router.Static("/res", "resources")
|
|
||||||
// Set a lower memory limit for multipart forms (default is 32 MiB)
|
|
||||||
router.MaxMultipartMemory = 8 << 20 // 8 MiB
|
|
||||||
|
|
||||||
router.GET("/", func(ctx *gin.Context) {
|
|
||||||
ctx.HTML(http.StatusOK, "index.tmpl", gin.H{})
|
|
||||||
})
|
|
||||||
|
|
||||||
webfs := webfilesystem.NewWebFileSystem(client, dBName, webFsCollection)
|
webfs := webfilesystem.NewWebFileSystem(client, dBName, webFsCollection)
|
||||||
|
appsStorage := apps.NewApplicationsStorage(map[string]apps.WebDEApplication{}, webfs)
|
||||||
|
// router := gin.New()
|
||||||
|
// router.Use(location.Default())
|
||||||
|
// router.LoadHTMLGlob("templates/**/*")
|
||||||
|
// router.Static("/res", "resources")
|
||||||
|
// // Set a lower memory limit for multipart forms (default is 32 MiB)
|
||||||
|
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
|
||||||
|
|
||||||
|
// router.GET("/", func(ctx *gin.Context) {
|
||||||
|
// ctx.HTML(http.StatusOK, "index.tmpl", gin.H{})
|
||||||
|
// })
|
||||||
|
|
||||||
webde := wde.NewWDE(webfs)
|
webde := wde.NewWDE(webfs)
|
||||||
|
|
||||||
|
//TODO Split to different apps init for private and public?
|
||||||
persPropsApp := personalprops.NewPersPropsApp(webfs)
|
persPropsApp := personalprops.NewPersPropsApp(webfs)
|
||||||
// finderApp := finder.FinderApplication{}
|
|
||||||
finderApp := finder.NewFinderApplication(webfs)
|
finderApp := finder.NewFinderApplication(webfs)
|
||||||
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
||||||
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
||||||
appsStorage := apps.NewApplicationsStorage(map[string]apps.WebDEApplication{}, webfs)
|
blogWriterApp := blogwriter.NewBlogWriterApp(webfs)
|
||||||
appsStorage.Apps["personal-properties"] = &persPropsApp
|
appsStorage.Apps["personal-properties"] = persPropsApp
|
||||||
appsStorage.Apps["finder"] = finderApp
|
appsStorage.Apps["finder"] = finderApp
|
||||||
appsStorage.Apps["img-viewer"] = &imgViewerApp
|
appsStorage.Apps["img-viewer"] = imgViewerApp
|
||||||
appsStorage.Apps["blog-viewer"] = blogViewerApp
|
appsStorage.Apps[blogViewerApp.GetAppID()] = blogViewerApp
|
||||||
|
appsStorage.Apps["BlogWriter"] = blogWriterApp
|
||||||
|
|
||||||
system := router.Group("system")
|
go routes.PublicRoutes(webfs, webde, appsStorage)
|
||||||
{
|
routes.PrivateRoutes(webfs, webde, appsStorage)
|
||||||
libsGroup := system.Group("libs")
|
|
||||||
{
|
|
||||||
imgLibGroup := libsGroup.Group("img")
|
|
||||||
{
|
|
||||||
imgLib := libs.NewImgLib(webfs)
|
|
||||||
imgLib.Route(imgLibGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
catLibGroup := libsGroup.Group("cat")
|
// system := router.Group("system")
|
||||||
{
|
// {
|
||||||
catLib := libs.NewCatLib(webfs)
|
// libsGroup := system.Group("libs")
|
||||||
catLib.Route(catLibGroup)
|
// {
|
||||||
}
|
// imgLibGroup := libsGroup.Group("img")
|
||||||
|
// {
|
||||||
|
// imgLib := libs.NewImgLib(webfs)
|
||||||
|
// imgLib.PublicRoutes(imgLibGroup)
|
||||||
|
// }
|
||||||
|
|
||||||
appsStorageGroup := libsGroup.Group("apps")
|
// catLibGroup := libsGroup.Group("cat")
|
||||||
{
|
// {
|
||||||
appsStorage.Route(appsStorageGroup)
|
// catLib := libs.NewCatLib(webfs)
|
||||||
}
|
// catLib.PublicRoutes(catLibGroup)
|
||||||
}
|
// }
|
||||||
|
|
||||||
wdeGroup := system.Group("wde")
|
// appsStorageGroup := libsGroup.Group("apps")
|
||||||
{
|
// {
|
||||||
routewde.Route(wdeGroup, webde)
|
// appsStorage.Route(appsStorageGroup)
|
||||||
}
|
// }
|
||||||
apps := system.Group("applications") //TODO to libs
|
// }
|
||||||
{
|
|
||||||
apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
|
||||||
appId := ctx.Param("appid")
|
|
||||||
method := ctx.Param("method")
|
|
||||||
|
|
||||||
app, isExist := appsStorage.Apps[appId]
|
// wdeGroup := system.Group("wde")
|
||||||
if !isExist {
|
// {
|
||||||
ctx.Status(http.StatusNoContent)
|
// routewde.PublicRoutes(wdeGroup, webde)
|
||||||
return
|
// }
|
||||||
}
|
// apps := system.Group("applications") //TODO to libs
|
||||||
switch method {
|
// {
|
||||||
case "getmanifest":
|
// apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
||||||
ctx.JSON(http.StatusOK, app.GetManifest())
|
// appId := ctx.Param("appid")
|
||||||
case "app.js":
|
// method := ctx.Param("method")
|
||||||
ctx.File("resources/sys/" + appId + "/" + appId + ".js")
|
|
||||||
case "app.css":
|
|
||||||
ctx.File("resources/sys/" + appId + "/" + appId + ".css")
|
|
||||||
default:
|
|
||||||
ctx.Status(http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fs := router.Group("fs")
|
// app, isExist := appsStorage.Apps[appId]
|
||||||
{
|
// if !isExist {
|
||||||
webfs.Route(fs)
|
// ctx.Status(http.StatusNoContent)
|
||||||
}
|
// return
|
||||||
app := router.Group("app")
|
// }
|
||||||
{
|
// switch method {
|
||||||
persPropApp := app.Group("AboutMe")
|
// case "getmanifest":
|
||||||
{
|
// ctx.JSON(http.StatusOK, app.GetManifest())
|
||||||
persPropsApp.Route(persPropApp)
|
// case "app.js":
|
||||||
}
|
// ctx.File("resources/sys/" + appId + "/" + appId + ".js")
|
||||||
finderAppRoute := app.Group("Finder")
|
// case "app.css":
|
||||||
{
|
// ctx.File("resources/sys/" + appId + "/" + appId + ".css")
|
||||||
finderApp.Routes(finderAppRoute)
|
// default:
|
||||||
}
|
// ctx.Status(http.StatusBadRequest)
|
||||||
imgViewerRoute := app.Group("img-viewer")
|
// }
|
||||||
{
|
// })
|
||||||
imgViewerApp.Route(imgViewerRoute)
|
// }
|
||||||
}
|
// }
|
||||||
blogViewerRoute := app.Group("blog-viewer")
|
|
||||||
{
|
|
||||||
blogViewerApp.Route(blogViewerRoute)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = router.Run(":8080")
|
// fs := router.Group("fs")
|
||||||
if err != nil {
|
// {
|
||||||
log.Panicf("error: %s", err)
|
// fsGroup := systemGroup.Group("fs")
|
||||||
}
|
// {
|
||||||
}
|
// webfs.PublicRoutes(fsGroup)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// app := router.Group("app")
|
||||||
|
// {
|
||||||
|
// persPropApp := app.Group("AboutMe")
|
||||||
|
// {
|
||||||
|
// persPropsApp.Route(persPropApp)
|
||||||
|
// }
|
||||||
|
// finderAppRoute := app.Group("Finder")
|
||||||
|
// {
|
||||||
|
// finderApp.Routes(finderAppRoute)
|
||||||
|
// }
|
||||||
|
// imgViewerRoute := app.Group("img-viewer")
|
||||||
|
// {
|
||||||
|
// imgViewerApp.Route(imgViewerRoute)
|
||||||
|
// }
|
||||||
|
// blogViewerRoute := app.Group("blog-viewer")
|
||||||
|
// {
|
||||||
|
// blogViewerApp.Route(blogViewerRoute)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// router.Use(cors.New(cors.Config{
|
||||||
|
// AllowAllOrigins: true,
|
||||||
|
// // AllowOrigins: []string{"http://localhost:8080", "http://localhost:9090"},
|
||||||
|
// // AllowMethods: []string{"PUT", "PATCH"},
|
||||||
|
// // AllowHeaders: []string{"Origin"},
|
||||||
|
// ExposeHeaders: []string{"Content-Length"},
|
||||||
|
// AllowCredentials: true,
|
||||||
|
// // AllowOriginFunc: func(origin string) bool {
|
||||||
|
// // return origin == "https://github.com"
|
||||||
|
// // },
|
||||||
|
// MaxAge: 12 * time.Hour,
|
||||||
|
// }))
|
||||||
|
// err = router.Run(":8080")
|
||||||
|
// if err != nil {
|
||||||
|
// log.Panicf("error: %s", err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// func index(c *gin.Context) {
|
// func index(c *gin.Context) {
|
||||||
|
11
personal-website.code-workspace
Normal file
11
personal-website.code-workspace
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "../personal-website-frontend"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
class AboutMe{
|
class AboutMe{
|
||||||
appId = "AboutMe"
|
static appID = "AboutMe"
|
||||||
/**
|
/**
|
||||||
* @param {HTMLElement} appElem
|
* @param {HTMLElement} appElem
|
||||||
*/
|
*/
|
||||||
@ -8,18 +8,17 @@ class AboutMe{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} chroot
|
|
||||||
* @param {[]string} args
|
* @param {[]string} args
|
||||||
|
* @param {Object} runContext
|
||||||
*/
|
*/
|
||||||
async NewWindow(chroot, args){
|
async NewWindow(args, runContext){
|
||||||
console.log(chroot)
|
const params = new URLSearchParams({
|
||||||
if (chroot == ""){
|
path: `:/aboutme.props`,
|
||||||
chroot = "/home/user" //FIXME
|
})
|
||||||
}
|
const response = await fetch(`/app/${AboutMe.appID}/render?`+ params,{
|
||||||
console.log(`${chroot}/AboutMe.app/aboutme.props`)
|
method: "POST",
|
||||||
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile, path: `${chroot}/AboutMe.app/aboutme.props`})
|
body: JSON.stringify(runContext)
|
||||||
const response = await fetch(`/app/${this.appId}/render?`+ params)
|
})
|
||||||
console.log(response)
|
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("Error TODO") //TODO
|
WebDesktopEnvironment.Alert("Error TODO") //TODO
|
||||||
return
|
return
|
@ -1,17 +1,19 @@
|
|||||||
class BlogViewer{
|
class BlogViewer{
|
||||||
appId = "blog-viewer"
|
static appID = "BlogViewer"
|
||||||
constructor(){
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string[]} chroot //TODO
|
|
||||||
* @param {string[]} args
|
* @param {string[]} args
|
||||||
|
* @param {Object} runContext
|
||||||
*/
|
*/
|
||||||
async NewWindow(args){
|
async NewWindow(args, runContext){
|
||||||
const response = await fetch(`app/${this.appId}/render?` + new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
isMobile: WebDesktopEnvironment.isMobile,
|
|
||||||
path: args[0],
|
path: args[0],
|
||||||
}))
|
})
|
||||||
|
runContext.runPath = args[0]
|
||||||
|
const response = await fetch(`app/${BlogViewer.appID}/render?` + params, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(runContext)
|
||||||
|
})
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("Error render TODO") //TODO
|
WebDesktopEnvironment.Alert("Error render TODO") //TODO
|
||||||
return
|
return
|
@ -25,7 +25,25 @@
|
|||||||
/* gap: 50px; */
|
/* gap: 50px; */
|
||||||
/* row-gap: 20px; */
|
/* row-gap: 20px; */
|
||||||
/* padding: 0px 20px 0px 20px; */
|
/* padding: 0px 20px 0px 20px; */
|
||||||
margin: 0px 20px 0px 20px;
|
/* margin: 0px 20px 0px 20px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.BlogView .ScrollContent {
|
||||||
|
position: relative;
|
||||||
|
width: 92%;
|
||||||
|
left: 4%;
|
||||||
|
right: 4%;
|
||||||
|
height: auto;
|
||||||
|
/* Auto layout */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
/* row-gap: 20px; */
|
||||||
|
/* padding: 0px 20px 0px 20px; */
|
||||||
|
/* margin: 0px 20px 0px 20px; */
|
||||||
|
/* padding-left: 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.BlogView .header-h1{
|
.BlogView .header-h1{
|
||||||
@ -43,6 +61,19 @@
|
|||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.BlogView .image{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image .ImageProp{
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
/* left: 50%;
|
||||||
|
margin-left: -50%; */
|
||||||
|
}
|
||||||
|
|
||||||
.BlogView .plain-text{
|
.BlogView .plain-text{
|
||||||
/* Auto layout */
|
/* Auto layout */
|
||||||
display: flex;
|
display: flex;
|
10
res/dev-fs/apps/BlogWriter/BlogWriter.js
Normal file
10
res/dev-fs/apps/BlogWriter/BlogWriter.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class BlogWriter{
|
||||||
|
static AppId = "BlogWriter"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string[]} args
|
||||||
|
*/
|
||||||
|
async NewWindow(args){
|
||||||
|
console.log("kek")
|
||||||
|
}
|
||||||
|
}
|
311
res/dev-fs/apps/Finder/finder.js
Normal file
311
res/dev-fs/apps/Finder/finder.js
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
class Finder{
|
||||||
|
static AppId = "Finder"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string[]} args
|
||||||
|
*/
|
||||||
|
async NewWindow(args, runContext){
|
||||||
|
let newFinder = new FinderWindow()
|
||||||
|
await newFinder.Init(args, runContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async RenderProperites(path){
|
||||||
|
if (path == null || path ==""){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
path: path
|
||||||
|
})
|
||||||
|
const response = await fetch(`/app/${Finder.AppId}/renderProps?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("Error in properties render") //TODO
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const html = await response.text()
|
||||||
|
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.AppId, 350, 500 )
|
||||||
|
newWindow.innerHTML = html
|
||||||
|
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||||
|
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FinderWindow{
|
||||||
|
curPath = ""
|
||||||
|
fileView = undefined
|
||||||
|
windowElem = undefined
|
||||||
|
|
||||||
|
async Init(args, runContext){
|
||||||
|
if (args[1] === "-desktop"){
|
||||||
|
//todo pass div id, not div in args[]
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
isMobile: WebDesktopEnvironment.isMobile,
|
||||||
|
path: args[0]
|
||||||
|
})
|
||||||
|
const response = await fetch(`/app/${Finder.AppId}/renderDesktop?` + params,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(runContext)
|
||||||
|
})
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("Error in render desktop") //TODO
|
||||||
|
}
|
||||||
|
const html = await response.text()
|
||||||
|
args[2].innerHTML = html
|
||||||
|
|
||||||
|
this.fileView = new FileView(
|
||||||
|
args[2].querySelector(".FileTileView"), (event) =>{this.Click(event)},
|
||||||
|
(event) => { this.RightClick(event) },
|
||||||
|
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||||
|
() => { this.ReRenderDir() }
|
||||||
|
)
|
||||||
|
this.RenderDir(args[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile})
|
||||||
|
const response = await fetch(`/app/${Finder.AppId}/render?` + params,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(runContext)
|
||||||
|
})
|
||||||
|
if (response.status != 200){
|
||||||
|
const error = await response.json()
|
||||||
|
WebDesktopEnvironment.Alert(error.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const html = await response.text()
|
||||||
|
|
||||||
|
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.AppId, 500, 350 )
|
||||||
|
newWindow.innerHTML = html
|
||||||
|
|
||||||
|
this.fileView = new FileView(
|
||||||
|
newWindow.querySelector(".FileTileView"),
|
||||||
|
(event) => { this.Click(event) },
|
||||||
|
(event) => { this.RightClick(event) },
|
||||||
|
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||||
|
() => { this.ReRenderDir() }
|
||||||
|
)
|
||||||
|
|
||||||
|
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||||
|
|
||||||
|
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
||||||
|
this.RenderDir('/')
|
||||||
|
})
|
||||||
|
|
||||||
|
newWindow.querySelector("#HomeButton").addEventListener('click', () =>{
|
||||||
|
this.RenderDir('/home/user')
|
||||||
|
})
|
||||||
|
|
||||||
|
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView"))
|
||||||
|
|
||||||
|
this.windowElem = newWindow
|
||||||
|
this.RenderDir(args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
*/
|
||||||
|
RenderDir(path){
|
||||||
|
this.curPath = path
|
||||||
|
this.fileView.OpenFolder(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
ReRenderDir(){
|
||||||
|
this.RenderDir(this.curPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {DragEvent} event
|
||||||
|
* @param {HTMLElement} draggedElem
|
||||||
|
*/
|
||||||
|
async DropEvent(event){
|
||||||
|
// console.log(event.dataTransfer.getData("dropType"))
|
||||||
|
if (event.dataTransfer.getData("dropType") == "move"){
|
||||||
|
const sourcePath= event.dataTransfer.getData("filePath")
|
||||||
|
const targetPath = this.curPath + "/" + event.dataTransfer.getData("fileName")
|
||||||
|
const res = await WebFS.MoveFile(sourcePath, targetPath)
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
} else {
|
||||||
|
WebDesktopEnvironment.Alert("UWAGA TODO MOVE FILE ERROR") //TODO
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(event, this.curPath)
|
||||||
|
let files = event.dataTransfer.files
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
const file = files[i];
|
||||||
|
console.log("file:" + file.name)
|
||||||
|
|
||||||
|
const res = await WebFS.UploadFile(file, this.curPath)
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
parentPath: this.curPath,
|
||||||
|
})
|
||||||
|
const response = await fetch('/fs/upload/?' + params,
|
||||||
|
{
|
||||||
|
method: "POST", //TODO Change to PUT?
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("ERROR IN UPLOADING FILE")//TODO
|
||||||
|
} else {
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MouseEvent} event
|
||||||
|
*/
|
||||||
|
Click(event){
|
||||||
|
this.OpenFile(this.curPath, event.target.getAttribute("name"), event.target.getAttribute("filetype"))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath
|
||||||
|
*/
|
||||||
|
async OpenFile(parentPath, fileName, fileType){
|
||||||
|
// console.log(parentPath, fileName, fileType)
|
||||||
|
// const splittedPath = filePath.split("/")
|
||||||
|
// const fileName = splittedPath[splittedPath.length - 1]
|
||||||
|
const fileExtension = fileName.split(".")[fileName.split(".").length - 1] //FIXME
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case fileType == "objectlink":
|
||||||
|
WebDesktopEnvironment.Alert("Links not supported yet")
|
||||||
|
break
|
||||||
|
case fileType == "pathlink":
|
||||||
|
let res = await WebFS.ReadPathLink(`${parentPath}/${fileName}`)
|
||||||
|
console.log(res)
|
||||||
|
this.OpenFile(res.parentPath, res.name, res.filetype)
|
||||||
|
break
|
||||||
|
case fileExtension == "app":
|
||||||
|
WebDesktopEnvironment.Open(`${parentPath}/${fileName}`, [])
|
||||||
|
break
|
||||||
|
case fileExtension == "blog":
|
||||||
|
WebDesktopEnvironment.Open(`/Applications/BlogViewer.app`, [`${parentPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
case fileType == "directory":
|
||||||
|
WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
case fileExtension == "blog":
|
||||||
|
WebDesktopEnvironment.Open("/Applications/BlogViewer.app", [`${parentPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
case fileExtension == "jpeg" | fileExtension == "png":
|
||||||
|
WebDesktopEnvironment.Open("img-viewer", [`${parentPath}/${fileName}`])
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WebDesktopEnvironment.Alert("Unsupported file type")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MouseEvent} event
|
||||||
|
*/
|
||||||
|
RightClick(event){
|
||||||
|
this.CreateContextMenu(event.target, [event.clientY, event.clientX])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} target
|
||||||
|
* @param {string[]} pos
|
||||||
|
*/
|
||||||
|
async CreateContextMenu(target, pos){
|
||||||
|
let context = ""
|
||||||
|
const fileName = target.getAttribute("name") //TODO check for null
|
||||||
|
const fileType = target.getAttribute("fileType")
|
||||||
|
if (target.classList.contains("FileTileView"))
|
||||||
|
{
|
||||||
|
context = "FileTileView"
|
||||||
|
} else {
|
||||||
|
context = fileType
|
||||||
|
}
|
||||||
|
let path = ""
|
||||||
|
if (fileName === null){
|
||||||
|
path = this.curPath
|
||||||
|
} else {
|
||||||
|
path = `${this.curPath}/${fileName}`
|
||||||
|
}
|
||||||
|
const params = new URLSearchParams({context: context, path: path})
|
||||||
|
const response = await fetch(`/app/${Finder.AppId}/contextMenu?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("ERROR in Context menu TODO"); //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const html = await response.text()
|
||||||
|
let overlay = document.createElement("div") //TODO Move to WDE.CreateOverlay()
|
||||||
|
overlay.setAttribute('id', 'finder-context-menu-overlay')
|
||||||
|
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.top = pos[0] + "px";
|
||||||
|
menu.style.left = pos[1] + "px";
|
||||||
|
|
||||||
|
menu.innerHTML = html
|
||||||
|
// menu.children[0].firstElementChild.remove()
|
||||||
|
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', async (event) => {
|
||||||
|
if (event.target.classList.contains("Row")){ //TODO add uuid id to rows to more accurate checks??
|
||||||
|
let res = false
|
||||||
|
switch (event.target.children[0].getAttribute("action")) {
|
||||||
|
case "createPathLink":
|
||||||
|
res = await WebFS.CreatePathLink(`${this.curPath}/${fileName}`, `${this.curPath}/Link to ${fileName}` )
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "createDir":
|
||||||
|
res = await WebFS.CreateDirectory(`${this.curPath}`)
|
||||||
|
console.log(res)
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "deleteFile":
|
||||||
|
res = await WebFS.DeleteFile(`${this.curPath}/${fileName}`)
|
||||||
|
console.log(res)
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "getInfo":
|
||||||
|
Finder.RenderProperites(path)
|
||||||
|
break
|
||||||
|
case "openAsDir":
|
||||||
|
WebDesktopEnvironment.Open(`/Applications/${Finder.AppId}.app`,[`${this.curPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
overlay.remove()
|
||||||
|
})
|
||||||
|
overlay.addEventListener('contextmenu', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
overlay.remove()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,131 +1,32 @@
|
|||||||
class Finder{
|
class FinderAdmin{
|
||||||
static appId = "Finder"
|
static AppId = "FinderAdmin"
|
||||||
appId = "Finder"
|
|
||||||
fileView = undefined
|
|
||||||
path = "/"
|
|
||||||
homePath = "/home/user"
|
|
||||||
windowElement
|
|
||||||
// previousPath = "/"
|
|
||||||
pathHistory = [] //FIXME Fixed length
|
|
||||||
constructor(){
|
|
||||||
// this.appElem = appElem
|
|
||||||
// WebDesktopEnvironment.RegisterApp(this)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* @param {string[]} args
|
* @param {string[]} args
|
||||||
*/
|
*/
|
||||||
async NewWindow(args){
|
async NewWindow(args, runContext){
|
||||||
let newFinder = new FinderWindow()
|
let newFinder = new FinderWindow()
|
||||||
await newFinder.Init(args)
|
await newFinder.Init(args, runContext)
|
||||||
return
|
|
||||||
this.path = args[0]
|
|
||||||
if (args[1] == "desktop"){
|
|
||||||
this.NewDesktop(args)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile})
|
|
||||||
fetch(`/app/${Finder.appId}/render?` + params)
|
|
||||||
.then((response) => response.text())
|
|
||||||
.then((html) => {
|
|
||||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.appId, 500, 350 )
|
|
||||||
newWindow.innerHTML = html
|
|
||||||
|
|
||||||
this.fileView = new FileView(newWindow.querySelector(".FileTileView"),
|
|
||||||
(event) =>{ this.Click(event) },
|
|
||||||
(event) =>{ this.RightClick(event) },
|
|
||||||
(event, draggedElem) =>{ this.DropEvent(event, draggedElem) },
|
|
||||||
)
|
|
||||||
this.OpenDir(this.path)
|
|
||||||
|
|
||||||
newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
|
||||||
this.OpenDir('/')
|
|
||||||
})
|
|
||||||
|
|
||||||
newWindow.querySelector("#HomeButton").addEventListener('click', () =>{
|
|
||||||
this.OpenDir('/home/user')
|
|
||||||
})
|
|
||||||
|
|
||||||
this.windowElement = newWindow
|
|
||||||
|
|
||||||
if (!WebDesktopEnvironment.isMobile){
|
|
||||||
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView"))
|
|
||||||
// console.log(newWindow.querySelector("#closeWindowButton"))
|
|
||||||
|
|
||||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
|
||||||
|
|
||||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
WebDesktopEnvironment.Alert(error);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string[]} args
|
|
||||||
*/
|
|
||||||
NewDesktop(args){
|
|
||||||
fetch(`${window.location.origin}/application/${Finder.appId}/renderDesktop?` + new URLSearchParams({
|
|
||||||
isMobile: WebDesktopEnvironment.isMobile,
|
|
||||||
path: args[0]
|
|
||||||
}))
|
|
||||||
.then((response) => response.text())
|
|
||||||
.then((html) => {
|
|
||||||
// console.log(args)
|
|
||||||
args[2].innerHTML = html
|
|
||||||
|
|
||||||
this.fileView = new FileView(args[2].querySelector(".FileTileView"), (event) =>{
|
|
||||||
this.Click(event, true)
|
|
||||||
})
|
|
||||||
this.OpenDir(this.path)
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
WebDesktopEnvironment.Alert(error);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenPreviousDir(){
|
|
||||||
// if (this.pathHistory.length > 0){
|
|
||||||
// // console.log(this.pathHistory)
|
|
||||||
// let path = this.pathHistory[this.pathHistory.length - 1]
|
|
||||||
// // console.log(typeof( this.pathHistory))
|
|
||||||
// this.pathHistory.pop()
|
|
||||||
// this.OpenDir(this.path)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} path
|
|
||||||
*/
|
|
||||||
OpenDir(path){
|
|
||||||
this.path = path
|
|
||||||
this.fileView.OpenFolder(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// */
|
|
||||||
// OpenNewDir(){
|
|
||||||
// WebDesktopEnvironment.Open("finder", [this.path])
|
|
||||||
// }
|
|
||||||
/**
|
/**
|
||||||
* @param {string} path
|
* @param {string} path
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
static async RenderProperites(path){
|
static async RenderProperites(path){
|
||||||
|
if (path == null || path ==""){
|
||||||
|
return
|
||||||
|
}
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
path: path
|
path: path
|
||||||
})
|
})
|
||||||
const response = await fetch(`/application/${Finder.appId}/renderProps?` + params)
|
const response = await fetch(`/app/Finder/renderProps?` + params)
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("Error in properties render") //TODO
|
WebDesktopEnvironment.Alert("Error in properties render") //TODO
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const html = response.text()
|
const html = await response.text()
|
||||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.appId, 350, 500 )
|
let newWindow = WebDesktopEnvironment.CreateNewWindow(FinderAdmin.AppId, 350, 500 )
|
||||||
newWindow.innerHTML = html
|
newWindow.innerHTML = html
|
||||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||||
@ -135,42 +36,49 @@ class Finder{
|
|||||||
|
|
||||||
|
|
||||||
class FinderWindow{
|
class FinderWindow{
|
||||||
CurPath = ""
|
curPath = ""
|
||||||
fileView = undefined
|
fileView = undefined
|
||||||
windowElem = undefined
|
windowElem = undefined
|
||||||
|
addressBar = undefined
|
||||||
|
|
||||||
async Init(args){
|
async Init(args, runContext){
|
||||||
// console.log(args)
|
|
||||||
if (args[1] === "-desktop"){
|
if (args[1] === "-desktop"){
|
||||||
|
//todo pass div id, not div in args[]
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
isMobile: WebDesktopEnvironment.isMobile,
|
isMobile: WebDesktopEnvironment.isMobile,
|
||||||
path: args[0]
|
path: args[0]
|
||||||
})
|
})
|
||||||
const response = await fetch(`/app/${Finder.appId}/renderDesktop?` + params)
|
const response = await fetch(`/app/Finder/renderDesktop?` + params)
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("Error in render desktop") //TODO
|
WebDesktopEnvironment.Alert("Error in render desktop") //TODO
|
||||||
}
|
}
|
||||||
const html = await response.text()
|
const html = await response.text()
|
||||||
args[2].innerHTML = html
|
args[2].innerHTML = html
|
||||||
|
|
||||||
this.fileView = new FileView(args[2].querySelector(".FileTileView"), (event) =>{
|
this.fileView = new FileView(
|
||||||
this.Click(event, true)
|
args[2].querySelector(".FileTileView"), (event) =>{this.Click(event)},
|
||||||
})
|
(event) => { this.RightClick(event) },
|
||||||
|
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||||
|
() => { this.ReRenderDir() }
|
||||||
|
)
|
||||||
this.RenderDir(args[0])
|
this.RenderDir(args[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile})
|
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile})
|
||||||
const response = await fetch(`/app/${Finder.appId}/render?` + params)
|
const response = await fetch(`/app/Finder/render?` + params,{
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(runContext)
|
||||||
|
})
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("Finder ERROR TODO") //TODO
|
const error = await response.json()
|
||||||
|
WebDesktopEnvironment.Alert(error.message)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const html = await response.text()
|
const html = await response.text()
|
||||||
|
|
||||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.appId, 500, 350 )
|
let newWindow = WebDesktopEnvironment.CreateNewWindow(FinderAdmin.AppId, 500, 350 )
|
||||||
newWindow.innerHTML = html
|
newWindow.innerHTML = html
|
||||||
|
|
||||||
// console.log(this.ReRenderDir)
|
|
||||||
this.fileView = new FileView(
|
this.fileView = new FileView(
|
||||||
newWindow.querySelector(".FileTileView"),
|
newWindow.querySelector(".FileTileView"),
|
||||||
(event) => { this.Click(event) },
|
(event) => { this.Click(event) },
|
||||||
@ -180,9 +88,7 @@ class FinderWindow{
|
|||||||
)
|
)
|
||||||
|
|
||||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||||
|
|
||||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
||||||
@ -195,18 +101,23 @@ class FinderWindow{
|
|||||||
|
|
||||||
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView"))
|
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView"))
|
||||||
|
|
||||||
|
|
||||||
this.windowElem = newWindow
|
this.windowElem = newWindow
|
||||||
|
this.addressBar = newWindow.querySelector(".AddressBar")
|
||||||
this.RenderDir(args[0])
|
this.RenderDir(args[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
*/
|
||||||
RenderDir(path){
|
RenderDir(path){
|
||||||
this.CurPath = path
|
console.log(path)
|
||||||
|
this.curPath = path
|
||||||
|
this.addressBar.innerHTML = path
|
||||||
this.fileView.OpenFolder(path)
|
this.fileView.OpenFolder(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
ReRenderDir(){
|
ReRenderDir(){
|
||||||
this.RenderDir(this.CurPath)
|
this.RenderDir(this.curPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,7 +128,7 @@ class FinderWindow{
|
|||||||
// console.log(event.dataTransfer.getData("dropType"))
|
// console.log(event.dataTransfer.getData("dropType"))
|
||||||
if (event.dataTransfer.getData("dropType") == "move"){
|
if (event.dataTransfer.getData("dropType") == "move"){
|
||||||
const sourcePath= event.dataTransfer.getData("filePath")
|
const sourcePath= event.dataTransfer.getData("filePath")
|
||||||
const targetPath = this.CurPath + "/" + event.dataTransfer.getData("fileName")
|
const targetPath = this.curPath + "/" + event.dataTransfer.getData("fileName")
|
||||||
const res = await WebFS.MoveFile(sourcePath, targetPath)
|
const res = await WebFS.MoveFile(sourcePath, targetPath)
|
||||||
if (res){
|
if (res){
|
||||||
this.ReRenderDir()
|
this.ReRenderDir()
|
||||||
@ -225,17 +136,20 @@ class FinderWindow{
|
|||||||
WebDesktopEnvironment.Alert("UWAGA TODO MOVE FILE ERROR") //TODO
|
WebDesktopEnvironment.Alert("UWAGA TODO MOVE FILE ERROR") //TODO
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WebDesktopEnvironment.Alert("Not fixed yet")
|
console.log(event, this.curPath)
|
||||||
return
|
|
||||||
let formData = new FormData()
|
|
||||||
let files = event.dataTransfer.files
|
let files = event.dataTransfer.files
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
const element = files[i];
|
const file = files[i];
|
||||||
console.log(element)
|
console.log("file:" + file.name)
|
||||||
formData.append("file", element) //FIXME Conn reset
|
|
||||||
|
const res = await WebFS.UploadFile(file, this.curPath)
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
parentPath: this.CurPath,
|
parentPath: this.curPath,
|
||||||
})
|
})
|
||||||
const response = await fetch('/fs/upload/?' + params,
|
const response = await fetch('/fs/upload/?' + params,
|
||||||
{
|
{
|
||||||
@ -255,26 +169,40 @@ class FinderWindow{
|
|||||||
* @param {MouseEvent} event
|
* @param {MouseEvent} event
|
||||||
*/
|
*/
|
||||||
Click(event){
|
Click(event){
|
||||||
let fileType = event.target.getAttribute("fileType")
|
this.OpenFile(this.curPath, event.target.getAttribute("name"), event.target.getAttribute("filetype"))
|
||||||
let fileName = event.target.getAttribute("name")
|
|
||||||
const fileExtension = fileName.split(".")[fileName.split(".").length - 1] //FIXME
|
|
||||||
switch (fileType) {
|
|
||||||
case "directory":
|
|
||||||
if (fileExtension == "app"){
|
|
||||||
WebDesktopEnvironment.Open(`${this.CurPath}/${fileName}`, [])
|
|
||||||
} else{
|
|
||||||
WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${this.CurPath}/${fileName}`])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath
|
||||||
|
*/
|
||||||
|
async OpenFile(parentPath, fileName, fileType){
|
||||||
|
// console.log(parentPath, fileName, fileType)
|
||||||
|
// const splittedPath = filePath.split("/")
|
||||||
|
// const fileName = splittedPath[splittedPath.length - 1]
|
||||||
|
const fileExtension = fileName.split(".")[fileName.split(".").length - 1] //FIXME
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case fileType == "objectlink":
|
||||||
|
WebDesktopEnvironment.Alert("Links not supported yet")
|
||||||
break
|
break
|
||||||
case "blog":
|
case fileType == "pathlink":
|
||||||
WebDesktopEnvironment.Open("/Applications/BlogViewer.app", [`${this.CurPath}/${fileName}`])
|
let res = await WebFS.ReadPathLink(`${parentPath}/${fileName}`)
|
||||||
|
console.log(res)
|
||||||
|
this.OpenFile(res.parentPath, res.name, res.filetype)
|
||||||
break
|
break
|
||||||
case "jpeg":
|
case fileExtension == "app":
|
||||||
case "png":
|
WebDesktopEnvironment.Open(`${parentPath}/${fileName}`, [])
|
||||||
WebDesktopEnvironment.Open("img-viewer", [this.CurPath + "/" + fileName])
|
break
|
||||||
|
case fileType == "directory":
|
||||||
|
WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
case fileExtension == "blog":
|
||||||
|
WebDesktopEnvironment.Open("/Applications/BlogViewer.app", [`${parentPath}/${fileName}`])
|
||||||
|
break
|
||||||
|
case fileExtension == "jpeg" | fileExtension == "png":
|
||||||
|
WebDesktopEnvironment.Open("img-viewer", [`${parentPath}/${fileName}`])
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// console.log("Unsupported file type")
|
|
||||||
WebDesktopEnvironment.Alert("Unsupported file type")
|
WebDesktopEnvironment.Alert("Unsupported file type")
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -293,7 +221,7 @@ class FinderWindow{
|
|||||||
*/
|
*/
|
||||||
async CreateContextMenu(target, pos){
|
async CreateContextMenu(target, pos){
|
||||||
let context = ""
|
let context = ""
|
||||||
const fileName = target.getAttribute("name")
|
const fileName = target.getAttribute("name") //TODO check for null
|
||||||
const fileType = target.getAttribute("fileType")
|
const fileType = target.getAttribute("fileType")
|
||||||
if (target.classList.contains("FileTileView"))
|
if (target.classList.contains("FileTileView"))
|
||||||
{
|
{
|
||||||
@ -301,8 +229,14 @@ class FinderWindow{
|
|||||||
} else {
|
} else {
|
||||||
context = fileType
|
context = fileType
|
||||||
}
|
}
|
||||||
const params = new URLSearchParams({context: context, path: `${this.CurPath}/${fileName}`})
|
let path = ""
|
||||||
const response = await fetch(`/app/${Finder.appId}/contextMenu?` + params)
|
if (fileName === null){
|
||||||
|
path = this.curPath
|
||||||
|
} else {
|
||||||
|
path = `${this.curPath}/${fileName}`
|
||||||
|
}
|
||||||
|
const params = new URLSearchParams({context: context, path: path})
|
||||||
|
const response = await fetch(`/app/Finder/contextMenu?` + params)
|
||||||
if (response.status != 200){
|
if (response.status != 200){
|
||||||
WebDesktopEnvironment.Alert("ERROR in Context menu TODO"); //TODO
|
WebDesktopEnvironment.Alert("ERROR in Context menu TODO"); //TODO
|
||||||
return
|
return
|
||||||
@ -331,25 +265,31 @@ class FinderWindow{
|
|||||||
if (event.target.classList.contains("Row")){ //TODO add uuid id to rows to more accurate checks??
|
if (event.target.classList.contains("Row")){ //TODO add uuid id to rows to more accurate checks??
|
||||||
let res = false
|
let res = false
|
||||||
switch (event.target.children[0].getAttribute("action")) {
|
switch (event.target.children[0].getAttribute("action")) {
|
||||||
|
case "createPathLink":
|
||||||
|
res = await WebFS.CreatePathLink(`${this.curPath}/${fileName}`, `${this.curPath}/Link to ${fileName}` )
|
||||||
|
if (res){
|
||||||
|
this.ReRenderDir()
|
||||||
|
}
|
||||||
|
break
|
||||||
case "createDir":
|
case "createDir":
|
||||||
res = await WebFS.CreateDirectory(`${this.CurPath}`)
|
res = await WebFS.CreateDirectory(`${this.curPath}`)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res){
|
if (res){
|
||||||
this.ReRenderDir()
|
this.ReRenderDir()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "deleteFile":
|
case "deleteFile":
|
||||||
res = await WebFS.DeleteFile(`${this.CurPath}/${fileName}`)
|
res = await WebFS.DeleteFile(`${this.curPath}/${fileName}`)
|
||||||
console.log(res)
|
console.log(res)
|
||||||
if (res){
|
if (res){
|
||||||
this.ReRenderDir()
|
this.ReRenderDir()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "getInfo":
|
case "getInfo":
|
||||||
res = await Finder.RenderProperites(`${this.CurPath}/${fileName}`)
|
Finder.RenderProperites(path)
|
||||||
break
|
break
|
||||||
case "openAsDir":
|
case "openAsDir":
|
||||||
WebDesktopEnvironment.Open(`/Applications/${Finder.appId}.app`,[`${this.CurPath}/${fileName}`])
|
WebDesktopEnvironment.Open(`/Applications/Finder.app`,[`${this.curPath}/${fileName}`])
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
53
res/dev-fs/apps/FinderAdmin/finder-admin.css
Normal file
53
res/dev-fs/apps/FinderAdmin/finder-admin.css
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
.FinderContent {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
/* Auto layout */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.FinderContent .ToolBar{
|
||||||
|
width: 100%;
|
||||||
|
height: 20px;
|
||||||
|
border-bottom: 1px solid #555555;
|
||||||
|
background-color: #EEEEEE;
|
||||||
|
|
||||||
|
/* Auto layout */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content:left;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0px;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ToolBar .AddressBar{
|
||||||
|
width:100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Focused .FinderContent .ToolBar{
|
||||||
|
border-bottom: 1px solid #000000;
|
||||||
|
background-color: #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.FinderContent .FinderFileView{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
|
||||||
|
/* Auto layout */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
@font-face{
|
@font-face{
|
||||||
font-family: "Virtue";
|
font-family: "Virtue";
|
||||||
src:url("./virtue.ttf");
|
src:url("/res/dev-fs/fonts/virtue.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face{
|
/* @font-face{
|
||||||
font-family: "Virtue";
|
font-family: "Virtue";
|
||||||
src:url("./virtue.ttf")
|
src:url("/res/dev-fs/fonts/virtue.ttf")
|
||||||
}
|
} */
|
||||||
|
|
||||||
/* @media screen and (max-device-width: 2048px) and (max-device-height: 2048px) {
|
/* @media screen and (max-device-width: 2048px) and (max-device-height: 2048px) {
|
||||||
html {
|
html {
|
54
res/dev-fs/wde/decorat.js
Normal file
54
res/dev-fs/wde/decorat.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
class WindowsCompositor{
|
||||||
|
static windowsLayer
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
this.windowLayer = document.body.querySelector('#windows-layer')
|
||||||
|
WindowsCompositor.windowsLayer = document.body.querySelector('#windows-layer')
|
||||||
|
if (!WebDesktopEnvironment.isMobile) {
|
||||||
|
let startDrag = function(event) {
|
||||||
|
let window = event.target.closest('.WindowFrame')
|
||||||
|
WindowsCompositor.bringWindowToFront(window)
|
||||||
|
if (event.target.classList.contains("DragArea")){
|
||||||
|
let xPosInit = event.offsetX
|
||||||
|
let yPosInit = event.offsetY
|
||||||
|
let dragWindow = function(event){
|
||||||
|
window.style.left = `${event.clientX - xPosInit}px`
|
||||||
|
window.style.top = `${event.clientY - yPosInit}px`
|
||||||
|
}
|
||||||
|
let stopDrag = function(){
|
||||||
|
removeEventListener('mousemove', dragWindow)
|
||||||
|
removeEventListener('mouseup', stopDrag)
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener('mousemove', dragWindow)
|
||||||
|
addEventListener('mouseup', stopDrag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WindowsCompositor.windowsLayer.addEventListener('mousedown', startDrag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} window
|
||||||
|
*/
|
||||||
|
static bringWindowToFront(window){ //FIXME
|
||||||
|
let previousWindow = WindowsCompositor.windowsLayer.lastChild
|
||||||
|
if (window == null || window == undefined){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (window != previousWindow){
|
||||||
|
WindowsCompositor.windowsLayer.insertBefore(window, previousWindow.nextSibling)
|
||||||
|
previousWindow.classList.remove("Focused")
|
||||||
|
window.classList.add("Focused")
|
||||||
|
} else {
|
||||||
|
window.classList.add("Focused")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ChangeURL(appWindow){
|
||||||
|
let appId = appWindow.getAttribute('appid')
|
||||||
|
window.history.replaceState(null, "", `/${appId}/`);
|
||||||
|
}
|
||||||
|
}
|
239
res/dev-fs/wde/wde.js
Normal file
239
res/dev-fs/wde/wde.js
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
//TODO Scroll to mobile desktop: https://css-tricks.com/scroll-fix-content/
|
||||||
|
|
||||||
|
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/blog1.blog"])
|
||||||
|
// WebDesktopEnvironment.Open("personal-properties", ["/home/user/aboutme.props"])
|
||||||
|
} else {
|
||||||
|
// WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// WebDesktopEnvironment.Open("personal-properties")
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
// const ErrorObject = {
|
||||||
|
// message string
|
||||||
|
// }
|
||||||
|
|
||||||
|
class WebDesktopEnvironment{
|
||||||
|
static Applications = {};
|
||||||
|
static isMobile = false
|
||||||
|
static decorat
|
||||||
|
static webFs
|
||||||
|
constructor(){
|
||||||
|
// WebDesktopEnvironment.isMobile = WebDesktopEnvironment.CheckMobile()
|
||||||
|
document.body.style.setProperty('--zoom', 1)
|
||||||
|
WebDesktopEnvironment.wc = new WindowsCompositor()
|
||||||
|
WebDesktopEnvironment.webFs = new WebFS()
|
||||||
|
this.loadWDE()
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadWDE(){
|
||||||
|
// await WebDesktopEnvironment.load2('/Applications/Finder.app', [ "desktop", document.querySelector('#desktop-layer')]) //FIXME
|
||||||
|
// await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/.desktop", "-desktop", document.querySelector('#desktop-layer')])
|
||||||
|
await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/Blogs",])
|
||||||
|
// await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user",])
|
||||||
|
// await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home",])
|
||||||
|
// WebDesktopEnvironment.Open('/Applications/AboutMe.app', [])
|
||||||
|
// WebDesktopEnvironment.Open('/Applications/FinderAdmin.app', ["/home/user",])
|
||||||
|
// await WebDesktopEnvironment.Open('/Applications/BlogViewer.app', ["/home/user/Blogs/blog1.blog",])
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} appPath
|
||||||
|
* @param {string[]} args
|
||||||
|
* @param {string} runPath
|
||||||
|
*/
|
||||||
|
static async Open(appPath, args, runPath){
|
||||||
|
const appManifest = await WebDesktopEnvironment.fetchApp(appPath)
|
||||||
|
|
||||||
|
if (appManifest === undefined) return //TODO return err
|
||||||
|
const runContext = {
|
||||||
|
isMobile: false,
|
||||||
|
bundlePath: appPath,
|
||||||
|
runPath: runPath //TODO
|
||||||
|
}
|
||||||
|
if (WebDesktopEnvironment.Applications[appManifest.appId] === undefined){
|
||||||
|
WebDesktopEnvironment.load2(appManifest, () =>{
|
||||||
|
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} appManifest
|
||||||
|
* @param {function} onload callback after script loading
|
||||||
|
*/
|
||||||
|
static async load2(appManifest, onload){
|
||||||
|
let appElem = document.createElement("div")
|
||||||
|
appElem.setAttribute("appId", appManifest.appId)
|
||||||
|
//TODO Render scripts nodes on server
|
||||||
|
//FIXME Not support more than one js now :)
|
||||||
|
let script = document.createElement("script")
|
||||||
|
script.setAttribute("src", appManifest.js[0]) //FIXME path by fs read
|
||||||
|
script.setAttribute("async", "false") //TODO Possible may creates a problems??
|
||||||
|
appElem.appendChild(script)
|
||||||
|
|
||||||
|
document.getElementById("applications").appendChild(appElem)
|
||||||
|
script.addEventListener('load', (event) => {
|
||||||
|
let newApp = eval(`new ${appManifest.appId}()`);
|
||||||
|
//TODO Check if newApp undefined
|
||||||
|
WebDesktopEnvironment.Applications[appManifest.appId] = newApp;
|
||||||
|
onload()
|
||||||
|
})
|
||||||
|
return //TODO return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {Object | undefined} //FIXME
|
||||||
|
*/
|
||||||
|
static async fetchApp(path){
|
||||||
|
// console.log("path: " + path )
|
||||||
|
const params = new URLSearchParams({path: path, mode: "json"})
|
||||||
|
const response = await fetch(`/system/loadApp?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
const error = await response.json()
|
||||||
|
WebDesktopEnvironment.Alert(error.message)
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
//TODO Validate manifest
|
||||||
|
const appManifest = response.json()
|
||||||
|
return appManifest
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} appId
|
||||||
|
* @param {number} width
|
||||||
|
* @param {number} height
|
||||||
|
* @returns {HTMLElement}
|
||||||
|
*/
|
||||||
|
static CreateNewWindow(appId, width, height) {
|
||||||
|
let newWindow = document.createElement("div")
|
||||||
|
newWindow.setAttribute('appid', appId)
|
||||||
|
if (WebDesktopEnvironment.isMobile){
|
||||||
|
newWindow.setAttribute("class", "MobileApplicationWindow")
|
||||||
|
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
||||||
|
return newWindow
|
||||||
|
} else {
|
||||||
|
newWindow.setAttribute("class", "WindowFrame ConvexElement")
|
||||||
|
newWindow.setAttribute("windowId", WebDesktopEnvironment.makeid(4)) //TODO:
|
||||||
|
|
||||||
|
newWindow.style.width = width.toString() + "px"
|
||||||
|
newWindow.style.height = height.toString() + "px"
|
||||||
|
|
||||||
|
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
||||||
|
return newWindow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {HTMLElement} window
|
||||||
|
*/
|
||||||
|
static CloseWindow(window) {
|
||||||
|
window.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
static CloseFocusedWindow() {
|
||||||
|
if (document.body.querySelector('#windows-layer').childElementCount > 1){
|
||||||
|
document.body.querySelector('#windows-layer').lastElementChild.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} html
|
||||||
|
*/
|
||||||
|
static SetBasicWindow(html){
|
||||||
|
this.basicWindow = html
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static GetBasicWindow(){
|
||||||
|
return this.basicWindow
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} alertText
|
||||||
|
*/
|
||||||
|
static Alert(alertText){
|
||||||
|
WebDesktopEnvironment.CreateAlertWindow(alertText)
|
||||||
|
console.log(alertText)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} alertText
|
||||||
|
*/
|
||||||
|
static CreateAlertWindow(alertText){
|
||||||
|
let newWindow = document.createElement("div")
|
||||||
|
newWindow.setAttribute("class", "WindowFrameless")
|
||||||
|
newWindow.setAttribute("windowId", "SuperUniqUUID") //TODO:
|
||||||
|
newWindow.style.cssText = "position:absolute;width:450px;height:116px; margin-left: -225px; margin-top:-58px;left: 50%;top: 50%;background-color:#FFFFFF;border: 1px solid #000000;box-shadow: 2px 2px 0px #000000;"
|
||||||
|
|
||||||
|
let alertImage = document.createElement("img")
|
||||||
|
alertImage.setAttribute("src", "/res/sys/wde/icons/ohno.png")
|
||||||
|
alertImage.style.cssText = "position:absolute; width:64px;height:64px;top:15px;left:25px"
|
||||||
|
newWindow.appendChild(alertImage)
|
||||||
|
|
||||||
|
let errorText = document.createElement("div")
|
||||||
|
errorText.style.cssText = "position:absolute; width: 300px; left:128px; top:30px;font-family: 'Virtue';"
|
||||||
|
errorText.innerHTML = alertText
|
||||||
|
newWindow.appendChild(errorText)
|
||||||
|
|
||||||
|
let closeButton = document.createElement("button")
|
||||||
|
closeButton.style.cssText = "position:absolute; left: 382px; bottom: 10px; background-color:#FFFFFF; width: 55px; height:18px; font-family: 'Virtue'; border-radius:4px;border: 1px solid #000000;"
|
||||||
|
closeButton.innerHTML = "Close"
|
||||||
|
closeButton.addEventListener('click', () => { newWindow.remove()})
|
||||||
|
newWindow.appendChild(closeButton)
|
||||||
|
|
||||||
|
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
||||||
|
}
|
||||||
|
|
||||||
|
static CheckMobile(){
|
||||||
|
var check = false;
|
||||||
|
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {num} length
|
||||||
|
*/
|
||||||
|
static makeid(length) {
|
||||||
|
let result = '';
|
||||||
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
const charactersLength = characters.length;
|
||||||
|
let counter = 0;
|
||||||
|
while (counter < length) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deprecated
|
||||||
|
var getJSON = function(url, callback) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.onload = function() {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status === 200) {
|
||||||
|
callback(null, xhr.response);
|
||||||
|
} else {
|
||||||
|
callback(status, xhr.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
};
|
131
res/dev-fs/wde/webfs.js
Normal file
131
res/dev-fs/wde/webfs.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
class WebFS{
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async CreateDirectory(path){
|
||||||
|
if (path == undefined){
|
||||||
|
WebDesktopEnvironment.Alert("Path is undefined")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
path: `${path}/New Directory`
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/createDir?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("DIRCTORY CREATION ERROR") //TODO
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async DeleteFile(path){
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
path: path
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/delete?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("DELETE ERROR") //TODO
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async MoveFile(sourcePath, targetPath){
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
sourcePath: sourcePath,
|
||||||
|
targetPath: targetPath
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/move?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
// WebDesktopEnvironment.Alert("Move ERROR") //TODO
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} linkPath
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static async ReadObjectLink(linkPath){
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
linkPath: linkPath,
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/readObjectLink?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("TODO") //TODO
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
const path = await response.text()
|
||||||
|
//TODO Validate
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sourcePath
|
||||||
|
* @param {string} linkPath
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static async CreatePathLink(sourcePath, linkPath){
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
sourcePath: sourcePath,
|
||||||
|
linkPath: linkPath,
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/createPathLink?` + params)
|
||||||
|
return response.status == 200
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} linkPath
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
static async ReadPathLink(linkPath){
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
linkPath: linkPath,
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/readPathLink?` + params)
|
||||||
|
if (response.status != 200){
|
||||||
|
WebDesktopEnvironment.Alert("TODO") //TODO
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// console.log(response)
|
||||||
|
const file = await response.json()
|
||||||
|
//TODO Validate
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {File} file
|
||||||
|
* @param {string} parentPath
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
static async UploadFile(file, parentPath){
|
||||||
|
console.log('here')
|
||||||
|
let formData = new FormData()
|
||||||
|
formData.append("file", file) //FIXME Conn reset
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
parentPath: parentPath,
|
||||||
|
})
|
||||||
|
const response = await fetch(`/system/fs/upload?` + params,
|
||||||
|
{
|
||||||
|
method: "POST", //TODO Change to PUT?
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status != 201){
|
||||||
|
const error = await response.json()
|
||||||
|
WebDesktopEnvironment.Alert(error.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
export class Application{
|
|
||||||
Init(){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
//
|
|
BIN
resources/img/default-avatar-photo-placeholder-profile-picture-vector.jpg
(Stored with Git LFS)
BIN
resources/img/default-avatar-photo-placeholder-profile-picture-vector.jpg
(Stored with Git LFS)
Binary file not shown.
@ -1,8 +0,0 @@
|
|||||||
<div id="prop" class="personal-properties-prop">
|
|
||||||
{{ range $book := .books }}
|
|
||||||
<h1>{{ .Title }}</h1>
|
|
||||||
<h3>{{ .Author }}</h3>
|
|
||||||
<hr/>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
|||||||
<div class="Personal-properties-bio">
|
|
||||||
<img src="res/img/default-avatar-photo-placeholder-profile-picture-vector.jpg" style="width: 48px;height: 48px;">
|
|
||||||
<div class="Personal-properties-textbio">
|
|
||||||
<div>{{ .Name }}</div>
|
|
||||||
<div>{{ .BasicBio }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{ range $props := .allprops }}
|
|
||||||
<div id="prop" class="Personal-properties-prop">
|
|
||||||
<div class="Personal-properties-prop-header">
|
|
||||||
Test Title:
|
|
||||||
</div>
|
|
||||||
<div class="Personal-properties-prop-content">
|
|
||||||
{{range $prop := $props}}
|
|
||||||
<div class="Personal-properties-prop-row">
|
|
||||||
<div class="Personal-properties-prop-key">{{.Key}}:</div>
|
|
||||||
<div class="Personal-properties-prop-values">
|
|
||||||
{{ range $value := .Values }}
|
|
||||||
<div class="Personal-properties-prop-value">
|
|
||||||
{{ $value }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
409
resources/wde.js
409
resources/wde.js
@ -1,409 +0,0 @@
|
|||||||
//TODO Scroll to mobile desktop: https://css-tricks.com/scroll-fix-content/
|
|
||||||
|
|
||||||
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/blog1.blog"])
|
|
||||||
// WebDesktopEnvironment.Open("personal-properties", ["/home/user/aboutme.props"])
|
|
||||||
} else {
|
|
||||||
// WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog/test-1.blog"])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// WebDesktopEnvironment.Open("personal-properties")
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
class WebDesktopEnvironment{
|
|
||||||
static Applications = {};
|
|
||||||
static isMobile = false
|
|
||||||
constructor(){
|
|
||||||
// WebDesktopEnvironment.isMobile = WebDesktopEnvironment.CheckMobile()
|
|
||||||
document.body.style.setProperty('--zoom', 1)
|
|
||||||
this.wc = new WindowsCompositor()
|
|
||||||
this.loadWDE()
|
|
||||||
let kek = new WebFS()
|
|
||||||
return
|
|
||||||
|
|
||||||
// let applications = document.createElement("div")
|
|
||||||
// applications.setAttribute('id', 'applications')
|
|
||||||
// document.body.appendChild(applications)
|
|
||||||
|
|
||||||
if( WebDesktopEnvironment.isMobile){
|
|
||||||
document.body.style.setProperty('--zoom', 3)
|
|
||||||
|
|
||||||
let mobileDesktop = document.createElement("div")
|
|
||||||
mobileDesktop.setAttribute('id', 'mobile-desktop')
|
|
||||||
document.body.appendChild(mobileDesktop)
|
|
||||||
|
|
||||||
fetch(`${window.location.origin}/system/wde/renderMobileDesktop` )
|
|
||||||
.then((response) => response.text())
|
|
||||||
.then((html) => {
|
|
||||||
mobileDesktop.innerHTML = html
|
|
||||||
WebDesktopEnvironment.LoadApp("finder", () =>{
|
|
||||||
new FileView("/kek", mobileDesktop.querySelector(".FileTileView"), Finder.Click)
|
|
||||||
|
|
||||||
mobileDesktop.querySelector('#about-me').addEventListener('click', (event) => {
|
|
||||||
//TODO Do not allow launch second instance
|
|
||||||
WebDesktopEnvironment.Open("personal-properties", [])
|
|
||||||
})
|
|
||||||
mobileDesktop.querySelector('#mobile-desktop-blog').addEventListener('click', (event) => {
|
|
||||||
//TODO Do not allow launch second instance
|
|
||||||
WebDesktopEnvironment.Open("blog-viewer", ['main-page'])
|
|
||||||
})
|
|
||||||
mobileDesktop.querySelector('#mobile-dekstop-close').addEventListener('click', (event) => {
|
|
||||||
// console.log('close')
|
|
||||||
WebDesktopEnvironment.CloseFocusedWindow()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
WebDesktopEnvironment.Alert(error);
|
|
||||||
})
|
|
||||||
|
|
||||||
} else{
|
|
||||||
|
|
||||||
// let desktopLayer = document.createElement("div")
|
|
||||||
// desktopLayer.setAttribute('id', 'desktop-layer')
|
|
||||||
// document.body.appendChild(desktopLayer)
|
|
||||||
WebDesktopEnvironment.Open("finder", ["/home/user", "desktop", desktopLayer])
|
|
||||||
|
|
||||||
// let windowsLayer = document.createElement("div")
|
|
||||||
// windowsLayer.setAttribute('id', 'windows-layer')
|
|
||||||
// document.body.appendChild(windowsLayer)
|
|
||||||
this.Autoload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadWDE(){
|
|
||||||
// await WebDesktopEnvironment.load2('/Applications/Finder.app', [ "desktop", document.querySelector('#desktop-layer')])
|
|
||||||
WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/.Desktop", "-desktop", document.querySelector('#desktop-layer')])
|
|
||||||
// WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user",])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} appPath
|
|
||||||
* @param {string[]} args
|
|
||||||
*/
|
|
||||||
static async Open(appPath, args){
|
|
||||||
WebDesktopEnvironment.fetchApp(appPath).then(async appManifest =>{
|
|
||||||
if (appManifest === undefined) return //TODO return err
|
|
||||||
if (WebDesktopEnvironment.Applications[appManifest.appId] === undefined){
|
|
||||||
WebDesktopEnvironment.load2(appManifest, () =>{
|
|
||||||
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} appManifest
|
|
||||||
* @param {function} onload callback after script loading
|
|
||||||
*/
|
|
||||||
static async load2(appManifest, onload){
|
|
||||||
let appElem = document.createElement("div")
|
|
||||||
appElem.setAttribute("appId", appManifest.appId)
|
|
||||||
//TODO Render scripts nodes on server
|
|
||||||
//FIXME Not support more than one js now :)
|
|
||||||
let script = document.createElement("script")
|
|
||||||
script.setAttribute("src", appManifest.js[0]) //FIXME path by fs read
|
|
||||||
script.setAttribute("async", "false") //TODO Possible may creates a problems??
|
|
||||||
appElem.appendChild(script)
|
|
||||||
|
|
||||||
document.getElementById("applications").appendChild(appElem)
|
|
||||||
script.addEventListener('load', (event) => {
|
|
||||||
let newApp = eval(`new ${appManifest.appId}()`);
|
|
||||||
//TODO Check if newApp undefined
|
|
||||||
WebDesktopEnvironment.Applications[appManifest.appId] = newApp;
|
|
||||||
onload()
|
|
||||||
})
|
|
||||||
return //TODO return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {Object | undefined} //FIXME
|
|
||||||
*/
|
|
||||||
static async fetchApp(path){
|
|
||||||
const params = new URLSearchParams({path: path})
|
|
||||||
const response = await fetch(`/system/libs/apps/loadApp?` + params)
|
|
||||||
if (response.status != 200){
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
const appManifest = response.json()
|
|
||||||
return appManifest
|
|
||||||
}
|
|
||||||
|
|
||||||
Autoload(){
|
|
||||||
// WebDesktopEnvironment.Open(["/home/user/AboutMe.app"])
|
|
||||||
// WebDesktopEnvironment.load2(["/home/user/AboutMe.app"])
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param {string} appId
|
|
||||||
* @param {function} func callback after script loading
|
|
||||||
* @returns {Application | undefined}
|
|
||||||
*/
|
|
||||||
static LoadApp(appId, func){
|
|
||||||
// console.log(`Load application ${appId}`)
|
|
||||||
|
|
||||||
let script = document.createElement("script")
|
|
||||||
script.setAttribute("appId", appId)
|
|
||||||
script.setAttribute("src", `${window.location.origin}/system/applications/${appId}/app.js`)
|
|
||||||
script.setAttribute("async", "false")
|
|
||||||
document.getElementById("applications").appendChild(script)
|
|
||||||
|
|
||||||
script.addEventListener('load', (event) =>{
|
|
||||||
switch (appId) {
|
|
||||||
case "finder":
|
|
||||||
let newFinderApp = new Finder()
|
|
||||||
this.Applications[appId] = newFinderApp
|
|
||||||
func()
|
|
||||||
return newFinderApp
|
|
||||||
case "personal-properties":
|
|
||||||
let newPersonalPropertiesApp = new PersonalProperties()
|
|
||||||
this.Applications[appId] = newPersonalPropertiesApp
|
|
||||||
func()
|
|
||||||
return newPersonalPropertiesApp
|
|
||||||
case "img-viewer":
|
|
||||||
let newImgViewer = new ImgViewer()
|
|
||||||
this.Applications[appId] = newImgViewer
|
|
||||||
func()
|
|
||||||
return newImgViewer
|
|
||||||
case "blog-viewer":
|
|
||||||
let newBlogViewer = new BlogViewer()
|
|
||||||
this.Applications[appId] = newBlogViewer
|
|
||||||
func()
|
|
||||||
return newBlogViewer
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} appId
|
|
||||||
* @param {number} width
|
|
||||||
* @param {number} height
|
|
||||||
* @returns {HTMLElement}
|
|
||||||
*/
|
|
||||||
static CreateNewWindow(appId, width, height) {
|
|
||||||
let newWindow = document.createElement("div")
|
|
||||||
newWindow.setAttribute('appid', appId)
|
|
||||||
if (WebDesktopEnvironment.isMobile){
|
|
||||||
newWindow.setAttribute("class", "MobileApplicationWindow")
|
|
||||||
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
|
||||||
return newWindow
|
|
||||||
} else {
|
|
||||||
newWindow.setAttribute("class", "WindowFrame ConvexElement")
|
|
||||||
newWindow.setAttribute("windowId", "SuperUniqUUID") //TODO:
|
|
||||||
|
|
||||||
newWindow.style.width = width.toString() + "px"
|
|
||||||
newWindow.style.height = height.toString() + "px"
|
|
||||||
|
|
||||||
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
|
||||||
// WindowsCompositor.bringWindowToFront(newWindow)
|
|
||||||
return newWindow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @param {HTMLElement} window
|
|
||||||
*/
|
|
||||||
static CloseWindow(window) {
|
|
||||||
window.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
static CloseFocusedWindow() {
|
|
||||||
if (document.body.querySelector('#windows-layer').childElementCount > 1){
|
|
||||||
document.body.querySelector('#windows-layer').lastElementChild.remove()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} html
|
|
||||||
*/
|
|
||||||
static SetBasicWindow(html){
|
|
||||||
this.basicWindow = html
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
static GetBasicWindow(){
|
|
||||||
return this.basicWindow
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} alertText
|
|
||||||
*/
|
|
||||||
static Alert(alertText){
|
|
||||||
WebDesktopEnvironment.CreateAlertWindow(alertText)
|
|
||||||
console.log(alertText)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} alertText
|
|
||||||
*/
|
|
||||||
static CreateAlertWindow(alertText){
|
|
||||||
// console.log("alertWinfdo")
|
|
||||||
let newWindow = document.createElement("div")
|
|
||||||
newWindow.setAttribute("class", "WindowFrameless")
|
|
||||||
newWindow.setAttribute("windowId", "SuperUniqUUID") //TODO:
|
|
||||||
newWindow.style.cssText = "position:absolute;width:450px;height:116px; left: 50%;top: 50%;background-color:#FFFFFF;border: 1px solid #000000;box-shadow: 2px 2px 0px #000000;"
|
|
||||||
|
|
||||||
let alertImage = document.createElement("img")
|
|
||||||
alertImage.setAttribute("src", "/res/sys/wde/icons/ohno.png")
|
|
||||||
alertImage.style.cssText = "position:absolute; width:64px;height:64px;top:15px;left:25px"
|
|
||||||
newWindow.appendChild(alertImage)
|
|
||||||
|
|
||||||
let errorText = document.createElement("div")
|
|
||||||
errorText.style.cssText = "position:absolute; width: 300px; left:128px; top:30px;font-family: 'Virtue';"
|
|
||||||
errorText.innerHTML = alertText
|
|
||||||
newWindow.appendChild(errorText)
|
|
||||||
|
|
||||||
let closeButton = document.createElement("button")
|
|
||||||
closeButton.style.cssText = "position:absolute; left: 382px; bottom: 10px; background-color:#FFFFFF; width: 55px; height:18px; font-family: 'Virtue'; border-radius:4px;border: 1px solid #000000;"
|
|
||||||
closeButton.innerHTML = "Close"
|
|
||||||
closeButton.addEventListener('click', () => { newWindow.remove()})
|
|
||||||
newWindow.appendChild(closeButton)
|
|
||||||
|
|
||||||
document.body.querySelector('#windows-layer').appendChild(newWindow)
|
|
||||||
}
|
|
||||||
|
|
||||||
static CheckMobile(){
|
|
||||||
var check = false;
|
|
||||||
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
|
|
||||||
return check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var getJSON = function(url, callback) {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open('GET', url, true);
|
|
||||||
xhr.responseType = 'json';
|
|
||||||
xhr.onload = function() {
|
|
||||||
var status = xhr.status;
|
|
||||||
if (status === 200) {
|
|
||||||
callback(null, xhr.response);
|
|
||||||
} else {
|
|
||||||
callback(status, xhr.response);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.send();
|
|
||||||
};
|
|
||||||
|
|
||||||
class WindowsCompositor{
|
|
||||||
static windowsLayer
|
|
||||||
|
|
||||||
constructor(){
|
|
||||||
this.windowLayer = document.body.querySelector('#windows-layer')
|
|
||||||
WindowsCompositor.windowsLayer = document.body.querySelector('#windows-layer')
|
|
||||||
if (!WebDesktopEnvironment.isMobile) {
|
|
||||||
let startDrag = function(event) {
|
|
||||||
let window = event.target.closest('.WindowFrame')
|
|
||||||
WindowsCompositor.bringWindowToFront(window)
|
|
||||||
if (event.target.classList.contains("DragArea")){
|
|
||||||
let xPosInit = event.offsetX
|
|
||||||
let yPosInit = event.offsetY
|
|
||||||
let dragWindow = function(event){
|
|
||||||
window.style.left = `${event.clientX - xPosInit}px`
|
|
||||||
window.style.top = `${event.clientY - yPosInit}px`
|
|
||||||
}
|
|
||||||
let stopDrag = function(){
|
|
||||||
removeEventListener('mousemove', dragWindow)
|
|
||||||
removeEventListener('mouseup', stopDrag)
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener('mousemove', dragWindow)
|
|
||||||
addEventListener('mouseup', stopDrag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowsCompositor.windowsLayer.addEventListener('mousedown', startDrag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {HTMLElement} window
|
|
||||||
*/
|
|
||||||
static bringWindowToFront(window){ //FIXME
|
|
||||||
if (window == null | window == undefined){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let previousWindow = WindowsCompositor.windowsLayer.lastChild
|
|
||||||
if (window != previousWindow){
|
|
||||||
WindowsCompositor.windowsLayer.insertBefore(previousWindow, window)
|
|
||||||
}
|
|
||||||
if (!window.classList.contains("Focused")){
|
|
||||||
previousWindow.classList.remove("Focused")
|
|
||||||
window.classList.add("Focused")
|
|
||||||
}
|
|
||||||
// WindowsCompositor.ChangeURL(window)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ChangeURL(appWindow){
|
|
||||||
let appId = appWindow.getAttribute('appid')
|
|
||||||
window.history.replaceState(null, "", `/${appId}/`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class WebFS{
|
|
||||||
/**
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
static async CreateDirectory(path){
|
|
||||||
if (path == undefined){
|
|
||||||
WebDesktopEnvironment.Alert("Path is undefined")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
path: `${path}/New Directory`
|
|
||||||
})
|
|
||||||
const response = await fetch(`/fs/createDir?` + params)
|
|
||||||
if (response.status != 200){
|
|
||||||
WebDesktopEnvironment.Alert("DIRCTORY CREATION ERROR") //TODO
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
static async DeleteFile(path){
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
path: path
|
|
||||||
})
|
|
||||||
const response = await fetch(`/fs/delete?` + params)
|
|
||||||
if (response.status != 200){
|
|
||||||
WebDesktopEnvironment.Alert("DELETE ERROR") //TODO
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
static async MoveFile(sourcePath, targetPath){
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
sourcePath: sourcePath,
|
|
||||||
targetPath: targetPath
|
|
||||||
})
|
|
||||||
const response = await fetch(`/fs/move?` + params)
|
|
||||||
if (response.status != 200){
|
|
||||||
// WebDesktopEnvironment.Alert("Move ERROR") //TODO
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
132
routes/private.go
Normal file
132
routes/private.go
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"personalwebsite/apps"
|
||||||
|
"personalwebsite/errormessage"
|
||||||
|
"personalwebsite/libs"
|
||||||
|
"personalwebsite/routewde"
|
||||||
|
"personalwebsite/wde"
|
||||||
|
"personalwebsite/webfilesystem"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/cors"
|
||||||
|
"github.com/gin-contrib/location"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/thinkerou/favicon"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PrivateRoutes(webfs *webfilesystem.WebFileSystem, webde *wde.WDE, appsStorage *apps.ApplicationsStorage) {
|
||||||
|
router := gin.New()
|
||||||
|
router.Use(location.Default())
|
||||||
|
router.Use(favicon.New("./res/dev-fs/wde/icons/ohno.png"))
|
||||||
|
router.LoadHTMLGlob("templates/**/*")
|
||||||
|
router.Static("/res", "res")
|
||||||
|
// Set a lower memory limit for multipart forms (default is 32 MiB)
|
||||||
|
router.MaxMultipartMemory = 8 << 20 // 8 MiB
|
||||||
|
|
||||||
|
router.GET("/", func(ctx *gin.Context) {
|
||||||
|
ctx.HTML(http.StatusOK, "index.tmpl", gin.H{})
|
||||||
|
})
|
||||||
|
systemGroup := router.Group("system")
|
||||||
|
{
|
||||||
|
libsGroup := systemGroup.Group("libs")
|
||||||
|
{
|
||||||
|
imgLibGroup := libsGroup.Group("img")
|
||||||
|
{
|
||||||
|
imgLib := libs.NewImgLib(webfs)
|
||||||
|
imgLib.PublicRoutes(imgLibGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
catLibGroup := libsGroup.Group("cat")
|
||||||
|
{
|
||||||
|
catLib := libs.NewCatLib(webfs)
|
||||||
|
catLib.PublicRoutes(catLibGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
appsStorageGroup := libsGroup.Group("apps")
|
||||||
|
{
|
||||||
|
appsStorage.PrivateRoute(appsStorageGroup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wdeGroup := systemGroup.Group("wde")
|
||||||
|
{
|
||||||
|
routewde.PublicRoutes(wdeGroup, webde)
|
||||||
|
}
|
||||||
|
|
||||||
|
fsGroup := systemGroup.Group("fs")
|
||||||
|
{
|
||||||
|
webfs.PrivateRoutes(fsGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
systemGroup.GET("/loadApp", func(ctx *gin.Context) {
|
||||||
|
appPath := ctx.Query("path")
|
||||||
|
if appPath == "" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
|
Message: "Path for the App not provided in request",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appBundleData := webfilesystem.DirectoryData{}
|
||||||
|
appBundle, err := webfs.Read(appPath, &appBundleData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: "Error in read App bundle",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if appBundle.Type != "directory" {
|
||||||
|
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||||
|
Message: "App bundle file is bad",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appManifestData := apps.ApplicationManifest{}
|
||||||
|
appManifestHeader, err := webfs.Read(path.Join(appPath, ".appmanifest"), &appManifestData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: "Error in read App manifest",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if appManifestHeader.Type != "application-manifest" {
|
||||||
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: "Error in read App manifest",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, appManifestData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
appsGroup := router.Group("app")
|
||||||
|
{
|
||||||
|
for _, app := range appsStorage.Apps {
|
||||||
|
appsRoutes := appsGroup.Group(app.GetAppID())
|
||||||
|
app.PrivateRoutes(appsRoutes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
router.Use(cors.New(cors.Config{
|
||||||
|
AllowAllOrigins: true,
|
||||||
|
// AllowOrigins: []string{"http://localhost:8080", "http://localhost:9090"},
|
||||||
|
// AllowMethods: []string{"PUT", "PATCH"},
|
||||||
|
// AllowHeaders: []string{"Origin"},
|
||||||
|
ExposeHeaders: []string{"Content-Length"},
|
||||||
|
AllowCredentials: true,
|
||||||
|
// AllowOriginFunc: func(origin string) bool {
|
||||||
|
// return origin == "https://github.com"
|
||||||
|
// },
|
||||||
|
MaxAge: 12 * time.Hour,
|
||||||
|
}))
|
||||||
|
err := router.Run(":8080")
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
103
routes/public.go
Normal file
103
routes/public.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package routes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"personalwebsite/apps"
|
||||||
|
"personalwebsite/libs"
|
||||||
|
"personalwebsite/routewde"
|
||||||
|
"personalwebsite/wde"
|
||||||
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/location"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/thinkerou/favicon"
|
||||||
|
)
|
||||||
|
|
||||||
|
func PublicRoutes(webfs *webfilesystem.WebFileSystem, webde *wde.WDE, appsStorage *apps.ApplicationsStorage) {
|
||||||
|
router := gin.New()
|
||||||
|
router.Use(location.Default())
|
||||||
|
router.LoadHTMLGlob("templates/**/*")
|
||||||
|
router.Use(favicon.New("./res/dev-fs/wde/icons/ohno.png")) // set favicon middleware
|
||||||
|
router.Static("/res", "res")
|
||||||
|
|
||||||
|
router.GET("/", func(ctx *gin.Context) {
|
||||||
|
ctx.HTML(http.StatusOK, "index.tmpl", gin.H{})
|
||||||
|
})
|
||||||
|
|
||||||
|
systemGroup := router.Group("system")
|
||||||
|
{
|
||||||
|
libsGroup := systemGroup.Group("libs")
|
||||||
|
{
|
||||||
|
imgLibGroup := libsGroup.Group("img")
|
||||||
|
{
|
||||||
|
imgLib := libs.NewImgLib(webfs)
|
||||||
|
imgLib.PublicRoutes(imgLibGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
catLibGroup := libsGroup.Group("cat")
|
||||||
|
{
|
||||||
|
catLib := libs.NewCatLib(webfs)
|
||||||
|
catLib.PublicRoutes(catLibGroup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wdeGroup := systemGroup.Group("wde")
|
||||||
|
{
|
||||||
|
routewde.PublicRoutes(wdeGroup, webde)
|
||||||
|
}
|
||||||
|
|
||||||
|
systemGroup.GET("/loadApp", func(ctx *gin.Context) {
|
||||||
|
appPath := ctx.Query("path")
|
||||||
|
if appPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appBundleData := webfilesystem.DirectoryData{}
|
||||||
|
appBundle, err := webfs.Read(appPath, &appBundleData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if appBundle.Type != "directory" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appManifestData := apps.ApplicationManifest{}
|
||||||
|
appManifestHeader, err := webfs.Read(path.Join(appPath, ".appmanifest"), &appManifestData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if appManifestHeader.Type != "application-manifest" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, appManifestData)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
fsGroup := systemGroup.Group("fs")
|
||||||
|
{
|
||||||
|
webfs.PublicRoutes(fsGroup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
appGroup := router.Group("app")
|
||||||
|
{
|
||||||
|
for _, app := range appsStorage.Apps {
|
||||||
|
appRoutes := appGroup.Group(app.GetAppID())
|
||||||
|
app.PublicRoutes(appRoutes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := router.Run(":7070")
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
@ -8,8 +8,8 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Route(route *gin.RouterGroup, wde *wde.WDE) {
|
func PublicRoutes(route *gin.RouterGroup, wde *wde.WDE) {
|
||||||
route.GET("/getbasicwindow", func(ctx *gin.Context) {
|
route.GET("/getbasicwindow", func(ctx *gin.Context) { //TODO Rename to renderGenericWindowFrame
|
||||||
ctx.HTML(http.StatusOK, "basic-window.html", nil)
|
ctx.HTML(http.StatusOK, "basic-window.html", nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ func Route(route *gin.RouterGroup, wde *wde.WDE) {
|
|||||||
{
|
{
|
||||||
widgets.GET("/file-tile-view", func(ctx *gin.Context) {
|
widgets.GET("/file-tile-view", func(ctx *gin.Context) {
|
||||||
url := location.Get(ctx)
|
url := location.Get(ctx)
|
||||||
// _ = url
|
|
||||||
path := ctx.Query("path")
|
path := ctx.Query("path")
|
||||||
if path == "" {
|
if path == "" {
|
||||||
ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||||
|
@ -2,34 +2,29 @@
|
|||||||
<html lang="en" dir="ltr">
|
<html lang="en" dir="ltr">
|
||||||
<title>Greg Brzezinski</title>
|
<title>Greg Brzezinski</title>
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="res/base.css">
|
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/base.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/wdeUI.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/wde/basic-widgets.css">
|
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/wdeUI.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/wde/wde-scrollbar.css">
|
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/basic-widgets.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/wde/basic-widgets.css">
|
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/wde-scrollbar.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/wde/file-view.css">
|
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/file-view.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/libs/fs.js">
|
|
||||||
<link rel="stylesheet" type="text/css" href="res/mobile-wdeUI.css">
|
<!-- TODO: Move css init to js -->
|
||||||
<link rel="stylesheet" href="/res/sys/wde/simple-scrollbar.css">
|
<link rel="stylesheet" href="res/dev-fs/apps/Finder/finder.css">
|
||||||
<link rel="stylesheet" type="text/css" href="res/sys/finder/finder.css">
|
<link rel="stylesheet" href="/res/dev-fs/apps/AboutMe/about-me.css">
|
||||||
<link rel="stylesheet" href="/res/sys/personal-properties/personal-properies.css">
|
<link rel="stylesheet" href="/res/dev-fs/apps/ImgViewer/img-viewer.css">
|
||||||
<link rel="stylesheet" href="/res/sys/img-viewer/img-viewer.css">
|
<link rel="stylesheet" href="/res/dev-fs/apps/BlogViewer/blog-viewer.css">
|
||||||
<link rel="stylesheet" href="/res/sys/blog-viewer/blog-viewer.css">
|
|
||||||
<script src="/res/sys/wde/wde-scrollbar.js"></script>
|
<script src="res/dev-fs/wde/wde.js"></script>
|
||||||
<script src="/res/sys/wde/file-view.js"></script>
|
<script src="res/dev-fs/wde/decorat.js"></script>
|
||||||
<script src="res/wde.js"></script>
|
<script src="res/dev-fs/wde/webfs.js"></script>
|
||||||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> -->
|
<script src="/res/dev-fs/wde/wde-scrollbar.js"></script>
|
||||||
<!-- <script src="res/decorat.js"></script> -->
|
<script src="/res/dev-fs/wde/file-view.js"></script>
|
||||||
<!-- TODO Load with app -->
|
|
||||||
<!-- <script src="res/personal-properties.js"></script> -->
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- <div id="WindowsLayer"></div> -->
|
|
||||||
<div id="applications"></div>
|
<div id="applications"></div>
|
||||||
<div id="desktop-layer"></div>
|
<div id="desktop-layer"></div>
|
||||||
<div id="windows-layer"></div>
|
<div id="windows-layer"></div>
|
||||||
<!-- <div id="TestWindow" style="width: 100px; height: 100px; background-color: darkkhaki; position: absolute;" >
|
|
||||||
<div id="TestWindowHeader" class="VisualDragArea" style="width: 100%;height: 15px; background-color: cornflowerblue;">
|
|
||||||
</div> -->
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -12,6 +12,13 @@
|
|||||||
<div class="Content">
|
<div class="Content">
|
||||||
<div class="ScrollContent">
|
<div class="ScrollContent">
|
||||||
{{ range $block := .blocks }}
|
{{ range $block := .blocks }}
|
||||||
|
{{ if eq $block.Type "image"}}
|
||||||
|
<div class="{{$block.Type}}" >
|
||||||
|
{{ range $data := $block.Data }}
|
||||||
|
<img class="ImageProp" src="/system/libs/img/get?path={{$data}}">
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
{{ else }}
|
||||||
<div class="{{$block.Type}}" >
|
<div class="{{$block.Type}}" >
|
||||||
{{ range $data := $block.Data }}
|
{{ range $data := $block.Data }}
|
||||||
<div style="font-size: inherit;">
|
<div style="font-size: inherit;">
|
||||||
@ -20,6 +27,7 @@
|
|||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{template "wde-widgets/scrollbar.tmpl" .}}
|
{{template "wde-widgets/scrollbar.tmpl" .}}
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
<div class="FinderContent">
|
<div class="FinderContent">
|
||||||
<!-- TODO Fix ConvexElement -->
|
<!-- TODO Fix ConvexElement -->
|
||||||
<div class="ToolBar ConvexElement">
|
<div class="ToolBar ConvexElement">
|
||||||
|
<button id="BackButton">Back</button>
|
||||||
|
<button id="UpButton">Up</button>
|
||||||
<button id="RootButton">/</button>
|
<button id="RootButton">/</button>
|
||||||
<button id="HomeButton">Home</button>
|
<button id="HomeButton">Home</button>
|
||||||
|
<div class="AddressBar" contentEditable="true">You Favorite Movie</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="FinderFileView">
|
<div class="FinderFileView">
|
||||||
<div class="FileTileView">
|
<div class="FileTileView">
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
{{ define "finder/app.tmpl" }}
|
{{ define "finder/app.tmpl" }}
|
||||||
<div class="TitleBar DragArea">
|
<div class="TitleBar DragArea">
|
||||||
<button id="closeWindowButton" class="Button" title="Close Window"></button>
|
<button id="closeWindowButton" class="Button" title="Close Window"></button>
|
||||||
<div class="TitleBarTest">
|
|
||||||
<div id="Drag" class="VisualDragArea"></div>
|
<div id="Drag" class="VisualDragArea"></div>
|
||||||
<div class="Lable">
|
<div class="Lable">
|
||||||
Files
|
Finder
|
||||||
</div>
|
</div>
|
||||||
<div id="Drag" class="VisualDragArea"></div>
|
<div id="Drag" class="VisualDragArea"></div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ToolBar">
|
|
||||||
<button id="BackButton">Back</button>
|
|
||||||
<button id="HomeButton">Home</button>
|
|
||||||
</div>
|
|
||||||
<div class="ContentBorder ConvexElement">
|
|
||||||
<div class="FileTileView">
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="ContentBorder" class="ContentBorder AdjectiveElement">
|
||||||
|
<div class="FinderContent">
|
||||||
|
<!-- TODO Fix ConvexElement -->
|
||||||
|
<div class="ToolBar ConvexElement">
|
||||||
|
Folder info
|
||||||
|
</div>
|
||||||
|
<div class="FinderFileView">
|
||||||
|
<div class="FileTileView">
|
||||||
</div>
|
</div>
|
||||||
{{template "wde-widgets/scrollbar.tmpl" .}}
|
{{template "wde-widgets/scrollbar.tmpl" .}}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
|||||||
<div>
|
<div>
|
||||||
file id : {{.file.MongoId}}
|
file id : {{.file.MongoId}}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
file type : {{.file.Type}}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
file data id : {{.file.Data}}
|
file data id : {{.file.Data}}
|
||||||
</div>
|
</div>
|
||||||
|
BIN
test-img/myphoto.jpg
(Stored with Git LFS)
BIN
test-img/myphoto.jpg
(Stored with Git LFS)
Binary file not shown.
24
wde/wde.go
24
wde/wde.go
@ -21,30 +21,6 @@ func NewWDE(webFs *webfilesystem.WebFileSystem) *WDE {
|
|||||||
type FilesWidget struct {
|
type FilesWidget struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
func (w *WDE) Render(path string) (gin.H, error) {
|
|
||||||
// list, err := w.fs.NewListDeprecated(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
return gin.H{
|
|
||||||
"Name": "Greg Brzezinski",
|
|
||||||
// "Files": list,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated
|
|
||||||
func (w *WDE) RenderContextMenu() (gin.H, error) {
|
|
||||||
// list, err := w.fs.List(path)
|
|
||||||
// if err != nil {
|
|
||||||
// return nil, err
|
|
||||||
// }
|
|
||||||
return gin.H{
|
|
||||||
"Name": "Greg Brzezinski",
|
|
||||||
// "Files": list,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *WDE) RenderFileTileView(directory string, host string) (gin.H, error) {
|
func (w *WDE) RenderFileTileView(directory string, host string) (gin.H, error) {
|
||||||
list, err := w.fs.ListDir(directory)
|
list, err := w.fs.ListDir(directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DirectoryData struct {
|
type DirectoryData struct {
|
||||||
MongoId primitive.ObjectID `bson:"_id"`
|
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||||
Parent primitive.ObjectID `bson:"parent_id"`
|
Parent primitive.ObjectID `bson:"parent_id" json:"parent"` //TODO: Delete
|
||||||
Children []primitive.ObjectID `bson:"children_id"`
|
Children []primitive.ObjectID `bson:"children_id" json:"children"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *WebFileSystem) CreateDirectory(dirPath string) (primitive.ObjectID, primitive.ObjectID, error) {
|
func (fs *WebFileSystem) CreateDirectory(dirPath string) (primitive.ObjectID, primitive.ObjectID, error) {
|
||||||
@ -96,15 +96,37 @@ func (fs *WebFileSystem) ListDir(dirPath string) ([]*FileHeader, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
children, err := fs.listDirByObjectID(dirId)
|
||||||
|
// dirData := DirectoryData{}
|
||||||
|
// _, err = fs.readFSDocs(dirId, &dirData)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // println(dirId.String())
|
||||||
|
// // println(dirData.MongoId.String())
|
||||||
|
|
||||||
|
// children := []*FileHeader{}
|
||||||
|
// for _, childID := range dirData.Children {
|
||||||
|
// childFile, err := fs.readFSDocs(childID, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// // println(err.Error())
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// children = append(children, childFile)
|
||||||
|
|
||||||
|
// }
|
||||||
|
return children, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) listDirByObjectID(dirId primitive.ObjectID) ([]*FileHeader, error) {
|
||||||
dirData := DirectoryData{}
|
dirData := DirectoryData{}
|
||||||
_, err = fs.readFSDocs(dirId, &dirData)
|
_, err := fs.readFSDocs(dirId, &dirData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// println(dirId.String())
|
|
||||||
// println(dirData.MongoId.String())
|
|
||||||
|
|
||||||
children := []*FileHeader{}
|
children := []*FileHeader{}
|
||||||
for _, childID := range dirData.Children {
|
for _, childID := range dirData.Children {
|
||||||
childFile, err := fs.readFSDocs(childID, nil)
|
childFile, err := fs.readFSDocs(childID, nil)
|
||||||
|
@ -5,13 +5,13 @@ package webfilesystem
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (fs *WebFileSystem) UploadFile(realFilepath string, parentPath string) error {
|
func (fs *WebFileSystem) UploadFile(realFilepath string, filePath string) error {
|
||||||
//TODO check is file exists
|
//TODO check is file exists
|
||||||
|
// parentPath := fs.GetParentPath(filePath)
|
||||||
file, err := os.ReadFile(realFilepath)
|
file, err := os.ReadFile(realFilepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -33,7 +33,7 @@ func (fs *WebFileSystem) UploadFile(realFilepath string, parentPath string) erro
|
|||||||
Bin: file,
|
Bin: file,
|
||||||
}
|
}
|
||||||
|
|
||||||
filePath := path.Join(parentPath, fileName)
|
// filePath := path.Join(parentPath, fileName)
|
||||||
|
|
||||||
switch extension {
|
switch extension {
|
||||||
case "jpg":
|
case "jpg":
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//TODO Transparently split to single data and header reading methods
|
||||||
func (fs *WebFileSystem) readFSDocs(fileID primitive.ObjectID, fileData interface{}) (*FileHeader, error) {
|
func (fs *WebFileSystem) readFSDocs(fileID primitive.ObjectID, fileData interface{}) (*FileHeader, error) {
|
||||||
fileHeader := &FileHeader{}
|
fileHeader := &FileHeader{}
|
||||||
filter := primitive.M{
|
filter := primitive.M{
|
||||||
@ -41,7 +42,33 @@ func (fs *WebFileSystem) writeFileToMongo(file *FileHeader, data interface{}) (p
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fs *WebFileSystem) removeFromMongo(fileId primitive.ObjectID) error {
|
func (fs *WebFileSystem) removeFromMongo(fileId primitive.ObjectID) error {
|
||||||
return errors.New("todo not implemented yet")
|
fileHeader, err := fs.readFSDocs(fileId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
filterHeader := primitive.M{
|
||||||
|
"_id": fileHeader.MongoId,
|
||||||
|
}
|
||||||
|
res, err := fs.webfsFilesTable.DeleteOne(fs.ctx, filterHeader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.DeletedCount < 1 {
|
||||||
|
return errors.New("no file header deleted")
|
||||||
|
}
|
||||||
|
|
||||||
|
filterData := primitive.M{
|
||||||
|
"_id": fileHeader.Data,
|
||||||
|
}
|
||||||
|
res, err = fs.webfsFilesData.DeleteOne(fs.ctx, filterData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if res.DeletedCount < 1 {
|
||||||
|
return errors.New("no file data deleted")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//Deprecated
|
//Deprecated
|
||||||
|
@ -8,7 +8,7 @@ func (fs *WebFileSystem) Read(filePath string, fileData interface{}) (*FileHeade
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileHeader, err := fs.readFSDocs(fileId, fileData)
|
fileHeader, err := fs.ReadByObjectID(fileId, fileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -22,5 +22,19 @@ func (fs *WebFileSystem) ReadByObjectID(fileID primitive.ObjectID, fileData inte
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fileHeader.Type == "objectlink" {
|
||||||
|
objectLinkData := ObjectLinkFileData{}
|
||||||
|
_, err := fs.readFSDocs(fileID, &objectLinkData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileHeader, err := fs.readFSDocs(objectLinkData.Link_id, fileData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fileHeader, nil
|
||||||
|
}
|
||||||
|
|
||||||
return fileHeader, nil
|
return fileHeader, nil
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,14 @@ package webfilesystem
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"personalwebsite/errormessage"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
func (fs *WebFileSystem) PrivateRoutes(route *gin.RouterGroup) {
|
||||||
|
fs.PublicRoutes(route)
|
||||||
route.POST("/upload", func(ctx *gin.Context) { //TODO To PUT request
|
route.POST("/upload", func(ctx *gin.Context) { //TODO To PUT request
|
||||||
// fileName := ctx.Query("fileName")
|
// fileName := ctx.Query("fileName")
|
||||||
// if fileName == "" {
|
// if fileName == "" {
|
||||||
@ -32,9 +35,11 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
|||||||
ctx.SaveUploadedFile(file, dst)
|
ctx.SaveUploadedFile(file, dst)
|
||||||
|
|
||||||
//TODO: Not Save to disk
|
//TODO: Not Save to disk
|
||||||
err := fs.UploadFile(dst, parentPath)
|
err := fs.UploadFile(dst, path.Join(parentPath, file.Filename))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.String(http.StatusInternalServerError, "TODO") //TODO
|
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||||
|
Message: err.Error(),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,6 +50,28 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
|||||||
ctx.Status(http.StatusCreated)
|
ctx.Status(http.StatusCreated)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//TODO Support Object links
|
||||||
|
// route.POST("/createlink", func(ctx *gin.Context) { //TODO To PUT request
|
||||||
|
// sourcePath := ctx.Query("sourcePath")
|
||||||
|
// if sourcePath == "" {
|
||||||
|
// ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// targetPath := ctx.Query("targetPath")
|
||||||
|
// if sourcePath == "" {
|
||||||
|
// ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// err := fs.CreateObjectLink(sourcePath, targetPath)
|
||||||
|
// if err != nil {
|
||||||
|
// ctx.String(http.StatusInternalServerError, err.Error()) //TODO
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ctx.Status(http.StatusCreated)
|
||||||
|
// })
|
||||||
|
|
||||||
// route.GET("writeFile", func(ctx *gin.Context) {
|
// route.GET("writeFile", func(ctx *gin.Context) {
|
||||||
// parentPath := ctx.Query("parentPath")
|
// parentPath := ctx.Query("parentPath")
|
||||||
// if parentPath == "" {
|
// if parentPath == "" {
|
||||||
@ -166,4 +193,67 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
|||||||
|
|
||||||
ctx.Status(http.StatusOK)
|
ctx.Status(http.StatusOK)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
route.GET("readObjectLink", func(ctx *gin.Context) {
|
||||||
|
linkPath := ctx.Query("linkPath")
|
||||||
|
if linkPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest) //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// file, err := fs.Read(linkPath, nil)
|
||||||
|
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
})
|
||||||
|
|
||||||
|
route.GET("createPathLink", func(ctx *gin.Context) {
|
||||||
|
sourcePath := ctx.Query("sourcePath")
|
||||||
|
if sourcePath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest) //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
linkPath := ctx.Query("linkPath")
|
||||||
|
if linkPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest) //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _, err := fs.CreatePathLink(sourcePath, linkPath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) PublicRoutes(route *gin.RouterGroup) {
|
||||||
|
route.GET("readPathLink", func(ctx *gin.Context) {
|
||||||
|
linkPath := ctx.Query("linkPath")
|
||||||
|
if linkPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest) //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
linkData := PathLinkFileData{}
|
||||||
|
linkHeader, err := fs.Read(linkPath, &linkData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusBadRequest) //TODO
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if linkHeader.Type != "pathlink" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHeader, err := fs.Read(linkData.Path, nil)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, FrontEndFile{
|
||||||
|
Name: FileHeader.Name,
|
||||||
|
Type: FileHeader.Type,
|
||||||
|
ParentPath: fs.GetParentPath(linkData.Path),
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,45 @@
|
|||||||
package webfilesystem
|
package webfilesystem
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
func (fs *WebFileSystem) validate() error {
|
func (fs *WebFileSystem) validate() error {
|
||||||
|
filter := primitive.M{
|
||||||
|
// "type": "directory",
|
||||||
|
}
|
||||||
|
cur, err := fs.webfsFilesTable.Find(fs.ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
orfanedDir, err := fs.Read("/orfaned", nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = orfanedDir
|
||||||
|
for cur.Next(fs.ctx) {
|
||||||
|
fileHeader := FileHeader{}
|
||||||
|
cur.Decode(&fileHeader)
|
||||||
|
if fileHeader.Name == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := fs.checkFileParent(&fileHeader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !res {
|
||||||
|
println(fileHeader.Name)
|
||||||
|
err := fs.moveByID(fileHeader.MongoId, primitive.NilObjectID, orfanedDir.MongoId, true)
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
println()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// println()
|
||||||
|
}
|
||||||
// rootHeader, rootData, err := fs.GetRootDir()
|
// rootHeader, rootData, err := fs.GetRootDir()
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return err
|
// return err
|
||||||
@ -53,6 +92,35 @@ func (fs *WebFileSystem) validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) checkFileParent(checkFileHeader *FileHeader) (bool, error) {
|
||||||
|
filter := primitive.M{
|
||||||
|
"type": "directory",
|
||||||
|
}
|
||||||
|
cur, err := fs.webfsFilesTable.Find(fs.ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// parentFounded := false
|
||||||
|
for cur.Next(fs.ctx) {
|
||||||
|
dirHeader := FileHeader{}
|
||||||
|
// dirData := DirectoryData{}
|
||||||
|
cur.Decode(&dirHeader)
|
||||||
|
_, err := fs.readFSDocs(dirHeader.MongoId, nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
children, err := fs.listDirByObjectID(dirHeader.MongoId)
|
||||||
|
for _, child := range children {
|
||||||
|
if child.MongoId == checkFileHeader.MongoId {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// println(child.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// func (fs *WebFileSystem) GetChildrenHeaders(directoryID primitive.ObjectID) ([]FileHeader, error) {
|
// func (fs *WebFileSystem) GetChildrenHeaders(directoryID primitive.ObjectID) ([]FileHeader, error) {
|
||||||
// fs.ReadByObjectID(directoryID, nil)
|
// fs.ReadByObjectID(directoryID, nil)
|
||||||
// }
|
// }
|
||||||
|
@ -3,6 +3,8 @@ package webfilesystem
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"path"
|
||||||
|
"personalwebsite/apps/appCtx"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -46,21 +48,31 @@ type BinaryFileData struct {
|
|||||||
|
|
||||||
type PlainTextFileData struct {
|
type PlainTextFileData struct {
|
||||||
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||||
Data string `bson:"data" json:"data"`
|
Data string `bson:"data" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated
|
type ObjectLinkFileData struct {
|
||||||
func (fs *WebFileSystem) ReadHeader(fileID primitive.ObjectID) (*FileHeader, error) {
|
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||||
file := &FileHeader{}
|
Link_id primitive.ObjectID `bson:"link_id" json:"-"`
|
||||||
filter := primitive.M{
|
|
||||||
"_id": fileID,
|
|
||||||
}
|
|
||||||
err := fs.webfsFilesTable.FindOne(fs.ctx, filter).Decode(file)
|
|
||||||
return file, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO To private, get name from path and set it to file struct, force set newObjectID
|
type PathLinkFileData struct {
|
||||||
|
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||||
|
Path string `bson:"path" json:"path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FrontEndFile struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"filetype"` //TODO: Rename to Type
|
||||||
|
ParentPath string `json:"parentPath"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO To private, get name from path and set it to file struct; force set newObjectID
|
||||||
func (fs *WebFileSystem) Write(filePath string, file *FileHeader, data interface{}) (primitive.ObjectID, primitive.ObjectID, error) {
|
func (fs *WebFileSystem) Write(filePath string, file *FileHeader, data interface{}) (primitive.ObjectID, primitive.ObjectID, error) {
|
||||||
|
if fs.CheckFileExist(filePath) {
|
||||||
|
return primitive.NilObjectID, primitive.NilObjectID, errors.New("file exists")
|
||||||
|
}
|
||||||
|
|
||||||
headerId, dataId, err := fs.writeFileToMongo(file, data)
|
headerId, dataId, err := fs.writeFileToMongo(file, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return primitive.NilObjectID, primitive.NilObjectID, err
|
return primitive.NilObjectID, primitive.NilObjectID, err
|
||||||
@ -168,7 +180,7 @@ func (fs *WebFileSystem) Move(sourcePath string, targetPath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
//TODO: use moveByID()
|
||||||
if targetParentDirHeader.Type != "directory" {
|
if targetParentDirHeader.Type != "directory" {
|
||||||
return errors.New("target parent object is not a directory")
|
return errors.New("target parent object is not a directory")
|
||||||
}
|
}
|
||||||
@ -183,7 +195,33 @@ func (fs *WebFileSystem) Move(sourcePath string, targetPath string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) moveByID(fileID primitive.ObjectID, oldDirID primitive.ObjectID, newDirID primitive.ObjectID, isForced bool) error {
|
||||||
|
//TODO check, if directory is child for parent-parent dir and other shit
|
||||||
|
targetDirData := DirectoryData{}
|
||||||
|
targetDirHeader, err := fs.readFSDocs(newDirID, &targetDirData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if targetDirHeader.Type != "directory" {
|
||||||
|
return errors.New("parent directory path is bad")
|
||||||
|
}
|
||||||
|
for _, childID := range targetDirData.Children {
|
||||||
|
if childID == fileID {
|
||||||
|
return errors.New("file already in this directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = fs.RemoveChildToDirectory(fileID, oldDirID)
|
||||||
|
if err != nil && !isForced {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fs.AppendChildToDirectory(fileID, newDirID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *WebFileSystem) Remove(filePath string) error {
|
func (fs *WebFileSystem) Remove(filePath string) error {
|
||||||
@ -215,9 +253,83 @@ func (fs *WebFileSystem) Remove(filePath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if parentPath == "/orfaned" { //TODO path to struct
|
||||||
|
err := fs.removeFromMongo(fileId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) CreateObjectLink(sourcePath string, linkPath string) error {
|
||||||
|
linkSplittedPath := fs.SplitPath(linkPath)
|
||||||
|
linkFileName := linkSplittedPath[len(linkSplittedPath)-1]
|
||||||
|
|
||||||
|
linkParentDirPath := fs.GetParentPath(linkPath)
|
||||||
|
linkParentDirPathID, err := fs.FindFile(linkParentDirPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sourceFileID, err := fs.FindFile(sourcePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newLinkHeader := FileHeader{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Name: linkFileName,
|
||||||
|
Type: "objectlink",
|
||||||
|
Icon: "",
|
||||||
|
Data: primitive.NewObjectID(),
|
||||||
|
}
|
||||||
|
newLinkData := ObjectLinkFileData{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Link_id: sourceFileID,
|
||||||
|
}
|
||||||
|
|
||||||
|
linkFileID, _, err := fs.Write(sourcePath, &newLinkHeader, newLinkData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = fs.AppendChildToDirectory(linkFileID, linkParentDirPathID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) CreatePathLink(sourcePath string, linkPath string) (primitive.ObjectID, primitive.ObjectID, error) {
|
||||||
|
sourceFileHeader, err := fs.Read(sourcePath, nil)
|
||||||
|
if err != nil {
|
||||||
|
return primitive.NilObjectID, primitive.NilObjectID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if sourceFileHeader.Type == "pathlink" {
|
||||||
|
return primitive.NilObjectID, primitive.NilObjectID, errors.New("multiplies pathlinks not supported yet") //TODO
|
||||||
|
}
|
||||||
|
splittedPath := strings.Split(linkPath, "/")
|
||||||
|
newLinkHeader := FileHeader{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Name: splittedPath[len(splittedPath)-1],
|
||||||
|
Type: "pathlink",
|
||||||
|
Icon: "",
|
||||||
|
Data: primitive.NewObjectID(),
|
||||||
|
}
|
||||||
|
newLinkData := PathLinkFileData{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Path: sourcePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
headerID, dataID, err := fs.Write(linkPath, &newLinkHeader, newLinkData)
|
||||||
|
if err != nil {
|
||||||
|
return primitive.NilObjectID, primitive.NilObjectID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerID, dataID, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *WebFileSystem) SplitPath(path string) []string {
|
func (fs *WebFileSystem) SplitPath(path string) []string {
|
||||||
resPath := []string{}
|
resPath := []string{}
|
||||||
splittedPath := strings.Split(path, "/")
|
splittedPath := strings.Split(path, "/")
|
||||||
@ -243,3 +355,23 @@ func (fs *WebFileSystem) GetParentPath(path string) string {
|
|||||||
}
|
}
|
||||||
return "/"
|
return "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) CheckFileExist(filePath string) bool {
|
||||||
|
fileHeader, err := fs.Read(filePath, nil)
|
||||||
|
if err == nil && fileHeader != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *WebFileSystem) RelativeToAbsolute(appCtx appCtx.AppContext, filePath string) string {
|
||||||
|
switch filePath[0] {
|
||||||
|
case '.':
|
||||||
|
return path.Join(appCtx.RunPath, filePath)
|
||||||
|
case ':':
|
||||||
|
filePath = strings.ReplaceAll(filePath, ":", "")
|
||||||
|
return path.Join(appCtx.BundlePath, filePath)
|
||||||
|
default:
|
||||||
|
return filePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user