Start loading apps by manifest
This commit is contained in:
parent
113b7ebc37
commit
c9e846e2cf
@ -18,8 +18,7 @@ func NewBlogViewerApp(webFs *webfilesystem.WebFileSystem) *BlogViewerApplication
|
|||||||
return &BlogViewerApplication{
|
return &BlogViewerApplication{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: apps.ApplicationManifest{
|
manifest: apps.ApplicationManifest{
|
||||||
AppId: "blog-viewer",
|
AppId: "blog-viewer",
|
||||||
WindowName: "",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication
|
|||||||
return &FinderApplication{
|
return &FinderApplication{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: apps.ApplicationManifest{
|
manifest: apps.ApplicationManifest{
|
||||||
AppId: "finder",
|
AppId: "finder",
|
||||||
WindowName: "TODO DELETE", //TODO DELETE
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,15 +64,21 @@ func (f *FinderApplication) RenderContextMenu(context string, data string) gin.H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FinderApplication) RenderProps(filePath string) gin.H {
|
func (f *FinderApplication) RenderProps(filePath string) (gin.H, error) {
|
||||||
// file, err := f.fs.NewReadDeprecated(filePath)
|
// file, err := f.fs.NewReadDeprecated(filePath)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
fileHeader, err := f.fs.Read(filePath, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return gin.H{
|
return gin.H{
|
||||||
// "file": file,
|
// "fileId": fileHeader.MongoId,
|
||||||
}
|
// "fileDataId": fileHeader.Data,
|
||||||
|
"file": fileHeader,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
// func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
||||||
|
@ -43,7 +43,11 @@ func (f *FinderApplication) Routes(routes *gin.RouterGroup) {
|
|||||||
|
|
||||||
routes.GET("renderProps", func(ctx *gin.Context) {
|
routes.GET("renderProps", func(ctx *gin.Context) {
|
||||||
filePath := ctx.Query("path")
|
filePath := ctx.Query("path")
|
||||||
ginH := f.RenderProps(filePath)
|
ginH, err := f.RenderProps(filePath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
ctx.HTML(http.StatusOK, "finder/props.tmpl", ginH)
|
ctx.HTML(http.StatusOK, "finder/props.tmpl", ginH)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) ImgViewerApp {
|
|||||||
newApp := ImgViewerApp{
|
newApp := ImgViewerApp{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: websiteapp.ApplicationManifest{
|
manifest: websiteapp.ApplicationManifest{
|
||||||
AppId: "img-viewer",
|
AppId: "img-viewer",
|
||||||
WindowName: "About me", //TODO: delete
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return newApp
|
return newApp
|
||||||
|
@ -18,8 +18,7 @@ func NewPersPropsApp(webFs *webfilesystem.WebFileSystem) PersonalPropertiesApp {
|
|||||||
newApp := PersonalPropertiesApp{
|
newApp := PersonalPropertiesApp{
|
||||||
fs: webFs,
|
fs: webFs,
|
||||||
manifest: websiteapp.ApplicationManifest{
|
manifest: websiteapp.ApplicationManifest{
|
||||||
AppId: "personal-properties",
|
AppId: "personal-properties",
|
||||||
WindowName: "About me",
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return newApp
|
return newApp
|
||||||
|
@ -2,10 +2,14 @@ package apps
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
|
"personalwebsite/webfilesystem"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//TODO to libs
|
||||||
type WebDEApplication interface {
|
type WebDEApplication interface {
|
||||||
// Render()
|
// Render()
|
||||||
GetManifest() ApplicationManifest
|
GetManifest() ApplicationManifest
|
||||||
@ -14,12 +18,41 @@ type WebDEApplication interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ApplicationManifest struct {
|
type ApplicationManifest struct {
|
||||||
AppId string `json:"appid"`
|
AppId string `bson:"appid" json:"appid"`
|
||||||
WindowName string `json:"windowname"`
|
Js []string `bson:"js" json:"js"`
|
||||||
|
Css []string `bson:"css" json:"css"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewApplicationsStorage(apps map[string]WebDEApplication, webfs *webfilesystem.WebFileSystem) *ApplicationsStorage {
|
||||||
|
return &ApplicationsStorage{
|
||||||
|
Apps: apps,
|
||||||
|
fs: webfs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApplicationsStorage struct {
|
type ApplicationsStorage struct {
|
||||||
Apps map[string]WebDEApplication
|
Apps map[string]WebDEApplication
|
||||||
|
fs *webfilesystem.WebFileSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
func (as *ApplicationsStorage) createApp(appName string, appId string, appPath string) error {
|
||||||
|
newAppData := ApplicationManifest{
|
||||||
|
AppId: appId,
|
||||||
|
}
|
||||||
|
|
||||||
|
newAppFile := webfilesystem.FileHeader{
|
||||||
|
MongoId: primitive.NewObjectID(),
|
||||||
|
Name: appName + ".appmanifest",
|
||||||
|
Type: "application",
|
||||||
|
Icon: "",
|
||||||
|
Data: primitive.NewObjectID(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := as.fs.Write(appPath+"/"+newAppFile.Name, &newAppFile, newAppData)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func NewApplicationsStorage() *ApplicationsStorage {
|
// func NewApplicationsStorage() *ApplicationsStorage {
|
||||||
@ -28,7 +61,7 @@ type ApplicationsStorage struct {
|
|||||||
// return &newStorage
|
// return &newStorage
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func Route(route *gin.RouterGroup, aStorage *ApplicationsStorage) {
|
func (aStorage *ApplicationsStorage) Route(route *gin.RouterGroup) {
|
||||||
route.GET("/get", func(ctx *gin.Context) {
|
route.GET("/get", func(ctx *gin.Context) {
|
||||||
appId := ctx.Query("appid")
|
appId := ctx.Query("appid")
|
||||||
if appId == "" {
|
if appId == "" {
|
||||||
@ -42,4 +75,51 @@ func Route(route *gin.RouterGroup, aStorage *ApplicationsStorage) {
|
|||||||
}
|
}
|
||||||
ctx.JSON(http.StatusOK, app.GetManifest())
|
ctx.JSON(http.StatusOK, app.GetManifest())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
route.GET("/loadApp", func(ctx *gin.Context) {
|
||||||
|
appPath := ctx.Query("path")
|
||||||
|
if appPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appManifestData := ApplicationManifest{}
|
||||||
|
fileHeader, err := aStorage.fs.Read(path.Join(appPath, ".appmanifest"), &appManifestData)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileHeader.Type != "application-manifest" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, appManifestData)
|
||||||
|
})
|
||||||
|
|
||||||
|
route.GET("/createApp", func(ctx *gin.Context) {
|
||||||
|
appId := ctx.Query("appId")
|
||||||
|
if appId == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appName := ctx.Query("appName")
|
||||||
|
if appName == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appPath := ctx.Query("path")
|
||||||
|
if appPath == "" {
|
||||||
|
ctx.Status(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := aStorage.createApp(appId, appName, appPath)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Status(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusOK)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
12
main.go
12
main.go
@ -73,9 +73,7 @@ func main() {
|
|||||||
finderApp := finder.NewFinderApplication(webfs)
|
finderApp := finder.NewFinderApplication(webfs)
|
||||||
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
||||||
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
||||||
appsStorage := apps.ApplicationsStorage{
|
appsStorage := apps.NewApplicationsStorage(map[string]apps.WebDEApplication{}, webfs)
|
||||||
Apps: map[string]apps.WebDEApplication{},
|
|
||||||
}
|
|
||||||
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
|
||||||
@ -90,12 +88,18 @@ func main() {
|
|||||||
imgLib := libs.NewImgLib(webfs)
|
imgLib := libs.NewImgLib(webfs)
|
||||||
imgLib.Route(imgLibGroup)
|
imgLib.Route(imgLibGroup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
appsStorageGroup := libsGroup.Group("apps")
|
||||||
|
{
|
||||||
|
appsStorage.Route(appsStorageGroup)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wdeGroup := system.Group("wde")
|
wdeGroup := system.Group("wde")
|
||||||
{
|
{
|
||||||
routewde.Route(wdeGroup, webde)
|
routewde.Route(wdeGroup, webde)
|
||||||
}
|
}
|
||||||
apps := system.Group("applications")
|
apps := system.Group("applications") //TODO to libs
|
||||||
{
|
{
|
||||||
apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
||||||
appId := ctx.Param("appid")
|
appId := ctx.Param("appid")
|
||||||
|
@ -5,6 +5,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
wde = new WebDesktopEnvironment
|
wde = new WebDesktopEnvironment
|
||||||
if (!WebDesktopEnvironment.isMobile){
|
if (!WebDesktopEnvironment.isMobile){
|
||||||
WebDesktopEnvironment.Open("finder", ["/home/user"])
|
WebDesktopEnvironment.Open("finder", ["/home/user"])
|
||||||
|
WebDesktopEnvironment.fetchApp("/home/user/AboutMe.app")
|
||||||
// WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog1.blog"])
|
// WebDesktopEnvironment.Open("blog-viewer", ["/home/user/blog1.blog"])
|
||||||
// WebDesktopEnvironment.Open("personal-properties", ["/home/user/aboutme.props"])
|
// WebDesktopEnvironment.Open("personal-properties", ["/home/user/aboutme.props"])
|
||||||
} else {
|
} else {
|
||||||
@ -115,6 +116,30 @@ class WebDesktopEnvironment{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @param {function} callbackFunc callback after script loading
|
||||||
|
* @returns {Application | undefined}
|
||||||
|
*/
|
||||||
|
static loadApp2(path, callbackFunc){
|
||||||
|
//var myObject = window[classNameString]; to load random classes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} path
|
||||||
|
* @returns {Application | undefined} //FIXME
|
||||||
|
*/
|
||||||
|
static fetchApp(path){
|
||||||
|
fetch(`/system/libs/apps/loadApp?` + new URLSearchParams({
|
||||||
|
path: path,
|
||||||
|
})) .then(async (response) => {
|
||||||
|
console.log(await response.json())
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
WebDesktopEnvironment.Alert(error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} appId
|
* @param {string} appId
|
||||||
* @param {string[]} args
|
* @param {string[]} args
|
||||||
|
@ -10,41 +10,47 @@
|
|||||||
<div class="ContentBorder">
|
<div class="ContentBorder">
|
||||||
<div class="PropertiesList">
|
<div class="PropertiesList">
|
||||||
<div class="Personal-properties-bio">
|
<div class="Personal-properties-bio">
|
||||||
<img src="data:{{ .headerProps.Icon.Header }},{{ .headerProps.Icon.Base64 }}" alt="File Icon" style="width: 48px;height: 48px;">
|
<!-- <img src="data:{{ .headerProps.Icon.Header }},{{ .headerProps.Icon.Base64 }}" alt="File Icon" style="width: 48px;height: 48px;"> -->
|
||||||
<div class="Personal-properties-textbio">
|
<div class="Personal-properties-textbio">
|
||||||
<div>{{ .file.Name }}</div>
|
<div>{{ .file.Name }}</div>
|
||||||
<!-- <div>{{ .headerProps.Info1 }}</div>
|
<!-- <div>{{ .headerProps.Info1 }}</div>
|
||||||
<div>{{ .headerProps.Info2 }}</div> -->
|
<div>{{ .headerProps.Info2 }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
file id : {{.file.MongoId}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
file data id : {{.file.Data}}
|
||||||
|
</div>
|
||||||
{{ range $propIsland := .allprops }}
|
{{ range $propIsland := .allprops }}
|
||||||
<div id="prop" class="Personal-properties-prop">
|
<div id="prop" class="Personal-properties-prop">
|
||||||
<div class="Personal-properties-prop-title">
|
<div class="Personal-properties-prop-title">
|
||||||
{{$propIsland.Header}}:
|
{{$propIsland.Header}}:
|
||||||
</div>
|
|
||||||
<div class="Personal-properties-prop-content">
|
|
||||||
{{range $prop := $propIsland.Props}}
|
|
||||||
<div class="Personal-properties-prop-row">
|
|
||||||
<div class="Personal-properties-prop-key">
|
|
||||||
{{$prop.Key}}:
|
|
||||||
{{ range $value := $prop.KeyComments }}
|
|
||||||
<div class="Personal-properties-prop-key-comments">
|
|
||||||
{{ $value }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
<div class="Personal-properties-prop-values">
|
|
||||||
{{ range $value := $prop.Values }}
|
|
||||||
<div class="Personal-properties-prop-value">
|
|
||||||
{{ $value }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
<div class="Personal-properties-prop-content">
|
||||||
|
{{range $prop := $propIsland.Props}}
|
||||||
|
<div class="Personal-properties-prop-row">
|
||||||
|
<div class="Personal-properties-prop-key">
|
||||||
|
{{$prop.Key}}:
|
||||||
|
{{ range $value := $prop.KeyComments }}
|
||||||
|
<div class="Personal-properties-prop-key-comments">
|
||||||
|
{{ $value }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
<div class="Personal-properties-prop-values">
|
||||||
|
{{ range $value := $prop.Values }}
|
||||||
|
<div class="Personal-properties-prop-value">
|
||||||
|
{{ $value }}
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
BIN
test-img/myphoto.jpg
(Stored with Git LFS)
Normal file
BIN
test-img/myphoto.jpg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -31,7 +31,7 @@ type FileHeader struct {
|
|||||||
Name string `bson:"name" json:"name"`
|
Name string `bson:"name" json:"name"`
|
||||||
Type string `bson:"type" json:"type"`
|
Type string `bson:"type" json:"type"`
|
||||||
Icon string `bson:"icon" json:"icon"`
|
Icon string `bson:"icon" json:"icon"`
|
||||||
Data primitive.ObjectID `bson:"data_id" json:"-"`
|
Data primitive.ObjectID `bson:"data_id" json:"-"` //TODO rename to DataId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fh *FileHeader) GetType() string {
|
func (fh *FileHeader) GetType() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user