From 9ec954ceb3102db5d7dbf42e12ba40fb94d52475 Mon Sep 17 00:00:00 2001 From: cyber-dream Date: Thu, 18 May 2023 04:57:44 +0300 Subject: [PATCH] Massive rework in blog viewer --- apps/BlogWriter/blogwriter.go | 28 ++ apps/blogviewer/blogfile.go | 4 +- apps/blogviewer/blogviewer.go | 78 +++-- apps/finder/finder.go | 17 +- apps/finder/finderadmin.go | 27 +- apps/finder/routes.go | 31 +- main.go | 6 +- .../apps/BlogViewer/BlogViewer.js} | 24 +- .../apps/BlogViewer}/blog-viewer.css | 33 +- .../dev-fs/apps/BlogWriter/BlogWriter.js | 10 + .../dev-fs/apps/FinderAdmin/FinderAdmin.js | 305 ++++++++++++++++++ .../dev-fs/apps/FinderAdmin/finder-admin.css | 53 +++ resources/dev-fs/apps/finder/finder.js | 30 +- resources/wde.js | 15 +- templates/base/index.tmpl | 6 +- templates/blog-viewer/app.tmpl | 22 +- templates/finder/admin-app.tmpl | 3 + templates/finder/app.tmpl | 4 +- webfilesystem/directory.go | 2 +- 19 files changed, 597 insertions(+), 101 deletions(-) create mode 100644 apps/BlogWriter/blogwriter.go rename resources/{sys/blog-viewer/blog-viewer.js => dev-fs/apps/BlogViewer/BlogViewer.js} (74%) rename resources/{sys/blog-viewer => dev-fs/apps/BlogViewer}/blog-viewer.css (62%) create mode 100644 resources/dev-fs/apps/BlogWriter/BlogWriter.js create mode 100644 resources/dev-fs/apps/FinderAdmin/FinderAdmin.js create mode 100644 resources/dev-fs/apps/FinderAdmin/finder-admin.css diff --git a/apps/BlogWriter/blogwriter.go b/apps/BlogWriter/blogwriter.go new file mode 100644 index 0000000..d1eabd0 --- /dev/null +++ b/apps/BlogWriter/blogwriter.go @@ -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) { + +} diff --git a/apps/blogviewer/blogfile.go b/apps/blogviewer/blogfile.go index a96c955..b367094 100644 --- a/apps/blogviewer/blogfile.go +++ b/apps/blogviewer/blogfile.go @@ -1,6 +1,6 @@ package blogviewer type BlogFileData struct { - Header string `bson:"header"` - Blocks []Block `bson:"blocks"` + Header string `bson:"header"` + Blocks []*Block `bson:"blocks"` } diff --git a/apps/blogviewer/blogviewer.go b/apps/blogviewer/blogviewer.go index edf39c8..0537d5c 100644 --- a/apps/blogviewer/blogviewer.go +++ b/apps/blogviewer/blogviewer.go @@ -2,6 +2,8 @@ package blogviewer import ( "net/http" + "path" + "personalwebsite/apps/appCtx" "personalwebsite/webfilesystem" "github.com/gin-gonic/gin" @@ -41,22 +43,27 @@ func (b *BlogViewerApplication) PublicRoutes(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) @@ -66,25 +73,17 @@ func (b *BlogViewerApplication) PublicRoutes(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) @@ -92,16 +91,51 @@ 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) 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, diff --git a/apps/finder/finder.go b/apps/finder/finder.go index 60f44f9..767fd08 100644 --- a/apps/finder/finder.go +++ b/apps/finder/finder.go @@ -1,7 +1,7 @@ package finder import ( - "personalwebsite/apps" + "personalwebsite/apps/appCtx" "personalwebsite/wde" "personalwebsite/webfilesystem" @@ -9,28 +9,23 @@ import ( ) type FinderApplication struct { - fs *webfilesystem.WebFileSystem - appID string - manifest apps.ApplicationManifest + fs *webfilesystem.WebFileSystem + appID string + // manifest apps.ApplicationManifest } func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication { return &FinderApplication{ fs: webFs, appID: "Finder", - manifest: apps.ApplicationManifest{ - AppId: "finder", - }, } } -func (f *FinderApplication) GetManifest() apps.ApplicationManifest { - return f.manifest -} + 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{} } diff --git a/apps/finder/finderadmin.go b/apps/finder/finderadmin.go index a3f7d63..c3aacb3 100644 --- a/apps/finder/finderadmin.go +++ b/apps/finder/finderadmin.go @@ -1,31 +1,19 @@ package finder import ( - "personalwebsite/apps" + "personalwebsite/apps/appCtx" "personalwebsite/wde" - "personalwebsite/webfilesystem" "github.com/gin-gonic/gin" ) -type FinderAdminApp struct { - fs *webfilesystem.WebFileSystem - manifest apps.ApplicationManifest -} - -func NewFinderAdminApp(webfs *webfilesystem.WebFileSystem) FinderAdminApp { - return FinderAdminApp{ - fs: webfs, - manifest: apps.ApplicationManifest{}, - } -} - -func (f *FinderAdminApp) RenderWindow() { +func (f *FinderApplication) RenderAdminWindow(appCtx appCtx.AppContext) gin.H { + 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{}) islands = append(islands, []wde.ContexMenuRow{ {Label: "Get Info", Action: "getInfo"}, @@ -46,7 +34,12 @@ func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath st switch context { case "directory": - if f.fs.GetExtension(filePath) == "app" { + 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"}, }) diff --git a/apps/finder/routes.go b/apps/finder/routes.go index f45fa7c..15a79c8 100644 --- a/apps/finder/routes.go +++ b/apps/finder/routes.go @@ -2,14 +2,23 @@ package finder import ( "net/http" + "personalwebsite/apps/appCtx" + "personalwebsite/errormessage" "github.com/gin-gonic/gin" ) func (f *FinderApplication) PublicRoutes(routes *gin.RouterGroup) { - routes.GET("render", func(ctx *gin.Context) { - isMobile := ctx.Query("isMobile") == "true" - ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(isMobile)) + 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 + } + ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(appCtx)) }) routes.GET("renderMobileDesktop", func(ctx *gin.Context) { @@ -48,14 +57,18 @@ func (f *FinderApplication) PublicRoutes(routes *gin.RouterGroup) { } func (f *FinderApplication) PrivateRoutes(routes *gin.RouterGroup) { - routes.GET("render", func(ctx *gin.Context) { - isMobile := ctx.Query("isMobile") == "true" - ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(isMobile)) + 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/app.tmpl", f.Render(appCtx)) }) - 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 == "" { diff --git a/main.go b/main.go index 560d2b0..fabc3ff 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "os" "personalwebsite/apps" + blogwriter "personalwebsite/apps/BlogWriter" "personalwebsite/apps/blogviewer" "personalwebsite/apps/finder" imgviewer "personalwebsite/apps/img-viewer" @@ -65,14 +66,17 @@ func main() { webde := wde.NewWDE(webfs) + //TODO Split to different apps init for private and public? persPropsApp := personalprops.NewPersPropsApp(webfs) finderApp := finder.NewFinderApplication(webfs) imgViewerApp := imgviewer.NewImgViewerApp(webfs) blogViewerApp := blogviewer.NewBlogViewerApp(webfs) + 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[blogViewerApp.GetAppID()] = blogViewerApp + appsStorage.Apps["BlogWriter"] = blogWriterApp go routes.PublicRoutes(webfs, webde, appsStorage) routes.PrivateRoutes(webfs, webde, appsStorage) diff --git a/resources/sys/blog-viewer/blog-viewer.js b/resources/dev-fs/apps/BlogViewer/BlogViewer.js similarity index 74% rename from resources/sys/blog-viewer/blog-viewer.js rename to resources/dev-fs/apps/BlogViewer/BlogViewer.js index a90a968..7893fb3 100644 --- a/resources/sys/blog-viewer/blog-viewer.js +++ b/resources/dev-fs/apps/BlogViewer/BlogViewer.js @@ -1,26 +1,28 @@ class BlogViewer{ - appId = "blog-viewer" - constructor(){ - } + static appID = "BlogViewer" /** - * @param {string[]} chroot //TODO - * @param {string[]} args + * @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 } const html = await response.text() - let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 500, 350 ) + let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 500, 350 ) newWindow.innerHTML = html - + let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".ScrollContent")) newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) { WebDesktopEnvironment.CloseWindow(newWindow) diff --git a/resources/sys/blog-viewer/blog-viewer.css b/resources/dev-fs/apps/BlogViewer/blog-viewer.css similarity index 62% rename from resources/sys/blog-viewer/blog-viewer.css rename to resources/dev-fs/apps/BlogViewer/blog-viewer.css index d1a8b8e..6a269fc 100644 --- a/resources/sys/blog-viewer/blog-viewer.css +++ b/resources/dev-fs/apps/BlogViewer/blog-viewer.css @@ -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; diff --git a/resources/dev-fs/apps/BlogWriter/BlogWriter.js b/resources/dev-fs/apps/BlogWriter/BlogWriter.js new file mode 100644 index 0000000..08a4ae9 --- /dev/null +++ b/resources/dev-fs/apps/BlogWriter/BlogWriter.js @@ -0,0 +1,10 @@ +class BlogWriter{ + static AppId = "BlogWriter" + + /** + * @param {string[]} args + */ + async NewWindow(args){ + console.log("kek") + } +} \ No newline at end of file diff --git a/resources/dev-fs/apps/FinderAdmin/FinderAdmin.js b/resources/dev-fs/apps/FinderAdmin/FinderAdmin.js new file mode 100644 index 0000000..3da280c --- /dev/null +++ b/resources/dev-fs/apps/FinderAdmin/FinderAdmin.js @@ -0,0 +1,305 @@ +class FinderAdmin{ + static AppId = "FinderAdmin" + + /** + * @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/renderProps?` + params) + if (response.status != 200){ + WebDesktopEnvironment.Alert("Error in properties render") //TODO + return false + } + 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) + }) + } +} + + +class FinderWindow{ + curPath = "" + fileView = undefined + windowElem = undefined + addressBar = 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/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)}, + (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/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(FinderAdmin.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.addressBar = newWindow.querySelector(".AddressBar") + this.RenderDir(args[0]) + } + + /** + * @param {string} path + */ + RenderDir(path){ + console.log(path) + this.curPath = path + this.addressBar.innerHTML = 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 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/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.app`,[`${this.curPath}/${fileName}`]) + break + default: + break; + } + } + overlay.remove() + }) + overlay.addEventListener('contextmenu', (event) => { + event.preventDefault(); + overlay.remove() + }) + } +} \ No newline at end of file diff --git a/resources/dev-fs/apps/FinderAdmin/finder-admin.css b/resources/dev-fs/apps/FinderAdmin/finder-admin.css new file mode 100644 index 0000000..f539069 --- /dev/null +++ b/resources/dev-fs/apps/FinderAdmin/finder-admin.css @@ -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; +} \ No newline at end of file diff --git a/resources/dev-fs/apps/finder/finder.js b/resources/dev-fs/apps/finder/finder.js index 329e84f..cac0c0f 100644 --- a/resources/dev-fs/apps/finder/finder.js +++ b/resources/dev-fs/apps/finder/finder.js @@ -4,9 +4,9 @@ class Finder{ /** * @param {string[]} args */ - async NewWindow(args){ + async NewWindow(args, runContext){ let newFinder = new FinderWindow() - await newFinder.Init(args) + await newFinder.Init(args, runContext) } /** @@ -40,14 +40,18 @@ class FinderWindow{ fileView = undefined windowElem = undefined - async Init(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.AppId}/renderDesktop?` + params, + { + method: "POST", + body: JSON.stringify(runContext) + }) if (response.status != 200){ WebDesktopEnvironment.Alert("Error in render desktop") //TODO } @@ -62,11 +66,16 @@ class FinderWindow{ ) this.RenderDir(args[0]) return - } - const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile}) - const response = await fetch(`/app/${Finder.AppId}/render?` + params) + } + 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){ - WebDesktopEnvironment.Alert("Finder ERROR TODO") //TODO + const error = await response.json() + WebDesktopEnvironment.Alert(error.message) return } const html = await response.text() @@ -187,6 +196,9 @@ class FinderWindow{ 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 @@ -249,7 +261,7 @@ class FinderWindow{ menu.style.left = pos[1] + "px"; menu.innerHTML = html - menu.children[0].firstElementChild.remove() + // 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) diff --git a/resources/wde.js b/resources/wde.js index ee3c97e..d138810 100644 --- a/resources/wde.js +++ b/resources/wde.js @@ -35,30 +35,33 @@ class WebDesktopEnvironment{ async loadWDE(){ // await WebDesktopEnvironment.load2('/Applications/Finder.app', [ "desktop", document.querySelector('#desktop-layer')]) - await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/.desktop", "-desktop", document.querySelector('#desktop-layer')]) - // WebDesktopEnvironment.Open('/Applications/Finder.app', ["/",]) - WebDesktopEnvironment.Open('/Applications/AboutMe.app', []) + // await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/.desktop", "-desktop", document.querySelector('#desktop-layer')]) + WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/Blogs",]) + // WebDesktopEnvironment.Open('/Applications/AboutMe.app', []) + // WebDesktopEnvironment.Open('/Applications/FinderAdmin.app', ["/home/user",]) + WebDesktopEnvironment.Open('/Applications/BlogViewer.app', ["/home/user/Blogs/blog1.blog",]) } /** * @param {string} appPath * @param {string[]} args + * @param {string} runPath */ - static async Open(appPath, args){ + 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: "todo" //TODO + 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) + WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext) } diff --git a/templates/base/index.tmpl b/templates/base/index.tmpl index 41d8999..f67cae2 100644 --- a/templates/base/index.tmpl +++ b/templates/base/index.tmpl @@ -7,15 +7,15 @@ - - + - + + diff --git a/templates/blog-viewer/app.tmpl b/templates/blog-viewer/app.tmpl index 9c06849..83a6077 100644 --- a/templates/blog-viewer/app.tmpl +++ b/templates/blog-viewer/app.tmpl @@ -12,13 +12,21 @@
{{ range $block := .blocks }} -
- {{ range $data := $block.Data }} -
- {{$data}} -
- {{ end }} -
+ {{ if eq $block.Type "image"}} +
+ {{ range $data := $block.Data }} + + {{ end }} +
+ {{ else }} +
+ {{ range $data := $block.Data }} +
+ {{$data}} +
+ {{ end }} +
+ {{ end }} {{ end }}
diff --git a/templates/finder/admin-app.tmpl b/templates/finder/admin-app.tmpl index 1c32e5f..f724d2f 100644 --- a/templates/finder/admin-app.tmpl +++ b/templates/finder/admin-app.tmpl @@ -13,8 +13,11 @@
+ + +
You Favorite Movie
diff --git a/templates/finder/app.tmpl b/templates/finder/app.tmpl index becf3ba..e3f23b7 100644 --- a/templates/finder/app.tmpl +++ b/templates/finder/app.tmpl @@ -4,7 +4,7 @@
- Finder + Admin Finder
@@ -13,6 +13,8 @@
+ +
diff --git a/webfilesystem/directory.go b/webfilesystem/directory.go index 095a429..826b109 100644 --- a/webfilesystem/directory.go +++ b/webfilesystem/directory.go @@ -8,7 +8,7 @@ import ( type DirectoryData struct { MongoId primitive.ObjectID `bson:"_id" json:"-"` - Parent primitive.ObjectID `bson:"parent_id" json:"parent"` + Parent primitive.ObjectID `bson:"parent_id" json:"parent"` //TODO: Delete Children []primitive.ObjectID `bson:"children_id" json:"children"` }