Massive rework in blog viewer

This commit is contained in:
cyber-dream 2023-05-18 04:57:44 +03:00
parent 5d160bddd9
commit 9ec954ceb3
19 changed files with 597 additions and 101 deletions

View 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) {
}

View File

@ -1,6 +1,6 @@
package blogviewer package blogviewer
type BlogFileData struct { type BlogFileData struct {
Header string `bson:"header"` Header string `bson:"header"`
Blocks []Block `bson:"blocks"` Blocks []*Block `bson:"blocks"`
} }

View File

@ -2,6 +2,8 @@ package blogviewer
import ( import (
"net/http" "net/http"
"path"
"personalwebsite/apps/appCtx"
"personalwebsite/webfilesystem" "personalwebsite/webfilesystem"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -41,22 +43,27 @@ func (b *BlogViewerApplication) PublicRoutes(route *gin.RouterGroup) {
ctx.JSON(http.StatusOK, "OK") ctx.JSON(http.StatusOK, "OK")
}) })
route.GET("render", func(ctx *gin.Context) { route.POST("render", func(ctx *gin.Context) {
isMobileParam := ctx.Query("isMobile")
path := ctx.Query("path") path := ctx.Query("path")
if path == "" { if path == "" {
ctx.JSON(http.StatusBadRequest, "no path provided") ctx.JSON(http.StatusBadRequest, "no path provided")
return return
} }
isMobile := isMobileParam == "true" appCtx := appCtx.AppContext{}
ginH, err := b.Render(path, isMobile) err := ctx.BindJSON(&appCtx)
if err != nil {
ctx.Status(http.StatusBadRequest)
return
}
ginH, err := b.Render(path, appCtx)
if err != nil { if err != nil {
ctx.JSON(http.StatusInternalServerError, "TODO") ctx.JSON(http.StatusInternalServerError, "TODO")
return return
} }
if isMobile { if appCtx.IsMobile {
ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH) ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH)
} else { } else {
ctx.HTML(http.StatusOK, "blog-viewer/app.tmpl", ginH) ctx.HTML(http.StatusOK, "blog-viewer/app.tmpl", ginH)
@ -66,25 +73,17 @@ func (b *BlogViewerApplication) PublicRoutes(route *gin.RouterGroup) {
} }
func (b *BlogViewerApplication) WriteMock(path string) error { func (b *BlogViewerApplication) WriteMock(path string) error {
blogFileHeader := webfilesystem.FileHeader{ blogFileHeader := webfilesystem.FileHeader{ //TODO to fs.CreateDirectory()
MongoId: primitive.NewObjectID(), MongoId: primitive.NewObjectID(),
Name: "blog1.blog", Name: "blog1.blog",
Type: "", Type: "directory",
Icon: "", Icon: "",
Data: [12]byte{}, Data: [12]byte{},
} }
blogFileData := BlogFileData{ blogFileData := webfilesystem.DirectoryData{
Header: "OMG THIS IS BLOG", MongoId: primitive.NewObjectID(),
Blocks: []Block{ Parent: [12]byte{},
{ Children: []primitive.ObjectID{},
Type: "plain-text",
Data: []string{
"Apoqiwepoqiwepo",
".,mas;dakls;d",
"q[poqwieqpipoi]",
},
},
},
} }
_, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData) _, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData)
@ -92,16 +91,51 @@ func (b *BlogViewerApplication) WriteMock(path string) error {
println(err.Error()) println(err.Error())
return err return err
} }
blogContentFileHeader := webfilesystem.FileHeader{
MongoId: primitive.NewObjectID(),
Name: ".content",
Type: "blog-content",
Icon: "",
Data: [12]byte{},
}
blogContentFileData := BlogFileData{
Header: "OMG THIS IS BLOG",
}
blogContentFileData.Blocks = append(blogContentFileData.Blocks, &Block{
Type: "plain-text",
Data: []string{
"Apoqiwepoqiwepo",
".,mas;dakls;d",
"q[poqwieqpipoi]",
},
})
_, _, err = b.fs.Write("/home/user/blog1.blog/.content", &blogContentFileHeader, blogContentFileData)
if err != nil {
println(err.Error())
return err
}
return nil return nil
} }
func (b *BlogViewerApplication) Render(filePath string, isMobile bool) (gin.H, error) { func (b *BlogViewerApplication) Render(filePath string, appCtx appCtx.AppContext) (gin.H, error) {
data := BlogFileData{} data := &BlogFileData{}
_, err := b.fs.Read(filePath, &data) _, err := b.fs.Read(path.Join(filePath, ".content"), &data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, block := range data.Blocks {
if block.Type == "image" {
newData := []string{}
for _, image := range block.Data {
newData = append(newData, b.fs.RelativeToAbsolute(appCtx, image))
}
block.Data = newData
}
}
return gin.H{ return gin.H{
"header": data.Header, "header": data.Header,
"blocks": data.Blocks, "blocks": data.Blocks,

View File

@ -1,7 +1,7 @@
package finder package finder
import ( import (
"personalwebsite/apps" "personalwebsite/apps/appCtx"
"personalwebsite/wde" "personalwebsite/wde"
"personalwebsite/webfilesystem" "personalwebsite/webfilesystem"
@ -9,28 +9,23 @@ import (
) )
type FinderApplication struct { type FinderApplication struct {
fs *webfilesystem.WebFileSystem fs *webfilesystem.WebFileSystem
appID string appID string
manifest apps.ApplicationManifest // manifest apps.ApplicationManifest
} }
func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication { func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication {
return &FinderApplication{ return &FinderApplication{
fs: webFs, fs: webFs,
appID: "Finder", appID: "Finder",
manifest: apps.ApplicationManifest{
AppId: "finder",
},
} }
} }
func (f *FinderApplication) GetManifest() apps.ApplicationManifest {
return f.manifest
}
func (f *FinderApplication) GetAppID() string { func (f *FinderApplication) GetAppID() string {
return f.appID return f.appID
} }
func (f *FinderApplication) Render(isMobile bool) gin.H { func (f *FinderApplication) Render(appCtx appCtx.AppContext) gin.H {
return gin.H{} return gin.H{}
} }

View File

@ -1,31 +1,19 @@
package finder package finder
import ( import (
"personalwebsite/apps" "personalwebsite/apps/appCtx"
"personalwebsite/wde" "personalwebsite/wde"
"personalwebsite/webfilesystem"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
type FinderAdminApp struct { func (f *FinderApplication) RenderAdminWindow(appCtx appCtx.AppContext) gin.H {
fs *webfilesystem.WebFileSystem
manifest apps.ApplicationManifest
}
func NewFinderAdminApp(webfs *webfilesystem.WebFileSystem) FinderAdminApp {
return FinderAdminApp{
fs: webfs,
manifest: apps.ApplicationManifest{},
}
}
func (f *FinderAdminApp) RenderWindow() {
return gin.H{}
} }
func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath string, data string) gin.H { func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath string, data string) gin.H {
islands := [][]wde.ContexMenuRow{} islands := [][]wde.ContexMenuRow{}
islands = append(islands, []wde.ContexMenuRow{}) // islands = append(islands, []wde.ContexMenuRow{})
islands = append(islands, []wde.ContexMenuRow{ islands = append(islands, []wde.ContexMenuRow{
{Label: "Get Info", Action: "getInfo"}, {Label: "Get Info", Action: "getInfo"},
@ -46,7 +34,12 @@ func (f *FinderApplication) RenderPrivateContextMenu(context string, filePath st
switch context { switch context {
case "directory": 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{ islands = append(islands, []wde.ContexMenuRow{
{Label: "Open as Directory", Action: "openAsDir"}, {Label: "Open as Directory", Action: "openAsDir"},
}) })

View File

@ -2,14 +2,23 @@ package finder
import ( import (
"net/http" "net/http"
"personalwebsite/apps/appCtx"
"personalwebsite/errormessage"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func (f *FinderApplication) PublicRoutes(routes *gin.RouterGroup) { func (f *FinderApplication) PublicRoutes(routes *gin.RouterGroup) {
routes.GET("render", func(ctx *gin.Context) { routes.POST("render", func(ctx *gin.Context) {
isMobile := ctx.Query("isMobile") == "true" appCtx := appCtx.AppContext{}
ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(isMobile)) 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) { 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) { func (f *FinderApplication) PrivateRoutes(routes *gin.RouterGroup) {
routes.GET("render", func(ctx *gin.Context) { routes.POST("render", func(ctx *gin.Context) {
isMobile := ctx.Query("isMobile") == "true" appCtx := appCtx.AppContext{}
ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(isMobile)) 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) { routes.GET("renderDesktop", func(ctx *gin.Context) {
path := ctx.Query("path") path := ctx.Query("path")
if path == "" { if path == "" {

View File

@ -7,6 +7,7 @@ import (
"os" "os"
"personalwebsite/apps" "personalwebsite/apps"
blogwriter "personalwebsite/apps/BlogWriter"
"personalwebsite/apps/blogviewer" "personalwebsite/apps/blogviewer"
"personalwebsite/apps/finder" "personalwebsite/apps/finder"
imgviewer "personalwebsite/apps/img-viewer" imgviewer "personalwebsite/apps/img-viewer"
@ -65,14 +66,17 @@ func main() {
webde := wde.NewWDE(webfs) webde := wde.NewWDE(webfs)
//TODO Split to different apps init for private and public?
persPropsApp := personalprops.NewPersPropsApp(webfs) persPropsApp := personalprops.NewPersPropsApp(webfs)
finderApp := finder.NewFinderApplication(webfs) finderApp := finder.NewFinderApplication(webfs)
imgViewerApp := imgviewer.NewImgViewerApp(webfs) imgViewerApp := imgviewer.NewImgViewerApp(webfs)
blogViewerApp := blogviewer.NewBlogViewerApp(webfs) blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
blogWriterApp := blogwriter.NewBlogWriterApp(webfs)
appsStorage.Apps["personal-properties"] = persPropsApp appsStorage.Apps["personal-properties"] = persPropsApp
appsStorage.Apps["finder"] = finderApp appsStorage.Apps["finder"] = finderApp
appsStorage.Apps["img-viewer"] = imgViewerApp appsStorage.Apps["img-viewer"] = imgViewerApp
appsStorage.Apps["blog-viewer"] = blogViewerApp appsStorage.Apps[blogViewerApp.GetAppID()] = blogViewerApp
appsStorage.Apps["BlogWriter"] = blogWriterApp
go routes.PublicRoutes(webfs, webde, appsStorage) go routes.PublicRoutes(webfs, webde, appsStorage)
routes.PrivateRoutes(webfs, webde, appsStorage) routes.PrivateRoutes(webfs, webde, appsStorage)

View File

@ -1,26 +1,28 @@
class BlogViewer{ class BlogViewer{
appId = "blog-viewer" static appID = "BlogViewer"
constructor(){
}
/** /**
* @param {string[]} chroot //TODO * @param {string[]} args
* @param {string[]} args * @param {Object} runContext
*/ */
async NewWindow(args){ async NewWindow(args, runContext){
const response = await fetch(`app/${this.appId}/render?` + new URLSearchParams({ const params = new URLSearchParams({
isMobile: WebDesktopEnvironment.isMobile,
path: args[0], path: args[0],
})) })
runContext.runPath = args[0]
const response = await fetch(`app/${BlogViewer.appID}/render?` + params, {
method: "POST",
body: JSON.stringify(runContext)
})
if (response.status != 200){ if (response.status != 200){
WebDesktopEnvironment.Alert("Error render TODO") //TODO WebDesktopEnvironment.Alert("Error render TODO") //TODO
return return
} }
const html = await response.text() const html = await response.text()
let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 500, 350 ) let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 500, 350 )
newWindow.innerHTML = html newWindow.innerHTML = html
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".ScrollContent")) let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".ScrollContent"))
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) { newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
WebDesktopEnvironment.CloseWindow(newWindow) WebDesktopEnvironment.CloseWindow(newWindow)

View File

@ -25,7 +25,25 @@
/* gap: 50px; */ /* gap: 50px; */
/* row-gap: 20px; */ /* row-gap: 20px; */
/* padding: 0px 20px 0px 20px; */ /* padding: 0px 20px 0px 20px; */
margin: 0px 20px 0px 20px; /* margin: 0px 20px 0px 20px; */
}
.BlogView .ScrollContent {
position: relative;
width: 92%;
left: 4%;
right: 4%;
height: auto;
/* Auto layout */
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
gap: 10px;
/* row-gap: 20px; */
/* padding: 0px 20px 0px 20px; */
/* margin: 0px 20px 0px 20px; */
/* padding-left: 20px; */
} }
.BlogView .header-h1{ .BlogView .header-h1{
@ -43,6 +61,19 @@
padding-bottom: 2px; padding-bottom: 2px;
} }
.BlogView .image{
width: 100%;
}
.image .ImageProp{
position: relative;
width: 100%;
height: auto;
/* left: 50%;
margin-left: -50%; */
}
.BlogView .plain-text{ .BlogView .plain-text{
/* Auto layout */ /* Auto layout */
display: flex; display: flex;

View File

@ -0,0 +1,10 @@
class BlogWriter{
static AppId = "BlogWriter"
/**
* @param {string[]} args
*/
async NewWindow(args){
console.log("kek")
}
}

View File

@ -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()
})
}
}

View 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;
}

View File

@ -4,9 +4,9 @@ class Finder{
/** /**
* @param {string[]} args * @param {string[]} args
*/ */
async NewWindow(args){ async NewWindow(args, runContext){
let newFinder = new FinderWindow() let newFinder = new FinderWindow()
await newFinder.Init(args) await newFinder.Init(args, runContext)
} }
/** /**
@ -40,14 +40,18 @@ class FinderWindow{
fileView = undefined fileView = undefined
windowElem = undefined windowElem = undefined
async Init(args){ async Init(args, runContext){
if (args[1] === "-desktop"){ if (args[1] === "-desktop"){
//todo pass div id, not div in args[] //todo pass div id, not div in args[]
const params = new URLSearchParams({ const params = new URLSearchParams({
isMobile: WebDesktopEnvironment.isMobile, isMobile: WebDesktopEnvironment.isMobile,
path: args[0] path: args[0]
}) })
const response = await fetch(`/app/${Finder.AppId}/renderDesktop?` + params) const response = await fetch(`/app/${Finder.AppId}/renderDesktop?` + params,
{
method: "POST",
body: JSON.stringify(runContext)
})
if (response.status != 200){ if (response.status != 200){
WebDesktopEnvironment.Alert("Error in render desktop") //TODO WebDesktopEnvironment.Alert("Error in render desktop") //TODO
} }
@ -62,11 +66,16 @@ class FinderWindow{
) )
this.RenderDir(args[0]) this.RenderDir(args[0])
return return
} }
const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile}) const params = new URLSearchParams({isMobile: WebDesktopEnvironment.isMobile})
const response = await fetch(`/app/${Finder.AppId}/render?` + params) const response = await fetch(`/app/${Finder.AppId}/render?` + params,
{
method: "POST",
body: JSON.stringify(runContext)
})
if (response.status != 200){ if (response.status != 200){
WebDesktopEnvironment.Alert("Finder ERROR TODO") //TODO const error = await response.json()
WebDesktopEnvironment.Alert(error.message)
return return
} }
const html = await response.text() const html = await response.text()
@ -187,6 +196,9 @@ class FinderWindow{
case fileExtension == "app": case fileExtension == "app":
WebDesktopEnvironment.Open(`${parentPath}/${fileName}`, []) WebDesktopEnvironment.Open(`${parentPath}/${fileName}`, [])
break break
case fileExtension == "blog":
WebDesktopEnvironment.Open(`/Applications/BlogViewer.app`, [`${parentPath}/${fileName}`])
break
case fileType == "directory": case fileType == "directory":
WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`]) WebDesktopEnvironment.Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`])
break break
@ -249,7 +261,7 @@ class FinderWindow{
menu.style.left = pos[1] + "px"; menu.style.left = pos[1] + "px";
menu.innerHTML = html 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 menu.children[0].lastElementChild.remove() //FIXME Can't ommit rendering of horLine in end of menu on backend
overlay.appendChild(menu) overlay.appendChild(menu)

View File

@ -35,30 +35,33 @@ class WebDesktopEnvironment{
async loadWDE(){ async loadWDE(){
// await WebDesktopEnvironment.load2('/Applications/Finder.app', [ "desktop", document.querySelector('#desktop-layer')]) // 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')]) // await WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/.desktop", "-desktop", document.querySelector('#desktop-layer')])
// WebDesktopEnvironment.Open('/Applications/Finder.app', ["/",]) WebDesktopEnvironment.Open('/Applications/Finder.app', ["/home/user/Blogs",])
WebDesktopEnvironment.Open('/Applications/AboutMe.app', []) // 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} appPath
* @param {string[]} args * @param {string[]} args
* @param {string} runPath
*/ */
static async Open(appPath, args){ static async Open(appPath, args, runPath){
const appManifest = await WebDesktopEnvironment.fetchApp(appPath) const appManifest = await WebDesktopEnvironment.fetchApp(appPath)
if (appManifest === undefined) return //TODO return err if (appManifest === undefined) return //TODO return err
const runContext = { const runContext = {
isMobile: false, isMobile: false,
bundlePath: appPath, bundlePath: appPath,
runPath: "todo" //TODO runPath: runPath //TODO
} }
if (WebDesktopEnvironment.Applications[appManifest.appId] === undefined){ if (WebDesktopEnvironment.Applications[appManifest.appId] === undefined){
WebDesktopEnvironment.load2(appManifest, () =>{ WebDesktopEnvironment.load2(appManifest, () =>{
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext) WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext)
}) })
} else { } else {
WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args) WebDesktopEnvironment.Applications[appManifest.appId].NewWindow(args, runContext)
} }

View File

@ -7,15 +7,15 @@
<link rel="stylesheet" type="text/css" href="res/wdeUI.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/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/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/wde/file-view.css">
<link rel="stylesheet" type="text/css" href="res/sys/libs/fs.js"> <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" type="text/css" href="res/mobile-wdeUI.css"> -->
<!-- TODO: Move css init to js --> <!-- TODO: Move css init to js -->
<link rel="stylesheet" type="text/css" href="res/dev-fs/apps/finder/finder.css"> <link rel="stylesheet" type="text/css" href="res/dev-fs/apps/FinderAdmin/finder-admin.css">
<link rel="stylesheet" href="/res/sys/personal-properties/personal-properies.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/img-viewer/img-viewer.css">
<link rel="stylesheet" href="/res/sys/blog-viewer/blog-viewer.css">
<link rel="stylesheet" href="res/dev-fs/apps/BlogViewer/blog-viewer.css">
<script src="/res/sys/wde/wde-scrollbar.js"></script> <script src="/res/sys/wde/wde-scrollbar.js"></script>
<script src="/res/sys/wde/file-view.js"></script> <script src="/res/sys/wde/file-view.js"></script>

View File

@ -12,13 +12,21 @@
<div class="Content"> <div class="Content">
<div class="ScrollContent"> <div class="ScrollContent">
{{ range $block := .blocks }} {{ range $block := .blocks }}
<div class="{{$block.Type}}" > {{ if eq $block.Type "image"}}
{{ range $data := $block.Data }} <div class="{{$block.Type}}" >
<div style="font-size: inherit;"> {{ range $data := $block.Data }}
{{$data}} <img class="ImageProp" src="/system/libs/img/get?path={{$data}}">
</div> {{ end }}
{{ end }} </div>
</div> {{ else }}
<div class="{{$block.Type}}" >
{{ range $data := $block.Data }}
<div style="font-size: inherit;">
{{$data}}
</div>
{{ end }}
</div>
{{ end }}
{{ end }} {{ end }}
</div> </div>
</div> </div>

View File

@ -13,8 +13,11 @@
<div class="FinderContent"> <div class="FinderContent">
<!-- TODO Fix ConvexElement --> <!-- TODO Fix ConvexElement -->
<div class="ToolBar ConvexElement"> <div class="ToolBar ConvexElement">
<button id="BackButton">Back</button>
<button id="UpButton">Up</button>
<button id="RootButton">/</button> <button id="RootButton">/</button>
<button id="HomeButton">Home</button> <button id="HomeButton">Home</button>
<div class="AddressBar" contentEditable="true">You Favorite Movie</div>
</div> </div>
<div class="FinderFileView"> <div class="FinderFileView">
<div class="FileTileView"> <div class="FileTileView">

View File

@ -4,7 +4,7 @@
<div id="Drag" class="VisualDragArea"></div> <div id="Drag" class="VisualDragArea"></div>
<div class="Lable"> <div class="Lable">
Finder Admin Finder
</div> </div>
<div id="Drag" class="VisualDragArea"></div> <div id="Drag" class="VisualDragArea"></div>
@ -13,6 +13,8 @@
<div class="FinderContent"> <div class="FinderContent">
<!-- TODO Fix ConvexElement --> <!-- TODO Fix ConvexElement -->
<div class="ToolBar ConvexElement"> <div class="ToolBar ConvexElement">
<button id="RootButton">/</button>
<button id="HomeButton">Home</button>
</div> </div>
<div class="FinderFileView"> <div class="FinderFileView">
<div class="FileTileView"> <div class="FileTileView">

View File

@ -8,7 +8,7 @@ import (
type DirectoryData struct { type DirectoryData struct {
MongoId primitive.ObjectID `bson:"_id" json:"-"` 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"` Children []primitive.ObjectID `bson:"children_id" json:"children"`
} }