Compare commits

...

9 commits

Author SHA1 Message Date
Ryan Stafford
a96b5b1cd2 fix dark default
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-08-08 18:03:03 -04:00
Ryan Stafford
d8292bb9be fix thumbnail default
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-08-08 17:57:47 -04:00
Ryan Stafford
3e1e3868f4 default settings, hide thumbnails option, github link. fixes #64, fixes #66, fixes #67
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-08-08 17:36:52 -04:00
Ryan Stafford
a91b08547b fix reply preview 500
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-07-31 14:41:55 -04:00
Ryan Stafford
624b7e4847 add fedilink. fixes #57
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-07-28 17:00:58 -04:00
Ryan Stafford
c935ffabea add version to make 2023-07-28 13:36:03 -04:00
Ryan Stafford
f5a423f2d5 remove mailto links from title
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-07-28 13:04:41 -04:00
Ryan Stafford
c5a53c79da show lemmy back end version
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-07-28 12:51:17 -04:00
Ryan Stafford
669749c12e fix settings save
Some checks are pending
Docker / docker-images (push) Waiting to run
2023-07-26 22:33:06 -04:00
10 changed files with 58 additions and 15 deletions

View file

@ -2,7 +2,7 @@
all: mlmym all: mlmym
mlmym: mlmym: VERSION
go build -v -o mlmym go build -v -o mlmym
dev: dev:

View file

