141 lines
3.2 KiB
Go
141 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"fmt"
|
|
"html"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
)
|
|
|
|
func isLightTheme(r *http.Request) bool {
|
|
theme := r.URL.Query().Get("th")
|
|
if theme == "light" || theme == "lightdark" {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func pageHeader(lightTheme bool, title string) []byte {
|
|
theme := "dark"
|
|
if lightTheme {
|
|
theme = "light"
|
|
}
|
|
return []byte(`<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>` + title + `</title>
|
|
<link rel="stylesheet" type="text/css" href="/css/medinet.css">
|
|
<link rel="stylesheet" type="text/css" href="/css/holo.css">
|
|
<link rel="stylesheet" type="text/css" href="/css/holo-` + theme + `.css">
|
|
<script src="/js/medinet.js"></script>
|
|
</head>
|
|
<body class="holo holo-` + theme + `">
|
|
<div class="holo-content">
|
|
<ul class="holo-list">
|
|
`)
|
|
}
|
|
|
|
func pageFooter() []byte {
|
|
return []byte(`
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
`)
|
|
}
|
|
|
|
func gravatar(light bool, size int, email string) string {
|
|
d := "https://medinet.rocket9labs.com/images/om_dark.png"
|
|
if light {
|
|
d = "https://medinet.rocket9labs.com/images/om_light.png"
|
|
}
|
|
return fmt.Sprintf("https://www.gravatar.com/avatar/%x?s=%d&d=%s", md5.Sum([]byte(email)), size, url.QueryEscape(d))
|
|
}
|
|
|
|
func formatLength(length int) string {
|
|
d := time.Duration(time.Duration(length) * time.Second)
|
|
return fmt.Sprintf("%d:%02d", int(d.Hours()), int(d.Minutes())%60)
|
|
}
|
|
|
|
func formatCompleted(completed int) string {
|
|
c := time.Unix(int64(completed), 0)
|
|
return c.Format("2006-01-02 3:04")
|
|
}
|
|
|
|
func formatRecentCompleted(completed int) string {
|
|
c := time.Unix(int64(completed), 0)
|
|
return c.Format("3:04 Jan 2")
|
|
}
|
|
|
|
func formatStreak(streakDay int) string {
|
|
if streakDay == 0 {
|
|
return ""
|
|
}
|
|
|
|
s := ""
|
|
if streakDay > 1 {
|
|
s = "s"
|
|
}
|
|
formatted := fmt.Sprintf("%d day%s of meditation", streakDay, s)
|
|
if streakDay < 10 {
|
|
formatted = "<small>" + formatted + "</small>"
|
|
}
|
|
|
|
return "<p>" + formatted + "</p>"
|
|
}
|
|
|
|
func formatMessage(message string) string {
|
|
if message == "" {
|
|
return ""
|
|
}
|
|
return "<p><small>" + html.EscapeString(message) + "</small></p>"
|
|
}
|
|
|
|
func escapeName(name string) string {
|
|
escapedName := html.EscapeString(name)
|
|
if len(name) >= 15 {
|
|
escapedName = "<small>" + escapedName + "</small>"
|
|
}
|
|
return escapedName
|
|
}
|
|
|
|
func printSession(w http.ResponseWriter, lightTheme bool, s *recentSession) {
|
|
showAccount := s.AccountID != 0
|
|
|
|
w.Write([]byte(`<table border="0" cellspacing="3px" cellpadding="0px" width="100%">
|
|
<tr>`))
|
|
|
|
if showAccount {
|
|
w.Write([]byte(fmt.Sprintf(`<td width="57px" height="57px" style="margin: 0px;padding: 0px;">
|
|
<img src="%s" width="57px" height="57px" style="margin: 0px;padding: 0px;">
|
|
</td>
|
|
<td>`, gravatar(lightTheme, 104, s.AccountEmail))))
|
|
} else {
|
|
w.Write([]byte(`<td colspan="2">`))
|
|
}
|
|
|
|
w.Write([]byte(fmt.Sprintf(`<div style="padding-left: 4px;"><span style="font-size: 2em;font-weight: bold;">%s</span>`, formatLength(s.Length))))
|
|
|
|
if showAccount {
|
|
w.Write([]byte("<br>" + escapeName(s.AccountName)))
|
|
}
|
|
|
|
var completed []byte
|
|
if showAccount {
|
|
completed = []byte(formatRecentCompleted(s.Completed))
|
|
} else {
|
|
completed = []byte(formatCompleted(s.Completed))
|
|
}
|
|
w.Write([]byte(fmt.Sprintf(`
|
|
</div></td>
|
|
<td align="right" style="vertical-align:top;font-size: 0.85em;">
|
|
%s
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
%s
|
|
%s
|
|
`, completed, formatStreak(s.StreakDay), formatMessage(s.Message))))
|
|
}
|