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
|
||||
COPY --from=build /usr/app/personalwebsite /usr/app/personalwebsite
|
||||
COPY ./templates /usr/app/templates
|
||||
COPY ./resources /usr/app/resources
|
||||
COPY ./res /usr/app/res
|
||||
|
||||
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 {
|
||||
Header string `bson:"header"`
|
||||
Blocks []Block `bson:"blocks"`
|
||||
Blocks []*Block `bson:"blocks"`
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
package blogviewer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"personalwebsite/apps"
|
||||
"path"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/errormessage"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -11,27 +14,65 @@ import (
|
||||
|
||||
type BlogViewerApplication struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
manifest apps.ApplicationManifest
|
||||
appID string
|
||||
}
|
||||
|
||||
func NewBlogViewerApp(webFs *webfilesystem.WebFileSystem) *BlogViewerApplication {
|
||||
return &BlogViewerApplication{
|
||||
fs: webFs,
|
||||
manifest: apps.ApplicationManifest{
|
||||
AppId: "blog-viewer",
|
||||
},
|
||||
appID: "BlogViewer",
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) GetManifest() apps.ApplicationManifest {
|
||||
return b.manifest
|
||||
func (b *BlogViewerApplication) GetAppID() string {
|
||||
return b.appID
|
||||
}
|
||||
func (b *BlogViewerApplication) PrivateRoutes(route *gin.RouterGroup) {
|
||||
b.PublicRoutes(route)
|
||||
|
||||
func (b *BlogViewerApplication) GetId() string {
|
||||
return b.manifest.AppId
|
||||
route.POST("edit", func(ctx *gin.Context) {
|
||||
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) Route(route *gin.RouterGroup) {
|
||||
func (b *BlogViewerApplication) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("writeMockBlog", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
@ -46,22 +87,27 @@ func (b *BlogViewerApplication) Route(route *gin.RouterGroup) {
|
||||
ctx.JSON(http.StatusOK, "OK")
|
||||
})
|
||||
|
||||
route.GET("render", func(ctx *gin.Context) {
|
||||
isMobileParam := ctx.Query("isMobile")
|
||||
route.POST("render", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||
return
|
||||
}
|
||||
|
||||
isMobile := isMobileParam == "true"
|
||||
ginH, err := b.Render(path, isMobile)
|
||||
appCtx := appCtx.AppContext{}
|
||||
err := ctx.BindJSON(&appCtx)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
ginH, err := b.Render(path, appCtx)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, "TODO")
|
||||
return
|
||||
}
|
||||
|
||||
if isMobile {
|
||||
if appCtx.IsMobile {
|
||||
ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH)
|
||||
} else {
|
||||
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 {
|
||||
blogFileHeader := webfilesystem.FileHeader{
|
||||
blogFileHeader := webfilesystem.FileHeader{ //TODO to fs.CreateDirectory()
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: "blog1.blog",
|
||||
Type: "",
|
||||
Type: "directory",
|
||||
Icon: "",
|
||||
Data: [12]byte{},
|
||||
}
|
||||
blogFileData := BlogFileData{
|
||||
Header: "OMG THIS IS BLOG",
|
||||
Blocks: []Block{
|
||||
{
|
||||
Type: "plain-text",
|
||||
Data: []string{
|
||||
"Apoqiwepoqiwepo",
|
||||
".,mas;dakls;d",
|
||||
"q[poqwieqpipoi]",
|
||||
},
|
||||
},
|
||||
},
|
||||
blogFileData := webfilesystem.DirectoryData{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Parent: [12]byte{},
|
||||
Children: []primitive.ObjectID{},
|
||||
}
|
||||
|
||||
_, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData)
|
||||
@ -97,16 +135,87 @@ func (b *BlogViewerApplication) WriteMock(path string) error {
|
||||
println(err.Error())
|
||||
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
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) Render(filePath string, isMobile bool) (gin.H, error) {
|
||||
data := BlogFileData{}
|
||||
_, err := b.fs.Read(filePath, &data)
|
||||
func (b *BlogViewerApplication) Read(filePath string) (*BlogFileData, error) {
|
||||
fileData := BlogFileData{}
|
||||
fileHeader, err := b.fs.Read(path.Join(filePath, ".content"), &fileData)
|
||||
if err != nil {
|
||||
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{
|
||||
"header": data.Header,
|
||||
"blocks": data.Blocks,
|
||||
|
@ -1,7 +1,7 @@
|
||||
package finder
|
||||
|
||||
import (
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
@ -10,114 +10,55 @@ import (
|
||||
|
||||
type FinderApplication struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
manifest apps.ApplicationManifest
|
||||
appID string
|
||||
// manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication {
|
||||
return &FinderApplication{
|
||||
fs: webFs,
|
||||
manifest: apps.ApplicationManifest{
|
||||
AppId: "finder",
|
||||
},
|
||||
appID: "Finder",
|
||||
}
|
||||
}
|
||||
func (f *FinderApplication) GetManifest() apps.ApplicationManifest {
|
||||
return f.manifest
|
||||
}
|
||||
func (f *FinderApplication) GetId() string {
|
||||
return f.manifest.AppId
|
||||
|
||||
func (f *FinderApplication) GetAppID() string {
|
||||
return f.appID
|
||||
}
|
||||
|
||||
func (f *FinderApplication) Render(isMobile bool) gin.H {
|
||||
func (f *FinderApplication) Render(appCtx appCtx.AppContext) 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 = append(islands, []wde.ContexMenuRow{})
|
||||
|
||||
if context == "FileTileView" {
|
||||
//TODO: Links read as source files in props info
|
||||
islands = append(islands, []wde.ContexMenuRow{
|
||||
{Label: "Get Info", Action: "getInfo"},
|
||||
{Label: "New Directory", Action: "createDir"},
|
||||
})
|
||||
if context == "FileTileView" {
|
||||
return gin.H{
|
||||
"Islands": islands,
|
||||
}
|
||||
}
|
||||
|
||||
switch context {
|
||||
case "directory":
|
||||
if f.fs.GetExtension(filePath) == "app" {
|
||||
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 *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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
// "fileId": fileHeader.MongoId,
|
||||
// "fileDataId": fileHeader.Data,
|
||||
"file": fileHeader,
|
||||
}, 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
|
||||
|
||||
import (
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/webfilesystem"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/wde"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type FinderAdminApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
func (f *FinderApplication) RenderAdminWindow(appCtx appCtx.AppContext) gin.H {
|
||||
|
||||
func NewFinderAdminApp(webfs *webfilesystem.WebFileSystem) FinderAdminApp {
|
||||
return FinderAdminApp{
|
||||
fs: webfs,
|
||||
manifest: apps.ApplicationManifest{},
|
||||
return gin.H{}
|
||||
}
|
||||
func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath string, data string) gin.H {
|
||||
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 (
|
||||
"net/http"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/errormessage"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
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))
|
||||
func (f *FinderApplication) PublicRoutes(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 bundle",
|
||||
})
|
||||
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))
|
||||
ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(appCtx))
|
||||
})
|
||||
|
||||
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) {
|
||||
context := ctx.Query("context")
|
||||
// if context == "" {
|
||||
// ctx.Status(http.StatusBadRequest)
|
||||
// return
|
||||
// }
|
||||
filePath := ctx.Query("path")
|
||||
if filePath == "" {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
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)
|
||||
})
|
||||
|
||||
|
@ -2,7 +2,6 @@ package imgviewer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
websiteapp "personalwebsite/apps"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -10,20 +9,20 @@ import (
|
||||
|
||||
type ImgViewerApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
manifest websiteapp.ApplicationManifest
|
||||
appID string
|
||||
}
|
||||
|
||||
func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) ImgViewerApp {
|
||||
func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) *ImgViewerApp {
|
||||
newApp := ImgViewerApp{
|
||||
fs: webFs,
|
||||
manifest: websiteapp.ApplicationManifest{
|
||||
AppId: "img-viewer",
|
||||
},
|
||||
appID: "ImgViewer",
|
||||
}
|
||||
return newApp
|
||||
return &newApp
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) Route(route *gin.RouterGroup) {
|
||||
func (p *ImgViewerApp) PrivateRoutes(route *gin.RouterGroup) {
|
||||
p.PublicRoutes(route)
|
||||
}
|
||||
func (p *ImgViewerApp) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("render", func(ctx *gin.Context) {
|
||||
isMobileParam := ctx.Query("isMobile")
|
||||
isMobile := isMobileParam == "true"
|
||||
@ -45,11 +44,8 @@ func (p *ImgViewerApp) Route(route *gin.RouterGroup) {
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) GetManifest() websiteapp.ApplicationManifest {
|
||||
return p.manifest
|
||||
}
|
||||
func (p *ImgViewerApp) GetId() string {
|
||||
return p.manifest.AppId
|
||||
func (p *ImgViewerApp) GetAppID() string {
|
||||
return p.appID
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) Render(filePath string, isMobile bool) (gin.H, error) {
|
||||
|
@ -2,50 +2,47 @@ package personalprops
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
websiteapp "personalwebsite/apps"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
//TODO Rename to AboutMe
|
||||
type PersonalPropertiesApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
manifest websiteapp.ApplicationManifest
|
||||
appID string
|
||||
}
|
||||
|
||||
func NewPersPropsApp(webFs *webfilesystem.WebFileSystem) PersonalPropertiesApp {
|
||||
func NewPersPropsApp(webFs *webfilesystem.WebFileSystem) *PersonalPropertiesApp {
|
||||
newApp := PersonalPropertiesApp{
|
||||
fs: webFs,
|
||||
manifest: websiteapp.ApplicationManifest{
|
||||
AppId: "personal-properties",
|
||||
},
|
||||
appID: "AboutMe",
|
||||
}
|
||||
return newApp
|
||||
return &newApp
|
||||
}
|
||||
|
||||
func (p *PersonalPropertiesApp) Route(route *gin.RouterGroup) {
|
||||
route.GET("writeMock", 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"
|
||||
func (p *PersonalPropertiesApp) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.POST("render", func(ctx *gin.Context) {
|
||||
filePath := ctx.Query("path")
|
||||
if filePath == "" {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
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 {
|
||||
ctx.JSON(http.StatusInternalServerError, "TODO") //TODO
|
||||
return
|
||||
}
|
||||
if isMobile {
|
||||
if appCtx.IsMobile {
|
||||
ctx.HTML(http.StatusOK, "personal-properties/mobile-app.tmpl", ginH)
|
||||
} else {
|
||||
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 {
|
||||
return p.manifest
|
||||
func (p *PersonalPropertiesApp) PrivateRoutes(router *gin.RouterGroup) {
|
||||
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 {
|
||||
@ -101,13 +107,14 @@ func (p *PersonalPropertiesApp) WriteMock() error {
|
||||
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{}
|
||||
filePath = p.fs.RelativeToAbsolute(appCtx, filePath)
|
||||
_, err := p.fs.Read(filePath, &propsData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
propsData.Header.IconPath = p.fs.RelativeToAbsolute(appCtx, propsData.Header.IconPath)
|
||||
return gin.H{
|
||||
"headerProps": propsData.Header,
|
||||
"allprops": propsData.Props,
|
||||
|
@ -12,9 +12,12 @@ import (
|
||||
//TODO to libs
|
||||
type WebDEApplication interface {
|
||||
// Render()
|
||||
GetManifest() ApplicationManifest
|
||||
GetAppID() string
|
||||
PublicRoutes(*gin.RouterGroup)
|
||||
PrivateRoutes(*gin.RouterGroup)
|
||||
// GetManifest() ApplicationManifest //TODO: Delete
|
||||
// GEtHtml()
|
||||
GetId() string
|
||||
// GetId() string
|
||||
}
|
||||
|
||||
type ApplicationManifest struct {
|
||||
@ -36,6 +39,25 @@ type ApplicationsStorage struct {
|
||||
}
|
||||
|
||||
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{
|
||||
AppId: appId,
|
||||
Js: []string{},
|
||||
@ -49,34 +71,27 @@ func (as *ApplicationsStorage) createApp(appName string, appId string, appPath s
|
||||
Icon: "",
|
||||
Data: primitive.NewObjectID(),
|
||||
}
|
||||
|
||||
//TODO: Create folder for app, etc
|
||||
_, _, err := as.fs.Write(appPath+"/"+newAppFile.Name, &newAppFile, newAppData)
|
||||
_, _, err = as.fs.Write(appPath+"/"+appBundleName+"/"+newAppFile.Name, &newAppFile, newAppData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// func NewApplicationsStorage() *ApplicationsStorage {
|
||||
// newStorage := ApplicationsStorage{}
|
||||
|
||||
// return &newStorage
|
||||
// }
|
||||
|
||||
func (aStorage *ApplicationsStorage) Route(route *gin.RouterGroup) {
|
||||
func (aStorage *ApplicationsStorage) PrivateRoute(route *gin.RouterGroup) {
|
||||
route.GET("/get", func(ctx *gin.Context) {
|
||||
appId := ctx.Query("appid")
|
||||
if appId == "" {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
app, isExist := aStorage.Apps[appId]
|
||||
if !isExist {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, app.GetManifest())
|
||||
// app, isExist := aStorage.Apps[appId]
|
||||
// if !isExist {
|
||||
// ctx.Status(http.StatusNoContent)
|
||||
// return
|
||||
// }
|
||||
// ctx.JSON(http.StatusOK, app.GetManifest())
|
||||
ctx.String(http.StatusMovedPermanently, "Obsolete")
|
||||
})
|
||||
|
||||
route.GET("/loadApp", func(ctx *gin.Context) {
|
||||
@ -120,7 +135,7 @@ func (aStorage *ApplicationsStorage) Route(route *gin.RouterGroup) {
|
||||
|
||||
err := aStorage.createApp(appId, appName, appPath)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
ctx.String(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
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/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
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/sse v0.1.0 // 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/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
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/ugorji/go/codec v1.2.9 // indirect
|
||||
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-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
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.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/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/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/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.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/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/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/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.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/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.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/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/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
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/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
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/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.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
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.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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
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/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/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/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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
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.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
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/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/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.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/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
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=
|
||||
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/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.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
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/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.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
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-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-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.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
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/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.3/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.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/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.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/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 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.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-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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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
|
||||
}
|
||||
|
||||
func (c *Cat) Route(route *gin.RouterGroup) {
|
||||
func (c *Cat) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("get", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
@ -52,7 +52,13 @@ func (c *Cat) Route(route *gin.RouterGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
mode := ctx.Query("mode")
|
||||
switch mode {
|
||||
case "json":
|
||||
ctx.JSON(http.StatusOK, data)
|
||||
default:
|
||||
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) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
@ -31,10 +31,6 @@ func (l *ImagLib) Route(route *gin.RouterGroup) {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// _, err = l.fs.readFSDocs(fileId, &imgData)
|
||||
// if err != nil {
|
||||
// ctx.Status(http.StatusInternalServerError)
|
||||
// }
|
||||
|
||||
ctx.Data(http.StatusOK, "image/jpeg", imgData.Bin)
|
||||
})
|
||||
|
205
main.go
205
main.go
@ -4,21 +4,18 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"personalwebsite/apps"
|
||||
blogwriter "personalwebsite/apps/BlogWriter"
|
||||
"personalwebsite/apps/blogviewer"
|
||||
"personalwebsite/apps/finder"
|
||||
imgviewer "personalwebsite/apps/img-viewer"
|
||||
"personalwebsite/apps/personalprops"
|
||||
"personalwebsite/libs"
|
||||
"personalwebsite/routewde"
|
||||
"personalwebsite/routes"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-contrib/location"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/joho/godotenv"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
@ -54,110 +51,130 @@ func main() {
|
||||
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)
|
||||
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)
|
||||
|
||||
//TODO Split to different apps init for private and public?
|
||||
persPropsApp := personalprops.NewPersPropsApp(webfs)
|
||||
// finderApp := finder.FinderApplication{}
|
||||
finderApp := finder.NewFinderApplication(webfs)
|
||||
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
||||
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
||||
appsStorage := apps.NewApplicationsStorage(map[string]apps.WebDEApplication{}, webfs)
|
||||
appsStorage.Apps["personal-properties"] = &persPropsApp
|
||||
blogWriterApp := blogwriter.NewBlogWriterApp(webfs)
|
||||
appsStorage.Apps["personal-properties"] = persPropsApp
|
||||
appsStorage.Apps["finder"] = finderApp
|
||||
appsStorage.Apps["img-viewer"] = &imgViewerApp
|
||||
appsStorage.Apps["blog-viewer"] = blogViewerApp
|
||||
appsStorage.Apps["img-viewer"] = imgViewerApp
|
||||
appsStorage.Apps[blogViewerApp.GetAppID()] = blogViewerApp
|
||||
appsStorage.Apps["BlogWriter"] = blogWriterApp
|
||||
|
||||
system := router.Group("system")
|
||||
{
|
||||
libsGroup := system.Group("libs")
|
||||
{
|
||||
imgLibGroup := libsGroup.Group("img")
|
||||
{
|
||||
imgLib := libs.NewImgLib(webfs)
|
||||
imgLib.Route(imgLibGroup)
|
||||
}
|
||||
go routes.PublicRoutes(webfs, webde, appsStorage)
|
||||
routes.PrivateRoutes(webfs, webde, appsStorage)
|
||||
|
||||
catLibGroup := libsGroup.Group("cat")
|
||||
{
|
||||
catLib := libs.NewCatLib(webfs)
|
||||
catLib.Route(catLibGroup)
|
||||
}
|
||||
// system := router.Group("system")
|
||||
// {
|
||||
// libsGroup := system.Group("libs")
|
||||
// {
|
||||
// imgLibGroup := libsGroup.Group("img")
|
||||
// {
|
||||
// imgLib := libs.NewImgLib(webfs)
|
||||
// imgLib.PublicRoutes(imgLibGroup)
|
||||
// }
|
||||
|
||||
appsStorageGroup := libsGroup.Group("apps")
|
||||
{
|
||||
appsStorage.Route(appsStorageGroup)
|
||||
}
|
||||
}
|
||||
// catLibGroup := libsGroup.Group("cat")
|
||||
// {
|
||||
// catLib := libs.NewCatLib(webfs)
|
||||
// catLib.PublicRoutes(catLibGroup)
|
||||
// }
|
||||
|
||||
wdeGroup := system.Group("wde")
|
||||
{
|
||||
routewde.Route(wdeGroup, webde)
|
||||
}
|
||||
apps := system.Group("applications") //TODO to libs
|
||||
{
|
||||
apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
||||
appId := ctx.Param("appid")
|
||||
method := ctx.Param("method")
|
||||
// appsStorageGroup := libsGroup.Group("apps")
|
||||
// {
|
||||
// appsStorage.Route(appsStorageGroup)
|
||||
// }
|
||||
// }
|
||||
|
||||
app, isExist := appsStorage.Apps[appId]
|
||||
if !isExist {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
switch method {
|
||||
case "getmanifest":
|
||||
ctx.JSON(http.StatusOK, app.GetManifest())
|
||||
case "app.js":
|
||||
ctx.File("resources/sys/" + appId + "/" + appId + ".js")
|
||||
case "app.css":
|
||||
ctx.File("resources/sys/" + appId + "/" + appId + ".css")
|
||||
default:
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
// wdeGroup := system.Group("wde")
|
||||
// {
|
||||
// routewde.PublicRoutes(wdeGroup, webde)
|
||||
// }
|
||||
// apps := system.Group("applications") //TODO to libs
|
||||
// {
|
||||
// apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
||||
// appId := ctx.Param("appid")
|
||||
// method := ctx.Param("method")
|
||||
|
||||
fs := router.Group("fs")
|
||||
{
|
||||
webfs.Route(fs)
|
||||
}
|
||||
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)
|
||||
}
|
||||
// app, isExist := appsStorage.Apps[appId]
|
||||
// if !isExist {
|
||||
// ctx.Status(http.StatusNoContent)
|
||||
// return
|
||||
// }
|
||||
// switch method {
|
||||
// case "getmanifest":
|
||||
// ctx.JSON(http.StatusOK, app.GetManifest())
|
||||
// case "app.js":
|
||||
// ctx.File("resources/sys/" + appId + "/" + appId + ".js")
|
||||
// case "app.css":
|
||||
// ctx.File("resources/sys/" + appId + "/" + appId + ".css")
|
||||
// default:
|
||||
// ctx.Status(http.StatusBadRequest)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
err = router.Run(":8080")
|
||||
if err != nil {
|
||||
log.Panicf("error: %s", err)
|
||||
}
|
||||
}
|
||||
// fs := router.Group("fs")
|
||||
// {
|
||||
// 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) {
|
||||
|
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{
|
||||
appId = "AboutMe"
|
||||
static appID = "AboutMe"
|
||||
/**
|
||||
* @param {HTMLElement} appElem
|
||||
*/
|
||||
@ -8,18 +8,17 @@ class AboutMe{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} chroot
|
||||
* @param {[]string} args
|
||||
* @param {Object} runContext
|
||||
*/
|
||||
async NewWindow(chroot, args){
|
||||
console.log(chroot)
|
||||
if (chroot == ""){
|
||||
chroot = "/home/user" //FIXME
|
||||
}
|
||||
console.log(`${chroot}/AboutMe.app/aboutme.props`)
|
||||
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile, path: `${chroot}/AboutMe.app/aboutme.props`})
|
||||
const response = await fetch(`/app/${this.appId}/render?`+ params)
|
||||
console.log(response)
|
||||
async NewWindow(args, runContext){
|
||||
const params = new URLSearchParams({
|
||||
path: `:/aboutme.props`,
|
||||
})
|
||||
const response = await fetch(`/app/${AboutMe.appID}/render?`+ params,{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
WebDesktopEnvironment.Alert("Error TODO") //TODO
|
||||
return
|
@ -1,17 +1,19 @@
|
||||
class BlogViewer{
|
||||
appId = "blog-viewer"
|
||||
constructor(){
|
||||
}
|
||||
static appID = "BlogViewer"
|
||||
|
||||
/**
|
||||
* @param {string[]} chroot //TODO
|
||||
* @param {string[]} args
|
||||
* @param {Object} runContext
|
||||
*/
|
||||
async NewWindow(args){
|
||||
const response = await fetch(`app/${this.appId}/render?` + new URLSearchParams({
|
||||
isMobile: WebDesktopEnvironment.isMobile,
|
||||
async NewWindow(args, runContext){
|
||||
const params = new URLSearchParams({
|
||||
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){
|
||||
WebDesktopEnvironment.Alert("Error render TODO") //TODO
|
||||
return
|
@ -25,7 +25,25 @@
|
||||
/* gap: 50px; */
|
||||
/* row-gap: 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{
|
||||
@ -43,6 +61,19 @@
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.BlogView .image{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.image .ImageProp{
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
||||
/* left: 50%;
|
||||
margin-left: -50%; */
|
||||
}
|
||||
|
||||
.BlogView .plain-text{
|
||||
/* Auto layout */
|
||||
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{
|
||||
static appId = "Finder"
|
||||
appId = "Finder"
|
||||
fileView = undefined
|
||||
path = "/"
|
||||
homePath = "/home/user"
|
||||
windowElement
|
||||
// previousPath = "/"
|
||||
pathHistory = [] //FIXME Fixed length
|
||||
constructor(){
|
||||
// this.appElem = appElem
|
||||
// WebDesktopEnvironment.RegisterApp(this)
|
||||
}
|
||||
class FinderAdmin{
|
||||
static AppId = "FinderAdmin"
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
*/
|
||||
async NewWindow(args){
|
||||
async NewWindow(args, runContext){
|
||||
let newFinder = new FinderWindow()
|
||||
await newFinder.Init(args)
|
||||
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);
|
||||
})
|
||||
await newFinder.Init(args, runContext)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @returns {boolean}
|
||||
*/
|
||||
static async RenderProperites(path){
|
||||
if (path == null || path ==""){
|
||||
return
|
||||
}
|
||||
const params = new URLSearchParams({
|
||||
path: path
|
||||
})
|
||||
const response = await fetch(`/application/${Finder.appId}/renderProps?` + params)
|
||||
const response = await fetch(`/app/Finder/renderProps?` + params)
|
||||
if (response.status != 200){
|
||||
WebDesktopEnvironment.Alert("Error in properties render") //TODO
|
||||
return false
|
||||
}
|
||||
const html = response.text()
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.appId, 350, 500 )
|
||||
const html = await response.text()
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(FinderAdmin.AppId, 350, 500 )
|
||||
newWindow.innerHTML = html
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
@ -135,42 +36,49 @@ class Finder{
|
||||
|
||||
|
||||
class FinderWindow{
|
||||
CurPath = ""
|
||||
curPath = ""
|
||||
fileView = undefined
|
||||
windowElem = undefined
|
||||
addressBar = undefined
|
||||
|
||||
async Init(args){
|
||||
// console.log(args)
|
||||
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)
|
||||
const response = await fetch(`/app/Finder/renderDesktop?` + params)
|
||||
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, true)
|
||||
})
|
||||
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)
|
||||
const response = await fetch(`/app/Finder/render?` + params,{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
WebDesktopEnvironment.Alert("Finder ERROR TODO") //TODO
|
||||
const error = await response.json()
|
||||
WebDesktopEnvironment.Alert(error.message)
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(Finder.appId, 500, 350 )
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(FinderAdmin.AppId, 500, 350 )
|
||||
newWindow.innerHTML = html
|
||||
|
||||
// console.log(this.ReRenderDir)
|
||||
this.fileView = new FileView(
|
||||
newWindow.querySelector(".FileTileView"),
|
||||
(event) => { this.Click(event) },
|
||||
@ -180,9 +88,7 @@ class FinderWindow{
|
||||
)
|
||||
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
|
||||
})
|
||||
|
||||
newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
||||
@ -195,18 +101,23 @@ class FinderWindow{
|
||||
|
||||
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".FileTileView"))
|
||||
|
||||
|
||||
this.windowElem = newWindow
|
||||
this.addressBar = newWindow.querySelector(".AddressBar")
|
||||
this.RenderDir(args[0])
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
*/
|
||||
RenderDir(path){
|
||||
this.CurPath = path
|
||||
console.log(path)
|
||||
this.curPath = path
|
||||
this.addressBar.innerHTML = path
|
||||
this.fileView.OpenFolder(path)
|
||||
}
|
||||
|
||||
ReRenderDir(){
|
||||
this.RenderDir(this.CurPath)
|
||||
this.RenderDir(this.curPath)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,7 +128,7 @@ class FinderWindow{
|
||||
// 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 targetPath = this.curPath + "/" + event.dataTransfer.getData("fileName")
|
||||
const res = await WebFS.MoveFile(sourcePath, targetPath)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
@ -225,17 +136,20 @@ class FinderWindow{
|
||||
WebDesktopEnvironment.Alert("UWAGA TODO MOVE FILE ERROR") //TODO
|
||||
}
|
||||
} else {
|
||||
WebDesktopEnvironment.Alert("Not fixed yet")
|
||||
return
|
||||
let formData = new FormData()
|
||||
console.log(event, this.curPath)
|
||||
let files = event.dataTransfer.files
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const element = files[i];
|
||||
console.log(element)
|
||||
formData.append("file", element) //FIXME Conn reset
|
||||
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,
|
||||
parentPath: this.curPath,
|
||||
})
|
||||
const response = await fetch('/fs/upload/?' + params,
|
||||
{
|
||||
@ -255,26 +169,40 @@ class FinderWindow{
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
Click(event){
|
||||
let fileType = 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}`])
|
||||
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 "blog":
|
||||
WebDesktopEnvironment.Open("/Applications/BlogViewer.app", [`${this.CurPath}/${fileName}`])
|
||||
case fileType == "pathlink":
|
||||
let res = await WebFS.ReadPathLink(`${parentPath}/${fileName}`)
|
||||
console.log(res)
|
||||
this.OpenFile(res.parentPath, res.name, res.filetype)
|
||||
break
|
||||
case "jpeg":
|
||||
case "png":
|
||||
WebDesktopEnvironment.Open("img-viewer", [this.CurPath + "/" + fileName])
|
||||
case fileExtension == "app":
|
||||
WebDesktopEnvironment.Open(`${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:
|
||||
// console.log("Unsupported file type")
|
||||
WebDesktopEnvironment.Alert("Unsupported file type")
|
||||
break;
|
||||
}
|
||||
@ -293,7 +221,7 @@ class FinderWindow{
|
||||
*/
|
||||
async CreateContextMenu(target, pos){
|
||||
let context = ""
|
||||
const fileName = target.getAttribute("name")
|
||||
const fileName = target.getAttribute("name") //TODO check for null
|
||||
const fileType = target.getAttribute("fileType")
|
||||
if (target.classList.contains("FileTileView"))
|
||||
{
|
||||
@ -301,8 +229,14 @@ class FinderWindow{
|
||||
} else {
|
||||
context = fileType
|
||||
}
|
||||
const params = new URLSearchParams({context: context, path: `${this.CurPath}/${fileName}`})
|
||||
const response = await fetch(`/app/${Finder.appId}/contextMenu?` + params)
|
||||
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/contextMenu?` + params)
|
||||
if (response.status != 200){
|
||||
WebDesktopEnvironment.Alert("ERROR in Context menu TODO"); //TODO
|
||||
return
|
||||
@ -331,25 +265,31 @@ class FinderWindow{
|
||||
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}`)
|
||||
res = await WebFS.CreateDirectory(`${this.curPath}`)
|
||||
console.log(res)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
break
|
||||
case "deleteFile":
|
||||
res = await WebFS.DeleteFile(`${this.CurPath}/${fileName}`)
|
||||
res = await WebFS.DeleteFile(`${this.curPath}/${fileName}`)
|
||||
console.log(res)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
break
|
||||
case "getInfo":
|
||||
res = await Finder.RenderProperites(`${this.CurPath}/${fileName}`)
|
||||
Finder.RenderProperites(path)
|
||||
break
|
||||
case "openAsDir":
|
||||
WebDesktopEnvironment.Open(`/Applications/${Finder.appId}.app`,[`${this.CurPath}/${fileName}`])
|
||||
WebDesktopEnvironment.Open(`/Applications/Finder.app`,[`${this.curPath}/${fileName}`])
|
||||
break
|
||||
default:
|
||||
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-family: "Virtue";
|
||||
src:url("./virtue.ttf");
|
||||
src:url("/res/dev-fs/fonts/virtue.ttf");
|
||||
}
|
||||
|
||||
@font-face{
|
||||
/* @font-face{
|
||||
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) {
|
||||
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"
|
||||
)
|
||||
|
||||
func Route(route *gin.RouterGroup, wde *wde.WDE) {
|
||||
route.GET("/getbasicwindow", func(ctx *gin.Context) {
|
||||
func PublicRoutes(route *gin.RouterGroup, wde *wde.WDE) {
|
||||
route.GET("/getbasicwindow", func(ctx *gin.Context) { //TODO Rename to renderGenericWindowFrame
|
||||
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) {
|
||||
url := location.Get(ctx)
|
||||
// _ = url
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
|
@ -2,34 +2,29 @@
|
||||
<html lang="en" dir="ltr">
|
||||
<title>Greg Brzezinski</title>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="res/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/sys/wde/wde-scrollbar.css">
|
||||
<link rel="stylesheet" type="text/css" href="res/sys/wde/basic-widgets.css">
|
||||
<link rel="stylesheet" type="text/css" href="res/sys/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">
|
||||
<link rel="stylesheet" href="/res/sys/wde/simple-scrollbar.css">
|
||||
<link rel="stylesheet" type="text/css" href="res/sys/finder/finder.css">
|
||||
<link rel="stylesheet" href="/res/sys/personal-properties/personal-properies.css">
|
||||
<link rel="stylesheet" href="/res/sys/img-viewer/img-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/sys/wde/file-view.js"></script>
|
||||
<script src="res/wde.js"></script>
|
||||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> -->
|
||||
<!-- <script src="res/decorat.js"></script> -->
|
||||
<!-- TODO Load with app -->
|
||||
<!-- <script src="res/personal-properties.js"></script> -->
|
||||
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/base.css">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="res/dev-fs/wde/wdeUI.css">
|
||||
<link rel="stylesheet" type="text/css" href="res/dev-fs/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/dev-fs/wde/file-view.css">
|
||||
|
||||
<!-- TODO: Move css init to js -->
|
||||
<link rel="stylesheet" href="res/dev-fs/apps/Finder/finder.css">
|
||||
<link rel="stylesheet" href="/res/dev-fs/apps/AboutMe/about-me.css">
|
||||
<link rel="stylesheet" href="/res/dev-fs/apps/ImgViewer/img-viewer.css">
|
||||
<link rel="stylesheet" href="/res/dev-fs/apps/BlogViewer/blog-viewer.css">
|
||||
|
||||
<script src="res/dev-fs/wde/wde.js"></script>
|
||||
<script src="res/dev-fs/wde/decorat.js"></script>
|
||||
<script src="res/dev-fs/wde/webfs.js"></script>
|
||||
<script src="/res/dev-fs/wde/wde-scrollbar.js"></script>
|
||||
<script src="/res/dev-fs/wde/file-view.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- <div id="WindowsLayer"></div> -->
|
||||
<div id="applications"></div>
|
||||
<div id="desktop-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>
|
||||
</html>
|
||||
|
@ -12,6 +12,13 @@
|
||||
<div class="Content">
|
||||
<div class="ScrollContent">
|
||||
{{ 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}}" >
|
||||
{{ range $data := $block.Data }}
|
||||
<div style="font-size: inherit;">
|
||||
@ -20,6 +27,7 @@
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{template "wde-widgets/scrollbar.tmpl" .}}
|
||||
|
@ -13,8 +13,11 @@
|
||||
<div class="FinderContent">
|
||||
<!-- TODO Fix ConvexElement -->
|
||||
<div class="ToolBar ConvexElement">
|
||||
<button id="BackButton">Back</button>
|
||||
<button id="UpButton">Up</button>
|
||||
<button id="RootButton">/</button>
|
||||
<button id="HomeButton">Home</button>
|
||||
<div class="AddressBar" contentEditable="true">You Favorite Movie</div>
|
||||
</div>
|
||||
<div class="FinderFileView">
|
||||
<div class="FileTileView">
|
||||
|
@ -1,24 +1,27 @@
|
||||
{{ define "finder/app.tmpl" }}
|
||||
<div class="TitleBar DragArea">
|
||||
<button id="closeWindowButton" class="Button" title="Close Window"></button>
|
||||
<div class="TitleBarTest">
|
||||
|
||||
<div id="Drag" class="VisualDragArea"></div>
|
||||
<div class="Lable">
|
||||
Files
|
||||
Finder
|
||||
</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>
|
||||
{{template "wde-widgets/scrollbar.tmpl" .}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
@ -20,6 +20,9 @@
|
||||
<div>
|
||||
file id : {{.file.MongoId}}
|
||||
</div>
|
||||
<div>
|
||||
file type : {{.file.Type}}
|
||||
</div>
|
||||
<div>
|
||||
file data id : {{.file.Data}}
|
||||
</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 {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
list, err := w.fs.ListDir(directory)
|
||||
if err != nil {
|
||||
|
@ -7,9 +7,9 @@ import (
|
||||
)
|
||||
|
||||
type DirectoryData struct {
|
||||
MongoId primitive.ObjectID `bson:"_id"`
|
||||
Parent primitive.ObjectID `bson:"parent_id"`
|
||||
Children []primitive.ObjectID `bson:"children_id"`
|
||||
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||
Parent primitive.ObjectID `bson:"parent_id" json:"parent"` //TODO: Delete
|
||||
Children []primitive.ObjectID `bson:"children_id" json:"children"`
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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{}
|
||||
_, err = fs.readFSDocs(dirId, &dirData)
|
||||
_, 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)
|
||||
|
@ -5,13 +5,13 @@ package webfilesystem
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"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
|
||||
// parentPath := fs.GetParentPath(filePath)
|
||||
file, err := os.ReadFile(realFilepath)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -33,7 +33,7 @@ func (fs *WebFileSystem) UploadFile(realFilepath string, parentPath string) erro
|
||||
Bin: file,
|
||||
}
|
||||
|
||||
filePath := path.Join(parentPath, fileName)
|
||||
// filePath := path.Join(parentPath, fileName)
|
||||
|
||||
switch extension {
|
||||
case "jpg":
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"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) {
|
||||
fileHeader := &FileHeader{}
|
||||
filter := primitive.M{
|
||||
@ -41,7 +42,33 @@ func (fs *WebFileSystem) writeFileToMongo(file *FileHeader, data interface{}) (p
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -8,7 +8,7 @@ func (fs *WebFileSystem) Read(filePath string, fileData interface{}) (*FileHeade
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileHeader, err := fs.readFSDocs(fileId, fileData)
|
||||
fileHeader, err := fs.ReadByObjectID(fileId, fileData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -22,5 +22,19 @@ func (fs *WebFileSystem) ReadByObjectID(fileID primitive.ObjectID, fileData inte
|
||||
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
|
||||
}
|
||||
|
@ -2,11 +2,14 @@ package webfilesystem
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/errormessage"
|
||||
|
||||
"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
|
||||
// fileName := ctx.Query("fileName")
|
||||
// if fileName == "" {
|
||||
@ -32,9 +35,11 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
||||
ctx.SaveUploadedFile(file, dst)
|
||||
|
||||
//TODO: Not Save to disk
|
||||
err := fs.UploadFile(dst, parentPath)
|
||||
err := fs.UploadFile(dst, path.Join(parentPath, file.Filename))
|
||||
if err != nil {
|
||||
ctx.String(http.StatusInternalServerError, "TODO") //TODO
|
||||
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@ -45,6 +50,28 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
||||
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) {
|
||||
// parentPath := ctx.Query("parentPath")
|
||||
// if parentPath == "" {
|
||||
@ -166,4 +193,67 @@ func (fs *WebFileSystem) Route(route *gin.RouterGroup) {
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
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()
|
||||
// if err != nil {
|
||||
// return err
|
||||
@ -53,6 +92,35 @@ func (fs *WebFileSystem) validate() error {
|
||||
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) {
|
||||
// fs.ReadByObjectID(directoryID, nil)
|
||||
// }
|
||||
|
@ -3,6 +3,8 @@ package webfilesystem
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"path"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"strings"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -46,21 +48,31 @@ type BinaryFileData struct {
|
||||
|
||||
type PlainTextFileData struct {
|
||||
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||
Data string `bson:"data" json:"data"`
|
||||
Data string `bson:"data" json:"-"`
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (fs *WebFileSystem) ReadHeader(fileID primitive.ObjectID) (*FileHeader, error) {
|
||||
file := &FileHeader{}
|
||||
filter := primitive.M{
|
||||
"_id": fileID,
|
||||
}
|
||||
err := fs.webfsFilesTable.FindOne(fs.ctx, filter).Decode(file)
|
||||
return file, err
|
||||
type ObjectLinkFileData struct {
|
||||
MongoId primitive.ObjectID `bson:"_id" json:"-"`
|
||||
Link_id primitive.ObjectID `bson:"link_id" json:"-"`
|
||||
}
|
||||
|
||||
//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) {
|
||||
if fs.CheckFileExist(filePath) {
|
||||
return primitive.NilObjectID, primitive.NilObjectID, errors.New("file exists")
|
||||
}
|
||||
|
||||
headerId, dataId, err := fs.writeFileToMongo(file, data)
|
||||
if err != nil {
|
||||
return primitive.NilObjectID, primitive.NilObjectID, err
|
||||
@ -168,7 +180,7 @@ func (fs *WebFileSystem) Move(sourcePath string, targetPath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//TODO: use moveByID()
|
||||
if targetParentDirHeader.Type != "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 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 {
|
||||
@ -215,9 +253,83 @@ func (fs *WebFileSystem) Remove(filePath string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if parentPath == "/orfaned" { //TODO path to struct
|
||||
err := fs.removeFromMongo(fileId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
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 {
|
||||
resPath := []string{}
|
||||
splittedPath := strings.Split(path, "/")
|
||||
@ -243,3 +355,23 @@ func (fs *WebFileSystem) GetParentPath(path string) string {
|
||||
}
|
||||
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