@ -3,14 +3,23 @@ a familiar desktop experience for [lemmy](https://join-lemmy.org).
![screenshot](https://raw.githubusercontent.com/rystaf/mlmym/main/screenshot1.png?raw=true) ![screenshot](https://raw.githubusercontent.com/rystaf/mlmym/main/screenshot1.png?raw=true)
### deployment ## deployment
```bash ```bash
docker run -it -p "8080:8080" ghcr.io/rystaf/mlmym:latest docker run -it -p "8080:8080" ghcr.io/rystaf/mlmym:latest
``` ```
### config ## config
Set the environment variable `LEMMY_DOMAIN` to run in single instance mode Set the environment variable `LEMMY_DOMAIN` to run in single instance mode
```bash ```bash
docker run -it -e LEMMY_DOMAIN='lemmydomain.com' -p "8080:8080" ghcr.io/rystaf/mlmym:latest docker run -it -e LEMMY_DOMAIN='lemmydomain.com' -p "8080:8080" ghcr.io/rystaf/mlmym:latest
``` ```
#### default user settings
| environment variable | default |
| -------------------- | ------- |
| DARK | false |
| HIDE_THUMBNAILS | false |
| LISTING | All |
| SORT | Hot |
| COMMENT_SORT | Hot |

View file

@ -56,7 +56,7 @@ func init() {
)) ))
templates = make(map[string]*template.Template) templates = make(map[string]*template.Template)
if !*watch { if !*watch {
for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html", "settings.html", "xhr.html"} { for _, name := range []string{"index.html", "login.html", "frontpage.html", "root.html", "settings.html", "xhr.html", "create_comment.html"} {
t := template.New(name).Funcs(funcMap) t := template.New(name).Funcs(funcMap)
glob, err := t.ParseGlob("templates/*") glob, err := t.ParseGlob("templates/*")
if err != nil { if err != nil {

View file

@ -1110,7 +1110,7 @@ form.create input[type=file], form.create select {
} }
.preferences label{ .preferences label{
display: inline-block; display: inline-block;
width: 130px; width: 150px;
margin-right: 5px; margin-right: 5px;
text-align: right; text-align: right;

View file

@ -296,8 +296,7 @@ function saveSettings(e) {
var targ = e.currentTarget || e.srcElement || e; var targ = e.currentTarget || e.srcElement || e;
var data = new FormData(targ) var data = new FormData(targ)
e.preventDefault() e.preventDefault()
var params = new URLSearchParams(data).toString() request(targ.target, data, function(res) {
request(targ.target, params, function(res) {
["endlessScrolling", "autoLoad"].map(function(x) { ["endlessScrolling", "autoLoad"].map(function(x) {
localStorage.setItem(x, data.get(x)=="on") localStorage.setItem(x, data.get(x)=="on")
}) })

View file

@ -152,7 +152,7 @@ var funcMap = template.FuncMap{
return body return body
} }
text := html2text.HTML2TextWithOptions(buf.String(), html2text.WithLinksInnerText()) text := html2text.HTML2TextWithOptions(buf.String(), html2text.WithLinksInnerText())
re := regexp.MustCompile(`\<https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)\>`) re := regexp.MustCompile(`\<(https?:\/\/|mailto)(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)\>`)
return re.ReplaceAllString(text, "") return re.ReplaceAllString(text, "")
}, },
"contains": strings.Contains, "contains": strings.Contains,
@ -208,6 +208,14 @@ func RegReplace(input string, match string, replace string) string {
return re.ReplaceAllString(input, replace) return re.ReplaceAllString(input, replace)
} }
func getenv(key, fallback string) string {
value := os.Getenv(key)
if len(value) == 0 {
return fallback
}
return value
}
func Initialize(Host string, r *http.Request) (State, error) { func Initialize(Host string, r *http.Request) (State, error) {
state := State{ state := State{
Host: Host, Host: Host,
@ -252,18 +260,27 @@ func Initialize(Host string, r *http.Request) (State, error) {
state.Listing = getCookie(r, "DefaultListingType") state.Listing = getCookie(r, "DefaultListingType")
state.Sort = getCookie(r, "DefaultSortType") state.Sort = getCookie(r, "DefaultSortType")
state.CommentSort = getCookie(r, "DefaultCommentSortType") state.CommentSort = getCookie(r, "DefaultCommentSortType")
state.Dark = getCookie(r, "Dark") != "" if dark := getCookie(r, "Dark"); dark != "" {
state.Dark = dark != "0"
} else {
state.Dark = os.Getenv("DARK") != ""
}
state.ShowNSFW = getCookie(r, "ShowNSFW") != "" state.ShowNSFW = getCookie(r, "ShowNSFW") != ""
state.HideInstanceNames = getCookie(r, "HideInstanceNames") != "" state.HideInstanceNames = getCookie(r, "HideInstanceNames") != ""
if hide := getCookie(r, "HideThumbnails"); hide != "" {
state.HideThumbnails = hide != "0"
} else {
state.HideThumbnails = os.Getenv("HIDE_THUMBNAILS") != ""
}
state.ParseQuery(r.URL.RawQuery) state.ParseQuery(r.URL.RawQuery)
if state.Sort == "" { if state.Sort == "" {
state.Sort = "Hot" state.Sort = getenv("SORT", "Hot")
} }
if state.CommentSort == "" { if state.CommentSort == "" {
state.CommentSort = "Hot" state.CommentSort = getenv("COMMENT_SORT", "Hot")
} }
if state.Listing == "" || state.Session == nil && state.Listing == "Subscribed" { if state.Listing == "" || state.Session == nil && state.Listing == "Subscribed" {
state.Listing = "All" state.Listing = getenv("LISTING", "All")
} }
return state, nil return state, nil
} }
@ -687,6 +704,7 @@ func Settings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
Render(w, "index.html", state) Render(w, "index.html", state)
return return
} }
state.GetSite()
switch r.Method { switch r.Method {
case "POST": case "POST":
for _, name := range []string{"DefaultSortType", "DefaultListingType", "DefaultCommentSortType"} { for _, name := range []string{"DefaultSortType", "DefaultListingType", "DefaultCommentSortType"} {
@ -697,8 +715,7 @@ func Settings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
setCookie(w, "", "Dark", "1") setCookie(w, "", "Dark", "1")
state.Dark = true state.Dark = true
} else { } else {
deleteCookie(w, state.Host, "Dark") setCookie(w, "", "Dark", "0")
deleteCookie(w, "", "Dark")
state.Dark = false state.Dark = false
} }
if r.FormValue("shownsfw") != "" { if r.FormValue("shownsfw") != "" {
@ -716,6 +733,13 @@ func Settings(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
deleteCookie(w, "", "HideInstanceNames") deleteCookie(w, "", "HideInstanceNames")
state.HideInstanceNames = false state.HideInstanceNames = false
} }
if r.FormValue("hideThumbnails") != "" {
setCookie(w, "", "HideThumbnails", "1")
state.HideInstanceNames = true
} else {
setCookie(w, "", "HideThumbnails", "0")
state.HideInstanceNames = false
}
state.Listing = r.FormValue("DefaultListingType") state.Listing = r.FormValue("DefaultListingType")
state.Sort = r.FormValue("DefaultSortType") state.Sort = r.FormValue("DefaultSortType")
state.CommentSort = r.FormValue("DefaultCommentSortType") state.CommentSort = r.FormValue("DefaultCommentSortType")

View file

@ -104,6 +104,7 @@ type State struct {
Dark bool Dark bool
ShowNSFW bool ShowNSFW bool
HideInstanceNames bool HideInstanceNames bool
HideThumbnails bool
} }
func (s State) Unknown() string { func (s State) Unknown() string {

View file

@ -52,6 +52,7 @@
{{ end }} {{ end }}
<ul class="buttons"> <ul class="buttons">
<li><a href="/{{.State.Host}}/comment/{{.P.Comment.ID}}">permalink</a></li> <li><a href="/{{.State.Host}}/comment/{{.P.Comment.ID}}">permalink</a></li>
<li><a href="{{.P.Comment.ApID}}">fedilink</a></li>
{{ if ne .Op "source"}} {{ if ne .Op "source"}}
<li><a class="source" for="c{{.P.Comment.ID}}" href="/{{.State.Host}}/comment/{{.P.Comment.ID}}?source">source</a></li> <li><a class="source" for="c{{.P.Comment.ID}}" href="/{{.State.Host}}/comment/{{.P.Comment.ID}}?source">source</a></li>
{{ else }} {{ else }}

View file

@ -23,11 +23,13 @@
{{ end }} {{ end }}
{{ if and (ne .State.Op "vote_post") (ne .State.Op "save_post") }} {{ if and (ne .State.Op "vote_post") (ne .State.Op "save_post") }}
</div> </div>
{{ if not .State.HideThumbnails }}
<div class="thumb"> <div class="thumb">
<a class="url" href="{{ if .Post.URL.IsValid }}{{ .Post.URL }}{{ else }}/{{ .State.Host }}/post/{{ .Post.ID }}{{ end }}"> <a class="url" href="{{ if .Post.URL.IsValid }}{{ .Post.URL }}{{ else }}/{{ .State.Host }}/post/{{ .Post.ID }}{{ end }}">
<div {{ if and .Post.NSFW (not (and .State.Community .State.Community.CommunityView.Community.NSFW))}}class="img-blur"{{end}} style="background-image: url({{thumbnail .Post}})"></div> <div {{ if and .Post.NSFW (not (and .State.Community .State.Community.CommunityView.Community.NSFW))}}class="img-blur"{{end}} style="background-image: url({{thumbnail .Post}})"></div>
</a> </a>
</div> </div>
{{ end }}
<div class="entry"> <div class="entry">
<div class="title"> <div class="title">
<a class="url" href="{{ if .Post.URL.IsValid }}{{ .Post.URL }}{{ else }}/{{ .State.Host }}/post/{{ .Post.ID }}{{ end }}">{{ rmmarkdown .Post.Name }}</a> <a class="url" href="{{ if .Post.URL.IsValid }}{{ .Post.URL }}{{ else }}/{{ .State.Host }}/post/{{ .Post.ID }}{{ end }}">{{ rmmarkdown .Post.Name }}</a>
@ -60,6 +62,7 @@
<div class="buttons"> <div class="buttons">
{{ if .Post.NSFW }}<span class="nsfw">NSFW</span>{{end}} {{ if .Post.NSFW }}<span class="nsfw">NSFW</span>{{end}}
<a href="/{{ .State.Host }}/post/{{ .Post.ID }}">{{ .Counts.Comments }} comments</a> <a href="/{{ .State.Host }}/post/{{ .Post.ID }}">{{ .Counts.Comments }} comments</a>
<a href="{{ .Post.ApID}}">fedilink</a>
{{ if and .State.Session (eq .State.Session.UserID .Post.CreatorID) }} {{ if and .State.Session (eq .State.Session.UserID .Post.CreatorID) }}
{{ if not .Post.Deleted }}<a href="/{{ .State.Host }}/post/{{ .Post.ID }}?edit">edit</a>{{end}} {{ if not .Post.Deleted }}<a href="/{{ .State.Host }}/post/{{ .Post.ID }}?edit">edit</a>{{end}}
<form class="link-btn" method="POST"> <form class="link-btn" method="POST">

View file

@ -125,7 +125,13 @@
<input type="checkbox" name="hideInstanceNames" {{ if .HideInstanceNames }}checked{{end}}> <input type="checkbox" name="hideInstanceNames" {{ if .HideInstanceNames }}checked{{end}}>
</div> </div>
<div> <div>
<label>mlmym: {{ .Version }}</label> <label>
hide thumbnails
</label>
<input type="checkbox" name="hideThumbnails" {{ if .HideThumbnails }}checked{{end}}>
</div>
<div>
<label>lemmy: {{ .Site.Version }}<br><a href="https://github.com/rystaf/mlmym">mlmym</a>: {{ .Version }}</label>
<input type="submit" value="save"> <input type="submit" value="save">
{{ if .XHR }}<input id="closesettings" type="submit" value="close">{{ end }} {{ if .XHR }}<input id="closesettings" type="submit" value="close">{{ end }}
</div> </div>