Merge pull request '[PORT] Replace DateTime with proper functions (gitea#32402)' (#5796) from gusted/forgejo-port-dateutils into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5796 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Otto <otto@codeberg.org>
This commit is contained in:
		
				commit
				
					
						f28e728317
					
				
			
		
					 39 changed files with 144 additions and 80 deletions
				
			
		| 
						 | 
				
			
			@ -52,6 +52,7 @@ func NewFuncMap() template.FuncMap {
 | 
			
		|||
		"StringUtils": NewStringUtils,
 | 
			
		||||
		"SliceUtils":  NewSliceUtils,
 | 
			
		||||
		"JsonUtils":   NewJsonUtils,
 | 
			
		||||
		"DateUtils":   NewDateUtils,
 | 
			
		||||
 | 
			
		||||
		// -----------------------------------------------------------------
 | 
			
		||||
		// svg / avatar / icon / color
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +69,7 @@ func NewFuncMap() template.FuncMap {
 | 
			
		|||
		"CountFmt":      base.FormatNumberSI,
 | 
			
		||||
		"TimeSince":     timeutil.TimeSince,
 | 
			
		||||
		"TimeSinceUnix": timeutil.TimeSinceUnix,
 | 
			
		||||
		"DateTime":      timeutil.DateTime,
 | 
			
		||||
		"DateTime":      dateTimeLegacy, // for backward compatibility only, do not use it anymore
 | 
			
		||||
		"Sec2Time":      util.SecToTime,
 | 
			
		||||
		"LoadTimes": func(startTime time.Time) string {
 | 
			
		||||
			return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										60
									
								
								modules/templates/util_date.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								modules/templates/util_date.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
// Copyright 2024 The Gitea Authors. All rights reserved.
 | 
			
		||||
// SPDX-License-Identifier: MIT
 | 
			
		||||
 | 
			
		||||
package templates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DateUtils struct {
 | 
			
		||||
	ctx context.Context
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewDateUtils(ctx context.Context) *DateUtils {
 | 
			
		||||
	return &DateUtils{ctx}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AbsoluteShort renders in "Jan 01, 2006" format
 | 
			
		||||
func (du *DateUtils) AbsoluteShort(time any) template.HTML {
 | 
			
		||||
	return timeutil.DateTime("short", time)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AbsoluteLong renders in "January 01, 2006" format
 | 
			
		||||
func (du *DateUtils) AbsoluteLong(time any) template.HTML {
 | 
			
		||||
	return timeutil.DateTime("long", time)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FullTime renders in "Jan 01, 2006 20:33:44" format
 | 
			
		||||
func (du *DateUtils) FullTime(time any) template.HTML {
 | 
			
		||||
	return timeutil.DateTime("full", time)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseLegacy parses the datetime in legacy format, eg: "2016-01-02" in server's timezone.
 | 
			
		||||
// It shouldn't be used in new code. New code should use Time or TimeStamp as much as possible.
 | 
			
		||||
func (du *DateUtils) ParseLegacy(datetime string) time.Time {
 | 
			
		||||
	return parseLegacy(datetime)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseLegacy(datetime string) time.Time {
 | 
			
		||||
	t, err := time.Parse(time.RFC3339, datetime)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t, _ = time.ParseInLocation(time.DateOnly, datetime, setting.DefaultUILocation)
 | 
			
		||||
	}
 | 
			
		||||
	return t
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func dateTimeLegacy(format string, datetime any, _ ...string) template.HTML {
 | 
			
		||||
	if !setting.IsProd || setting.IsInTesting {
 | 
			
		||||
		panic("dateTimeLegacy is for backward compatibility only, do not use it in new code")
 | 
			
		||||
	}
 | 
			
		||||
	if s, ok := datetime.(string); ok {
 | 
			
		||||
		datetime = parseLegacy(s)
 | 
			
		||||
	}
 | 
			
		||||
	return timeutil.DateTime(format, datetime)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +1,61 @@
 | 
			
		|||
// Copyright 2023 The Gitea Authors. All rights reserved.
 | 
			
		||||
// SPDX-License-Identifier: MIT
 | 
			
		||||
 | 
			
		||||
package timeutil
 | 
			
		||||
package templates
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"code.gitea.io/gitea/modules/setting"
 | 
			
		||||
	"code.gitea.io/gitea/modules/test"
 | 
			
		||||
	"code.gitea.io/gitea/modules/timeutil"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"github.com/stretchr/testify/require"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestDateTime(t *testing.T) {
 | 
			
		||||
	testTz, _ := time.LoadLocation("America/New_York")
 | 
			
		||||
	testTz, err := time.LoadLocation("America/New_York")
 | 
			
		||||
	require.NoError(t, err)
 | 
			
		||||
	defer test.MockVariableValue(&setting.DefaultUILocation, testTz)()
 | 
			
		||||
	defer test.MockVariableValue(&setting.IsInTesting, false)()
 | 
			
		||||
 | 
			
		||||
	du := NewDateUtils(nil)
 | 
			
		||||
 | 
			
		||||
	refTimeStr := "2018-01-01T00:00:00Z"
 | 
			
		||||
	refDateStr := "2018-01-01"
 | 
			
		||||
	refTime, _ := time.Parse(time.RFC3339, refTimeStr)
 | 
			
		||||
	refTimeStamp := TimeStamp(refTime.Unix())
 | 
			
		||||
	refTimeStamp := timeutil.TimeStamp(refTime.Unix())
 | 
			
		||||
 | 
			
		||||
	assert.EqualValues(t, "-", DateTime("short", nil))
 | 
			
		||||
	assert.EqualValues(t, "-", DateTime("short", 0))
 | 
			
		||||
	assert.EqualValues(t, "-", DateTime("short", time.Time{}))
 | 
			
		||||
	assert.EqualValues(t, "-", DateTime("short", TimeStamp(0)))
 | 
			
		||||
	for _, val := range []any{nil, 0, time.Time{}, timeutil.TimeStamp(0)} {
 | 
			
		||||
		for _, fun := range []func(val any) template.HTML{du.AbsoluteLong, du.AbsoluteShort, du.FullTime} {
 | 
			
		||||
			assert.EqualValues(t, "-", fun(val))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	actual := DateTime("short", "invalid")
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="invalid">invalid</absolute-date>`, actual)
 | 
			
		||||
	actual := dateTimeLegacy("short", "invalid")
 | 
			
		||||
	assert.EqualValues(t, `-`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = DateTime("short", refTimeStr)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = DateTime("short", refTime)
 | 
			
		||||
	actual = dateTimeLegacy("short", refTimeStr)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = DateTime("short", refDateStr)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01">2018-01-01</absolute-date>`, actual)
 | 
			
		||||
	actual = du.AbsoluteShort(refTime)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = DateTime("short", refTimeStamp)
 | 
			
		||||
	actual = du.AbsoluteLong(refTime)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="long" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = dateTimeLegacy("short", refDateStr)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00-05:00">2018-01-01</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = du.AbsoluteShort(refTimeStamp)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="short" day="numeric" date="2017-12-31T19:00:00-05:00">2017-12-31</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = DateTime("full", refTimeStamp)
 | 
			
		||||
	actual = du.AbsoluteLong(refTimeStamp)
 | 
			
		||||
	assert.EqualValues(t, `<absolute-date weekday="" year="numeric" month="long" day="numeric" date="2017-12-31T19:00:00-05:00">2017-12-31</absolute-date>`, actual)
 | 
			
		||||
 | 
			
		||||
	actual = du.FullTime(refTimeStamp)
 | 
			
		||||
	assert.EqualValues(t, `<relative-time weekday="" year="numeric" format="datetime" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" data-tooltip-content data-tooltip-interactive="true" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,9 +12,7 @@ import (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
// DateTime renders an absolute time HTML element by datetime.
 | 
			
		||||
func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
 | 
			
		||||
	// TODO: remove the extraAttrs argument, it's not used in any call to DateTime
 | 
			
		||||
 | 
			
		||||
func DateTime(format string, datetime any) template.HTML {
 | 
			
		||||
	if p, ok := datetime.(*time.Time); ok {
 | 
			
		||||
		datetime = *p
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -34,9 +32,6 @@ func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
 | 
			
		|||
	switch v := datetime.(type) {
 | 
			
		||||
	case nil:
 | 
			
		||||
		return "-"
 | 
			
		||||
	case string:
 | 
			
		||||
		datetimeEscaped = html.EscapeString(v)
 | 
			
		||||
		textEscaped = datetimeEscaped
 | 
			
		||||
	case time.Time:
 | 
			
		||||
		if v.IsZero() || v.Unix() == 0 {
 | 
			
		||||
			return "-"
 | 
			
		||||
| 
						 | 
				
			
			@ -51,10 +46,7 @@ func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
 | 
			
		|||
		panic(fmt.Sprintf("Unsupported time type %T", datetime))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	attrs := make([]string, 0, 10+len(extraAttrs))
 | 
			
		||||
	attrs = append(attrs, extraAttrs...)
 | 
			
		||||
	attrs = append(attrs, `weekday=""`, `year="numeric"`)
 | 
			
		||||
 | 
			
		||||
	attrs := []string{`weekday=""`, `year="numeric"`}
 | 
			
		||||
	switch format {
 | 
			
		||||
	case "short", "long": // date only
 | 
			
		||||
		attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,8 +48,8 @@ func Activity(ctx *context.Context) {
 | 
			
		|||
		ctx.Data["Period"] = "weekly"
 | 
			
		||||
		timeFrom = timeUntil.Add(-time.Hour * 168)
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Data["DateFrom"] = timeFrom.UTC().Format(time.RFC3339)
 | 
			
		||||
	ctx.Data["DateUntil"] = timeUntil.UTC().Format(time.RFC3339)
 | 
			
		||||
	ctx.Data["DateFrom"] = timeFrom
 | 
			
		||||
	ctx.Data["DateUntil"] = timeUntil
 | 
			
		||||
	ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string))
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,6 +102,7 @@ func NewTemplateContextForWeb(ctx *Context) TemplateContext {
 | 
			
		|||
	tmplCtx := NewTemplateContext(ctx)
 | 
			
		||||
	tmplCtx["Locale"] = ctx.Base.Locale
 | 
			
		||||
	tmplCtx["AvatarUtils"] = templates.NewAvatarUtils(ctx)
 | 
			
		||||
	tmplCtx["DateUtils"] = templates.NewDateUtils(ctx)
 | 
			
		||||
	return tmplCtx
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,8 +26,8 @@
 | 
			
		|||
							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td>
 | 
			
		||||
							<td>{{.TypeName}}</td>
 | 
			
		||||
							<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .UpdatedUnix}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .CreatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
 | 
			
		||||
							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{svg "octicon-pencil"}}</a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,8 +23,8 @@
 | 
			
		|||
							<td><button type="submit" class="ui primary button" name="op" value="{{.Name}}" title="{{ctx.Locale.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
 | 
			
		||||
							<td>{{ctx.Locale.Tr (printf "admin.dashboard.%s" .Name)}}</td>
 | 
			
		||||
							<td>{{.Spec}}</td>
 | 
			
		||||
							<td>{{DateTime "full" .Next}}</td>
 | 
			
		||||
							<td>{{if gt .Prev.Year 1}}{{DateTime "full" .Prev}}{{else}}-{{end}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.FullTime .Next}}</td>
 | 
			
		||||
							<td>{{if gt .Prev.Year 1}}{{ctx.DateUtils.FullTime .Prev}}{{else}}-{{end}}</td>
 | 
			
		||||
							<td>{{.ExecTimes}}</td>
 | 
			
		||||
							<td {{if ne .Status ""}}data-tooltip-content="{{.FormatLastMessage ctx.Locale}}"{{end}} >{{if eq .Status ""}}—{{else if eq .Status "finished"}}{{svg "octicon-check" 16}}{{else}}{{svg "octicon-x" 16}}{{end}}</td>
 | 
			
		||||
						</tr>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
						<td>{{.ID}}</td>
 | 
			
		||||
						<td>{{ctx.Locale.Tr .TrStr}}</td>
 | 
			
		||||
						<td class="view-detail auto-ellipsis tw-w-4/5"><span class="notice-description">{{.Description}}</span></td>
 | 
			
		||||
						<td nowrap>{{DateTime "short" .CreatedUnix}}</td>
 | 
			
		||||
						<td nowrap>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
 | 
			
		||||
						<td class="view-detail"><a href="#">{{svg "octicon-note" 16}}</a></td>
 | 
			
		||||
					</tr>
 | 
			
		||||
				{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,7 +63,7 @@
 | 
			
		|||
							<td>{{.NumTeams}}</td>
 | 
			
		||||
							<td>{{.NumMembers}}</td>
 | 
			
		||||
							<td>{{.NumRepos}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .CreatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
 | 
			
		||||
							<td><a href="{{.OrganisationLink}}/settings" data-tooltip-content="{{ctx.Locale.Tr "edit"}}">{{svg "octicon-pencil"}}</a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@
 | 
			
		|||
							{{end}}
 | 
			
		||||
							</td>
 | 
			
		||||
							<td>{{ctx.Locale.TrSize .CalculateBlobSize}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .Version.CreatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
 | 
			
		||||
							<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Paginater.Current}}&sort={{$.SortType}}" data-id="{{.Version.ID}}" data-name="{{.Package.Name}}" data-data-version="{{.Version.Version}}">{{svg "octicon-trash"}}</a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,8 +82,8 @@
 | 
			
		|||
							<td>{{.NumIssues}}</td>
 | 
			
		||||
							<td>{{ctx.Locale.TrSize .GitSize}}</td>
 | 
			
		||||
							<td>{{ctx.Locale.TrSize .LFSSize}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .UpdatedUnix}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .CreatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
 | 
			
		||||
							<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Paginater.Current}}&sort={{$.SortType}}" data-id="{{.ID}}" data-name="{{.Name}}">{{svg "octicon-trash"}}</a></td>
 | 
			
		||||
						</tr>
 | 
			
		||||
					{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,9 +96,9 @@
 | 
			
		|||
							<td>{{if .IsActive}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
 | 
			
		||||
							<td>{{if .IsRestricted}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
 | 
			
		||||
							<td>{{if index $.UsersTwoFaStatus .ID}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}</td>
 | 
			
		||||
							<td>{{DateTime "short" .CreatedUnix}}</td>
 | 
			
		||||
							<td>{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</td>
 | 
			
		||||
							{{if .LastLoginUnix}}
 | 
			
		||||
								<td>{{DateTime "short" .LastLoginUnix}}</td>
 | 
			
		||||
								<td>{{ctx.DateUtils.AbsoluteShort .LastLoginUnix}}</td>
 | 
			
		||||
							{{else}}
 | 
			
		||||
								<td><span>{{ctx.Locale.Tr "admin.users.never_login"}}</span></td>
 | 
			
		||||
							{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
							<a href="mailto:{{.Email}}">{{.Email}}</a>
 | 
			
		||||
						</span>
 | 
			
		||||
					{{end}}
 | 
			
		||||
					<span class="flex-text-inline">{{svg "octicon-calendar"}}{{ctx.Locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix)}}</span>
 | 
			
		||||
					<span class="flex-text-inline">{{svg "octicon-calendar"}}{{ctx.Locale.Tr "user.joined_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
					<td><a href="{{.VersionWebLink}}">{{.Version.Version}}</a></td>
 | 
			
		||||
					<td><a href="{{.Creator.HomeLink}}">{{.Creator.Name}}</a></td>
 | 
			
		||||
					<td>{{ctx.Locale.TrSize .CalculateBlobSize}}</td>
 | 
			
		||||
					<td>{{DateTime "short" .Version.CreatedUnix}}</td>
 | 
			
		||||
					<td>{{ctx.DateUtils.AbsoluteShort .Version.CreatedUnix}}</td>
 | 
			
		||||
				</tr>
 | 
			
		||||
			{{else}}
 | 
			
		||||
				<tr>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,7 +94,7 @@
 | 
			
		|||
				{{range .LatestVersions}}
 | 
			
		||||
					<div class="item tw-flex">
 | 
			
		||||
						<a class="tw-flex-1 gt-ellipsis" title="{{.Version}}" href="{{$.PackageDescriptor.PackageWebLink}}/{{PathEscape .LowerVersion}}">{{.Version}}</a>
 | 
			
		||||
						<span class="text small">{{DateTime "short" .CreatedUnix}}</span>
 | 
			
		||||
						<span class="text small">{{ctx.DateUtils.AbsoluteShort .CreatedUnix}}</span>
 | 
			
		||||
					</div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
				</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@
 | 
			
		|||
					{{if .Repository.ArchivedUnix.IsZero}}
 | 
			
		||||
						{{ctx.Locale.Tr "repo.archive.title"}}
 | 
			
		||||
					{{else}}
 | 
			
		||||
						{{ctx.Locale.Tr "repo.archive.title_date" (DateTime "long" .Repository.ArchivedUnix)}}
 | 
			
		||||
						{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@
 | 
			
		|||
						{{if .Repository.ArchivedUnix.IsZero}}
 | 
			
		||||
							{{ctx.Locale.Tr "repo.archive.title"}}
 | 
			
		||||
						{{else}}
 | 
			
		||||
							{{ctx.Locale.Tr "repo.archive.title_date" (DateTime "long" .Repository.ArchivedUnix)}}
 | 
			
		||||
							{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
					</div>
 | 
			
		||||
				{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,7 +71,7 @@
 | 
			
		|||
							{{$userName}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
					</span>
 | 
			
		||||
					<span class="time tw-flex tw-items-center">{{DateTime "full" $commit.Date}}</span>
 | 
			
		||||
					<span class="time tw-flex tw-items-center">{{ctx.DateUtils.FullTime $commit.Date}}</span>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</li>
 | 
			
		||||
		{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@
 | 
			
		|||
				{{if .Repository.ArchivedUnix.IsZero}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.archive.title"}}
 | 
			
		||||
				{{else}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.archive.title_date" (DateTime "long" .Repository.ArchivedUnix)}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.archive.title_date" (ctx.DateUtils.AbsoluteLong .Repository.ArchivedUnix)}}
 | 
			
		||||
				{{end}}
 | 
			
		||||
			</div>
 | 
			
		||||
		{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@
 | 
			
		|||
						{{if .Milestone.DeadlineString}}
 | 
			
		||||
							<span{{if .IsOverdue}} class="text red"{{end}}>
 | 
			
		||||
								{{svg "octicon-calendar"}}
 | 
			
		||||
								{{DateTime "short" .Milestone.DeadlineString}}
 | 
			
		||||
								{{ctx.DateUtils.AbsoluteShort (.Milestone.DeadlineString|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
							</span>
 | 
			
		||||
						{{else}}
 | 
			
		||||
							{{svg "octicon-calendar"}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@
 | 
			
		|||
									{{if .DeadlineString}}
 | 
			
		||||
										<span class="flex-text-inline {{if .IsOverdue}}text red{{end}}">
 | 
			
		||||
											{{svg "octicon-calendar" 14}}
 | 
			
		||||
											{{DateTime "short" .DeadlineString}}
 | 
			
		||||
											{{ctx.DateUtils.AbsoluteShort (.DeadlineString|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
										</span>
 | 
			
		||||
									{{else}}
 | 
			
		||||
										{{svg "octicon-calendar" 14}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -300,7 +300,8 @@
 | 
			
		|||
				{{template "shared/user/avatarlink" dict "user" .Poster}}
 | 
			
		||||
				<span class="text grey muted-links">
 | 
			
		||||
					{{template "shared/user/authorlink" .Poster}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.issues.due_date_added" (DateTime "long" .Content) $createdStr}}
 | 
			
		||||
					{{$dueDate := ctx.DateUtils.AbsoluteLong (.Content|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.issues.due_date_added" $dueDate $createdStr}}
 | 
			
		||||
				</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		{{else if eq .Type 17}}
 | 
			
		||||
| 
						 | 
				
			
			@ -311,8 +312,8 @@
 | 
			
		|||
					{{template "shared/user/authorlink" .Poster}}
 | 
			
		||||
					{{$parsedDeadline := StringUtils.Split .Content "|"}}
 | 
			
		||||
					{{if eq (len $parsedDeadline) 2}}
 | 
			
		||||
						{{$from := DateTime "long" (index $parsedDeadline 1)}}
 | 
			
		||||
						{{$to := DateTime "long" (index $parsedDeadline 0)}}
 | 
			
		||||
						{{$to := ctx.DateUtils.AbsoluteLong ((index $parsedDeadline 0)|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
						{{$from := ctx.DateUtils.AbsoluteLong ((index $parsedDeadline 1)|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
						{{ctx.Locale.Tr "repo.issues.due_date_modified" $to $from $createdStr}}
 | 
			
		||||
					{{end}}
 | 
			
		||||
				</span>
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +324,8 @@
 | 
			
		|||
				{{template "shared/user/avatarlink" dict "user" .Poster}}
 | 
			
		||||
				<span class="text grey muted-links">
 | 
			
		||||
					{{template "shared/user/authorlink" .Poster}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.issues.due_date_remove" (DateTime "long" .Content) $createdStr}}
 | 
			
		||||
					{{$dueDate := ctx.DateUtils.AbsoluteLong (.Content|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
					{{ctx.Locale.Tr "repo.issues.due_date_remove" $dueDate $createdStr}}
 | 
			
		||||
				</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		{{else if eq .Type 19}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@
 | 
			
		|||
			<div class="tw-flex tw-justify-between tw-items-center">
 | 
			
		||||
				<div class="due-date {{if .Issue.IsOverdue}}text red{{end}}" {{if .Issue.IsOverdue}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date_overdue"}}"{{end}}>
 | 
			
		||||
					{{svg "octicon-calendar" 16 "tw-mr-2"}}
 | 
			
		||||
					{{DateTime "long" .Issue.DeadlineUnix.FormatDate}}
 | 
			
		||||
					{{ctx.DateUtils.AbsoluteLong .Issue.DeadlineUnix}}
 | 
			
		||||
				</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					{{if and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<h2 class="ui header activity-header">
 | 
			
		||||
	<span>{{DateTime "long" .DateFrom}} - {{DateTime "long" .DateUntil}}</span>
 | 
			
		||||
	<span>{{ctx.DateUtils.AbsoluteLong .DateFrom}} - {{ctx.DateUtils.AbsoluteLong .DateUntil}}</span>
 | 
			
		||||
	<!-- Period -->
 | 
			
		||||
	<div class="ui floating dropdown jump filter">
 | 
			
		||||
		<div class="ui basic compact button">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@
 | 
			
		|||
									{{.Fingerprint}}
 | 
			
		||||
								</div>
 | 
			
		||||
								<div class="flex-item-body">
 | 
			
		||||
									<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{DateTime "short" .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}} - <span>{{ctx.Locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{ctx.Locale.Tr "settings.can_write_info"}} {{end}}</span></p>
 | 
			
		||||
									<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}} —  {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}} - <span>{{ctx.Locale.Tr "settings.can_read_info"}}{{if not .IsReadOnly}} / {{ctx.Locale.Tr "settings.can_write_info"}} {{end}}</span></p>
 | 
			
		||||
								</div>
 | 
			
		||||
							</div>
 | 
			
		||||
							<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,7 +154,7 @@
 | 
			
		|||
							<tr>
 | 
			
		||||
								<td>{{.PullMirror.RemoteAddress}}</td>
 | 
			
		||||
								<td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.pull"}}</td>
 | 
			
		||||
								<td>{{DateTime "full" .PullMirror.UpdatedUnix}}</td>
 | 
			
		||||
								<td>{{ctx.DateUtils.FullTime .PullMirror.UpdatedUnix}}</td>
 | 
			
		||||
								<td class="right aligned">
 | 
			
		||||
									<form method="post" class="tw-inline-block">
 | 
			
		||||
										{{.CsrfTokenHtml}}
 | 
			
		||||
| 
						 | 
				
			
			@ -243,9 +243,9 @@
 | 
			
		|||
							<tr>
 | 
			
		||||
								<td class="tw-break-anywhere">{{.RemoteAddress}}</td>
 | 
			
		||||
								<td>{{ctx.Locale.Tr "repo.settings.mirror_settings.direction.push"}}</td>
 | 
			
		||||
								<td>{{if .LastUpdateUnix}}{{DateTime "full" .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td>
 | 
			
		||||
								<td>{{if .LastUpdateUnix}}{{ctx.DateUtils.FullTime .LastUpdateUnix}}{{else}}{{ctx.Locale.Tr "never"}}{{end}} {{if .LastError}}<div class="ui red label" data-tooltip-content="{{.LastError}}">{{ctx.Locale.Tr "error"}}</div>{{end}}</td>
 | 
			
		||||
								<td>{{if not (eq (len .GetPublicKey) 0)}}<a data-clipboard-text="{{.GetPublicKey}}">{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.copy_public_key"}}</a>{{else}}{{ctx.Locale.Tr "repo.settings.mirror_settings.push_mirror.none_ssh"}}{{end}}</td>
 | 
			
		||||
								<td class="right aligned df">
 | 
			
		||||
								<td class="right aligned">
 | 
			
		||||
									<button
 | 
			
		||||
										class="ui tiny button show-modal"
 | 
			
		||||
										data-modal="#push-mirror-edit-modal"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
						{{else if .Location}}
 | 
			
		||||
							{{svg "octicon-location"}} {{.Location}}
 | 
			
		||||
						{{else}}
 | 
			
		||||
							{{svg "octicon-calendar"}} {{ctx.Locale.Tr "user.joined_on" (DateTime "short" .CreatedUnix)}}
 | 
			
		||||
							{{svg "octicon-calendar"}} {{ctx.Locale.Tr "user.joined_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}
 | 
			
		||||
						{{end}}
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,7 +117,7 @@
 | 
			
		|||
						<span class="due-date flex-text-inline" data-tooltip-content="{{ctx.Locale.Tr "repo.issues.due_date"}}">
 | 
			
		||||
							<span{{if .IsOverdue}} class="text red"{{end}}>
 | 
			
		||||
								{{svg "octicon-calendar" 14}}
 | 
			
		||||
								{{DateTime "short" (.DeadlineUnix.FormatDate)}}
 | 
			
		||||
								{{ctx.DateUtils.AbsoluteShort .DeadlineUnix}}
 | 
			
		||||
							</span>
 | 
			
		||||
						</span>
 | 
			
		||||
					{{end}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@
 | 
			
		|||
			</div>
 | 
			
		||||
			<div class="flex-item-trailing">
 | 
			
		||||
				<span class="color-text-light-2">
 | 
			
		||||
					{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}}
 | 
			
		||||
					{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}
 | 
			
		||||
				</span>
 | 
			
		||||
				<button class="ui btn interact-bg link-action tw-p-2"
 | 
			
		||||
					data-url="{{$.Link}}/delete?id={{.ID}}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@
 | 
			
		|||
					</li>
 | 
			
		||||
				{{end}}
 | 
			
		||||
			{{end}}
 | 
			
		||||
			<li>{{svg "octicon-calendar"}} <span>{{ctx.Locale.Tr "user.joined_on" (DateTime "short" .ContextUser.CreatedUnix)}}</span></li>
 | 
			
		||||
			<li>{{svg "octicon-calendar"}} <span>{{ctx.Locale.Tr "user.joined_on" (ctx.DateUtils.AbsoluteShort .ContextUser.CreatedUnix)}}</span></li>
 | 
			
		||||
			{{if and .Orgs .HasOrgsVisible}}
 | 
			
		||||
			<li>
 | 
			
		||||
				<ul class="user-orgs">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@
 | 
			
		|||
			</div>
 | 
			
		||||
			<div class="flex-item-trailing">
 | 
			
		||||
				<span class="color-text-light-2">
 | 
			
		||||
					{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}}
 | 
			
		||||
					{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}
 | 
			
		||||
				</span>
 | 
			
		||||
				<button class="btn interact-bg tw-p-2 show-modal"
 | 
			
		||||
					data-tooltip-content="{{ctx.Locale.Tr "actions.variables.edit"}}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,7 +116,7 @@
 | 
			
		|||
											{{if .DeadlineString}}
 | 
			
		||||
												<span{{if .IsOverdue}} class="text red"{{end}}>
 | 
			
		||||
													{{svg "octicon-calendar" 14}}
 | 
			
		||||
													{{DateTime "short" .DeadlineString}}
 | 
			
		||||
													{{ctx.DateUtils.AbsoluteShort (.DeadlineString|ctx.DateUtils.ParseLegacy)}}
 | 
			
		||||
												</span>
 | 
			
		||||
											{{else}}
 | 
			
		||||
												{{svg "octicon-calendar" 14}}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@
 | 
			
		|||
								</ul>
 | 
			
		||||
							</details>
 | 
			
		||||
							<div class="flex-item-body">
 | 
			
		||||
								<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{DateTime "short" .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
								<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@
 | 
			
		|||
				<div class="flex-item-main">
 | 
			
		||||
					<div class="flex-item-title">{{.Application.Name}}</div>
 | 
			
		||||
					<div class="flex-item-body">
 | 
			
		||||
						<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}}</p>
 | 
			
		||||
						<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}</p>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,15 +63,9 @@
 | 
			
		|||
						<b>{{ctx.Locale.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.PaddedKeyID}} {{end}}
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="flex-item-body">
 | 
			
		||||
						<p>
 | 
			
		||||
							{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .AddedUnix)}}
 | 
			
		||||
							-
 | 
			
		||||
							{{if not .ExpiredUnix.IsZero}}
 | 
			
		||||
								{{ctx.Locale.Tr "settings.valid_until_date" (DateTime "short" .ExpiredUnix)}}
 | 
			
		||||
							{{else}}
 | 
			
		||||
								{{ctx.Locale.Tr "settings.valid_forever"}}
 | 
			
		||||
							{{end}}
 | 
			
		||||
						</p>
 | 
			
		||||
						<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .AddedUnix)}}</p>
 | 
			
		||||
						-
 | 
			
		||||
						<p>{{if not .ExpiredUnix.IsZero}}{{ctx.Locale.Tr "settings.valid_until_date" (ctx.DateUtils.AbsoluteShort .ExpiredUnix)}}{{else}}{{ctx.Locale.Tr "settings.valid_forever"}}{{end}}</p>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@
 | 
			
		|||
					<div class="flex-item-main">
 | 
			
		||||
						<div class="flex-item-title">{{.Name}}</div>
 | 
			
		||||
						<div class="flex-item-body">
 | 
			
		||||
							<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}} —  {{svg "octicon-info" 16}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateTime "short" .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
							<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}} —  {{svg "octicon-info" 16}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,7 +53,7 @@
 | 
			
		|||
								{{.Fingerprint}}
 | 
			
		||||
						</div>
 | 
			
		||||
						<div class="flex-item-body">
 | 
			
		||||
								<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}} — {{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{DateTime "short" .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
								<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}} —	{{svg "octicon-info"}} {{if .HasUsed}}{{ctx.Locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="text green"{{end}}>{{ctx.DateUtils.AbsoluteShort .UpdatedUnix}}</span>{{else}}{{ctx.Locale.Tr "settings.no_activity"}}{{end}}</p>
 | 
			
		||||
						</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@
 | 
			
		|||
				<div class="flex-item-main">
 | 
			
		||||
					<div class="flex-item-title">{{.Name}}</div>
 | 
			
		||||
					<div class="flex-item-body">
 | 
			
		||||
						<p>{{ctx.Locale.Tr "settings.added_on" (DateTime "short" .CreatedUnix)}}</p>
 | 
			
		||||
						<p>{{ctx.Locale.Tr "settings.added_on" (ctx.DateUtils.AbsoluteShort .CreatedUnix)}}</p>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="flex-item-trailing">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue