Skip to content

Commit

Permalink
add default aspect ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
oktalz committed Dec 3, 2024
1 parent 894d1f3 commit 9e9ea66
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 19 deletions.
33 changes: 21 additions & 12 deletions config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@ import (
"github.com/peterbourgon/ff/v4/ffhelp"
)

type AspectRatio struct {
AspectRatio string
ValueChanged chan string
}

type Config struct {
Version bool `ff:"short: v, long: version, usage: 'show version'"`
Tag bool `ff:"short: t, long: tag, usage: 'show tag'"`
Compress string `ff:"short: c, long: compress, usage: 'compress current folder'"`
File string `ff:"short: f, long: file, usage: 'file to open (.tar.gz format)'"`
GIT string `ff:"short: g, long: git, usage: 'git repository URL'"`
GITKey string `ff:" long: key, usage: 'ssh key used for git clone auth'"`
Dir string `ff:"short: d, long: dir, usage: 'directory to open'"`
Help bool `ff:" long: help, usage: 'help'"`

Address string `ff:"short: h, long:host, default: 127.0.0.1, usage: 'address that present will listen on'"`
Port int `ff:"short: p, long:port, default: 8080, usage: 'port that present will listen on'"`
Version bool `ff:"short: v, long: version, usage: 'show version'"`
Address string `ff:"short: h, long: host, default: 127.0.0.1, usage: 'address that present will listen on'"`
Port int `ff:"short: p, long: port, default: 8080, usage: 'port that present will listen on'"`
Tag bool `ff:"short: t, long: tag, usage: 'show tag'"`
Compress string `ff:"short: c, long: compress, usage: 'compress current folder'"`
File string `ff:"short: f, long: file, usage: 'file to open (.tar.gz format)'"`
GIT string `ff:"short: g, long: git, usage: 'git repository URL'"`
GITKey string `ff:" long: key, usage: 'ssh key used for git clone auth'"`
Dir string `ff:"short: d, long: dir, usage: 'directory to open'"`
Help bool `ff:" long: help, usage: 'help'"`
AspectRatio AspectRatio

Security Security
Controls Controls
Expand All @@ -48,7 +53,11 @@ type Controls struct {
}

func Get() Config {
configuration := Config{}
configuration := Config{
AspectRatio: AspectRatio{
ValueChanged: make(chan string),
},
}
security := Security{}
controls := Controls{}
update := Update{}
Expand Down
3 changes: 3 additions & 0 deletions data/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func Init(server Server, config configuration.Config) { //nolint:funlen,gocognit
for range filesModified {
muPresentation.Lock()
presentation = reader.ReadFiles()
if presentation.Options.AspectRatio != "" {
config.AspectRatio.ValueChanged <- presentation.Options.AspectRatio
}
var err error
for i := range presentation.Slides {
var adminHTML string
Expand Down
10 changes: 8 additions & 2 deletions data/reader/reader-slides.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import (

func ReadFiles() types.Presentation { //nolint:funlen,gocognit,gocyclo,cyclop,maintidx
ro := types.ReadOptions{
DefaultFontSize: "5vh",
DefaultFontSize: "5svh",
EveryDashIsATransition: false,
DefaultTerminalFontSize: "6vh",
DefaultTerminalFontSize: "6svh",
DefaultBackgroundColor: "white",
DefaultTerminalFontColor: "black",
DefaultTerminalBackgroundColor: "rgb(253, 246, 227)",
HidePageNumber: true,
KeepPagePrintOnCut: false,
AspectRatio: "",
ForceAspectRatio: false,
}
endpoints := map[string]types.TerminalCommand{}

Expand Down Expand Up @@ -55,6 +57,9 @@ func ReadFiles() types.Presentation { //nolint:funlen,gocognit,gocyclo,cyclop,ma
}

presentationFile := processSlides(buff.String(), ro)
if presentationFile.Options.AspectRatio != "" {
presentationFiles.Options.AspectRatio = presentationFile.Options.AspectRatio
}
presentationFiles.Slides = append(presentationFiles.Slides, presentationFile.Slides...)
if presentationFile.Title != "" {
presentationFiles.Title = presentationFile.Title
Expand Down Expand Up @@ -434,6 +439,7 @@ func ReadFiles() types.Presentation { //nolint:funlen,gocognit,gocyclo,cyclop,ma
}

return types.Presentation{
Options: presentationFiles.Options,
Slides: presentations,
CSS: presentationFiles.CSS,
JS: presentationFiles.JS,
Expand Down
10 changes: 10 additions & 0 deletions data/reader/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,13 @@ func processSlides(fileContent string, ro types.ReadOptions) types.Presentation
lines[index] = ""
continue
}
if strings.HasPrefix(line, ".global.aspect-ratio(") && strings.HasSuffix(line, ")") {
aspect := strings.TrimPrefix(line, ".global.aspect-ratio(")
aspect = strings.TrimSuffix(aspect, ")")
ro.AspectRatio = aspect
lines[index] = ""
continue
}
if strings.HasPrefix(line, ".global.background-color(") && strings.HasSuffix(line, ")") {
currentBackgroundColor = strings.TrimPrefix(line, ".global.background-color(")
currentBackgroundColor = strings.TrimSuffix(currentBackgroundColor, ")")
Expand Down Expand Up @@ -612,6 +619,9 @@ func processSlides(fileContent string, ro types.ReadOptions) types.Presentation
}
}
return types.Presentation{
Options: types.PresentationOptions{
AspectRatio: ro.AspectRatio,
},
Slides: slides,
Title: title,
Replacers: replacersAfter,
Expand Down
1 change: 1 addition & 0 deletions examples/showcase/.slide
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.global.font-size(5svh)
.global.aspect-ratio(16x9)
.title(Present - example slides)

.replace.after{#space#}(&nbsp;)
Expand Down
4 changes: 4 additions & 0 deletions handlers/cast-ws.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import (

func CastWS(server data.Server, config configuration.Config) http.Handler { //nolint:funlen,gocognit,revive
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
conn, err := websocket.Accept(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
Expand Down
160 changes: 160 additions & 0 deletions handlers/frame.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package handlers

import (
"hash/fnv"
"log"
"net/http"
"strconv"
"strings"
"sync"

configuration "github.com/oktalz/present/config"
)

func IFrame(config configuration.Config) http.Handler { //nolint:funlen
eTagFrame := ""
var mu sync.RWMutex
pageResult := page
aspectRatioChange := func() {
mu.Lock()
defer mu.Unlock()
pageResult = page
if config.AspectRatio.AspectRatio != "" {
aspectRatio := strings.Split(config.AspectRatio.AspectRatio, ":")
if len(aspectRatio) == 1 {
aspectRatio = strings.Split(config.AspectRatio.AspectRatio, "x")
}
if len(aspectRatio) == 2 {
width, _ := strconv.Atoi(aspectRatio[0])
height, _ := strconv.Atoi(aspectRatio[1])
pageResult = strings.Replace(pageResult, "widthRatio = 16", "widthRatio = "+strconv.Itoa(width), 1)
pageResult = strings.Replace(pageResult, "heightRatio = 9", "heightRatio = "+strconv.Itoa(height), 1)
}
}
hasher := fnv.New64a()
hasher.Write([]byte(pageResult))
eTagFrame = strconv.FormatUint(hasher.Sum64(), 16)
}

aspectRatioChange()
go func() {
for {
aspectRatio := <-config.AspectRatio.ValueChanged
config.AspectRatio.AspectRatio = aspectRatio
aspectRatioChange()
}
}()

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = cookieIDValue(w, r)
userOK, adminPrivileges := cookieAuth(config.Security.UserPwd, config.Security.AdminPwd, r)
if config.Security.AdminPwdDisable && !adminPrivileges {
adminPrivileges = true
}
if config.Security.UserPwd != "" && !adminPrivileges {
if !(userOK) {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
}

origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
if r.Method == http.MethodOptions {
return
}

var response []byte
_ = response
eTag := r.Header.Get("If-None-Match")
mu.RLock()
defer mu.RUnlock()
if eTagFrame == eTag {
w.WriteHeader(http.StatusNotModified)
return
}

w.Header().Set("Content-Type", "text/html")
w.Header().Set("ETag", eTagFrame)
w.WriteHeader(http.StatusOK)

_, err := w.Write([]byte(pageResult))
if err != nil {
log.Println(err)
return
}
})
}

var page = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.iframe-container {
max-height: 100vh;
max-width: 100vw;
position: relative;
margin: auto;
}
.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
}
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
</style>
</head>
<body>
<div class="iframe-container">
<iframe src="/print" id="present-iframe" name="present-iframe" sandbox="allow-scripts allow-same-origin allow-storage-access-by-user-activation"></iframe>
</div>
<script>
widthRatio = 16
heightRatio = 9
console.log(location.origin)
document.getElementById('present-iframe').src = location.origin+'/print';
calcAspectRatioFit = function() {
expectedRatio = widthRatio / heightRatio
currentRatio = window.innerWidth / window.innerHeight
if (widthRatio >= heightRatio) {
if (currentRatio < expectedRatio) {
document.querySelector('.iframe-container').style.width = '100svw';
document.querySelector('.iframe-container').style.height = (window.innerWidth * heightRatio / widthRatio) + 'px';
} else {
document.querySelector('.iframe-container').style.width = (window.innerHeight * widthRatio / heightRatio) + 'px';
document.querySelector('.iframe-container').style.height = '100svh';
}
} else {
if (currentRatio < expectedRatio) {
document.querySelector('.iframe-container').style.width = '100svw';
document.querySelector('.iframe-container').style.height = (window.innerWidth * heightRatio / widthRatio) + 'px';
} else {
document.querySelector('.iframe-container').style.width = (window.innerHeight * widthRatio / heightRatio) + 'px';
document.querySelector('.iframe-container').style.height = '100svh';
}
}
}
calcAspectRatioFit()
window.addEventListener("resize", calcAspectRatioFit);
</script>
</body>
</html>
`
5 changes: 4 additions & 1 deletion handlers/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import "net/http"

func AccessControlAllow(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
next.ServeHTTP(w, r)
Expand Down
11 changes: 10 additions & 1 deletion handlers/homepage.go → handlers/no-layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/oktalz/present/data"
)

func Homepage(config configuration.Config) http.Handler {
func NoLayout(config configuration.Config) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = cookieIDValue(w, r)
userOK, adminPrivileges := cookieAuth(config.Security.UserPwd, config.Security.AdminPwd, r)
Expand All @@ -22,6 +22,15 @@ func Homepage(config configuration.Config) http.Handler {
}
}

origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}
w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS")
if r.Method == http.MethodOptions {
return
}

var response []byte
var status int
eTag := r.Header.Get("If-None-Match")
Expand Down
5 changes: 5 additions & 0 deletions http-file-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ func (s *fallbackFileServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

origin := r.Header.Get("Origin")
if origin != "" {
w.Header().Set("Access-Control-Allow-Origin", origin)
}

rw := responseWriter{ //nolint:exhaustruct
CustomHeader: make(http.Header),
StatusCode: http.StatusOK,
Expand Down
6 changes: 4 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ func configureServer(config configuration.Config) {
wsServer := data.NewServer()
data.Init(wsServer, config)

// http.Handle("/cast", handlers.Cast())
http.Handle("/cast", handlers.CastWS(wsServer, config))
http.Handle("/ws", handlers.WS(wsServer, config))

http.Handle("/{$}", handlers.Homepage(config))
// http.Handle("/{$}", handlers.NoLayout(config))
http.Handle("/{$}", handlers.IFrame(config))
http.Handle("/print", handlers.NoLayout(config))
http.Handle("/iframe", handlers.IFrame(config))
http.Handle("/login", handlers.Login(loginPage))
http.Handle("GET /api/login", handlers.APILogin(config))
http.Handle("GET /api/users", handlers.APIUsers(config))
Expand Down
7 changes: 7 additions & 0 deletions types/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ type Menu struct {
Title string
}

type PresentationOptions struct {
AspectRatio string
}

type Presentation struct {
CSS string
Options PresentationOptions
JS string
Slides []Slide
Menu []Menu
Expand All @@ -105,6 +110,8 @@ type TerminalOutputLine struct {

type ReadOptions struct {
DefaultFontSize string
AspectRatio string
ForceAspectRatio bool
DefaultBackgroundColor string
EveryDashIsATransition bool
DefaultTerminalFontSize string
Expand Down
2 changes: 1 addition & 1 deletion ui/web.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ onPageChange = function() {
{{- end -}}
return;
};
</script
</script>
</html>

{{ define "slide" }}
Expand Down

0 comments on commit 9e9ea66

Please sign in to comment.