Compare commits
No commits in common. "main" and "templates-integration" have entirely different histories.
main
...
templates-
8
.gitignore
vendored
8
.gitignore
vendored
@ -22,11 +22,3 @@
|
||||
go.work
|
||||
|
||||
/__debug_bin
|
||||
.env
|
||||
|
||||
front/dist/*
|
||||
|
||||
front/node_modules
|
||||
.parcel-cache
|
||||
**/node_modules/
|
||||
front/node_modules/*
|
17
Dockerfile
17
Dockerfile
@ -1,17 +0,0 @@
|
||||
### STAGE 1: build ###
|
||||
FROM golang:1.18-alpine AS build
|
||||
WORKDIR /usr/app
|
||||
COPY . .
|
||||
RUN go build .
|
||||
RUN ls -a
|
||||
|
||||
### STAGE 2: Run ###
|
||||
FROM golang:1.18-alpine
|
||||
WORKDIR /usr/app
|
||||
COPY --from=build /usr/app/personalwebsite /usr/app/personalwebsite
|
||||
COPY ./templates /usr/app/templates
|
||||
COPY ./res /usr/app/res
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD [ "/usr/app/personalwebsite" ]
|
@ -1,37 +0,0 @@
|
||||
package blogwriter
|
||||
|
||||
import (
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type BlogWriterApplication struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
appID string
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewBlogWriterApp(webfs *webfilesystem.WebFileSystem) *BlogWriterApplication {
|
||||
return &BlogWriterApplication{
|
||||
fs: webfs,
|
||||
appID: "BlogWriter",
|
||||
}
|
||||
}
|
||||
func (bw *BlogWriterApplication) GetManifest() apps.ApplicationManifest {
|
||||
return bw.manifest
|
||||
}
|
||||
func (bw *BlogWriterApplication) GetAppID() string {
|
||||
return bw.appID
|
||||
}
|
||||
|
||||
func (bw *BlogWriterApplication) GetPath() string {
|
||||
return bw.path
|
||||
}
|
||||
|
||||
func (bw *BlogWriterApplication) PublicRoutes(routes *gin.RouterGroup) {}
|
||||
func (bw *BlogWriterApplication) PrivateRoutes(routes *gin.RouterGroup) {
|
||||
|
||||
}
|
@ -1,335 +0,0 @@
|
||||
package aboutme
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/errormessage"
|
||||
"personalwebsite/libs"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type AboutMeApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
appID string
|
||||
mLib libs.MarkdownLib
|
||||
titleBarConfig wde.TitleBarConfig //TODO to app manifest?
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewAboutMeApp(webFs *webfilesystem.WebFileSystem) *AboutMeApp {
|
||||
manifest := apps.ApplicationManifest{}
|
||||
_, err := webFs.Read(path.Join("/Applications/AboutMe.app", ".appmanifest"), &manifest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newApp := AboutMeApp{
|
||||
fs: webFs,
|
||||
appID: "AboutMe",
|
||||
path: "/Applications/AboutMe.app",
|
||||
titleBarConfig: wde.TitleBarConfig{
|
||||
Lable: "About Me",
|
||||
CloseButton: true,
|
||||
HasIcon: true,
|
||||
IconPath: "/Icons/GenericApp.icn",
|
||||
IconSize: "16",
|
||||
},
|
||||
manifest: manifest,
|
||||
}
|
||||
return &newApp
|
||||
}
|
||||
func (p *AboutMeApp) GetPath() string {
|
||||
return p.path
|
||||
}
|
||||
func (p *AboutMeApp) GetManifest() apps.ApplicationManifest {
|
||||
return p.manifest
|
||||
}
|
||||
func (p *AboutMeApp) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.POST("render", func(ctx *gin.Context) {
|
||||
filePath := ctx.Query("path")
|
||||
if filePath == "" {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
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 appCtx.IsMobile {
|
||||
ctx.HTML(http.StatusOK, "personal-properties/mobile-app.tmpl", ginH)
|
||||
} else {
|
||||
ctx.HTML(http.StatusOK, "personal-properties/app.tmpl", ginH)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) 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)
|
||||
})
|
||||
|
||||
router.GET("getMock", func(ctx *gin.Context) {
|
||||
ctx.JSON(http.StatusOK, PropertiesFileData{
|
||||
Header: HeaderIsland{
|
||||
Name: "",
|
||||
IconPath: "",
|
||||
Value1: "",
|
||||
Value2: "",
|
||||
},
|
||||
Links: []HeaderLink{
|
||||
{
|
||||
Text: "",
|
||||
Url: "",
|
||||
Icon: "",
|
||||
},
|
||||
},
|
||||
Islands: []Island{
|
||||
{
|
||||
Header: "qq",
|
||||
Properties: []IslandProperty{
|
||||
{
|
||||
Key: "22",
|
||||
KeyComments: []string{
|
||||
"45",
|
||||
"12",
|
||||
},
|
||||
Values: []string{
|
||||
"aaaa",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
router.GET("read", func(ctx *gin.Context) {
|
||||
filePath := ctx.Query("path")
|
||||
if filePath == "" {
|
||||
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||
Message: "File path is empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
propData, err := p.Read(filePath)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, propData)
|
||||
})
|
||||
|
||||
router.POST("edit", func(ctx *gin.Context) {
|
||||
filePath := ctx.Query("path")
|
||||
if filePath == "" {
|
||||
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||
Message: "File path is empty",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
propsData := PropertiesFileData{}
|
||||
err := ctx.BindJSON(&propsData)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, errormessage.ErrorMessage{
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = p.Edit(filePath, propsData)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, errormessage.ErrorMessage{
|
||||
Message: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusOK)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) GetAppID() string {
|
||||
return p.appID
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) WriteMock() error {
|
||||
fileHeader := webfilesystem.FileHeader{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: "aboutme.props",
|
||||
Type: "personal-properties",
|
||||
Icon: "",
|
||||
}
|
||||
fileData := PropertiesFileData{
|
||||
Header: HeaderIsland{
|
||||
Name: "Test Name",
|
||||
IconPath: "test icon path",
|
||||
},
|
||||
}
|
||||
_, _, err := p.fs.Write("/Applications/AboutMe.app/aboutme.props", &fileHeader, fileData)
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) Read(filePath string) (*PropertiesFileData, error) {
|
||||
propData := PropertiesFileData{}
|
||||
fileHeader, err := p.fs.Read(path.Join(filePath, "aboutme.props"), &propData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if fileHeader.Type != "personal-properties" {
|
||||
return nil, errors.New("wrong file type")
|
||||
}
|
||||
return &propData, nil
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) Edit(filePath string, blogData PropertiesFileData) error {
|
||||
propsPath := path.Join(filePath, "aboutme.props")
|
||||
fileHeader, err := p.fs.Read(propsPath, nil)
|
||||
if err != nil {
|
||||
if err.Error() == "file not found" { //FIXME
|
||||
p.WriteMock()
|
||||
p.Edit(filePath, blogData)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if fileHeader.Type != "personal-properties" {
|
||||
return errors.New("wrong file type")
|
||||
}
|
||||
|
||||
err = p.fs.Remove(propsPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileHeader.MongoId = primitive.NewObjectID()
|
||||
_, _, err = p.fs.Write(propsPath, fileHeader, blogData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *AboutMeApp) Render(appCtx appCtx.AppContext, filePath string) (gin.H, error) {
|
||||
//Read file from WebFS
|
||||
propsData := &PropertiesFileData{}
|
||||
filePath = p.fs.RelativeToAbsolute(appCtx, filePath)
|
||||
_, err := p.fs.Read(filePath, &propsData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Render Markdown strings
|
||||
renderedIslands := []RenderedIsland{}
|
||||
for _, island := range propsData.Islands {
|
||||
newRenderedIsland := RenderedIsland{
|
||||
Header: island.Header,
|
||||
Properties: []RenderedIslandProperty{},
|
||||
}
|
||||
for _, property := range island.Properties {
|
||||
newRenderedIslandProperty := RenderedIslandProperty{
|
||||
Key: property.Key,
|
||||
KeyComments: property.KeyComments,
|
||||
Values: []template.HTML{},
|
||||
}
|
||||
for _, value := range property.Values {
|
||||
renderedValue := p.mLib.Render([]byte(value), true)
|
||||
newRenderedIslandProperty.Values = append(newRenderedIslandProperty.Values, renderedValue)
|
||||
}
|
||||
newRenderedIsland.Properties = append(newRenderedIsland.Properties, newRenderedIslandProperty)
|
||||
}
|
||||
renderedIslands = append(renderedIslands, newRenderedIsland)
|
||||
}
|
||||
|
||||
//Make icon path absolute
|
||||
propsData.Header.IconPath = p.fs.RelativeToAbsolute(appCtx, propsData.Header.IconPath)
|
||||
|
||||
absoluteLinks := []HeaderLink{}
|
||||
for _, link := range propsData.Links {
|
||||
absoluteLinks = append(absoluteLinks, HeaderLink{
|
||||
Text: link.Text,
|
||||
Url: link.Url,
|
||||
Icon: p.fs.RelativeToAbsolute(appCtx, link.Icon),
|
||||
})
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
"TitleBarConfig": p.titleBarConfig,
|
||||
"HeaderProps": propsData.Header,
|
||||
"Links": absoluteLinks,
|
||||
"Islands": renderedIslands,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type PropertiesFileData struct {
|
||||
Header HeaderIsland `bson:"header" json:"header"`
|
||||
Links []HeaderLink `bson:"links" json:"links"`
|
||||
Islands []Island `bson:"islands" json:"islands"` //TODO rename
|
||||
}
|
||||
|
||||
type HeaderIsland struct {
|
||||
Name string `bson:"name" json:"name"`
|
||||
IconPath string `bson:"iconpath" json:"iconpath"`
|
||||
Value1 string `bson:"value1" json:"value1"` //TODO Rename to value
|
||||
Value2 string `bson:"value2" json:"value2"`
|
||||
}
|
||||
|
||||
type HeaderLink struct {
|
||||
Text string `bson:"text" json:"text"`
|
||||
Url string `bson:"url" json:"url"`
|
||||
Icon string `bson:"icon" json:"icon"`
|
||||
}
|
||||
|
||||
type Island struct {
|
||||
Header string `bson:"header" json:"header"`
|
||||
Properties []IslandProperty `bson:"properties" json:"properties"`
|
||||
}
|
||||
|
||||
type IslandProperty struct {
|
||||
Key string `bson:"key" json:"key"`
|
||||
KeyComments []string `bson:"keycomment" json:"keycomment"`
|
||||
Values []string `bson:"values" json:"values"`
|
||||
}
|
||||
|
||||
type RenderedIsland struct {
|
||||
Header string
|
||||
Properties []RenderedIslandProperty
|
||||
}
|
||||
|
||||
type RenderedIslandProperty struct {
|
||||
Key string
|
||||
KeyComments []string
|
||||
Values []template.HTML
|
||||
}
|
||||
|
||||
// type Value struct {
|
||||
// Blocks []ValueBlock
|
||||
// }
|
||||
|
||||
// type ValueBlock struct {
|
||||
// Type string
|
||||
// Data string
|
||||
// }
|
@ -1,8 +0,0 @@
|
||||
package appCtx
|
||||
|
||||
//TODO to websiteapp package
|
||||
type AppContext struct {
|
||||
IsMobile bool `json:"isMobile"`
|
||||
BundlePath string `json:"bundlePath"`
|
||||
RunPath string `json:"runPath"`
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package blogviewer
|
||||
|
||||
import "html/template"
|
||||
|
||||
type BlogFileData struct {
|
||||
Header string `bson:"header"`
|
||||
Blocks []*Block `bson:"blocks"`
|
||||
}
|
||||
|
||||
type Block struct {
|
||||
Type string `bson:"type"`
|
||||
Data []string `bson:"data"`
|
||||
}
|
||||
|
||||
type RenderedBlock struct {
|
||||
Type string `bson:"type"`
|
||||
Data []template.HTML `bson:"data"`
|
||||
}
|
@ -1,266 +0,0 @@
|
||||
package blogviewer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/errormessage"
|
||||
"personalwebsite/libs"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type BlogViewerApplication struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
appID string
|
||||
mLib libs.MarkdownLib
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewBlogViewerApp(webFs *webfilesystem.WebFileSystem) *BlogViewerApplication {
|
||||
return &BlogViewerApplication{
|
||||
fs: webFs,
|
||||
appID: "BlogViewer",
|
||||
mLib: libs.MarkdownLib{},
|
||||
}
|
||||
}
|
||||
func (b *BlogViewerApplication) GetManifest() apps.ApplicationManifest {
|
||||
return b.manifest
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) GetAppID() string {
|
||||
return b.appID
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) GetPath() string {
|
||||
return b.path
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) PrivateRoutes(route *gin.RouterGroup) {
|
||||
b.PublicRoutes(route)
|
||||
|
||||
route.POST("test", func(ctx *gin.Context) {
|
||||
blogData := BlogFileData{}
|
||||
err := ctx.BindJSON(&blogData)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mLib := libs.MarkdownLib{}
|
||||
for _, block := range blogData.Blocks {
|
||||
for _, str := range block.Data {
|
||||
test := []byte(str)
|
||||
mLib.Render(test, true)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
route.GET("writeMockBlog", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||
return
|
||||
}
|
||||
err := b.WriteMock(path)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, "OK")
|
||||
})
|
||||
|
||||
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) PublicRoutes(route *gin.RouterGroup) {
|
||||
|
||||
route.POST("render", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||
return
|
||||
}
|
||||
|
||||
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 appCtx.IsMobile {
|
||||
ctx.HTML(http.StatusOK, "blog-viewer/mobile-app.tmpl", ginH)
|
||||
} else {
|
||||
ctx.HTML(http.StatusOK, "blog-viewer/app.tmpl", ginH)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BlogViewerApplication) WriteMock(path string) error {
|
||||
blogFileHeader := webfilesystem.FileHeader{ //TODO to fs.CreateDirectory()
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: "blog1.blog",
|
||||
Type: "directory",
|
||||
Icon: "",
|
||||
Data: [12]byte{},
|
||||
}
|
||||
blogFileData := webfilesystem.DirectoryData{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Parent: [12]byte{},
|
||||
Children: []primitive.ObjectID{},
|
||||
}
|
||||
|
||||
_, _, err := b.fs.Write("/home/user/blog1.blog", &blogFileHeader, blogFileData)
|
||||
if err != nil {
|
||||
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) 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
|
||||
}
|
||||
|
||||
newData := []RenderedBlock{}
|
||||
for _, block := range data.Blocks {
|
||||
newBlock := RenderedBlock{}
|
||||
switch block.Type {
|
||||
case "image":
|
||||
// for _, image := range block.Data {
|
||||
// newData = append(newData, b.fs.RelativeToAbsolute(appCtx, image))
|
||||
// }
|
||||
case "markdown":
|
||||
for _, data := range block.Data {
|
||||
renderedMD := b.mLib.Render([]byte(data), true)
|
||||
newBlock.Data = append(newBlock.Data, renderedMD)
|
||||
}
|
||||
newData = append(newData, newBlock)
|
||||
}
|
||||
// block.Data = newData
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
"header": data.Header,
|
||||
"blocks": newData,
|
||||
// "html": html,
|
||||
}, nil
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package finder
|
||||
|
||||
import (
|
||||
"path"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type FinderApplication struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
appID string
|
||||
titleBarConfig wde.TitleBarConfig
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
// manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewFinderApplication(webFs *webfilesystem.WebFileSystem) *FinderApplication {
|
||||
manifest := apps.ApplicationManifest{}
|
||||
_, err := webFs.Read(path.Join("/Applications/Finder.app", ".appmanifest"), &manifest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &FinderApplication{
|
||||
fs: webFs,
|
||||
path: "/Applications/Finder.app",
|
||||
appID: "Finder",
|
||||
titleBarConfig: wde.TitleBarConfig{
|
||||
Lable: "Finder",
|
||||
CloseButton: true,
|
||||
HasIcon: true,
|
||||
IconPath: "/Icons/GenericFolder.icn",
|
||||
IconSize: "16",
|
||||
},
|
||||
manifest: manifest,
|
||||
}
|
||||
}
|
||||
func (f *FinderApplication) GetManifest() apps.ApplicationManifest {
|
||||
return f.manifest
|
||||
}
|
||||
func (f *FinderApplication) GetAppID() string {
|
||||
return f.appID
|
||||
}
|
||||
|
||||
func (f *FinderApplication) GetPath() string {
|
||||
return f.path
|
||||
}
|
||||
|
||||
func (f *FinderApplication) Render(appCtx appCtx.AppContext) gin.H {
|
||||
return gin.H{
|
||||
"TitleBarConfig": f.titleBarConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FinderApplication) RenderPublicContextMenu(context string, filePath string, data string) gin.H {
|
||||
islands := [][]wde.ContexMenuRow{}
|
||||
islands = append(islands, []wde.ContexMenuRow{})
|
||||
|
||||
//TODO: Links read as source files in props info
|
||||
islands = append(islands, []wde.ContexMenuRow{
|
||||
{Label: "Get Info", Action: "getInfo"},
|
||||
})
|
||||
if context == "FileTileView" {
|
||||
return gin.H{
|
||||
"Islands": islands,
|
||||
}
|
||||
}
|
||||
|
||||
switch context {
|
||||
default:
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
"Islands": islands,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FinderApplication) RenderProps(filePath string) (gin.H, error) {
|
||||
fileHeader, err := f.fs.Read(filePath, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gin.H{
|
||||
"file": fileHeader,
|
||||
}, nil
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package finder
|
||||
|
||||
import (
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/wde"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
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{
|
||||
{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,
|
||||
}
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
package finder
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"personalwebsite/apps/appCtx"
|
||||
"personalwebsite/errormessage"
|
||||
|
||||
mobile "github.com/floresj/go-contrib-mobile"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
d := mobile.GetDevice(ctx)
|
||||
switch {
|
||||
case d.Mobile():
|
||||
ctx.HTML(http.StatusOK, "templates/finder/mobile-app.tmpl", gin.H{
|
||||
// "autostart": autostart,
|
||||
})
|
||||
default:
|
||||
ctx.HTML(http.StatusOK, "finder/app.tmpl", f.Render(appCtx))
|
||||
}
|
||||
})
|
||||
|
||||
//Obsolete
|
||||
routes.GET("renderMobileDesktop", func(ctx *gin.Context) {
|
||||
ctx.HTML(http.StatusOK, "finder/mobile-desktop.tmpl", gin.H{})
|
||||
})
|
||||
|
||||
routes.POST("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.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 bundle",
|
||||
})
|
||||
return
|
||||
}
|
||||
d := mobile.GetDevice(ctx)
|
||||
switch {
|
||||
case d.Mobile():
|
||||
ctx.HTML(http.StatusOK, "finder/mobile-app.tmpl", f.Render(appCtx))
|
||||
default:
|
||||
ctx.HTML(http.StatusOK, "finder/admin-app.tmpl", f.Render(appCtx))
|
||||
}
|
||||
})
|
||||
|
||||
routes.GET("renderMobileDesktop", func(ctx *gin.Context) {
|
||||
ctx.HTML(http.StatusOK, "finder/mobile-desktop.tmpl", gin.H{})
|
||||
})
|
||||
routes.POST("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)
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package imgviewer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ImgViewerApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
appID string
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewImgViewerApp(webFs *webfilesystem.WebFileSystem) *ImgViewerApp {
|
||||
newApp := ImgViewerApp{
|
||||
fs: webFs,
|
||||
appID: "ImgViewer",
|
||||
}
|
||||
return &newApp
|
||||
}
|
||||
func (p *ImgViewerApp) PrivateRoutes(route *gin.RouterGroup) {
|
||||
p.PublicRoutes(route)
|
||||
}
|
||||
func (i *ImgViewerApp) GetManifest() apps.ApplicationManifest {
|
||||
return i.manifest
|
||||
}
|
||||
func (p *ImgViewerApp) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("render", func(ctx *gin.Context) {
|
||||
isMobileParam := ctx.Query("isMobile")
|
||||
isMobile := isMobileParam == "true"
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.JSON(http.StatusBadRequest, "no path provided")
|
||||
return
|
||||
}
|
||||
ginH, err := p.Render(path, isMobile)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, "TODO")
|
||||
return
|
||||
}
|
||||
if isMobile {
|
||||
ctx.HTML(http.StatusOK, "img-viewer/mobile-app.tmpl", ginH)
|
||||
} else {
|
||||
ctx.HTML(http.StatusOK, "img-viewer/app.tmpl", ginH)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) GetPath() string {
|
||||
return p.path
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) GetAppID() string {
|
||||
return p.appID
|
||||
}
|
||||
|
||||
func (p *ImgViewerApp) Render(filePath string, isMobile bool) (gin.H, error) {
|
||||
// file, err := p.fs.NewRead(filePath)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// println(file.Data.(primitive.Binary).Data)
|
||||
|
||||
// img, err := p.fs.NewRead(path)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// data, err := libs.ReadImage(img)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// url := location.Get(ctx)
|
||||
return gin.H{
|
||||
"imgUrl": "/system/libs/img/get?path=" + filePath,
|
||||
// "header": data.Header,
|
||||
// "base64": data.Base64,
|
||||
}, nil
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package sunboard
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/apps"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type SunboardApp struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
wde *wde.WDE
|
||||
appID string
|
||||
appStorage *apps.ApplicationsStorage
|
||||
path string
|
||||
manifest apps.ApplicationManifest
|
||||
}
|
||||
|
||||
func NewSunboardApp(webFs *webfilesystem.WebFileSystem, wde *wde.WDE, appStorage *apps.ApplicationsStorage) *SunboardApp {
|
||||
manifest := apps.ApplicationManifest{}
|
||||
_, err := webFs.Read(path.Join("/Applications/Sunboard.app", ".appmanifest"), &manifest)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
newApp := SunboardApp{
|
||||
fs: webFs,
|
||||
wde: wde,
|
||||
appID: "Sunboard",
|
||||
appStorage: appStorage,
|
||||
path: "/Applications/Sunboard.app",
|
||||
manifest: manifest,
|
||||
}
|
||||
return &newApp
|
||||
}
|
||||
|
||||
func (a *SunboardApp) GetAppID() string {
|
||||
return a.appID
|
||||
}
|
||||
|
||||
func (a *SunboardApp) PublicRoutes(route *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
func (a *SunboardApp) GetPath() string {
|
||||
return a.path
|
||||
}
|
||||
func (a *SunboardApp) GetManifest() apps.ApplicationManifest {
|
||||
return a.manifest
|
||||
}
|
||||
|
||||
func (a *SunboardApp) PrivateRoutes(router *gin.RouterGroup) {
|
||||
router.POST("render", func(ctx *gin.Context) {
|
||||
appIcons := []appIcon{}
|
||||
for _, app := range a.appStorage.Apps {
|
||||
if app.GetAppID() == "Sunboard" { //FIXME
|
||||
continue
|
||||
}
|
||||
|
||||
if app.GetManifest().Iconpath == "" {
|
||||
continue
|
||||
}
|
||||
println(app.GetAppID() + " : " + app.GetPath())
|
||||
// iconPath := path.Join(, "icon.icn")
|
||||
appIcons = append(appIcons, appIcon{
|
||||
Type: "Icon",
|
||||
Icon: "/system/libs/img/icon/get?path=" + app.GetManifest().Iconpath + "&size=32",
|
||||
Lable: app.GetAppID(),
|
||||
AppId: app.GetAppID(),
|
||||
Path: app.GetPath(),
|
||||
})
|
||||
}
|
||||
ctx.HTML(http.StatusOK, "sunboard/sunboard.html", gin.H{
|
||||
"AppsIcons": appIcons,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type appIcon struct {
|
||||
AppId string
|
||||
Type string
|
||||
Icon string
|
||||
Lable string
|
||||
Path string
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
//TODO to libs
|
||||
type WebDEApplication interface {
|
||||
// Render()
|
||||
GetAppID() string
|
||||
PublicRoutes(*gin.RouterGroup)
|
||||
PrivateRoutes(*gin.RouterGroup)
|
||||
GetPath() string
|
||||
GetManifest() ApplicationManifest
|
||||
// GEtHtml()
|
||||
// GetId() string
|
||||
}
|
||||
|
||||
type ApplicationManifest struct {
|
||||
AppId string `bson:"appid" json:"appId"`
|
||||
Js []string `bson:"js" json:"js"`
|
||||
Css []string `bson:"css" json:"css"`
|
||||
Iconpath string `bson:"iconpath" json:"iconpath"`
|
||||
}
|
||||
|
||||
func NewApplicationsStorage(apps map[string]WebDEApplication, webfs *webfilesystem.WebFileSystem) *ApplicationsStorage {
|
||||
return &ApplicationsStorage{
|
||||
Apps: apps,
|
||||
fs: webfs,
|
||||
}
|
||||
}
|
||||
|
||||
type ApplicationsStorage struct {
|
||||
Apps map[string]WebDEApplication
|
||||
fs *webfilesystem.WebFileSystem
|
||||
}
|
||||
|
||||
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{},
|
||||
Css: []string{},
|
||||
}
|
||||
|
||||
newAppFile := webfilesystem.FileHeader{
|
||||
MongoId: primitive.NewObjectID(),
|
||||
Name: ".appmanifest",
|
||||
Type: "application-manifest",
|
||||
Icon: "",
|
||||
Data: primitive.NewObjectID(),
|
||||
}
|
||||
_, _, err = as.fs.Write(appPath+"/"+appBundleName+"/"+newAppFile.Name, &newAppFile, newAppData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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())
|
||||
ctx.String(http.StatusMovedPermanently, "Obsolete")
|
||||
})
|
||||
|
||||
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.String(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusOK)
|
||||
})
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package errormessage
|
||||
|
||||
type ErrorMessage struct {
|
||||
Message string `json:"message"`
|
||||
}
|
BIN
front/dist/Charcoal.cb9045e5.woff2
vendored
BIN
front/dist/Charcoal.cb9045e5.woff2
vendored
Binary file not shown.
BIN
front/dist/Geneva.41461b69.woff2
vendored
BIN
front/dist/Geneva.41461b69.woff2
vendored
Binary file not shown.
157
front/dist/apps/about-me/about-me.css
vendored
157
front/dist/apps/about-me/about-me.css
vendored
@ -1,157 +0,0 @@
|
||||
@font-face {
|
||||
font-family: Geneva;
|
||||
src: url("../../Geneva.41461b69.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Charcoal;
|
||||
src: url("../../Charcoal.cb9045e5.woff2");
|
||||
}
|
||||
|
||||
.large-system-font, .ShortBio > .Text > .Name, .Island .Title, .Island .Key {
|
||||
letter-spacing: .35px;
|
||||
font-family: Charcoal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.small-system-font, .views-font {
|
||||
font-family: Geneva;
|
||||
}
|
||||
|
||||
.PersPropsContent {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.PersPropsContent .PropsView {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.PropertiesList {
|
||||
flex-direction: column;
|
||||
flex-grow: 0;
|
||||
order: 0;
|
||||
align-self: flex-start;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.PropertiesList .ShortBio {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ShortBio .Image {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.ShortBio .Text {
|
||||
align-self: stretch;
|
||||
align-items: left;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
order: 0;
|
||||
gap: 1px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.PropertiesList .Links {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: end;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Links > a {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: end;
|
||||
gap: 2px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.PropertiesList .Links .Link {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.PropertiesList .Island {
|
||||
border: 1px solid #888;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding-bottom: 10px;
|
||||
box-shadow: 1px 1px #fff, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.Island .Title {
|
||||
background-color: #ddd;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: -9px;
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.Island .Content {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Island .Row {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.Island .Key {
|
||||
text-align: end;
|
||||
white-space: nowrap;
|
||||
width: 34%;
|
||||
position: relative;
|
||||
top: -1.5px;
|
||||
}
|
||||
|
||||
.Island .KeyComment {
|
||||
color: #646464;
|
||||
text-align: end;
|
||||
white-space: normal;
|
||||
font-size: 9px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.Island .Values {
|
||||
flex-direction: column;
|
||||
justify-content: left;
|
||||
gap: 5px;
|
||||
width: 55%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=about-me.css.map */
|
1
front/dist/apps/about-me/about-me.css.map
vendored
1
front/dist/apps/about-me/about-me.css.map
vendored
@ -1 +0,0 @@
|
||||
{"mappings":"ACiBA;;;;;AAKA;;;;;AAKA;;;;;;AAMA;;;;AD/BA;;;;;;;;;;AAYA;;;;;AAKA;;;;;;;;;;;AAkBA;;;;;;;;AAsBA;;;;;;AAMA;;;;;;;;;;;AAuBA;;;;;;;;;;AAiBA;;;;;;;;;AAeA;;;;;AAMA;;;;;;;;AAeA;;;;;;;;;AAWA;;;;;;;;;AAWA;;;;;;;;;;AAUA;;;;;;;;AAcA;;;;;;;;AAUA","sources":["src/apps/about-me/about-me.less","src/theme.less"],"sourcesContent":["@import \"../../theme.less\";\n\n.PersPropsContent{\n width: 100%;\n height: 100%;\n\n /* Auto layout */\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: flex-start;\n padding: 0px;\n}\n\n.PersPropsContent .PropsView{\n /* background-color: rebeccapurple; */\n width: 100%;\n height: auto;\n}\n.PropertiesList{\n /* width: 100%;\n height: auto; */\n\n /* Inside auto layout */\n order: 0;\n align-self: flex-start;\n flex-grow: 0;\n\n /* Auto layout */\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n padding: 12px;\n gap:16px;\n}\n\n\n.PropertiesList .ShortBio{\n /* width: 100%;\n height: auto; */\n /* margin-right: -20px; */\n\n // background-color: aquamarine;\n /* Inside auto layout */\n width: 100%;\n // flex: none;\n // order: 0;\n // align-self: stretch;\n // flex-grow: 1;\n\n /* Auto layout */\n display: flex;\n flex-direction: row;\n align-items: center;\n // padding: 0px;\n // margin-right: 20;\n gap:15px;\n}\n\n.ShortBio .Image{\n width: 48px;\n height: 48px;\n padding-left: 10px;\n}\n\n.ShortBio .Text{\n /* width: 100%;\n height: auto; */\n\n /* Inside auto layout */\n flex: none;\n order: 0;\n align-self: stretch;\n flex-grow: 1;\n \n /* Auto layout */\n display: flex;\n flex-direction: column;\n align-items: left;\n padding: 0px;\n gap:1px;\n}\n\n.ShortBio > .Text > .Name{\n &:extend(.large-system-font);\n // background-color: aqua;\n}\n\n.PropertiesList .Links {\n // position: absolute;\n // right: 14px;\n // top: 27px;\n // background-color: aqua;\n height: auto;\n width: auto;\n\n // background-color: aqua;\n /* Auto layout */\n display: flex;\n flex-direction: column;\n align-items: end;\n justify-content: center;\n padding: 0px;\n // gap:4px;\n}\n.Links > a{\n /* Auto layout */\n display: flex;\n flex-direction: row;\n align-items: end;\n justify-content: center;\n padding: 0px;\n gap: 2px;\n}\n.Links > a > .link-lable{\n // background-color: aqua;\n // line-height: 60px;\n // display:table\n}\n\n.PropertiesList .Links .Link {\n /* background-color:brown; */\n width: 16px;\n height: 16px;\n}\n\n.PropertiesList .Island{\n width: 100%;\n height: auto;\n border: 1px solid #888888;\n box-shadow: 1px 1px 0px #FFFFFF, inset 1px 1px 0px #FFFFFF;\n padding-bottom: 10px;\n\n /* Auto layout */\n /* display: flex;\n flex-direction: column;\n align-items: center;\n padding: 0px;\n gap:1px; */\n}\n\n.Island .Title {\n //FIXME\n &:extend(.large-system-font);\n position:relative;\n display: inline-block;\n max-width: 100%;\n background-color: #DDDDDD;\n left: 12px;\n top: -9px;\n}\n\n.Island .Content{\n width: 100%;\n /* top: 0px; */\n /* Auto layout */\n display: flex;\n flex-direction: column;\n justify-content: center;\n padding: 0px;\n gap: 12px;\n}\n\n.Island .Row{\n margin-left: 12px;\n margin-right: 12px;\n /* Auto layout */\n display: flex;\n flex-direction: row;\n justify-content: center;\n padding: 0px;\n gap: 5px;\n}\n.Island .Key{\n position: relative;\n &:extend(.large-system-font);\n // font-family: \"Virtue\";\n // font-size: 11px;\n // letter-spacing: 0.35px;\n text-align: end;\n width: 34%;\n white-space: nowrap;\n top: -1.5px;\n\n /* font-weight: bold; */\n}\n\n.Island .KeyComment{\n /* color: rgb(129, 129, 129); TODO*/\n color: #646464;\n font-size: 9px;\n font-style: italic;\n text-align: end;\n white-space:normal;\n /* filter: drop-shadow(-.5px -.5px 0px #616161); */\n}\n\n.Island .Values{\n width: 55%;\n display: flex;\n flex-direction: column;\n justify-content: left;\n padding: 0px;\n gap: 5px;\n\n}\n\n.Values .Value{\n /* width: 55%; */\n\n}",null],"names":[],"version":3,"file":"about-me.css.map","sourceRoot":"/__parcel_source_root/"}
|
81
front/dist/apps/finder/finder.css
vendored
81
front/dist/apps/finder/finder.css
vendored
@ -1,81 +0,0 @@
|
||||
@font-face {
|
||||
font-family: Geneva;
|
||||
src: url("../../Geneva.41461b69.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Charcoal;
|
||||
src: url("../../Charcoal.cb9045e5.woff2");
|
||||
}
|
||||
|
||||
.large-system-font {
|
||||
letter-spacing: .35px;
|
||||
font-family: Charcoal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.small-system-font, .views-font {
|
||||
font-family: Geneva;
|
||||
}
|
||||
|
||||
.adjective {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.convex {
|
||||
box-shadow: 1px 1px #00000040, inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.border .grey {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.border .black {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.shadow .grey {
|
||||
box-shadow: 1px 1px #555;
|
||||
}
|
||||
|
||||
.shadow .black {
|
||||
box-shadow: 1px 1px #000;
|
||||
}
|
||||
|
||||
.rows-fill-shadowed {
|
||||
filter: drop-shadow(1px 1px #777);
|
||||
background: linear-gradient(#0000 0%, #fff 0% 50%, #0000 50%) 0 0 / 2px 2px;
|
||||
}
|
||||
|
||||
.finder-content {
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.finder-content > .tool-bar {
|
||||
border-bottom: 1px solid #555;
|
||||
width: 100%;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
.window-frame.Focused .tool-bar {
|
||||
border-bottom: 1px solid #000;
|
||||
box-shadow: inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.finder-content > .file-view-container {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=finder.css.map */
|
1
front/dist/apps/finder/finder.css.map
vendored
1
front/dist/apps/finder/finder.css.map
vendored
@ -1 +0,0 @@
|
||||
{"mappings":"ACiBA;;;;;AAKA;;;;;AAKA;;;;;;AAMA;;;;ACjCA;;;;AAIA;;;;AAMA;;;;AAAA;;;;AAUA;;;;AAAA;;;;AAWA;;;;;AF5BA;;;;;;;;;;AAYA;;;;;;AAMA;;;;;AAKA","sources":["src/apps/finder/finder.less","src/theme.less","src/wde/effects.less"],"sourcesContent":["@import \"../../theme.less\";\n@import \"../../wde/effects.less\";\n\n.finder-content {\n width: 100%;\n height: 100%;\n\n /* Auto layout */\n display: flex;\n flex-direction: column;\n justify-content: start;\n align-items: flex-start;\n padding: 0px;\n}\n\n.finder-content > .tool-bar{\n width: 100%;\n min-height: 20px;\n border-bottom: @eff-border-grey;\n}\n\n.window-frame.Focused .tool-bar{\n border-bottom: 1px solid #000000;\n box-shadow: @eff-box-shadow-convex;\n}\n\n.finder-content > .file-view-container{\n width: 100%;\n height: 100%;\n\n // background-color: #FFFFFF;\n\n /* Auto layout */\n display: flex;\n flex-direction: row;\n justify-content: center;\n align-items: flex-start;\n padding: 0px;\n}",null,null],"names":[],"version":3,"file":"finder.css.map","sourceRoot":"/__parcel_source_root/"}
|
370
front/dist/desktop.css
vendored
370
front/dist/desktop.css
vendored
@ -1,370 +0,0 @@
|
||||
.WdePrimitives .adjective {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.WdePrimitives .black-border {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.FileTileView {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.FileTileView.DragDropBorder {
|
||||
box-shadow: inset 0 0 0 4px #99c;
|
||||
}
|
||||
|
||||
.FileTileView .FlexContainer {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
flex-flow: wrap;
|
||||
place-content: flex-start;
|
||||
align-items: flex-start;
|
||||
gap: 20px 50px;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 15px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.FileTileView::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.FileTileView .Tile {
|
||||
flex-flow: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.FileTileView .Icon {
|
||||
background-size: cover;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Icon {
|
||||
filter: brightness(.4);
|
||||
}
|
||||
|
||||
.FileTileView .Lable {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Lable {
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.scrollbar-place {
|
||||
border-left: 1px solid #555;
|
||||
flex: 1 0 auto;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
width: 14px;
|
||||
height: 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.Focused .active .scrollbar-place {
|
||||
background-color: #aaa;
|
||||
border-left: 1px solid #000;
|
||||
box-shadow: inset -1px 0 #ffffff4a, inset -2px 0 #ffffff30, inset 1px 1px #00000024, inset 2px 2px #00000030;
|
||||
}
|
||||
|
||||
.scroll-element {
|
||||
visibility: hidden;
|
||||
background: #99f;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
width: 14px;
|
||||
height: 31px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
position: relative;
|
||||
box-shadow: 0 -1px #000, 0 1px #000, 0 2px #00000021, 0 3px #00000030, inset 0 1px #ffffff80, inset 1px 0 #ffffff80, inset -1px -1px #6666cce8;
|
||||
}
|
||||
|
||||
.Focused .active .scroll-element {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.drag-element {
|
||||
pointer-events: none;
|
||||
filter: drop-shadow(1px 1px #339);
|
||||
background: linear-gradient(#0000 0%, #ccf 0% 50%, #0000 50%) 0 0 / 2px 2px;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.ScrollContent {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.ScrollContent::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.adjective {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.convex {
|
||||
box-shadow: 1px 1px #00000040, inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.border .grey {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.border .black {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.shadow .grey {
|
||||
box-shadow: 1px 1px #555;
|
||||
}
|
||||
|
||||
.shadow .black {
|
||||
box-shadow: 1px 1px #000;
|
||||
}
|
||||
|
||||
.rows-fill-shadowed, .window-frame.Focused .title-bar .visual-drag-area {
|
||||
filter: drop-shadow(1px 1px #777);
|
||||
background: linear-gradient(#0000 0%, #fff 0% 50%, #0000 50%) 0 0 / 2px 2px;
|
||||
}
|
||||
|
||||
.wde-button {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #000;
|
||||
border-radius: 3px;
|
||||
width: auto;
|
||||
height: 20px;
|
||||
box-shadow: inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.wde-button:active {
|
||||
background-color: #666;
|
||||
box-shadow: inset 1px 1px #00000045, inset -1px -1px gray;
|
||||
}
|
||||
|
||||
.ContentBorder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ContextMenu {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #000;
|
||||
width: auto;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ContextMenu .Content {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ContextMenu .Row {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.ContextMenu .Row:hover {
|
||||
color: #fff;
|
||||
background-color: #339;
|
||||
}
|
||||
|
||||
.ContextMenu .Row .Lable {
|
||||
white-space: nowrap;
|
||||
margin-left: 20px;
|
||||
margin-right: 12px;
|
||||
font-family: Virtue;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Geneva;
|
||||
src: url("Geneva.41461b69.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Charcoal;
|
||||
src: url("Charcoal.cb9045e5.woff2");
|
||||
}
|
||||
|
||||
.large-system-font, .title-bar .lable {
|
||||
letter-spacing: .35px;
|
||||
font-family: Charcoal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.small-system-font, .views-font, body {
|
||||
font-family: Geneva;
|
||||
}
|
||||
|
||||
.window-frame {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #555;
|
||||
flex-direction: column;
|
||||
flex: 1 0 auto;
|
||||
order: 1;
|
||||
align-self: stretch;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
padding: 2px 6px 4px 4px;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
box-shadow: 1px 1px #555;
|
||||
}
|
||||
|
||||
.window-frame.Focused {
|
||||
background-color: #ccc;
|
||||
border: 1px solid #000;
|
||||
box-shadow: 1px 1px #555, inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.content-border {
|
||||
background-color: #eee;
|
||||
border: 1px solid #555;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.Focused .content-border {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #000;
|
||||
box-shadow: -1px -1px #00000040, 1px 1px #fff;
|
||||
}
|
||||
|
||||
.title-bar {
|
||||
flex-direction: row;
|
||||
flex: none;
|
||||
order: 0;
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
width: 100%;
|
||||
height: 13px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.title-bar .lable {
|
||||
color: gray;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar .lable {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar .visual-drag-area {
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
.title-bar > .icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.title-bar > .button {
|
||||
visibility: hidden;
|
||||
background: linear-gradient(135deg, #999 18.18%, #fff 81.82%);
|
||||
border: 1px solid #222;
|
||||
flex: none;
|
||||
order: 0;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
padding: 0%;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
box-shadow: .5px .5px 0 .5px #fff, -.5px -.5px 0 .5px #00000040, inset 1px 1px #ffffff80, inset -1px -1px #00000045;
|
||||
}
|
||||
|
||||
.title-bar > .button:active {
|
||||
background-color: #0006;
|
||||
box-shadow: .5px .5px 0 .5px #fff, -.5px -.5px 0 .5px #00000040;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar > .button {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.NoClick {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Click {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
src: url("Geneva.41461b69.woff2");
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-khtml-user-select: none;
|
||||
touch-action: manipulation;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 11px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#applications {
|
||||
visibility: hidden;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: static;
|
||||
}
|
||||
|
||||
#windows-layer {
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: static;
|
||||
}
|
||||
|
||||
#desktop-layer {
|
||||
background-color: #99c;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=desktop.css.map */
|
1
front/dist/desktop.css.map
vendored
1
front/dist/desktop.css.map
vendored
@ -1 +0,0 @@
|
||||
{"mappings":"ACAA;;;;AAAA;;;;ACCA;;;;;AAWA;;;;AAKA;;;;;;;;;;;;;AAqBA;;;;;AAKA;;;;;;;;;;;AAkBA;;;;;;AAeA;;;;AAIA;;;;AAIA;;;;;;ACrEA;;;;;;;;;;;;AAsBA;;;;;;AASA;;;;;;;;;;;;;;;AAyBA;;;;AAIA;;;;;;;;;AAeA;;;;;;;AAgBA;;;;;AC1GA;;;;AAIA;;;;AAMA;;;;AAAA;;;;AAUA;;;;AAAA;;;;AAWA;;;;;AE5BA;;;;;;;;;AACI;;;;;ACJJ;;;;;;AAUA;;;;;;;;AAUA;;;;;;;;;AAgBA;;;;;AAYA;;;;;AAKA;;;;;;;ACpCA;;;;;AAKA;;;;;AAKA;;;;;;AAMA;;;;AC9BA;;;;;;;;;;;;;;;AAyBA;;;;;;AAOA;;;;;;;;AAUA;;;;;;AJ1CA;;;;;;;;;;;;;;AAmBA;;;;;;;;AAcA;;;;AAIA;;;;;;AAOA;;;;;AAOA;;;;;;;;;;;;;;AAQI;;;;;AAmBJ;;;;ALvEA;;;;AAGA;;;;AAYA;;;;;AAKA;;;;;;;;;;;;;;AAwBA;;;;;;;AAOA;;;;;;AAOA","sources":["src/desktop.less","src/wde/primitives.less","src/wde/widgets/file-view/file-view.less","src/wde/widgets/scrollbar/scrollbar.less","src/wde/effects.less","src/wde/widgets/title-bar/title-bar.less","src/wde/widgets/button/button.less","src/wde/widgets/basic-widgets.less","src/theme.less","src/wde/window-frame.less"],"sourcesContent":["@import \"./wde/primitives.less\";\n@import \"./wde/widgets/file-view/file-view.less\";\n@import \"./wde/widgets/scrollbar/scrollbar.less\";\n@import \"./wde/widgets/button/button.less\";\n// @import \"./wde/legacy-ui.less\";\n@import \"./wde/widgets/basic-widgets.less\";\n@import \"./theme.less\";\n@import \"./wde/window-frame.less\";\n@import \"./wde/widgets/title-bar/title-bar.less\";\n\n.NoClick {\n pointer-events: none;\n}\n.Click {\n pointer-events: all;\n}\n// .DragArea\n\n// *{\n// font-family: Verdana, Geneva, sans-serif;\n// font-size: 11px;\n// font-style: normal;\n// font-weight:initial;\n// }\n\n*::-webkit-scrollbar { /* WebKit */\n width: 0;\n height: 0;\n}\n\nbody{\n &:extend(.views-font);\n // zoom: var(--zoom);\n position: absolute;\n width: 100%;\n height: 100%;\n margin: 0px;\n\n font-size: 11px;\n\n // font-family: \"Geneva\";\n src:url(\"./fonts/Geneva.woff2\");\n\n /* font: normal 14px Summer Pixel 22, \"res/SummerPixel22Regular.ttf\"; */\n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Safari */\n -khtml-user-select: none; /* Konqueror HTML */\n -moz-user-select: none; /* Old versions of Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* Non-prefixed version, currently\n supported by Chrome, Edge, Opera and Firefox */\n touch-action: manipulation;\n}\n\n#applications{\n position: static;\n width: 0px;\n height: 0px;\n visibility: hidden;\n}\n\n#windows-layer {\n width: 0px;\n height: 0px;\n /* position: fixed; */\n position: static;\n}\n\n#desktop-layer{\n position: fixed;\n /* margin: 0px; */\n width: 100%;\n height: 100%;\n background-color: @col-ceil;\n}",null,null,null,null,null,null,null,null,null],"names":[],"version":3,"file":"desktop.css.map","sourceRoot":"/__parcel_source_root/"}
|
168
front/dist/mobile.css
vendored
168
front/dist/mobile.css
vendored
@ -1,168 +0,0 @@
|
||||
.WdePrimitives .adjective {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.WdePrimitives .black-border {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#mobile-sunboard {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#icons {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.apps-list {
|
||||
flex-wrap: wrap;
|
||||
flex: 1 0 0;
|
||||
align-content: flex-start;
|
||||
align-self: stretch;
|
||||
align-items: flex-start;
|
||||
gap: 64px 0;
|
||||
padding: 64px 16px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-icon {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
width: 100px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-icon .icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Geneva;
|
||||
src: url("Geneva.41461b69.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Charcoal;
|
||||
src: url("Charcoal.cb9045e5.woff2");
|
||||
}
|
||||
|
||||
.large-system-font {
|
||||
letter-spacing: .35px;
|
||||
font-family: Charcoal;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.small-system-font, .views-font, body {
|
||||
font-family: Geneva;
|
||||
}
|
||||
|
||||
.adjective {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.convex {
|
||||
box-shadow: 1px 1px #00000040, inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.border .grey {
|
||||
border: 1px solid #555;
|
||||
}
|
||||
|
||||
.border .black {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
.shadow .grey {
|
||||
box-shadow: 1px 1px #555;
|
||||
}
|
||||
|
||||
.shadow .black {
|
||||
box-shadow: 1px 1px #000;
|
||||
}
|
||||
|
||||
.rows-fill-shadowed {
|
||||
filter: drop-shadow(1px 1px #777);
|
||||
background: linear-gradient(#0000 0%, #fff 0% 50%, #0000 50%) 0 0 / 2px 2px;
|
||||
}
|
||||
|
||||
.wde-button, .wde-mobile-button {
|
||||
background-color: #ddd;
|
||||
border: 1px solid #000;
|
||||
border-radius: 3px;
|
||||
width: auto;
|
||||
height: 20px;
|
||||
box-shadow: inset -1px -1px #00000045, inset 1px 1px #fff;
|
||||
}
|
||||
|
||||
.wde-button:active, .wde-mobile-button:active {
|
||||
background-color: #666;
|
||||
box-shadow: inset 1px 1px #00000045, inset -1px -1px gray;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Geneva;
|
||||
src: url("Geneva.41461b69.woff2");
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-khtml-user-select: none;
|
||||
touch-action: manipulation;
|
||||
background-color: silver;
|
||||
background-position: 0 0, 0 0, -5px -5px, 5px 5px;
|
||||
background-size: 10px 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#mobile-app-views {
|
||||
background: #ddd;
|
||||
border: 1px solid #000;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
inset: 16px 16px 100px;
|
||||
overflow: hidden;
|
||||
box-shadow: 1px 1px #000;
|
||||
}
|
||||
|
||||
#controls-bar {
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
align-items: center;
|
||||
gap: 53px;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.mobile-app-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wde-mobile-button {
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 95px;
|
||||
height: 35px;
|
||||
padding-right: 5px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=mobile.css.map */
|
1
front/dist/mobile.css.map
vendored
1
front/dist/mobile.css.map
vendored
@ -1 +0,0 @@
|
||||
{"mappings":"ACAA;;;;AAAA;;;;ACGA;;;;;;;;;AAWA;;;;;AAaA;;;;;;;;;;;AAYA;;;;;;;;AAaA;;;;;ACnCA;;;;;AAKA;;;;;AAKA;;;;;;AAMA;;;;ACjCA;;;;AAIA;;;;AAMA;;;;AAAA;;;;AAUA;;;;AAAA;;;;AAWA;;;;;AC5BA;;;;;;;;;AACI;;;;;ALCJ;;;;;AAKA;;;;;;;;;;;;;;;;AAwCA;;;;;;;;;;AAaA;;;;;;;;;;;;AAiBA;;;;;AAOA","sources":["src/mobile.less","src/wde/primitives.less","src/wde/sunboard/sunboard-mobile.less","src/theme.less","src/wde/effects.less","src/wde/widgets/button/button.less"],"sourcesContent":["@import \"./wde/sunboard/sunboard-mobile.less\";\n@import \"./theme.less\";\n@import \"./wde/effects.less\";\n@import \"./wde/widgets/button/button.less\";\n\n@font-face{\n font-family: \"Geneva\";\n src:url(\"./fonts/Geneva.woff2\");\n} \n\nbody{\n &:extend(.views-font);\n // zoom: 2;\n position: absolute;\n width: 100%;\n height: 100%;\n margin: 0px;\n\n\n font-size: 12px;\n\n /* font: normal 14px Summer Pixel 22, \"res/SummerPixel22Regular.ttf\"; */\n -webkit-touch-callout: none; /* iOS Safari */\n -webkit-user-select: none; /* Safari */\n -khtml-user-select: none; /* Konqueror HTML */\n -moz-user-select: none; /* Old versions of Firefox */\n -ms-user-select: none; /* Internet Explorer/Edge */\n user-select: none; /* Non-prefixed version, currently\n supported by Chrome, Edge, Opera and Firefox */\n touch-action: manipulation;\n\n background-color: @col-argent;\n // /* Auto layout */\n // display: flex;\n // flex-direction: column;\n // align-items: flex-start;\n // justify-content: flex-start;\n // margin: 32px;\n\n // background-image:\n // linear-gradient(45deg, @col-argent 25%, transparent 25%),\n // linear-gradient(45deg, transparent 75%, @col-argent 75%),\n // linear-gradient(45deg, transparent 75%, @col-argent 75%),\n // linear-gradient(45deg, @col-argent 25%, #777777 25%); \n\n background-size:10px 10px; \n\n background-position:0 0, 0 0, -5px -5px, 5px 5px;\n}\n\n#mobile-app-views{\n position: absolute;\n // background-color: aqua;\n inset: 16px;\n bottom: 100px;\n \n border-radius: 5px;\n border: @eff-border-black;\n box-shadow: @eff-box-shadow-black;\n background: @col-gainsboro;\n overflow: hidden;\n}\n\n#controls-bar{\n position: absolute;\n\n width: 100%;\n height: 100px;\n // background-color: @col-argent;\n bottom: 0px;\n\n /* Auto layout */\n display: flex;\n // padding: 10px;\n justify-content: center;\n align-items: center;\n gap: 53px;\n align-self: stretch;\n}\n\n.mobile-app-view{\n // background-color: burlywood;\n width: 100%;\n height: 100%;\n // position: absolute;\n}\n\n.wde-mobile-button{\n &:extend(.wde-button);\n &:active{\n &:extend(.wde-button:active);\n }\n height: 35px;\n width: 95px;\n /* Auto layout */\n display: flex;\n // padding: 10px;\n flex-direction: row;\n justify-content: center;\n align-items: center;\n padding-right: 5px;\n // gap: 53px;\n // align-self: stretch;\n}\n\n.wde-mobile-button > .icon{\n \n // width: 8rem;\n // height: 8rem;\n}",null,null,null,null,null],"names":[],"version":3,"file":"mobile.css.map","sourceRoot":"/__parcel_source_root/"}
|
5873
front/package-lock.json
generated
5873
front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@parcel/transformer-less": "^2.9.3",
|
||||
"parcel": "^2.9.3"
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import WDEApplication from "../../wde/application.js"
|
||||
import AbstractWebDesktopEnvironment from "../../wde/wde.js"
|
||||
export default class AboutMe extends WDEApplication{
|
||||
/**
|
||||
* @constructor
|
||||
* @param {AbstractWebDesktopEnvironment} wde
|
||||
*/
|
||||
constructor(wde, appManifest){
|
||||
super(wde, "AboutMe", appManifest)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[]string} args
|
||||
* @param {Object} runContext
|
||||
*/
|
||||
async NewWindow(args, runContext){
|
||||
let html = await this.#renderView(runContext)
|
||||
|
||||
let newWindow = this.WDE().Decorat.CreateNewWindow(this.AppId, 360, document.body.clientHeight*0.8)
|
||||
// console.log(html)
|
||||
// return
|
||||
newWindow.innerHTML = html
|
||||
newWindow.style.height = 'auto'
|
||||
|
||||
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', () => {
|
||||
super.WDE().CloseWindow(newWindow)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
* @param {import("../../wde/wde.js").runContext} runContext
|
||||
*/
|
||||
async NewView(args, runContext){
|
||||
let html = await this.#renderView(runContext)
|
||||
let newView = super.WDE().Decorat.CreateNewView(this.AppId)
|
||||
newView.innerHTML = html
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../wde/wde.js").runContext} runContext
|
||||
* @returns
|
||||
*/
|
||||
async #renderView(runContext){
|
||||
const params = new URLSearchParams({
|
||||
path: `:/aboutme.props`,
|
||||
})
|
||||
const response = await fetch(`/app/${this.AppId}/render?`+ params,{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
// super.WDE().Alert("Error TODO") //TODO
|
||||
return
|
||||
}
|
||||
const html = await response.text() //Validate
|
||||
return html
|
||||
}
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
@import "../../theme.less";
|
||||
|
||||
.PersPropsContent{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.PersPropsContent .PropsView{
|
||||
/* background-color: rebeccapurple; */
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.PropertiesList{
|
||||
/* width: 100%;
|
||||
height: auto; */
|
||||
|
||||
/* Inside auto layout */
|
||||
order: 0;
|
||||
align-self: flex-start;
|
||||
flex-grow: 0;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 12px;
|
||||
gap:16px;
|
||||
}
|
||||
|
||||
|
||||
.PropertiesList .ShortBio{
|
||||
/* width: 100%;
|
||||
height: auto; */
|
||||
/* margin-right: -20px; */
|
||||
|
||||
// background-color: aquamarine;
|
||||
/* Inside auto layout */
|
||||
width: 100%;
|
||||
// flex: none;
|
||||
// order: 0;
|
||||
// align-self: stretch;
|
||||
// flex-grow: 1;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
// padding: 0px;
|
||||
// margin-right: 20;
|
||||
gap:15px;
|
||||
}
|
||||
|
||||
.ShortBio .Image{
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.ShortBio .Text{
|
||||
/* width: 100%;
|
||||
height: auto; */
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
flex-grow: 1;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: left;
|
||||
padding: 0px;
|
||||
gap:1px;
|
||||
}
|
||||
|
||||
.ShortBio > .Text > .Name{
|
||||
&:extend(.large-system-font);
|
||||
// background-color: aqua;
|
||||
}
|
||||
|
||||
.PropertiesList .Links {
|
||||
// position: absolute;
|
||||
// right: 14px;
|
||||
// top: 27px;
|
||||
// background-color: aqua;
|
||||
height: auto;
|
||||
width: auto;
|
||||
|
||||
// background-color: aqua;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
padding: 0px;
|
||||
// gap:4px;
|
||||
}
|
||||
.Links > a{
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: end;
|
||||
justify-content: center;
|
||||
padding: 0px;
|
||||
gap: 2px;
|
||||
}
|
||||
.Links > a > .link-lable{
|
||||
// background-color: aqua;
|
||||
// line-height: 60px;
|
||||
// display:table
|
||||
}
|
||||
|
||||
.PropertiesList .Links .Link {
|
||||
/* background-color:brown; */
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.PropertiesList .Island{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border: 1px solid #888888;
|
||||
box-shadow: 1px 1px 0px #FFFFFF, inset 1px 1px 0px #FFFFFF;
|
||||
padding-bottom: 10px;
|
||||
|
||||
/* Auto layout */
|
||||
/* display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0px;
|
||||
gap:1px; */
|
||||
}
|
||||
|
||||
.Island .Title {
|
||||
//FIXME
|
||||
&:extend(.large-system-font);
|
||||
position:relative;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
background-color: #DDDDDD;
|
||||
left: 12px;
|
||||
top: -9px;
|
||||
}
|
||||
|
||||
.Island .Content{
|
||||
width: 100%;
|
||||
/* top: 0px; */
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 0px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.Island .Row{
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
padding: 0px;
|
||||
gap: 5px;
|
||||
}
|
||||
.Island .Key{
|
||||
position: relative;
|
||||
&:extend(.large-system-font);
|
||||
// font-family: "Virtue";
|
||||
// font-size: 11px;
|
||||
// letter-spacing: 0.35px;
|
||||
text-align: end;
|
||||
width: 34%;
|
||||
white-space: nowrap;
|
||||
top: -1.5px;
|
||||
|
||||
/* font-weight: bold; */
|
||||
}
|
||||
|
||||
.Island .KeyComment{
|
||||
/* color: rgb(129, 129, 129); TODO*/
|
||||
color: #646464;
|
||||
font-size: 9px;
|
||||
font-style: italic;
|
||||
text-align: end;
|
||||
white-space:normal;
|
||||
/* filter: drop-shadow(-.5px -.5px 0px #616161); */
|
||||
}
|
||||
|
||||
.Island .Values{
|
||||
width: 55%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: left;
|
||||
padding: 0px;
|
||||
gap: 5px;
|
||||
|
||||
}
|
||||
|
||||
.Values .Value{
|
||||
/* width: 55%; */
|
||||
|
||||
}
|
@ -1,380 +0,0 @@
|
||||
import AbstractWebDesktopEnvironment from "../../wde/wde.js"
|
||||
import Finder from "./finder.js"
|
||||
|
||||
|
||||
export default class FinderWindow{
|
||||
#appId = "Finder" //FIXME
|
||||
curPath = ""
|
||||
fileView = undefined
|
||||
windowElem = undefined
|
||||
/** @type {Finder} */
|
||||
#finder
|
||||
/**
|
||||
* @deprecated move to this.#finder.WDE()
|
||||
* @type {AbstractWebDesktopEnvironment}
|
||||
*/
|
||||
#wde
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Finder}
|
||||
* @param {AbstractWebDesktopEnvironment} wde
|
||||
*/
|
||||
constructor(finder, wde){
|
||||
this.#finder = finder
|
||||
this.#wde = wde
|
||||
}
|
||||
/**
|
||||
* @param {Finder} finder
|
||||
* @param {*} args
|
||||
* @param {import("../../wde/wde.js").runContext} runContext
|
||||
* @returns
|
||||
*/
|
||||
async Init(finder, args, runContext){
|
||||
// console.log(args)
|
||||
this.#finder = finder
|
||||
if (runContext.isMobile){
|
||||
console.log("Mobile Finder!")
|
||||
this.CreateMobileView(args, runContext)
|
||||
return
|
||||
}
|
||||
if (args[1] == "--desktop"){
|
||||
let desktopNode = document.body.querySelector(`#${args[2]}`)
|
||||
if (desktopNode == null){
|
||||
this.#wde.Alert("Desktop node not found")
|
||||
return
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
path: args[0]
|
||||
})
|
||||
const response = await fetch(`/app/${this.#appId}/renderDesktop?` + params,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
console.log(response.status)
|
||||
// this.#wde.Alert("Error in render desktop") //TODO
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
desktopNode.innerHTML = html
|
||||
|
||||
// console.log(this.#wde)
|
||||
|
||||
this.fileView = new this.#wde.FileView(
|
||||
desktopNode.querySelector(".FileTileView"), (event) =>{this.Click(event)},
|
||||
(event) => { this.RightClick(event) },
|
||||
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||
() => { this.ReRenderDir() },
|
||||
this.#wde)
|
||||
this.RenderDir(args[0])
|
||||
return
|
||||
}
|
||||
const params = new URLSearchParams({isMobile: false}) //FIXME
|
||||
const response = await fetch(`/app/${this.#appId}/render?` + params,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
const error = await response.json()
|
||||
this.#wde.Alert(error.message)
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
|
||||
let newWindow = this.#wde.Decorat.CreateNewWindow(this.#appId, 500, 350 )
|
||||
newWindow.innerHTML = html
|
||||
//TODO change icons for every folder
|
||||
// newWindow.querySelector(".title-bar").querySelector(".icon").setAttribute("src","/system/libs/img/icon/get?path=/Icons/GenericFolder.icn&size=16")
|
||||
|
||||
// console.log(newWindow.querySelector(".FileTileView"))
|
||||
|
||||
this.fileView = new this.#wde.FileView(
|
||||
newWindow.querySelector(".FileTileView"),
|
||||
(event) => { this.Click(event) },
|
||||
(event) => { this.RightClick(event) },
|
||||
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||
() => { this.ReRenderDir() },
|
||||
this.#wde)
|
||||
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', () => {
|
||||
this.#wde.Decorat.CloseWindow(newWindow)
|
||||
})
|
||||
|
||||
// newWindow.querySelector("#RootButton").addEventListener('click', () =>{
|
||||
// this.RenderDir('/')
|
||||
// })
|
||||
|
||||
// newWindow.querySelector("#HomeButton").addEventListener('click', () =>{
|
||||
// this.RenderDir('/home/user')
|
||||
// })
|
||||
|
||||
// let scrollBar = new this.#wde.ScrollBar(newWindow.querySelector(".scrollbar-place"), newWindow.querySelector(".FileTileView"))
|
||||
|
||||
this.windowElem = newWindow
|
||||
this.RenderDir(args[0])
|
||||
}
|
||||
|
||||
CreateDesktopWindow(){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} args
|
||||
* @param {import("../../wde/wde-desktop.js").runContext} runContext
|
||||
* @returns
|
||||
*/
|
||||
async CreateMobileView(args, runContext){
|
||||
const params = new URLSearchParams({isMobile: false}) //FIXME
|
||||
const response = await fetch(`/app/${this.#appId}/render?` + params,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
const error = await response.json()
|
||||
this.#finder.WDE().Alert(error.message)
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
// console.log(html)
|
||||
// console.log(this.#finder.WDE())
|
||||
let newView = this.#finder.WDE().Decorat.CreateNewView(this.#appId)
|
||||
newView.innerHTML = html
|
||||
|
||||
this.fileView = new this.#wde.FileView(
|
||||
newView.querySelector(".FileTileView"),
|
||||
(event) => { this.Click(event) },
|
||||
(event) => { this.RightClick(event) },
|
||||
(event, draggedElem) => { this.DropEvent(event, draggedElem)},
|
||||
() => { this.ReRenderDir() },
|
||||
this.#wde)
|
||||
|
||||
// newView.querySelector("#closeWindowButton").addEventListener('click', () => {
|
||||
// this.#wde.Decorat.CloseWindow(newView)
|
||||
// })
|
||||
|
||||
// newView.querySelector("#RootButton").addEventListener('click', () =>{
|
||||
// this.RenderDir('/')
|
||||
// })
|
||||
|
||||
// newView.querySelector("#HomeButton").addEventListener('click', () =>{
|
||||
// this.RenderDir('/home/user')
|
||||
// })
|
||||
|
||||
// let scrollBar = new this.#wde.ScrollBar(newView.querySelector(".scrollbar-place"), newView.querySelector(".FileTileView"))
|
||||
|
||||
this.windowElem = newView
|
||||
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 this.#finder.WDE().WebFS().MoveFile(sourcePath, targetPath)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
} else {
|
||||
this.#wde.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 this.#finder.WDE().WebFS().UploadFile(file, this.curPath)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
this.#wde.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} fileName
|
||||
*/
|
||||
getFileExtension(fileName){
|
||||
return fileName.split(".")[fileName.split(".").length - 1] //FIXME
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 = this.getFileExtension(fileName)
|
||||
console.log(fileExtension)
|
||||
switch (true) {
|
||||
case fileType == "objectlink":
|
||||
this.#finder.WDE().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":
|
||||
this.#finder.WDE().Open(`${parentPath}/${fileName}`, [])
|
||||
break
|
||||
case fileExtension == "blog":
|
||||
this.#finder.WDE().Open(`/Applications/BlogViewer.app`, [`${parentPath}/${fileName}`])
|
||||
break
|
||||
case fileType == "directory":
|
||||
this.#finder.WDE().Open(`/Applications/Finder.app`, [`${parentPath}/${fileName}`])
|
||||
break
|
||||
case fileExtension == "blog":
|
||||
this.#finder.WDE().Open("/Applications/BlogViewer.app", [`${parentPath}/${fileName}`])
|
||||
break
|
||||
case fileExtension == "jpeg" | fileExtension == "png":
|
||||
this.#finder.WDE().Open("img-viewer", [`${parentPath}/${fileName}`])
|
||||
break;
|
||||
default:
|
||||
this.#finder.WDE().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/${this.#appId}/contextMenu?` + params)
|
||||
if (response.status != 200){
|
||||
this.#wde.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 this.#finder.WDE().WebFS().CreatePathLink(`${this.curPath}/${fileName}`, `${this.curPath}/Link to ${fileName}` )
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
break
|
||||
case "createDir":
|
||||
res = await this.#finder.WDE().WebFS().CreateDirectory(`${this.curPath}`)
|
||||
// console.log(res)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
break
|
||||
case "deleteFile":
|
||||
res = await this.#finder.WDE().WebFS().DeleteFile(`${this.curPath}/${fileName}`)
|
||||
// console.log(res)
|
||||
if (res){
|
||||
this.ReRenderDir()
|
||||
}
|
||||
break
|
||||
case "getInfo":
|
||||
this.#finder.RenderProperites(path)
|
||||
break
|
||||
case "openAsDir":
|
||||
this.#finder.WDE().Open(`/Applications/${this.#appId}.app`,[`${this.curPath}/${fileName}`])
|
||||
break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
overlay.remove()
|
||||
})
|
||||
overlay.addEventListener('contextmenu', (event) => {
|
||||
event.preventDefault();
|
||||
overlay.remove()
|
||||
})
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// require("./finder.less")
|
||||
|
||||
import WDEApplication from "../../wde/application.js"
|
||||
import AbstractWebDesktopEnvironment from "../../wde/wde.js"
|
||||
import FinderWindow from "./finder-window.js"
|
||||
|
||||
export default class Finder extends WDEApplication{
|
||||
/** @deprecated */
|
||||
static AppId = "Finder"
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {AbstractWebDesktopEnvironment} wde
|
||||
*/
|
||||
constructor(wde){
|
||||
super(wde, "Finder")
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
* @param {import("../../wde/wde.js").runContext} runContext
|
||||
*/
|
||||
async NewWindow(args, runContext){
|
||||
let newFinder = new FinderWindow(this, super.WDE())
|
||||
await newFinder.Init(this, args, runContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
* @param {import("../../wde/wde.js").runContext} runContext
|
||||
*/
|
||||
async NewView(args, runContext){
|
||||
let newFinderView = new FinderWindow(this, super.WDE())
|
||||
await newFinderView.Init(this, args, runContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
async RenderProperites(path){
|
||||
if (path == null || path ==""){
|
||||
return
|
||||
}
|
||||
const params = new URLSearchParams({
|
||||
path: path
|
||||
})
|
||||
|
||||
const response = await fetch(`/app/${this.AppId}/renderProps?` + params)
|
||||
if (response.status != 200){
|
||||
this.WDE().Alert("Error in render properties widget") //TODO
|
||||
return false
|
||||
}
|
||||
const html = await response.text()
|
||||
|
||||
let newWindow = this.WDE().Decorat.CreateNewWindow(this.AppId, 350, 500 )
|
||||
newWindow.innerHTML = html
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', () => {
|
||||
// console.log(this.WDE().Decorat())
|
||||
this.WDE().Decorat.CloseWindow(newWindow)
|
||||
})
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
@import "../../theme.less";
|
||||
@import "../../wde/effects.less";
|
||||
|
||||
.finder-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
align-items: flex-start;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.finder-content > .tool-bar{
|
||||
width: 100%;
|
||||
min-height: 20px;
|
||||
border-bottom: @eff-border-grey;
|
||||
}
|
||||
|
||||
.window-frame.Focused .tool-bar{
|
||||
border-bottom: 1px solid #000000;
|
||||
box-shadow: @eff-box-shadow-convex;
|
||||
}
|
||||
|
||||
.finder-content > .file-view-container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// background-color: #FFFFFF;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 0px;
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
@import "./wde/primitives.less";
|
||||
@import "./wde/widgets/file-view/file-view.less";
|
||||
@import "./wde/widgets/scrollbar/scrollbar.less";
|
||||
@import "./wde/widgets/button/button.less";
|
||||
// @import "./wde/legacy-ui.less";
|
||||
@import "./wde/widgets/basic-widgets.less";
|
||||
@import "./theme.less";
|
||||
@import "./wde/window-frame.less";
|
||||
@import "./wde/widgets/title-bar/title-bar.less";
|
||||
|
||||
.NoClick {
|
||||
pointer-events: none;
|
||||
}
|
||||
.Click {
|
||||
pointer-events: all;
|
||||
}
|
||||
// .DragArea
|
||||
|
||||
// *{
|
||||
// font-family: Verdana, Geneva, sans-serif;
|
||||
// font-size: 11px;
|
||||
// font-style: normal;
|
||||
// font-weight:initial;
|
||||
// }
|
||||
|
||||
*::-webkit-scrollbar { /* WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
body{
|
||||
&:extend(.views-font);
|
||||
// zoom: var(--zoom);
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
|
||||
font-size: 11px;
|
||||
|
||||
// font-family: "Geneva";
|
||||
src:url("./fonts/Geneva.woff2");
|
||||
|
||||
/* font: normal 14px Summer Pixel 22, "res/SummerPixel22Regular.ttf"; */
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Old versions of Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
#applications{
|
||||
position: static;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#windows-layer {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
/* position: fixed; */
|
||||
position: static;
|
||||
}
|
||||
|
||||
#desktop-layer{
|
||||
position: fixed;
|
||||
/* margin: 0px; */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: @col-ceil;
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -1,110 +0,0 @@
|
||||
@import "./wde/sunboard/sunboard-mobile.less";
|
||||
@import "./theme.less";
|
||||
@import "./wde/effects.less";
|
||||
@import "./wde/widgets/button/button.less";
|
||||
|
||||
@font-face{
|
||||
font-family: "Geneva";
|
||||
src:url("./fonts/Geneva.woff2");
|
||||
}
|
||||
|
||||
body{
|
||||
&:extend(.views-font);
|
||||
// zoom: 2;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
|
||||
|
||||
font-size: 12px;
|
||||
|
||||
/* font: normal 14px Summer Pixel 22, "res/SummerPixel22Regular.ttf"; */
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Old versions of Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
touch-action: manipulation;
|
||||
|
||||
background-color: @col-argent;
|
||||
// /* Auto layout */
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: flex-start;
|
||||
// justify-content: flex-start;
|
||||
// margin: 32px;
|
||||
|
||||
// background-image:
|
||||
// linear-gradient(45deg, @col-argent 25%, transparent 25%),
|
||||
// linear-gradient(45deg, transparent 75%, @col-argent 75%),
|
||||
// linear-gradient(45deg, transparent 75%, @col-argent 75%),
|
||||
// linear-gradient(45deg, @col-argent 25%, #777777 25%);
|
||||
|
||||
background-size:10px 10px;
|
||||
|
||||
background-position:0 0, 0 0, -5px -5px, 5px 5px;
|
||||
}
|
||||
|
||||
#mobile-app-views{
|
||||
position: absolute;
|
||||
// background-color: aqua;
|
||||
inset: 16px;
|
||||
bottom: 100px;
|
||||
|
||||
border-radius: 5px;
|
||||
border: @eff-border-black;
|
||||
box-shadow: @eff-box-shadow-black;
|
||||
background: @col-gainsboro;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#controls-bar{
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
// background-color: @col-argent;
|
||||
bottom: 0px;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
// padding: 10px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 53px;
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.mobile-app-view{
|
||||
// background-color: burlywood;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// position: absolute;
|
||||
}
|
||||
|
||||
.wde-mobile-button{
|
||||
&:extend(.wde-button);
|
||||
&:active{
|
||||
&:extend(.wde-button:active);
|
||||
}
|
||||
height: 35px;
|
||||
width: 95px;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
// padding: 10px;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-right: 5px;
|
||||
// gap: 53px;
|
||||
// align-self: stretch;
|
||||
}
|
||||
|
||||
.wde-mobile-button > .icon{
|
||||
|
||||
// width: 8rem;
|
||||
// height: 8rem;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
@col-ceil: #9999CC;
|
||||
|
||||
@col-argent: #C0C0C0;
|
||||
@col-chinese-silver: #CCCCCC;
|
||||
@col-gainsboro: #DDDDDD;
|
||||
|
||||
@col-bright-grey: #EEEEEE;
|
||||
@col-davys-grey: #555555;
|
||||
@col-granite-gray: #666666;
|
||||
@col-grey: #808080;
|
||||
|
||||
@col-black: #000000;
|
||||
@col-white: #FFFFFF;
|
||||
@col-raisin-black: #222222;
|
||||
|
||||
|
||||
|
||||
@font-face{
|
||||
font-family: "Geneva";
|
||||
src:url("./fonts/Geneva.woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Charcoal";
|
||||
src: url('./fonts/Charcoal.woff2');
|
||||
}
|
||||
|
||||
.large-system-font{
|
||||
font-family: "Charcoal";
|
||||
// font-weight: bold;
|
||||
letter-spacing: 0.35px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.small-system-font{
|
||||
font-family: "Geneva";
|
||||
}
|
||||
.views-font{
|
||||
font-family: "Geneva";
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import AbstractWebDesktopEnvironment from "./wde.js"
|
||||
|
||||
export default class WDEApplication{
|
||||
/** @type {AbstractWebDesktopEnvironment} */
|
||||
#wde
|
||||
/** @type {string} */
|
||||
AppId
|
||||
//TODO types
|
||||
AppManifest
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {AbstractWebDesktopEnvironment} wde
|
||||
*/
|
||||
constructor(wde, AppId, manifest){
|
||||
this.#wde = wde //TODO: Vaidate
|
||||
// console.log(wde)
|
||||
this.AppId = AppId //TODO: Validate
|
||||
this.AppManifest = manifest
|
||||
}
|
||||
|
||||
/** @returns {AbstractWebDesktopEnvironment} */
|
||||
WDE(){
|
||||
return this.#wde
|
||||
}
|
||||
|
||||
async NewWindow(){
|
||||
|
||||
}
|
||||
|
||||
/** @returns {Element} */
|
||||
async NewView(){
|
||||
return this.#wde.Decorat.CreateNewView(this.AppId)
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
export default class DesktopDecorat{
|
||||
/** @type {Element} */
|
||||
#windowsLayer
|
||||
|
||||
constructor(){
|
||||
this.#windowsLayer = document.body.querySelector('#windows-layer') //TODO Validate if null
|
||||
|
||||
let startDrag = (event) => {
|
||||
let window = event.target.closest('.window-frame')
|
||||
this.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)
|
||||
}
|
||||
}
|
||||
this.#windowsLayer.addEventListener('mousedown', startDrag)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} window
|
||||
*/
|
||||
bringWindowToFront(window){ //FIXME
|
||||
let previousWindow = this.#windowsLayer.lastChild
|
||||
if (window == null || window == undefined){
|
||||
return
|
||||
}
|
||||
if (window != previousWindow){
|
||||
this.#windowsLayer.insertBefore(window, previousWindow.nextSibling)
|
||||
previousWindow.classList.remove("Focused")
|
||||
window.classList.add("Focused")
|
||||
} else {
|
||||
window.classList.add("Focused")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} appId
|
||||
* @param {number} width
|
||||
* @param {number} height
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
CreateNewWindow(appId, width, height) {
|
||||
let newWindow = document.createElement("div")
|
||||
newWindow.setAttribute('appid', appId)
|
||||
|
||||
// newWindow.setAttribute("class", "WindowFrame ConvexElement")
|
||||
newWindow.setAttribute("class", "window-frame")
|
||||
newWindow.setAttribute("windowId", this.#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
|
||||
*/
|
||||
CloseWindow(window) {
|
||||
window.remove()
|
||||
}
|
||||
|
||||
CloseFocusedWindow() {
|
||||
if (document.body.querySelector('#windows-layer').childElementCount > 1){
|
||||
document.body.querySelector('#windows-layer').lastElementChild.remove()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static ChangeURL(appWindow){
|
||||
let appId = appWindow.getAttribute('appid')
|
||||
window.history.replaceState(null, "", `/${appId}/`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {num} length
|
||||
*/
|
||||
#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;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
export default class MobileDecorat {
|
||||
/** @type {Element} */
|
||||
#applicationsNode
|
||||
constructor(){
|
||||
this.#applicationsNode = document.body.querySelector("#mobile-app-views") //TODO validate
|
||||
this.#loadControlsBar()
|
||||
}
|
||||
|
||||
#loadControlsBar(){
|
||||
let bar = document.body.querySelector("#controls-bar") //TODO Validate
|
||||
console.log(bar)
|
||||
bar.querySelector("#back").addEventListener('click', () => {
|
||||
this.BackAction()
|
||||
})
|
||||
}
|
||||
/**
|
||||
* @param {string} appId
|
||||
* @returns {Element}
|
||||
*/
|
||||
CreateNewView(appId){
|
||||
let newView = document.createElement("div")
|
||||
newView.setAttribute("class", "mobile-app-view")
|
||||
newView.setAttribute("appId", appId)
|
||||
// this.#applicationsNode.appendChild(newView)
|
||||
this.#applicationsNode.insertBefore(newView, this.#applicationsNode.firstChild)
|
||||
return newView
|
||||
}
|
||||
|
||||
Open(){
|
||||
|
||||
}
|
||||
BackAction(){
|
||||
console.log(this.#applicationsNode.childNodes.length)
|
||||
if (this.#applicationsNode.childNodes.length <= 1) return
|
||||
this.#applicationsNode.firstChild.remove()
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
.adjective{
|
||||
border: 1px solid #555555;
|
||||
}
|
||||
|
||||
.convex{
|
||||
box-shadow: 1px 1px 0px rgba(0, 0, 0, 0.25),
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27),
|
||||
inset 1px 1px 0px #FFFFFF;
|
||||
}
|
||||
|
||||
.border{
|
||||
.grey{
|
||||
border: 1px solid @col-davys-grey;
|
||||
}
|
||||
.black{
|
||||
border: 1px solid @col-black;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.shadow{ //FIXME: shadow must be 2px offset from windows borders
|
||||
.grey{
|
||||
box-shadow: 1px 1px 0px @col-davys-grey;
|
||||
}
|
||||
.black{
|
||||
box-shadow: 1px 1px 0px @col-black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.rows-fill-shadowed{
|
||||
background: linear-gradient(transparent 0%, white 0%, white 50%, transparent 50%);
|
||||
background-size: 2px 2px;
|
||||
filter: drop-shadow(1px 1px 0px #777777);
|
||||
}
|
||||
@eff-border-black: 1px solid @col-black;
|
||||
@eff-border-grey: 1px solid @col-davys-grey;
|
||||
|
||||
@eff-box-shadow-grey: 1px 1px 0px @col-davys-grey;
|
||||
@eff-box-shadow-black: 1px 1px 0px @col-black;
|
||||
|
||||
@eff-box-shadow-convex: inset -1px -1px 0px rgba(0, 0, 0, 0.27),inset 1px 1px 0px @col-white;
|
||||
@eff-box-shadow-convex-inverted: inset 1px 1px 0px rgba(0, 0, 0, 0.27),inset -1px -1px 0px @col-grey;
|
||||
@eff-box-shadow-adjective: -1px -1px 0px rgba(0, 0, 0, 0.25), 1px 1px 0px #FFFFFF;
|
@ -1,232 +0,0 @@
|
||||
// .WindowFrame {
|
||||
// /* Auto layout */
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
// align-items: flex-start;
|
||||
// padding: 4px;
|
||||
// padding-top: 2px;
|
||||
// padding-right: 6px;
|
||||
// gap: 4px;
|
||||
|
||||
// position: absolute;
|
||||
|
||||
// background: #DDDDDD;
|
||||
// border: 1px solid #555555;
|
||||
|
||||
|
||||
// /* Inside auto layout */
|
||||
// flex: none;
|
||||
// order: 1;
|
||||
// align-self: stretch;
|
||||
// flex-grow: 1;
|
||||
// }
|
||||
|
||||
/* TODO Add shadows to windows */
|
||||
.WindowFrame.Focused{
|
||||
border: 1px solid #000000;
|
||||
background-color: #CCCCCC;
|
||||
}
|
||||
|
||||
.WindowFrameShadow {
|
||||
box-shadow: 2px 2px 0px #555555;
|
||||
}
|
||||
|
||||
/* FIXME Not work on context menu */
|
||||
.WindowFrameShadow.Focused {
|
||||
box-shadow: 2px 2px 0px #000000;
|
||||
}
|
||||
|
||||
.ConvexElement.Focused {
|
||||
box-shadow: 1px 1px 0px rgba(0, 0, 0, 0.25),
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27),
|
||||
inset 1px 1px 0px #FFFFFF;
|
||||
}
|
||||
|
||||
.AdjectiveElement {
|
||||
border: 1px solid #555555;
|
||||
}
|
||||
|
||||
.Focused .AdjectiveElement {
|
||||
border: 1px solid #000000;
|
||||
box-shadow: -1px -1px 0px rgba(0, 0, 0, 0.25),
|
||||
1px 1px 0px #FFFFFF;
|
||||
/* inset -1px -1px 0px rgba(0, 0, 0, 0.27), */
|
||||
/* inset 1px 1px 0px #FFFFFF;*/
|
||||
}
|
||||
|
||||
.AdjectiveHorizontalLine {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid #FFFFFF;
|
||||
width: 100%;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.AdjectiveHorizontalLine:last-child {
|
||||
height: 0%;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
.WindowFrame .TitleBar {
|
||||
width: 100%;
|
||||
height: 13px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
padding: 0px;
|
||||
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.WindowFrame .TitleBar .Lable {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
/* font-size: 13px; */
|
||||
color:#777777;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
|
||||
font-family: "Virtue";
|
||||
letter-spacing: 0.35px;
|
||||
}
|
||||
|
||||
.WindowFrame.Focused .TitleBar .Lable {
|
||||
color:#000000;
|
||||
}
|
||||
|
||||
|
||||
.WindowFrame .TitleBar .Button {
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
padding: 0%;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
visibility: hidden;
|
||||
|
||||
background: linear-gradient(135deg, #999999 18.18%, #FFFFFF 81.82%);
|
||||
border: 1px solid #222222;
|
||||
box-shadow: 0.5px 0.5px 0px 0.5px #FFFFFF,
|
||||
-0.5px -0.5px 0px 0.5px rgba(0, 0, 0, 0.25),
|
||||
inset 1px 1px 0px rgba(255, 255, 255, 0.5),
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27);
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.WindowFrame.Focused .TitleBar .Button {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.WindowFrame .TitleBar .Button:active {
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
/* Green */
|
||||
box-shadow: 0.5px 0.5px 0px 0.5px #FFFFFF,
|
||||
-0.5px -0.5px 0px 0.5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.Focused .VisualDragArea {
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 11px;
|
||||
background: linear-gradient(transparent 0%, white 0%, white 50%, transparent 50%);
|
||||
background-size: 2px 2px;
|
||||
filter: drop-shadow(1px 1px 0px #777777);
|
||||
}
|
||||
|
||||
.MobileContentBorder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #DDDDDD;
|
||||
/* border: 1px solid #000000; */
|
||||
|
||||
/* box-shadow: -1px -1px 0px rgba(0, 0, 0, 0.25),
|
||||
1px 1px 0px #FFFFFF,
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27),
|
||||
inset 1px 1px 0px #FFFFFF; */
|
||||
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.MobileApplicationWindow {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.MobileWindowFrameBottomBar {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
/*
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 5px;
|
||||
padding: 0px; */
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.MobileWindowFrameBottomBarButton {
|
||||
min-width: 11px;
|
||||
width: auto;
|
||||
height: 15px;
|
||||
padding: 0px 4px 0px 4px;
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
|
||||
background: linear-gradient(135deg, #999999 18.18%, #FFFFFF 81.82%);
|
||||
border: 1px solid #222222;
|
||||
box-shadow: 0.5px 0.5px 0px 0.5px #FFFFFF,
|
||||
-0.5px -0.5px 0px 0.5px rgba(0, 0, 0, 0.25),
|
||||
inset 1px 1px 0px rgba(255, 255, 255, 0.5),
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27);
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.MobileWindowFrameBottomBar .MobileLable {
|
||||
position: absolute;
|
||||
/* top:1px; */
|
||||
/* font-size: 13px; */
|
||||
left: 50%;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
|
||||
font-family: "Virtue";
|
||||
letter-spacing: 0.35px;
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
.WdePrimitives {
|
||||
|
||||
.adjective{
|
||||
border: 1px solid #555555;
|
||||
}
|
||||
|
||||
.black-border{
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import MobileWebDesktopEnvironment from "../wde-mobile.js"
|
||||
|
||||
export default class MobileDesktop{
|
||||
/**@type {Element} */
|
||||
#icons
|
||||
/** @type {MobileWebDesktopEnvironment} */
|
||||
#wde
|
||||
constructor(wde){
|
||||
this.#wde = wde
|
||||
this.load()
|
||||
}
|
||||
|
||||
async load(){
|
||||
let view = this.#createDesktopView()
|
||||
}
|
||||
|
||||
async #createDesktopView(){
|
||||
let view = this.#wde.Decorat.CreateNewView("Sunboard") //FIXME
|
||||
|
||||
const params = new URLSearchParams({
|
||||
// path: args[0] //FIXME
|
||||
path: "/" //FIXME
|
||||
})
|
||||
const response = await fetch(`/app/Sunboard/render?` + params,
|
||||
{
|
||||
method: "POST",
|
||||
// body: JSON.stringify(runContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
console.log(response.status)
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
view.innerHTML = html
|
||||
|
||||
let iconsList = view.querySelectorAll(".app-icon")
|
||||
iconsList.forEach(element => {
|
||||
let path = element.getAttribute('path') //TODO: Validate
|
||||
|
||||
element.addEventListener('click', () => {
|
||||
this.#wde.Open(path, ["/"], "") //FIXME
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
async createFileView(){
|
||||
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
@import "../../theme.less";
|
||||
@import "../primitives.less";
|
||||
|
||||
#mobile-sunboard{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#icons{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// background-color: @col-ceil;
|
||||
}
|
||||
|
||||
// #down-bar{
|
||||
// &:extend(.WdePrimitives.AdjectiveElement);
|
||||
// width: 100%;
|
||||
// height: 150px;
|
||||
// background-color: @col-argent;
|
||||
// }
|
||||
|
||||
.apps-list{
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
padding: 64px 16px;
|
||||
align-items: flex-start;
|
||||
align-content: flex-start;
|
||||
gap: 64px 0px;
|
||||
flex: 1 0 0;
|
||||
align-self: stretch;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.app-icon{
|
||||
// background-color: rgba(0, 255, 255, 0.133);
|
||||
width: 100px;
|
||||
// height: 100px;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
// padding: 4px 8px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.app-icon .icon{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
// background-color: beige;
|
||||
}
|
||||
|
||||
.app-icon .lable{
|
||||
|
||||
}
|
||||
|
@ -1,144 +0,0 @@
|
||||
import DesktopDecorat from "./decorat/desktop-decorat.js";
|
||||
import WDEScrollBar from "./widgets/scrollbar/scrollbar.js";
|
||||
import WebFS from "../web-fs/web-fs.js";
|
||||
import WDEApplication from "./application.js";
|
||||
import WDEFileView from "./widgets/file-view/file-view.js";
|
||||
import AbstractWebDesktopEnvironment from "./wde.js";
|
||||
|
||||
// import DesktopSunBoard from "./sunboard/sunboard-desktop.js";
|
||||
export default class WebDesktopEnvironment extends AbstractWebDesktopEnvironment{
|
||||
/** @type {string} */
|
||||
test = ""
|
||||
/** @type {WDEFileView} */
|
||||
FileView = WDEFileView
|
||||
/** @type {WDEScrollBar} */
|
||||
ScrollBar = WDEScrollBar
|
||||
/**@type {DesktopDecorat} */
|
||||
Decorat
|
||||
/** @type {Object<string, WDEApplication>} */
|
||||
static Applications = {};
|
||||
/** @deprecated */
|
||||
static isMobile = false
|
||||
// static decorat
|
||||
static webFs
|
||||
|
||||
/** @deprecated */
|
||||
basicWindow
|
||||
|
||||
constructor(){
|
||||
super("localhost:8080")
|
||||
super._SetWDE(this)
|
||||
document.body.style.setProperty('--zoom', 1)
|
||||
this.Decorat = new DesktopDecorat()
|
||||
|
||||
WebDesktopEnvironment.webFs = new WebFS()
|
||||
this.FileView = WDEFileView
|
||||
this.loadWDE()
|
||||
// this.#devLoadSunboard()
|
||||
}
|
||||
|
||||
async loadWDE(){
|
||||
await this.Open("/Applications/Finder.app", ["/home/user/.Desktop","--desktop", "desktop-layer"])
|
||||
await this.Open("/Applications/Finder.app", ["/", ""])
|
||||
// await this.Open("/Applications/AboutMe.app", [])
|
||||
return
|
||||
|
||||
let autoStart = document.body.querySelector("wde-autostart")
|
||||
if (autoStart == null){
|
||||
WebDesktopEnvironment.Alert("Error in loading DE: Autostart not presented")
|
||||
return
|
||||
}
|
||||
for (const child of autoStart.children) {
|
||||
if (child.nodeName != "APP") continue
|
||||
let appPath = child.getAttribute("app-path")
|
||||
if (appPath == null) continue
|
||||
|
||||
let args = []
|
||||
let argsRaw = child.querySelector("args")
|
||||
if (argsRaw == null) continue
|
||||
|
||||
for (const argRaw of argsRaw.children) {
|
||||
let arg = argRaw.getAttribute("string")
|
||||
if (arg == null) continue
|
||||
args.push(arg)
|
||||
}
|
||||
|
||||
// console.log(appPath, args)
|
||||
await this.Open(appPath, args)
|
||||
}
|
||||
autoStart.remove()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} appPath
|
||||
* @param {string[]} args
|
||||
* @param {string} runPath
|
||||
*/
|
||||
async Open(appPath, args, runPath){
|
||||
const runContext = {
|
||||
isMobile: false,
|
||||
bundlePath: appPath,
|
||||
runPath: runPath
|
||||
}
|
||||
|
||||
super._Open(appPath, args, runPath, (appManifest) =>{
|
||||
super._GetApp(appManifest.appId).NewWindow(args, runContext)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param {string} html
|
||||
*/
|
||||
static SetBasicWindow(html){
|
||||
this.basicWindow = html
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @returns {string}
|
||||
*/
|
||||
static GetBasicWindow(){
|
||||
return this.basicWindow
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} alertText
|
||||
*/
|
||||
Alert(alertText){
|
||||
this.#createAlertWindow(alertText)
|
||||
console.log(alertText)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} alertText
|
||||
*/
|
||||
#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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,55 +0,0 @@
|
||||
import MobileDecorat from "./decorat/mobile-decorat.js"
|
||||
import MobileSunboard from "./sunboard/sunboard-mobile.js"
|
||||
import AbstractWebDesktopEnvironment from "./wde.js"
|
||||
import WDEFileView from "./widgets/file-view/file-view.js"
|
||||
export default class MobileWebDesktopEnvironment extends AbstractWebDesktopEnvironment{
|
||||
/** @type {MobileDecorat} */
|
||||
Decorat
|
||||
/** @type {WDEFileView} */
|
||||
FileView
|
||||
/** @type {MobileSunboard} */
|
||||
#sunBoard
|
||||
constructor(){
|
||||
super()
|
||||
super._SetWDE(this)
|
||||
document.body.style.setProperty('--zoom', 3)
|
||||
this.Decorat = new MobileDecorat()
|
||||
this.FileView = WDEFileView
|
||||
this.#sunBoard = new MobileSunboard(this)
|
||||
// this.loadWDE()
|
||||
|
||||
document.addEventListener("touchstart", function(){}, true);//For working :active in css
|
||||
|
||||
}
|
||||
|
||||
loadWDE(){
|
||||
this.#initControlsBar()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} appPath
|
||||
* @param {string[]} args
|
||||
* @param {string} runPath
|
||||
*/
|
||||
async Open(appPath, args, runPath){
|
||||
const runContext = {
|
||||
isMobile: true,
|
||||
bundlePath: appPath,
|
||||
runPath: runPath
|
||||
}
|
||||
|
||||
super._Open(appPath, args, runPath, (appManifest) =>{
|
||||
// console.log(super._GetApp(appManifest.appId))
|
||||
super._GetApp(appManifest.appId).NewView(args, runContext)
|
||||
}, this)
|
||||
|
||||
}
|
||||
|
||||
#initControlsBar(){
|
||||
let barNode = document.body.querySelector("#controls-bar")//TODO Validate
|
||||
|
||||
barNode.querySelector("#back").addEventListener('click', () => {
|
||||
this.Decorat.BackAction()
|
||||
})
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
import WDEApplication from "./application.js"
|
||||
import WebFS from "../web-fs/web-fs.js"
|
||||
export default class AbstractWebDesktopEnvironment{
|
||||
/** @type {string} */
|
||||
#apiAddress
|
||||
/** @type {Object<string, WDEApplication>} */
|
||||
_applications = {}
|
||||
/** @type {AbstractWebDesktopEnvironment} */
|
||||
#wde
|
||||
/** @type {WebFS} */
|
||||
#webFS
|
||||
|
||||
/** @constructor */
|
||||
constructor(apiAddress){
|
||||
this.#apiAddress = apiAddress
|
||||
this.#webFS = WebFS
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @returns {string}
|
||||
*/
|
||||
GetApiAddress(){
|
||||
return `${location.protocol}//${this.#apiAddress}`
|
||||
}
|
||||
/** @type {AbstractWebDesktopEnvironment} */
|
||||
_SetWDE(wde){
|
||||
this.#wde = wde
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Object | undefined} //FIXME
|
||||
*/
|
||||
async _FetchAppManifest(path){
|
||||
console.log(path)
|
||||
// console.log(this.GetApiAddress())
|
||||
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) //FIXME
|
||||
return undefined
|
||||
}
|
||||
//TODO Validate manifest
|
||||
const appManifest = response.json()
|
||||
return appManifest
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} appPath
|
||||
* @param {runContext} runContext
|
||||
* @param {string} runPath
|
||||
* @param {function} callback
|
||||
*/
|
||||
async _Open(appPath, runContext, runPath, callback){
|
||||
const appManifest = await this._FetchAppManifest(appPath)
|
||||
|
||||
if (appManifest === undefined) return //TODO return err
|
||||
|
||||
if (this._applications[appManifest.appId] === undefined){
|
||||
this.#loadApp(appManifest, () => {
|
||||
callback(appManifest)
|
||||
})
|
||||
} else {
|
||||
callback(appManifest)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} appManifest
|
||||
* @param {function} onload callback after script loading
|
||||
*/
|
||||
async #loadApp(appManifest, onload){
|
||||
let newApp
|
||||
// console.log(appManifest)
|
||||
await import(appManifest.js[0]).then((app) => {newApp = app}) //FIXME
|
||||
let newAppClass = new newApp.default(this.#wde, appManifest)
|
||||
this._applications[appManifest.appId] = newAppClass
|
||||
|
||||
let cssFile = document.createElement( "link" );
|
||||
cssFile.rel = "stylesheet";
|
||||
cssFile.type = "text/css";
|
||||
cssFile.href = appManifest.css[0];
|
||||
document.head.appendChild( cssFile );
|
||||
|
||||
onload()
|
||||
return //TODO return result
|
||||
}
|
||||
|
||||
_GetApp(appId){
|
||||
// console.log(appId)
|
||||
return this._applications[appId]
|
||||
}
|
||||
|
||||
/** @returns {WebFS} */
|
||||
WebFS(){
|
||||
return this.#webFS
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} alertText
|
||||
*/
|
||||
Alert(alertText){}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} runContext
|
||||
* @property {boolean} isMobile
|
||||
* @property {string} appPath
|
||||
* @property {string} runPath //TODO
|
||||
*/
|
||||
|
||||
/** //TODO
|
||||
* @typedef {Object} appManifest
|
||||
*/
|
@ -1,60 +0,0 @@
|
||||
.ContentBorder { /*TODO Delete, deprecated*/
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* background-color: #DDDDDD;
|
||||
border: 1px solid #000000; */
|
||||
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ContextMenu {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
background-color: #DDDDDD;
|
||||
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
.ContextMenu .Content{
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
/* padding: 4px;
|
||||
padding-top: 2px;
|
||||
padding-right: 6px;
|
||||
gap: 4px; */
|
||||
}
|
||||
|
||||
.ContextMenu .Row {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
|
||||
}
|
||||
|
||||
.ContextMenu .SectionBreaker {
|
||||
|
||||
/* background-color: rebeccapurple; */
|
||||
|
||||
}
|
||||
|
||||
.ContextMenu .Row:hover{
|
||||
background-color: #333399;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.ContextMenu .Row .Lable{
|
||||
margin-left: 20px;
|
||||
margin-right: 12px;
|
||||
font-family: "Virtue";
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
@import "../../effects.less";
|
||||
@import "../../../theme.less";
|
||||
|
||||
.wde-button{
|
||||
&:active{
|
||||
background-color: @col-granite-gray;
|
||||
box-shadow: @eff-box-shadow-convex-inverted;
|
||||
// background-color: red;
|
||||
}
|
||||
background-color: @col-gainsboro;
|
||||
box-shadow: @eff-box-shadow-convex;
|
||||
border: @eff-border-black;
|
||||
border-radius: 3px;
|
||||
|
||||
|
||||
height: 20px;
|
||||
width: auto;
|
||||
|
||||
}
|
||||
|
||||
// .wde-button:active{
|
||||
// background-color: red;
|
||||
// }
|
||||
|
||||
// .wde-button:hover{
|
||||
// background-color: pink;
|
||||
// }
|
@ -1,138 +0,0 @@
|
||||
import AbstractWebDesktopEnvironment from "../../wde.js"
|
||||
|
||||
|
||||
export default class WDEFileView{
|
||||
path = ""
|
||||
parentElem = undefined
|
||||
selected = []
|
||||
/** @type {AbstractWebDesktopEnvironment} */
|
||||
#wde
|
||||
/**
|
||||
* @param {HTMLElement} fileViewElem
|
||||
* @param {Function} doubleClickCallback
|
||||
* @param {Function} rightClickCallback
|
||||
* @param {Function} updateFileViewCallback
|
||||
*/
|
||||
constructor(fileViewElem, doubleClickCallback, rightClickCallback, fileUploadCallback, updateFileViewCallback, wde){
|
||||
this.#wde = wde
|
||||
//TODO check all params
|
||||
this.parentElem = fileViewElem
|
||||
|
||||
fileViewElem.addEventListener('click', (event) => {
|
||||
if (event.target.classList[0] == 'file-view')
|
||||
{
|
||||
this.DeselectAll()
|
||||
return
|
||||
}
|
||||
if (event.detail === 1){
|
||||
this.DeselectAll()
|
||||
this.Select([event.target])
|
||||
} else if (event.detail === 2) {
|
||||
doubleClickCallback(event)
|
||||
}
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('contextmenu', (event) => {
|
||||
event.preventDefault();
|
||||
if (event.target.classList.contains("Tile")){
|
||||
this.DeselectAll()
|
||||
this.Select([event.target])
|
||||
}
|
||||
this.Select([event.target])
|
||||
rightClickCallback(event)
|
||||
})
|
||||
|
||||
if (fileUploadCallback !== undefined) {
|
||||
let counter = 0
|
||||
let draggedElem = undefined
|
||||
|
||||
fileViewElem.addEventListener('dragstart', (event) => {
|
||||
// console.log(event.target)
|
||||
// console.log(this.path)
|
||||
// draggedElem = event.target
|
||||
event.dataTransfer.setData("fileName", event.target.getAttribute("name"))
|
||||
event.dataTransfer.setData("filePath", this.path + "/" + event.target.getAttribute("name"))
|
||||
event.dataTransfer.setData("dropType", "move")
|
||||
// console.log(updateFileViewCallback)
|
||||
// event.dataTransfer.setData("updateCallback", updateFileViewCallback)
|
||||
// event.dataTransfer.setData("fileName", )
|
||||
// console.log(draggedElem)
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragenter', function(event) {
|
||||
event.preventDefault();
|
||||
counter++
|
||||
fileViewElem.classList.add("DragDropBorder")
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragend', function(event) {
|
||||
// console.log(fileViewElem)
|
||||
event.preventDefault();
|
||||
counter--
|
||||
if (counter === 0){
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
}
|
||||
// updateFileViewCallback()
|
||||
// draggedElem = undefined
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragleave', function(event) {
|
||||
// console.log(fileViewElem)
|
||||
event.preventDefault();
|
||||
counter--
|
||||
if (counter === 0){
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
}
|
||||
// draggedElem = undefined
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragover', function(event) {
|
||||
event.preventDefault();
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener("drop", (event) => {
|
||||
event.preventDefault();
|
||||
fileUploadCallback(event)
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
// updateFileViewCallback()
|
||||
// this.OpenFolder(this.path)
|
||||
// draggedElem = undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[]Element} elements
|
||||
*/
|
||||
Select(elements){
|
||||
elements.forEach(element => {
|
||||
this.selected.push(element)
|
||||
element.classList.add("Selected")
|
||||
});
|
||||
}
|
||||
|
||||
DeselectAll(){
|
||||
this.selected.forEach(element => {
|
||||
element.classList.remove("Selected")
|
||||
});
|
||||
this.selected = []
|
||||
}
|
||||
|
||||
/** Get html of folder by path
|
||||
* @param {string} path
|
||||
*/
|
||||
async OpenFolder(path){
|
||||
this.path = path
|
||||
const params = new URLSearchParams({
|
||||
path: path
|
||||
})
|
||||
const response = await fetch(`/system/wde/widgets/file-tile-view?` + params)
|
||||
if (response.status != 200){
|
||||
//TODO Error text message
|
||||
this.#wde.Alert("Error in render folder view") //TODO
|
||||
return
|
||||
}
|
||||
let html = await response.text()
|
||||
this.parentElem.innerHTML = html
|
||||
}
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
@import "../../../theme.less";
|
||||
.FileTileView{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// background-color: @col-white;
|
||||
|
||||
|
||||
|
||||
/* FIXME Bug, on desktop mode top ~10 pixel are not active, like margin:10px */
|
||||
}
|
||||
|
||||
.FileTileView.DragDropBorder{
|
||||
box-shadow: inset 0px 0px 0px 4px #9999CC;
|
||||
/* background-color: blue; */
|
||||
}
|
||||
|
||||
.FileTileView .FlexContainer{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
gap: 50px;
|
||||
row-gap: 20px;
|
||||
/* padding: 15px; Shit fix TODO: */
|
||||
margin: 15px;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
|
||||
/* overflow: scroll; */
|
||||
/* overflow-x: hidden; */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
}
|
||||
|
||||
.FileTileView::-webkit-scrollbar { /* WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.FileTileView .Tile{
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 2px;
|
||||
padding: 0px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.FileTileView .Selected{
|
||||
/* inherits: ; */
|
||||
/* background-color: black; */
|
||||
}
|
||||
|
||||
.FileTileView .Icon{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
/* background-image: url("./icons/folder.png"); */
|
||||
background-size: cover;
|
||||
|
||||
// image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
|
||||
// image-rendering: -moz-crisp-edges; /* Firefox */
|
||||
// image-rendering: -o-crisp-edges; /* Opera */
|
||||
// image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
|
||||
// image-rendering: pixelated; /* Universal support since 2021 */
|
||||
// image-rendering: optimize-contrast; /* CSS3 Proposed */
|
||||
// -ms-interpolation-mode: nearest-neighbor; /* IE8+ */
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Icon{
|
||||
filter: brightness(0.4);
|
||||
}
|
||||
|
||||
.FileTileView .Lable{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Lable{
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
export default class WdeScrollBar{
|
||||
/**
|
||||
* @param {HTMLElement} scrollBarContainer
|
||||
* @param {HTMLElement} content
|
||||
*/
|
||||
constructor(scrollBarContainer, content){
|
||||
let nonNativeScroll = false
|
||||
console.log(scrollBarContainer, content)
|
||||
// let handler = scrollBarContainer.children[0]
|
||||
//TODO On scroll move focus on window?
|
||||
let handler = scrollBarContainer.querySelector(".scroll-element") //TODO Refactor classes
|
||||
// console.log(handler)
|
||||
|
||||
handler.style.height = (content.clientHeight /content.scrollHeight)* handler.parentElement.clientHeight + 'px'
|
||||
|
||||
let max = handler.parentElement.clientHeight - handler.clientHeight
|
||||
let yPosInit = 0
|
||||
|
||||
handler.addEventListener('mousedown', (event) => {
|
||||
nonNativeScroll = true
|
||||
yPosInit = event.clientY - Number(handler.style.top.replace('px','' ))
|
||||
|
||||
document.addEventListener('mousemove', drag);
|
||||
document.addEventListener('mouseup', stop)
|
||||
})
|
||||
|
||||
content.addEventListener('scroll', (event) =>{
|
||||
if (!this.nonNativeScroll){
|
||||
let handlerPathLength = handler.parentElement.clientHeight - handler.clientHeight //TODO recalculate only on resize event
|
||||
let coefficient = (content.scrollHeight - content.clientHeight) /handlerPathLength
|
||||
handler.style.top = content.scrollTop/coefficient + 'px'
|
||||
}
|
||||
})
|
||||
|
||||
function drag() {
|
||||
// console.log(event.clientY - yPosInit, Number(handler.style.top.replace('px','' )))
|
||||
let pos = event.clientY - yPosInit
|
||||
let clampPos = Math.min(Math.max(pos, 0), max)
|
||||
handler.style.top = clampPos + "px";
|
||||
|
||||
let handlerPathLength = handler.parentElement.clientHeight - handler.clientHeight //TODO recalculate only on resize event
|
||||
let coefficient = (content.scrollHeight - content.clientHeight) /handlerPathLength
|
||||
// console.log(clampPos, coefficient, content.clientHeight, clampPos* coefficient)
|
||||
|
||||
content.scrollTop = clampPos* coefficient
|
||||
}
|
||||
function stop() {
|
||||
// console.log("stop")
|
||||
document.removeEventListener('mousemove', drag);
|
||||
document.removeEventListener('mouseup', stop)
|
||||
nonNativeScroll = false
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
// .scroller {
|
||||
// overflow-y: scroll;
|
||||
// scrollbar-color: #0A4C95 #C2D2E4;
|
||||
// border-radius: 0px;
|
||||
// }
|
||||
|
||||
// .scroll-content {
|
||||
// position: relative;
|
||||
// width: 400px;
|
||||
// height: 414px;
|
||||
// top: -17px;
|
||||
// padding: 20px 10px 20px 10px;
|
||||
// overflow-y: auto;
|
||||
// }
|
||||
|
||||
.scrollbar-place{
|
||||
overflow: hidden;
|
||||
|
||||
border-left: @eff-border-grey;
|
||||
width: 14px;
|
||||
height: 100%;
|
||||
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 14px;
|
||||
height: 100%;
|
||||
|
||||
// background-color: #EEEEEE;
|
||||
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.Focused .active .scrollbar-place{
|
||||
border-left: @eff-border-black;
|
||||
background-color: #AAAAAA;
|
||||
box-shadow: inset -1px 0px 0px rgba(255, 255, 255, 0.29),
|
||||
inset -2px 0px 0px rgba(255, 255, 255, 0.19),
|
||||
inset 1px 1px 0px rgba(0, 0, 0, 0.14),
|
||||
inset 2px 2px 0px rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
.scroll-element{
|
||||
position: relative;
|
||||
visibility: hidden;
|
||||
width: 14px;
|
||||
height: 31px;
|
||||
|
||||
background: #9999FF;
|
||||
|
||||
box-shadow: 0px -1px 0px #000000,
|
||||
0px 1px 0px #000000,
|
||||
0px 2px 0px rgba(0, 0, 0, 0.13),
|
||||
0px 3px 0px rgba(0, 0, 0, 0.19),
|
||||
inset 0px 1px 0px rgba(255, 255, 255, 0.5),
|
||||
inset 1px 0px 0px rgba(255, 255, 255, 0.5),
|
||||
inset -1px -1px 0px rgba(102, 102, 204, 0.91);
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
gap: 5px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.Focused .active .scroll-element{
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.drag-element{
|
||||
pointer-events: none;
|
||||
/* background-color: #0A4C95; */
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
margin-left: -1px;
|
||||
|
||||
background: linear-gradient(transparent 0%,#CCCCFF 0%, #CCCCFF 50%, transparent 50%);
|
||||
background-size: 2px 2px;
|
||||
|
||||
/* TODO white pixels in rows start */
|
||||
filter: drop-shadow(1px 1px 0px #333399);
|
||||
}
|
||||
|
||||
/* TODO to wde css */
|
||||
.ScrollContent {
|
||||
/* width: 100%;
|
||||
height: 100%; */
|
||||
overflow: scroll;
|
||||
overflow-x: hidden;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
|
||||
/* Auto layout */
|
||||
/* display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
padding: 0px; */
|
||||
}
|
||||
|
||||
.ScrollContent::-webkit-scrollbar { /* WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
@import "../../effects.less";
|
||||
@import "../../../theme.less";
|
||||
|
||||
.title-bar{
|
||||
width: 100%;
|
||||
height: 13px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
padding: 0px;
|
||||
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
align-self: stretch;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.title-bar .lable{
|
||||
position: relative;
|
||||
top: 1px;
|
||||
/* font-size: 13px; */
|
||||
color: @col-grey;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
|
||||
&:extend(.large-system-font);
|
||||
|
||||
// font-family: "Virtue";
|
||||
// letter-spacing: 0.35px;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar .lable{
|
||||
color: @col-black;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar .visual-drag-area{
|
||||
&:extend(.rows-fill-shadowed);
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
.title-bar > .icon{
|
||||
// background-color: aqua;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
|
||||
.title-bar > .button{
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
padding: 0%;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
visibility: hidden;
|
||||
|
||||
&:active{
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
/* Green */
|
||||
box-shadow: 0.5px 0.5px 0px 0.5px #FFFFFF,
|
||||
-0.5px -0.5px 0px 0.5px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
background: linear-gradient(135deg, #999999 18.18%, #FFFFFF 81.82%);
|
||||
border: 1px solid @col-raisin-black;
|
||||
box-shadow: 0.5px 0.5px 0px 0.5px #FFFFFF,
|
||||
-0.5px -0.5px 0px 0.5px rgba(0, 0, 0, 0.25),
|
||||
inset 1px 1px 0px rgba(255, 255, 255, 0.5),
|
||||
inset -1px -1px 0px rgba(0, 0, 0, 0.27);
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.window-frame.Focused .title-bar > .button{
|
||||
visibility:visible;
|
||||
}
|
||||
|
||||
// .window-frame.Focused .title-bar > .button:active{
|
||||
// background-color: aqua;
|
||||
// }
|
@ -1,50 +0,0 @@
|
||||
@import "../theme.less";
|
||||
@import "./effects.less";
|
||||
|
||||
.window-frame{
|
||||
position: absolute;
|
||||
|
||||
border: @eff-border-grey;
|
||||
box-shadow: @eff-box-shadow-grey;
|
||||
position: absolute;
|
||||
background-color: @col-gainsboro;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: 4px;
|
||||
padding-top: 2px;
|
||||
padding-right: 6px;
|
||||
gap: 4px;
|
||||
|
||||
/* Inside auto layout */
|
||||
flex: none;
|
||||
order: 1;
|
||||
align-self: stretch;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
|
||||
.window-frame.Focused{
|
||||
background-color: @col-chinese-silver;
|
||||
border: @eff-border-black;
|
||||
box-shadow: @eff-box-shadow-grey, @eff-box-shadow-convex;
|
||||
}
|
||||
|
||||
|
||||
.content-border{
|
||||
border: @eff-border-grey;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: @col-bright-grey;
|
||||
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.Focused .content-border{
|
||||
background-color: @col-gainsboro;
|
||||
border: @eff-border-black;
|
||||
box-shadow: @eff-box-shadow-adjective;
|
||||
}
|
@ -1,131 +0,0 @@
|
||||
export default 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
|
||||
}
|
||||
}
|
29
go.mod
29
go.mod
@ -4,51 +4,28 @@ go 1.18
|
||||
|
||||
require github.com/gin-gonic/gin v1.9.0
|
||||
|
||||
require (
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.8.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/floresj/go-contrib-mobile v0.0.0-20150714204826-47557cfa26f5
|
||||
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
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.2 // indirect
|
||||
github.com/goccy/go-json v0.10.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.24
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/russross/blackfriday v1.6.0
|
||||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
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.6
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||
golang.org/x/crypto v0.5.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
121
go.sum
121
go.sum
@ -1,180 +1,71 @@
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
|
||||
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/floresj/go-contrib-mobile v0.0.0-20150714204826-47557cfa26f5 h1:e+OSfbvxkjub+bPlfDmqENiV9IEOnLUk9TU7fMhu2Ks=
|
||||
github.com/floresj/go-contrib-mobile v0.0.0-20150714204826-47557cfa26f5/go.mod h1:2F+cddOTo8Rjp/98JPjMwZRCcCA1dP1VeNBvfk/tU6I=
|
||||
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/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
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=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
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 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
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/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw=
|
||||
github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
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 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
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=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
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 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
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=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
go.mongodb.org/mongo-driver v1.11.6 h1:XM7G6PjiGAO5betLF13BIa5TlLUUE3uJ/2Ox3Lz1K+o=
|
||||
go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY=
|
||||
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/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.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.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.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.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
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/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
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=
|
||||
|
BIN
icons/genericApp/color/16.png
(Stored with Git LFS)
BIN
icons/genericApp/color/16.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/genericApp/color/32.png
(Stored with Git LFS)
BIN
icons/genericApp/color/32.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/genericDocument/color/16.png
(Stored with Git LFS)
BIN
icons/genericDocument/color/16.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/genericDocument/color/32.png
(Stored with Git LFS)
BIN
icons/genericDocument/color/32.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/genericFolder/color/16.png
(Stored with Git LFS)
BIN
icons/genericFolder/color/16.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/genericFolder/color/32.png
(Stored with Git LFS)
BIN
icons/genericFolder/color/32.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 6.4 KiB |
BIN
icons/github/color/github.png
(Stored with Git LFS)
BIN
icons/github/color/github.png
(Stored with Git LFS)
Binary file not shown.
BIN
icons/hand/color/8.png
(Stored with Git LFS)
BIN
icons/hand/color/8.png
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
BIN
icons/twitter/color/twitter.png
(Stored with Git LFS)
BIN
icons/twitter/color/twitter.png
(Stored with Git LFS)
Binary file not shown.
64
libs/cat.go
64
libs/cat.go
@ -1,64 +0,0 @@
|
||||
package libs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//TODO Use this to get json from back
|
||||
type Cat struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
}
|
||||
|
||||
func NewCatLib(webfs *webfilesystem.WebFileSystem) *Cat {
|
||||
return &Cat{
|
||||
fs: webfs,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cat) Get(filePath string) (string, error) {
|
||||
file, err := c.fs.Read(filePath, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if file.Type != "plaintext" {
|
||||
return "", errors.New("todo")
|
||||
}
|
||||
|
||||
fileData := webfilesystem.PlainTextFileData{}
|
||||
_, err = c.fs.Read(filePath, &fileData)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fileData.Data, nil
|
||||
}
|
||||
|
||||
func (c *Cat) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("get", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.String(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
return
|
||||
}
|
||||
|
||||
data, err := c.Get(path)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
mode := ctx.Query("mode")
|
||||
switch mode {
|
||||
case "json":
|
||||
ctx.JSON(http.StatusOK, data)
|
||||
default:
|
||||
ctx.String(http.StatusOK, "plaintext", data)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package libs
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type ImagLib struct {
|
||||
fs *webfilesystem.WebFileSystem
|
||||
}
|
||||
|
||||
func NewImgLib(webfs *webfilesystem.WebFileSystem) *ImagLib {
|
||||
return &ImagLib{
|
||||
fs: webfs,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ImagLib) PublicRoutes(route *gin.RouterGroup) {
|
||||
route.GET("get", func(ctx *gin.Context) {
|
||||
path := ctx.Query("path")
|
||||
if path == "" {
|
||||
ctx.String(http.StatusBadRequest, "TODO") //TODO json error struct
|
||||
return
|
||||
}
|
||||
|
||||
imgData := Img{}
|
||||
_, err := l.fs.Read(path, &imgData)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data(http.StatusOK, "image/jpeg", imgData.Bin)
|
||||
})
|
||||
|
||||
iconGroup := route.Group("icon")
|
||||
iconGroup.GET("get", func(ctx *gin.Context) {
|
||||
iconPath := ctx.Query("path")
|
||||
iconType := ctx.Query("type")
|
||||
_ = iconType
|
||||
iconSize := ctx.Query("size")
|
||||
|
||||
imgData := Img{}
|
||||
_, err := l.fs.Read(path.Join(iconPath, "color", iconSize+".png"), &imgData)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
ctx.Data(http.StatusOK, "image/jpeg", imgData.Bin)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func GetBase64Image(img *Base64Img, min string) (string, error) {
|
||||
imgString := ""
|
||||
switch min {
|
||||
case "min32":
|
||||
imgString = "data:" + img.Header + ", " + img.Base64Miniature32
|
||||
default:
|
||||
imgString = "data:" + img.Header + ", " + img.Base64
|
||||
}
|
||||
|
||||
return imgString, nil
|
||||
}
|
||||
|
||||
type Base64Img struct {
|
||||
Header string `bson:"header"`
|
||||
Base64 string `bson:"base64"`
|
||||
Base64Miniature32 string `bson:"base64min32"`
|
||||
}
|
||||
|
||||
type Img struct {
|
||||
Header string `bson:"header"`
|
||||
Bin []byte `bson:"bin"`
|
||||
// BinMin32 []byte `bson:"binmin32"`
|
||||
}
|
17
libs/libs.go
17
libs/libs.go
@ -1,17 +0,0 @@
|
||||
package libs
|
||||
|
||||
import (
|
||||
"personalwebsite/webfilesystem"
|
||||
)
|
||||
|
||||
type Libs struct {
|
||||
Imglib *ImagLib
|
||||
Cat *Cat
|
||||
}
|
||||
|
||||
func NewLibs(webfs *webfilesystem.WebFileSystem) Libs {
|
||||
return Libs{
|
||||
Imglib: NewImgLib(webfs),
|
||||
Cat: NewCatLib(webfs),
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package libs
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"strings"
|
||||
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
type MarkdownLib struct {
|
||||
}
|
||||
|
||||
func (ml *MarkdownLib) Render(md []byte, supressParagraph bool) template.HTML {
|
||||
output := blackfriday.Run(md)
|
||||
if supressParagraph {
|
||||
output = []byte(strings.ReplaceAll(string(output), "<p>", ""))
|
||||
output = []byte(strings.ReplaceAll(string(output), "</p>", ""))
|
||||
}
|
||||
_ = output
|
||||
html := bluemonday.UGCPolicy().SanitizeBytes(output)
|
||||
// println(string(html))
|
||||
kek := template.HTML(html)
|
||||
return kek
|
||||
}
|
||||
|
||||
// func (ml MarkdownLib) MarkDowner(args ...interface{}) template.HTML {
|
||||
// s := blackfriday.MarkdownCommon([]byte(fmt.Sprintf("%s", args...)))
|
||||
|
||||
// return template.HTML(s)
|
||||
// }
|
186
main.go
186
main.go
@ -1,100 +1,114 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"net/http"
|
||||
"personalwebsite/routewde"
|
||||
"personalwebsite/websiteapp"
|
||||
"personalwebsite/websiteapp/finder"
|
||||
"personalwebsite/websiteapp/personalprops"
|
||||
|
||||
"personalwebsite/apps"
|
||||
blogwriter "personalwebsite/apps/BlogWriter"
|
||||
"personalwebsite/apps/aboutme"
|
||||
"personalwebsite/apps/blogviewer"
|
||||
"personalwebsite/apps/finder"
|
||||
imgviewer "personalwebsite/apps/img-viewer"
|
||||
"personalwebsite/apps/sunboard"
|
||||
"personalwebsite/routes"
|
||||
"personalwebsite/wde"
|
||||
"personalwebsite/webfilesystem"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// func main() {
|
||||
// router := gin.Default()
|
||||
// router.LoadHTMLGlob("templates/**/*")
|
||||
// router.GET("/posts/index", func(c *gin.Context) {
|
||||
// c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
|
||||
// "title": "Posts",
|
||||
// })
|
||||
// })
|
||||
// router.GET("/users/index", func(c *gin.Context) {
|
||||
// c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
|
||||
// "title": "Users",
|
||||
// })
|
||||
// })
|
||||
// router.Run(":8080")
|
||||
// }
|
||||
|
||||
func main() {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
println("No .env file found")
|
||||
// hostUrl := "http://localhost:8080/"
|
||||
router := gin.New()
|
||||
|
||||
router.LoadHTMLGlob("templates/**/*")
|
||||
router.Static("/res", "resources")
|
||||
|
||||
router.GET("/", func(ctx *gin.Context) {
|
||||
ctx.HTML(http.StatusOK, "index.tmpl", gin.H{})
|
||||
})
|
||||
|
||||
persPropsApp := personalprops.NewPersPropsApp()
|
||||
finderApp := finder.FinerApplication{}
|
||||
appsStorage := websiteapp.ApplicationsStorage{
|
||||
Apps: map[string]websiteapp.WebDEApplication{},
|
||||
}
|
||||
appsStorage.Apps["personal-properties"] = &persPropsApp
|
||||
appsStorage.Apps["finder"] = &finderApp
|
||||
system := router.Group("system")
|
||||
{
|
||||
|
||||
wde := system.Group("wde")
|
||||
{
|
||||
routewde.Route(wde)
|
||||
}
|
||||
apps := system.Group("applications")
|
||||
{
|
||||
apps.GET("/:appid/:method", func(ctx *gin.Context) {
|
||||
appId := ctx.Param("appid")
|
||||
method := ctx.Param("method")
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
websiteapp.Route(apps.Group("/storage"), &appsStorage)
|
||||
// personalpropsroute.Route(apps.Group("/personalproperties"))
|
||||
}
|
||||
|
||||
mongoConnect, err := FindEnv("MONGO_CONNECT")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
app := router.Group("application")
|
||||
{
|
||||
app.GET("test", func(ctx *gin.Context) {
|
||||
ctx.Status(http.StatusOK)
|
||||
})
|
||||
persPropApp := app.Group("personal-properties")
|
||||
{
|
||||
persPropApp.GET("render", func(ctx *gin.Context) {
|
||||
ctx.HTML(http.StatusOK, "personal-properties/app.tmpl", persPropsApp.Render())
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
router.GET("/test", func(ctx *gin.Context) {
|
||||
ctx.HTML(200, "kek/kek.tmpl", gin.H{})
|
||||
})
|
||||
// router.GET("/room/:roomid", roomGET)
|
||||
// router.POST("/room-post/:roomid", roomPOST)
|
||||
// router.GET("/stream/:roomid", streamRoom)
|
||||
|
||||
dBName, err := FindEnv("DATABASE")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
webFsCollection, err := FindEnv("COLLECTION_WEBFS")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
publicPort, err := FindEnv("PUBLIC_PORT")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
privatePort, err := FindEnv("PRIVATE_PORT")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
clientOptions := options.Client().ApplyURI(mongoConnect)
|
||||
client, err := mongo.Connect(context.TODO(), clientOptions)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = client.Ping(context.TODO(), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
webfs := webfilesystem.NewWebFileSystem(client, dBName, webFsCollection)
|
||||
appsStorage := apps.NewApplicationsStorage(map[string]apps.WebDEApplication{}, webfs)
|
||||
|
||||
webde := wde.NewWDE(webfs)
|
||||
|
||||
//TODO Split to different apps init for private and public?
|
||||
persPropsApp := aboutme.NewAboutMeApp(webfs)
|
||||
finderApp := finder.NewFinderApplication(webfs)
|
||||
imgViewerApp := imgviewer.NewImgViewerApp(webfs)
|
||||
blogViewerApp := blogviewer.NewBlogViewerApp(webfs)
|
||||
blogWriterApp := blogwriter.NewBlogWriterApp(webfs)
|
||||
sunBoardApp := sunboard.NewSunboardApp(webfs, webde, appsStorage)
|
||||
|
||||
appsStorage.Apps["personal-properties"] = persPropsApp
|
||||
appsStorage.Apps["finder"] = finderApp
|
||||
appsStorage.Apps["img-viewer"] = imgViewerApp
|
||||
appsStorage.Apps[blogViewerApp.GetAppID()] = blogViewerApp
|
||||
appsStorage.Apps["BlogWriter"] = blogWriterApp
|
||||
appsStorage.Apps["Sunboard"] = sunBoardApp
|
||||
|
||||
go routes.PublicRoutes(publicPort, webfs, webde, appsStorage)
|
||||
routes.PrivateRoutes(privatePort, webfs, webde, appsStorage)
|
||||
}
|
||||
|
||||
// TODO to for loop with aal vars in slice
|
||||
func FindEnv(parameter string) (string, error) {
|
||||
path, exists := os.LookupEnv(parameter)
|
||||
|
||||
if exists {
|
||||
println("[ENV] Requsted " + parameter + " = " + path) //FIXME Only in Debug log
|
||||
return path, nil
|
||||
} else {
|
||||
panic("[ENV] Requsted " + parameter + " not found")
|
||||
return "", errors.New("env parameter not found")
|
||||
// port := os.Getenv("PORT")
|
||||
// if port == "" {
|
||||
// port = "8080"
|
||||
// }
|
||||
if err := router.Run(":8080"); err != nil {
|
||||
log.Panicf("error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func index(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "base.html", nil)
|
||||
}
|
||||
|
@ -11,9 +11,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="WindowsLayer"></div>
|
||||
<div id="Applications"></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 id="TestWindowHeader" class="WindowDragArea" style="width: 100%;height: 15px; background-color: cornflowerblue;">
|
||||
</div> -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -3,11 +3,11 @@
|
||||
<div id="WindowBorder" class="Frame">
|
||||
<div id="TestWindowHeader" class="WindowFrameTopBar">
|
||||
<button class="WindowFrameTopBarButton"></button>
|
||||
<div id="Drag" class="VisualDragArea"></div>
|
||||
<div class="Lable">
|
||||
<div id="Drag" class="WindowDragArea"></div>
|
||||
<div class="WindowFrameTitle">
|
||||
Test Title
|
||||
</div>
|
||||
<div id="Drag" class="VisualDragArea"></div>
|
||||
<div id="Drag" class="WindowDragArea"></div>
|
||||
<button class="WindowFrameTopBarButton" ></button>
|
||||
</div>
|
||||
<div id="ContentFrame" class="ContentFrame">
|
||||
|
@ -1,37 +0,0 @@
|
||||
class AboutMe{
|
||||
static appID = "AboutMe"
|
||||
/**
|
||||
* @param {HTMLElement} appElem
|
||||
*/
|
||||
constructor(appElem){
|
||||
this.appElem = appElem
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[]string} args
|
||||
* @param {Object} runContext
|
||||
*/
|
||||
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
|
||||
}
|
||||
const html = await response.text()
|
||||
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 360, document.body.clientHeight*0.8 )
|
||||
|
||||
newWindow.innerHTML = html
|
||||
newWindow.style.height = 'auto'
|
||||
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', () => {
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
})
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
class BlogViewer{
|
||||
static appID = "BlogViewer"
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
* @param {Object} runContext
|
||||
*/
|
||||
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 )
|
||||
newWindow.innerHTML = html
|
||||
|
||||
let scrollBar = new WdeScrollBar(newWindow.querySelector(".ScrollbarPlace"), newWindow.querySelector(".ScrollContent"))
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MouseEvent} event
|
||||
* @param {string} path
|
||||
*/
|
||||
static Click(event, path){
|
||||
let fileType = event.target.getAttribute("fileType")
|
||||
switch (fileType) {
|
||||
case "app":
|
||||
//TODO get real id
|
||||
WebDesktopEnvironment.Open("personal-properties", [])
|
||||
break;
|
||||
case "img":
|
||||
WebDesktopEnvironment.Open("img-viewer", ["pizda"])
|
||||
break;
|
||||
default:
|
||||
console.log("Unsupported file type")
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
.BlogView{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
/* gap: 50px; */
|
||||
/* row-gap: 20px; */
|
||||
/* padding: 0px 20px 0px 20px; */
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.BlogView .Content {
|
||||
overflow: scroll;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
/* gap: 50px; */
|
||||
/* row-gap: 20px; */
|
||||
/* padding: 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{
|
||||
font-size:x-large;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.BlogView .header-h2{
|
||||
font-size:large;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.BlogView .header-h3{
|
||||
font-size:larger;
|
||||
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;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
gap: 5px;
|
||||
/* row-gap: 20px; */
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
class BlogWriter{
|
||||
static AppId = "BlogWriter"
|
||||
|
||||
/**
|
||||
* @param {string[]} args
|
||||
*/
|
||||
async NewWindow(args){
|
||||
console.log("kek")
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
.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;
|
||||
}
|
||||
|
||||
.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,317 +0,0 @@
|
||||
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, appContext){
|
||||
if (args[1] == "--desktop"){
|
||||
let desktopNode = document.body.querySelector(`#${args[2]}`)
|
||||
if (desktopNode == null){
|
||||
WebDesktopEnvironment.Alert("Desktop node not found")
|
||||
return
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
path: args[0]
|
||||
})
|
||||
const response = await fetch(`/app/${Finder.AppId}/renderDesktop?` + params,
|
||||
{
|
||||
method: "POST",
|
||||
body: JSON.stringify(appContext)
|
||||
})
|
||||
if (response.status != 200){
|
||||
console.log(response.status)
|
||||
WebDesktopEnvironment.Alert("Error in render desktop") //TODO
|
||||
return
|
||||
}
|
||||
const html = await response.text()
|
||||
desktopNode.innerHTML = html
|
||||
|
||||
this.fileView = new FileView(
|
||||
desktopNode.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(appContext)
|
||||
})
|
||||
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,305 +0,0 @@
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
.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,18 +0,0 @@
|
||||
.Img-Viewer-Picture-Container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.Img-Viewer-Picture{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* background-image: url("./test-image.jpg");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center; */
|
||||
}
|
||||
|
||||
|
||||
.Img-Viewer-Picture-Toolbar{
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
class ImgViewer{
|
||||
appId = "img-viewer"
|
||||
/**
|
||||
* @param {string[]} args
|
||||
*/
|
||||
NewWindow(args){
|
||||
fetch(`${window.location.origin}/application/${this.appId}/render?`+ new URLSearchParams({
|
||||
isMobile: WebDesktopEnvironment.isMobile,
|
||||
path: args[0]
|
||||
}))
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
let newWindow = WebDesktopEnvironment.CreateNewWindow(this.appId, 450,400 )
|
||||
newWindow.innerHTML = html
|
||||
|
||||
if (!WebDesktopEnvironment.isMobile){
|
||||
newWindow.querySelector("#closeWindowButton").addEventListener('click', function (params) {
|
||||
WebDesktopEnvironment.CloseWindow(newWindow)
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
WebDesktopEnvironment.Alert(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
BIN
res/dev-fs/apps/ImgViewer/test-image.jpg
(Stored with Git LFS)
BIN
res/dev-fs/apps/ImgViewer/test-image.jpg
(Stored with Git LFS)
Binary file not shown.
@ -1,73 +0,0 @@
|
||||
@font-face{
|
||||
font-family: "Virtue";
|
||||
src:url("/res/dev-fs/fonts/virtue.ttf");
|
||||
}
|
||||
|
||||
/* @font-face{
|
||||
font-family: "Virtue";
|
||||
src:url("/res/dev-fs/fonts/virtue.ttf")
|
||||
} */
|
||||
|
||||
/* @media screen and (max-device-width: 2048px) and (max-device-height: 2048px) {
|
||||
html {
|
||||
zoom: 3
|
||||
}
|
||||
} */
|
||||
|
||||
.NoClick {
|
||||
pointer-events: none;
|
||||
}
|
||||
.Click {
|
||||
pointer-events: all;
|
||||
}
|
||||
*{
|
||||
font-family: Verdana, Geneva, sans-serif;
|
||||
font-size: 11px;
|
||||
font-style: normal;
|
||||
font-weight:initial;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar { /* WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
body{
|
||||
zoom: var(--zoom);
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
|
||||
/* font: normal 14px Summer Pixel 22, "res/SummerPixel22Regular.ttf"; */
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-khtml-user-select: none; /* Konqueror HTML */
|
||||
-moz-user-select: none; /* Old versions of Firefox */
|
||||
-ms-user-select: none; /* Internet Explorer/Edge */
|
||||
user-select: none; /* Non-prefixed version, currently
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
#applications{
|
||||
position: static;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#windows-layer {
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
/* position: fixed; */
|
||||
position: static;
|
||||
}
|
||||
|
||||
#desktop-layer{
|
||||
position: fixed;
|
||||
/* margin: 0px; */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #9999CC;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
.ContentBorder { /*TODO Delete, deprecated*/
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* background-color: #DDDDDD;
|
||||
border: 1px solid #000000; */
|
||||
|
||||
overflow: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.ContextMenu {
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
background-color: #DDDDDD;
|
||||
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
|
||||
.ContextMenu .Content{
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
/* padding: 4px;
|
||||
padding-top: 2px;
|
||||
padding-right: 6px;
|
||||
gap: 4px; */
|
||||
}
|
||||
|
||||
.ContextMenu .Row {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
|
||||
}
|
||||
|
||||
.ContextMenu .SectionBreaker {
|
||||
|
||||
/* background-color: rebeccapurple; */
|
||||
|
||||
}
|
||||
|
||||
.ContextMenu .Row:hover{
|
||||
background-color: #333399;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.ContextMenu .Row .Lable{
|
||||
margin-left: 20px;
|
||||
margin-right: 12px;
|
||||
font-family: "Virtue";
|
||||
|
||||
white-space: nowrap;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
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}/`);
|
||||
}
|
||||
}
|
149
res/dev-fs/wde/dist/desktop.js
vendored
149
res/dev-fs/wde/dist/desktop.js
vendored
File diff suppressed because one or more lines are too long
159
res/dev-fs/wde/dist/finder.js
vendored
159
res/dev-fs/wde/dist/finder.js
vendored
File diff suppressed because one or more lines are too long
14
res/dev-fs/wde/dist/init.js
vendored
14
res/dev-fs/wde/dist/init.js
vendored
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
49
res/dev-fs/wde/dist/mobile.js
vendored
49
res/dev-fs/wde/dist/mobile.js
vendored
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
||||
* This devtool is neither made for production nor for readable output files.
|
||||
* It uses "eval()" calls to create a separate source file in the browser devtools.
|
||||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||||
* or disable the default devtool with "devtool: false".
|
||||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||||
*/
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ "./src/mobile.js":
|
||||
/*!***********************!*\
|
||||
!*** ./src/mobile.js ***!
|
||||
\***********************/
|
||||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
eval("__webpack_require__.r(__webpack_exports__);\nObject(function webpackMissingModule() { var e = new Error(\"Cannot find module './wde/wde-mobile'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());\n\nrequire(\"./mobile.less\");\ndocument.addEventListener('DOMContentLoaded', function () {\n var wde = new Object(function webpackMissingModule() { var e = new Error(\"Cannot find module './wde/wde-mobile'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }())();\n}, false);\n\n//# sourceURL=webpack://my-webpack-project/./src/mobile.js?");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The require scope
|
||||
/******/ var __webpack_require__ = {};
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/ // startup
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ // This entry module can't be inlined because the eval devtool is used.
|
||||
/******/ var __webpack_exports__ = {};
|
||||
/******/ __webpack_modules__["./src/mobile.js"](0, __webpack_exports__, __webpack_require__);
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
@ -1,86 +0,0 @@
|
||||
.FileTileView{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
|
||||
|
||||
/* FIXME Bug, on desktop mode top ~10 pixel are not active, like margin:10px */
|
||||
}
|
||||
|
||||
.FileTileView.DragDropBorder{
|
||||
box-shadow: inset 0px 0px 0px 4px #9999CC;
|
||||
/* background-color: blue; */
|
||||
}
|
||||
|
||||
.FileTileView .FlexContainer{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
gap: 50px;
|
||||
row-gap: 20px;
|
||||
/* padding: 15px; Shit fix TODO: */
|
||||
margin: 15px;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
|
||||
/* overflow: scroll; */
|
||||
/* overflow-x: hidden; */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* Internet Explorer 10+ */
|
||||
}
|
||||
|
||||
.FileTileView::-webkit-scrollbar { /* WebKit */
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.FileTileView .Tile{
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* Auto layout */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 2px;
|
||||
padding: 0px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.FileTileView .Selected{
|
||||
/* inherits: ; */
|
||||
/* background-color: black; */
|
||||
}
|
||||
|
||||
.FileTileView .Icon{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
/* background-image: url("./icons/folder.png"); */
|
||||
background-size: cover;
|
||||
|
||||
image-rendering: optimizeSpeed; /* STOP SMOOTHING, GIVE ME SPEED */
|
||||
image-rendering: -moz-crisp-edges; /* Firefox */
|
||||
image-rendering: -o-crisp-edges; /* Opera */
|
||||
image-rendering: -webkit-optimize-contrast; /* Chrome (and eventually Safari) */
|
||||
image-rendering: pixelated; /* Universal support since 2021 */
|
||||
image-rendering: optimize-contrast; /* CSS3 Proposed */
|
||||
-ms-interpolation-mode: nearest-neighbor; /* IE8+ */
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Icon{
|
||||
filter: brightness(0.4);
|
||||
}
|
||||
|
||||
.FileTileView .Lable{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.FileTileView .Selected .Lable{
|
||||
white-space: nowrap;
|
||||
color: white;
|
||||
background-color: black;
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
class FileView{
|
||||
path = ""
|
||||
parentElem = undefined
|
||||
selected = []
|
||||
/**
|
||||
* @param {HTMLElement} fileViewElem
|
||||
* @param {Function} doubleClickCallback
|
||||
* @param {Function} rightClickCallback
|
||||
* @param {Function} updateFileViewCallback
|
||||
*/
|
||||
constructor(fileViewElem, doubleClickCallback, rightClickCallback, fileUploadCallback, updateFileViewCallback){
|
||||
//TODO check all params
|
||||
this.parentElem = fileViewElem
|
||||
|
||||
fileViewElem.addEventListener('click', (event) => {
|
||||
if (event.target.classList[0] == 'FileTileView')
|
||||
{
|
||||
this.DeselectAll()
|
||||
return
|
||||
}
|
||||
if (event.detail === 1){
|
||||
this.DeselectAll()
|
||||
this.Select([event.target])
|
||||
} else if (event.detail === 2) {
|
||||
doubleClickCallback(event)
|
||||
}
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('contextmenu', (event) => {
|
||||
event.preventDefault();
|
||||
if (event.target.classList.contains("Tile")){
|
||||
this.DeselectAll()
|
||||
this.Select([event.target])
|
||||
}
|
||||
this.Select([event.target])
|
||||
rightClickCallback(event)
|
||||
})
|
||||
|
||||
if (fileUploadCallback !== undefined) {
|
||||
let counter = 0
|
||||
let draggedElem = undefined
|
||||
|
||||
fileViewElem.addEventListener('dragstart', (event) => {
|
||||
// console.log(event.target)
|
||||
// console.log(this.path)
|
||||
// draggedElem = event.target
|
||||
event.dataTransfer.setData("fileName", event.target.getAttribute("name"))
|
||||
event.dataTransfer.setData("filePath", this.path + "/" + event.target.getAttribute("name"))
|
||||
event.dataTransfer.setData("dropType", "move")
|
||||
// console.log(updateFileViewCallback)
|
||||
// event.dataTransfer.setData("updateCallback", updateFileViewCallback)
|
||||
// event.dataTransfer.setData("fileName", )
|
||||
// console.log(draggedElem)
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragenter', function(event) {
|
||||
event.preventDefault();
|
||||
counter++
|
||||
fileViewElem.classList.add("DragDropBorder")
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragend', function(event) {
|
||||
// console.log(fileViewElem)
|
||||
event.preventDefault();
|
||||
counter--
|
||||
if (counter === 0){
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
}
|
||||
// updateFileViewCallback()
|
||||
// draggedElem = undefined
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragleave', function(event) {
|
||||
// console.log(fileViewElem)
|
||||
event.preventDefault();
|
||||
counter--
|
||||
if (counter === 0){
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
}
|
||||
// draggedElem = undefined
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener('dragover', function(event) {
|
||||
event.preventDefault();
|
||||
})
|
||||
|
||||
fileViewElem.addEventListener("drop", (event) => {
|
||||
event.preventDefault();
|
||||
fileUploadCallback(event)
|
||||
fileViewElem.classList.remove("DragDropBorder")
|
||||
// updateFileViewCallback()
|
||||
// this.OpenFolder(this.path)
|
||||
// draggedElem = undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {[]Element} elements
|
||||
*/
|
||||
Select(elements){
|
||||
elements.forEach(element => {
|
||||
this.selected.push(element)
|
||||
element.classList.add("Selected")
|
||||
});
|
||||
}
|
||||
|
||||
DeselectAll(){
|
||||
this.selected.forEach(element => {
|
||||
element.classList.remove("Selected")
|
||||
});
|
||||
this.selected = []
|
||||
}
|
||||
|
||||
/** Get html of folder by path
|
||||
* @param {string} path
|
||||
*/
|
||||
async OpenFolder(path){
|
||||
this.path = path
|
||||
const params = new URLSearchParams({
|
||||
path: path
|
||||
})
|
||||
const response = await fetch(`/system/wde/widgets/file-tile-view?` + params)
|
||||
if (response.status != 200){
|
||||
//TODO Error text message
|
||||
WebDesktopEnvironment.Alert("TODO")
|
||||
return
|
||||
}
|
||||
let html = await response.text()
|
||||
this.parentElem.innerHTML = html
|
||||
}
|
||||
}
|
BIN
res/dev-fs/wde/icons/about-me.png
(Stored with Git LFS)
BIN
res/dev-fs/wde/icons/about-me.png
(Stored with Git LFS)
Binary file not shown.
BIN
res/dev-fs/wde/icons/desktop.png
(Stored with Git LFS)
BIN
res/dev-fs/wde/icons/desktop.png
(Stored with Git LFS)
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user