mirror of
1
Fork 0

[chore] Use shorter timestamps in frontend for replies (#875)

* rename timestampShort -> timestampVague

* add ParseISO8601

* start fiddling with timestamp

* pad/margin a bit more consistently

* remove visibilty icon, change timestamp use

* update timestamp logic

* check + log errors

* properly cut-off long display- and usernames

Co-authored-by: f0x <f0x@cthu.lu>
This commit is contained in:
tobi 2022-10-02 15:54:42 +02:00 committed by GitHub
parent 196e474e43
commit deba75cad1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 32 deletions

View File

@ -30,7 +30,18 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/log"
"github.com/superseriousbusiness/gotosocial/internal/regexes" "github.com/superseriousbusiness/gotosocial/internal/regexes"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
const (
justTime = "15:04"
dateYear = "Jan 02, 2006"
dateTime = "Jan 02, 15:04"
dateYearTime = "Jan 02, 2006, 15:04"
monthYear = "Jan, 2006"
badTimestamp = "bad timestamp"
) )
// LoadTemplates loads html templates for use by the given engine // LoadTemplates loads html templates for use by the given engine
@ -76,13 +87,44 @@ func noescapeAttr(str string) template.HTMLAttr {
} }
func timestamp(stamp string) string { func timestamp(stamp string) string {
t, _ := time.Parse(time.RFC3339, stamp) t, err := util.ParseISO8601(stamp)
return t.Format("January 2, 2006, 15:04:05") if err != nil {
log.Errorf("error parsing timestamp %s: %s", stamp, err)
return badTimestamp
}
t = t.Local()
tYear, tMonth, tDay := t.Date()
now := time.Now()
currentYear, currentMonth, currentDay := now.Date()
switch {
case tYear == currentYear && tMonth == currentMonth && tDay == currentDay:
return "Today, " + t.Format(justTime)
case tYear == currentYear:
return t.Format(dateTime)
default:
return t.Format(dateYear)
}
} }
func timestampShort(stamp string) string { func timestampPrecise(stamp string) string {
t, _ := time.Parse(time.RFC3339, stamp) t, err := util.ParseISO8601(stamp)
return t.Format("January, 2006") if err != nil {
log.Errorf("error parsing timestamp %s: %s", stamp, err)
return badTimestamp
}
return t.Local().Format(dateYearTime)
}
func timestampVague(stamp string) string {
t, err := util.ParseISO8601(stamp)
if err != nil {
log.Errorf("error parsing timestamp %s: %s", stamp, err)
return badTimestamp
}
return t.Format(monthYear)
} }
type iconWithLabel struct { type iconWithLabel struct {
@ -154,13 +196,14 @@ func emojify(emojis []model.Emoji, text template.HTML) template.HTML {
func LoadTemplateFunctions(engine *gin.Engine) { func LoadTemplateFunctions(engine *gin.Engine) {
engine.SetFuncMap(template.FuncMap{ engine.SetFuncMap(template.FuncMap{
"escape": escape, "escape": escape,
"noescape": noescape, "noescape": noescape,
"noescapeAttr": noescapeAttr, "noescapeAttr": noescapeAttr,
"oddOrEven": oddOrEven, "oddOrEven": oddOrEven,
"visibilityIcon": visibilityIcon, "visibilityIcon": visibilityIcon,
"timestamp": timestamp, "timestamp": timestamp,
"timestampShort": timestampShort, "timestampVague": timestampVague,
"emojify": emojify, "timestampPrecise": timestampPrecise,
"emojify": emojify,
}) })
} }

View File

@ -28,3 +28,8 @@ const ISO8601 = "2006-01-02T15:04:05.000Z"
func FormatISO8601(t time.Time) string { func FormatISO8601(t time.Time) string {
return t.UTC().Format(ISO8601) return t.UTC().Format(ISO8601)
} }
// ParseISO8601 parses the given time string according to the ISO8601 const.
func ParseISO8601(in string) (time.Time, error) {
return time.Parse(ISO8601, in)
}

View File

@ -75,28 +75,27 @@ main {
background: $bg; background: $bg;
} }
} }
.displayname, .username {
justify-self: start;
align-self: start;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* margin-top: -0.5rem; */
line-height: 2rem;
}
.displayname { .displayname {
font-weight: bold; font-weight: bold;
font-size: 1.2rem; font-size: 1.2rem;
line-height: 2rem;
margin-top: -0.5rem;
align-self: start;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.username { .username {
color: $link-fg; color: $link-fg;
line-height: 2rem;
margin-top: -0.5rem;
align-self: start;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
input.spoiler:checked ~ .content { input.spoiler:checked ~ .content {
@ -180,7 +179,7 @@ main {
} }
.media { .media {
margin-top: 0.6rem; margin-top: 0.5rem;
border-radius: $br; border-radius: $br;
grid-column: span 3; grid-column: span 3;
display: grid; display: grid;
@ -362,6 +361,7 @@ main {
.text { .text {
grid-column: 1 / span 3; grid-column: 1 / span 3;
padding-top: 0.5rem;
} }
.not-expanded { .not-expanded {
@ -372,6 +372,10 @@ main {
.info { .info {
display: flex; display: flex;
} }
.media {
margin-bottom: 0.5rem;
}
} }
} }

View File

@ -21,7 +21,7 @@
</div> </div>
</div> </div>
<div class="accountstats"> <div class="accountstats">
<div class="entry">Joined <b>{{.account.CreatedAt | timestampShort}}</b></div> <div class="entry">Joined <b>{{.account.CreatedAt | timestampVague}}</b></div>
<div class="entry">Followed by <b>{{.account.FollowersCount}}</b></div> <div class="entry">Followed by <b>{{.account.FollowersCount}}</b></div>
<div class="entry">Following <b>{{.account.FollowingCount}}</b></div> <div class="entry">Following <b>{{.account.FollowingCount}}</b></div>
<div class="entry">Posted <b>{{.account.StatusesCount}}</b></div> <div class="entry">Posted <b>{{.account.StatusesCount}}</b></div>

View File

@ -3,7 +3,6 @@
<a href="{{.Account.URL}}" class="displayname">{{if .Account.DisplayName}}{{emojify .Account.Emojis (escape .Account.DisplayName)}}{{else}}{{.Account.Username}}{{end}}</a> <a href="{{.Account.URL}}" class="displayname">{{if .Account.DisplayName}}{{emojify .Account.Emojis (escape .Account.DisplayName)}}{{else}}{{.Account.Username}}{{end}}</a>
<a href="{{.Account.URL}}" class="username">@{{.Account.Acct}}</a> <a href="{{.Account.URL}}" class="username">@{{.Account.Acct}}</a>
<div class="not-expanded"> <div class="not-expanded">
<span class="visibility">{{.Visibility | visibilityIcon}}</span>
<span class="date">{{.CreatedAt | timestamp}}</span> <span class="date">{{.CreatedAt | timestamp}}</span>
</div> </div>
<div class="text"> <div class="text">
@ -45,7 +44,7 @@
{{end}} {{end}}
</div> </div>
<div class="info"> <div class="info">
<div id="date">{{.CreatedAt | timestamp}}</div> <div id="date">{{.CreatedAt | timestampPrecise}}</div>
<div class="stats"> <div class="stats">
<div id="replies"><i aria-label="Replies" class="fa fa-reply-all"></i> {{.RepliesCount}}</div> <div id="replies"><i aria-label="Replies" class="fa fa-reply-all"></i> {{.RepliesCount}}</div>
<div id="boosts"><i aria-label="Boosts" class="fa fa-retweet"></i> {{.ReblogsCount}}</div> <div id="boosts"><i aria-label="Boosts" class="fa fa-retweet"></i> {{.ReblogsCount}}</div>