mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Refactor struct's time to remove unnecessary memory usage (#3142)
* refactor struct's time to remove unnecessary memory usage * use AsTimePtr simple code * fix tests * fix time compare * fix template on gpg * use AddDuration instead of Add
This commit is contained in:
		| @@ -18,6 +18,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| @@ -85,15 +86,9 @@ type Action struct { | |||||||
| 	Comment     *Comment    `xorm:"-"` | 	Comment     *Comment    `xorm:"-"` | ||||||
| 	IsDeleted   bool        `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsDeleted   bool        `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	RefName     string | 	RefName     string | ||||||
| 	IsPrivate   bool      `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsPrivate   bool           `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	Content     string    `xorm:"TEXT"` | 	Content     string         `xorm:"TEXT"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (a *Action) AfterLoad() { |  | ||||||
| 	a.Created = time.Unix(a.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetOpType gets the ActionType of this action. | // GetOpType gets the ActionType of this action. | ||||||
| @@ -229,7 +224,7 @@ func (a *Action) GetContent() string { | |||||||
|  |  | ||||||
| // GetCreate returns the action creation time. | // GetCreate returns the action creation time. | ||||||
| func (a *Action) GetCreate() time.Time { | func (a *Action) GetCreate() time.Time { | ||||||
| 	return a.Created | 	return a.CreatedUnix.AsTime() | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetIssueInfos returns a list of issues associated with | // GetIssueInfos returns a list of issues associated with | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| @@ -26,14 +25,8 @@ const ( | |||||||
| type Notice struct { | type Notice struct { | ||||||
| 	ID          int64 `xorm:"pk autoincr"` | 	ID          int64 `xorm:"pk autoincr"` | ||||||
| 	Type        NoticeType | 	Type        NoticeType | ||||||
| 	Description string    `xorm:"TEXT"` | 	Description string         `xorm:"TEXT"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (n *Notice) AfterLoad() { |  | ||||||
| 	n.Created = time.Unix(n.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // TrStr returns a translation format string. | // TrStr returns a translation format string. | ||||||
|   | |||||||
| @@ -10,11 +10,11 @@ import ( | |||||||
| 	"mime/multipart" | 	"mime/multipart" | ||||||
| 	"os" | 	"os" | ||||||
| 	"path" | 	"path" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Attachment represent a attachment of issue/comment/release. | // Attachment represent a attachment of issue/comment/release. | ||||||
| @@ -25,15 +25,8 @@ type Attachment struct { | |||||||
| 	ReleaseID     int64  `xorm:"INDEX"` | 	ReleaseID     int64  `xorm:"INDEX"` | ||||||
| 	CommentID     int64 | 	CommentID     int64 | ||||||
| 	Name          string | 	Name          string | ||||||
| 	DownloadCount int64     `xorm:"DEFAULT 0"` | 	DownloadCount int64          `xorm:"DEFAULT 0"` | ||||||
| 	Created       time.Time `xorm:"-"` | 	CreatedUnix   util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix   int64     `xorm:"created"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the value of a field of |  | ||||||
| // this object. |  | ||||||
| func (a *Attachment) AfterLoad() { |  | ||||||
| 	a.Created = time.Unix(a.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // IncreaseDownloadCount is update download count + 1 | // IncreaseDownloadCount is update download count + 1 | ||||||
|   | |||||||
| @@ -29,12 +29,10 @@ type ProtectedBranch struct { | |||||||
| 	BranchName       string `xorm:"UNIQUE(s)"` | 	BranchName       string `xorm:"UNIQUE(s)"` | ||||||
| 	CanPush          bool   `xorm:"NOT NULL DEFAULT false"` | 	CanPush          bool   `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	EnableWhitelist  bool | 	EnableWhitelist  bool | ||||||
| 	WhitelistUserIDs []int64   `xorm:"JSON TEXT"` | 	WhitelistUserIDs []int64        `xorm:"JSON TEXT"` | ||||||
| 	WhitelistTeamIDs []int64   `xorm:"JSON TEXT"` | 	WhitelistTeamIDs []int64        `xorm:"JSON TEXT"` | ||||||
| 	Created          time.Time `xorm:"-"` | 	CreatedUnix      util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix      int64     `xorm:"created"` | 	UpdatedUnix      util.TimeStamp `xorm:"updated"` | ||||||
| 	Updated          time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix      int64     `xorm:"updated"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // IsProtected returns if the branch is protected | // IsProtected returns if the branch is protected | ||||||
| @@ -197,19 +195,13 @@ func (repo *Repository) DeleteProtectedBranch(id int64) (err error) { | |||||||
|  |  | ||||||
| // DeletedBranch struct | // DeletedBranch struct | ||||||
| type DeletedBranch struct { | type DeletedBranch struct { | ||||||
| 	ID          int64     `xorm:"pk autoincr"` | 	ID          int64          `xorm:"pk autoincr"` | ||||||
| 	RepoID      int64     `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	RepoID      int64          `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Name        string    `xorm:"UNIQUE(s) NOT NULL"` | 	Name        string         `xorm:"UNIQUE(s) NOT NULL"` | ||||||
| 	Commit      string    `xorm:"UNIQUE(s) NOT NULL"` | 	Commit      string         `xorm:"UNIQUE(s) NOT NULL"` | ||||||
| 	DeletedByID int64     `xorm:"INDEX"` | 	DeletedByID int64          `xorm:"INDEX"` | ||||||
| 	DeletedBy   *User     `xorm:"-"` | 	DeletedBy   *User          `xorm:"-"` | ||||||
| 	Deleted     time.Time `xorm:"-"` | 	DeletedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	DeletedUnix int64     `xorm:"INDEX created"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (deletedBranch *DeletedBranch) AfterLoad() { |  | ||||||
| 	deletedBranch.Deleted = time.Unix(deletedBranch.DeletedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AddDeletedBranch adds a deleted branch to the database | // AddDeletedBranch adds a deleted branch to the database | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/git" | 	"code.gitea.io/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"github.com/keybase/go-crypto/openpgp" | 	"github.com/keybase/go-crypto/openpgp" | ||||||
| @@ -26,17 +27,14 @@ import ( | |||||||
|  |  | ||||||
| // GPGKey represents a GPG key. | // GPGKey represents a GPG key. | ||||||
| type GPGKey struct { | type GPGKey struct { | ||||||
| 	ID                int64     `xorm:"pk autoincr"` | 	ID                int64          `xorm:"pk autoincr"` | ||||||
| 	OwnerID           int64     `xorm:"INDEX NOT NULL"` | 	OwnerID           int64          `xorm:"INDEX NOT NULL"` | ||||||
| 	KeyID             string    `xorm:"INDEX CHAR(16) NOT NULL"` | 	KeyID             string         `xorm:"INDEX CHAR(16) NOT NULL"` | ||||||
| 	PrimaryKeyID      string    `xorm:"CHAR(16)"` | 	PrimaryKeyID      string         `xorm:"CHAR(16)"` | ||||||
| 	Content           string    `xorm:"TEXT NOT NULL"` | 	Content           string         `xorm:"TEXT NOT NULL"` | ||||||
| 	Created           time.Time `xorm:"-"` | 	CreatedUnix       util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix       int64 | 	ExpiredUnix       util.TimeStamp | ||||||
| 	Expired           time.Time `xorm:"-"` | 	AddedUnix         util.TimeStamp | ||||||
| 	ExpiredUnix       int64 |  | ||||||
| 	Added             time.Time `xorm:"-"` |  | ||||||
| 	AddedUnix         int64 |  | ||||||
| 	SubsKey           []*GPGKey `xorm:"-"` | 	SubsKey           []*GPGKey `xorm:"-"` | ||||||
| 	Emails            []*EmailAddress | 	Emails            []*EmailAddress | ||||||
| 	CanSign           bool | 	CanSign           bool | ||||||
| @@ -47,17 +45,11 @@ type GPGKey struct { | |||||||
|  |  | ||||||
| // BeforeInsert will be invoked by XORM before inserting a record | // BeforeInsert will be invoked by XORM before inserting a record | ||||||
| func (key *GPGKey) BeforeInsert() { | func (key *GPGKey) BeforeInsert() { | ||||||
| 	key.AddedUnix = time.Now().Unix() | 	key.AddedUnix = util.TimeStampNow() | ||||||
| 	key.ExpiredUnix = key.Expired.Unix() |  | ||||||
| 	key.CreatedUnix = key.Created.Unix() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| func (key *GPGKey) AfterLoad(session *xorm.Session) { | func (key *GPGKey) AfterLoad(session *xorm.Session) { | ||||||
| 	key.Added = time.Unix(key.AddedUnix, 0).Local() |  | ||||||
| 	key.Expired = time.Unix(key.ExpiredUnix, 0).Local() |  | ||||||
| 	key.Created = time.Unix(key.CreatedUnix, 0).Local() |  | ||||||
|  |  | ||||||
| 	err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey) | 	err := session.Where("primary_key_id=?", key.KeyID).Find(&key.SubsKey) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error(3, "Find Sub GPGkeys[%d]: %v", key.KeyID, err) | 		log.Error(3, "Find Sub GPGkeys[%d]: %v", key.KeyID, err) | ||||||
| @@ -163,8 +155,8 @@ func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, e | |||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		PrimaryKeyID:      primaryID, | 		PrimaryKeyID:      primaryID, | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		Created:           pubkey.CreationTime, | 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		Expired:           expiry, | 		ExpiredUnix:       util.TimeStamp(expiry.Unix()), | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
| 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| @@ -236,8 +228,8 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) { | |||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		PrimaryKeyID:      "", | 		PrimaryKeyID:      "", | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		Created:           pubkey.CreationTime, | 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		Expired:           expiry, | 		ExpiredUnix:       util.TimeStamp(expiry.Unix()), | ||||||
| 		Emails:            emails, | 		Emails:            emails, | ||||||
| 		SubsKey:           subkeys, | 		SubsKey:           subkeys, | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
|   | |||||||
| @@ -7,6 +7,8 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -109,7 +111,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg== | |||||||
| 	key := &GPGKey{ | 	key := &GPGKey{ | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		Created:           pubkey.CreationTime, | 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		CanSign:           pubkey.CanSign(), | 		CanSign:           pubkey.CanSign(), | ||||||
| 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptComms:   pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | 		CanEncryptStorage: pubkey.PubKeyAlgo.CanEncrypt(), | ||||||
| @@ -119,7 +121,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg== | |||||||
| 	cannotsignkey := &GPGKey{ | 	cannotsignkey := &GPGKey{ | ||||||
| 		KeyID:             pubkey.KeyIdString(), | 		KeyID:             pubkey.KeyIdString(), | ||||||
| 		Content:           content, | 		Content:           content, | ||||||
| 		Created:           pubkey.CreationTime, | 		CreatedUnix:       util.TimeStamp(pubkey.CreationTime.Unix()), | ||||||
| 		CanSign:           false, | 		CanSign:           false, | ||||||
| 		CanEncryptComms:   false, | 		CanEncryptComms:   false, | ||||||
| 		CanEncryptStorage: false, | 		CanEncryptStorage: false, | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ import ( | |||||||
| 	"path" | 	"path" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| @@ -45,31 +44,15 @@ type Issue struct { | |||||||
| 	NumComments     int | 	NumComments     int | ||||||
| 	Ref             string | 	Ref             string | ||||||
|  |  | ||||||
| 	Deadline     time.Time `xorm:"-"` | 	DeadlineUnix util.TimeStamp `xorm:"INDEX"` | ||||||
| 	DeadlineUnix int64     `xorm:"INDEX"` | 	CreatedUnix  util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	Created      time.Time `xorm:"-"` | 	UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	CreatedUnix  int64     `xorm:"INDEX created"` |  | ||||||
| 	Updated      time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix  int64     `xorm:"INDEX updated"` |  | ||||||
|  |  | ||||||
| 	Attachments []*Attachment `xorm:"-"` | 	Attachments []*Attachment `xorm:"-"` | ||||||
| 	Comments    []*Comment    `xorm:"-"` | 	Comments    []*Comment    `xorm:"-"` | ||||||
| 	Reactions   ReactionList  `xorm:"-"` | 	Reactions   ReactionList  `xorm:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // BeforeUpdate is invoked from XORM before updating this object. |  | ||||||
| func (issue *Issue) BeforeUpdate() { |  | ||||||
| 	issue.DeadlineUnix = issue.Deadline.Unix() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the value of a field of |  | ||||||
| // this object. |  | ||||||
| func (issue *Issue) AfterLoad() { |  | ||||||
| 	issue.Deadline = time.Unix(issue.DeadlineUnix, 0).Local() |  | ||||||
| 	issue.Created = time.Unix(issue.CreatedUnix, 0).Local() |  | ||||||
| 	issue.Updated = time.Unix(issue.UpdatedUnix, 0).Local() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (issue *Issue) loadRepo(e Engine) (err error) { | func (issue *Issue) loadRepo(e Engine) (err error) { | ||||||
| 	if issue.Repo == nil { | 	if issue.Repo == nil { | ||||||
| 		issue.Repo, err = getRepositoryByID(e, issue.RepoID) | 		issue.Repo, err = getRepositoryByID(e, issue.RepoID) | ||||||
| @@ -307,8 +290,8 @@ func (issue *Issue) APIFormat() *api.Issue { | |||||||
| 		Labels:   apiLabels, | 		Labels:   apiLabels, | ||||||
| 		State:    issue.State(), | 		State:    issue.State(), | ||||||
| 		Comments: issue.NumComments, | 		Comments: issue.NumComments, | ||||||
| 		Created:  issue.Created, | 		Created:  issue.CreatedUnix.AsTime(), | ||||||
| 		Updated:  issue.Updated, | 		Updated:  issue.UpdatedUnix.AsTime(), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if issue.Milestone != nil { | 	if issue.Milestone != nil { | ||||||
| @@ -322,7 +305,7 @@ func (issue *Issue) APIFormat() *api.Issue { | |||||||
| 			HasMerged: issue.PullRequest.HasMerged, | 			HasMerged: issue.PullRequest.HasMerged, | ||||||
| 		} | 		} | ||||||
| 		if issue.PullRequest.HasMerged { | 		if issue.PullRequest.HasMerged { | ||||||
| 			apiIssue.PullRequest.Merged = &issue.PullRequest.Merged | 			apiIssue.PullRequest.Merged = issue.PullRequest.MergedUnix.AsTimePtr() | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/builder" | 	"github.com/go-xorm/builder" | ||||||
| @@ -17,6 +16,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/markup" | 	"code.gitea.io/gitea/modules/markup" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. | // CommentType defines whether a comment is just a simple comment, an action (like close) or a reference. | ||||||
| @@ -98,10 +98,8 @@ type Comment struct { | |||||||
| 	Content         string `xorm:"TEXT"` | 	Content         string `xorm:"TEXT"` | ||||||
| 	RenderedContent string `xorm:"-"` | 	RenderedContent string `xorm:"-"` | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` | 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
|  |  | ||||||
| 	// Reference issue in commit message | 	// Reference issue in commit message | ||||||
| 	CommitSHA string `xorm:"VARCHAR(40)"` | 	CommitSHA string `xorm:"VARCHAR(40)"` | ||||||
| @@ -115,9 +113,6 @@ type Comment struct { | |||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| func (c *Comment) AfterLoad(session *xorm.Session) { | func (c *Comment) AfterLoad(session *xorm.Session) { | ||||||
| 	c.Created = time.Unix(c.CreatedUnix, 0).Local() |  | ||||||
| 	c.Updated = time.Unix(c.UpdatedUnix, 0).Local() |  | ||||||
|  |  | ||||||
| 	var err error | 	var err error | ||||||
| 	c.Attachments, err = getAttachmentsByCommentID(session, c.ID) | 	c.Attachments, err = getAttachmentsByCommentID(session, c.ID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -191,8 +186,8 @@ func (c *Comment) APIFormat() *api.Comment { | |||||||
| 		IssueURL: c.IssueURL(), | 		IssueURL: c.IssueURL(), | ||||||
| 		PRURL:    c.PRURL(), | 		PRURL:    c.PRURL(), | ||||||
| 		Body:     c.Content, | 		Body:     c.Content, | ||||||
| 		Created:  c.Created, | 		Created:  c.CreatedUnix.AsTime(), | ||||||
| 		Updated:  c.Updated, | 		Updated:  c.UpdatedUnix.AsTime(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,9 +33,9 @@ func TestCreateComment(t *testing.T) { | |||||||
| 	assert.EqualValues(t, "Hello", comment.Content) | 	assert.EqualValues(t, "Hello", comment.Content) | ||||||
| 	assert.EqualValues(t, issue.ID, comment.IssueID) | 	assert.EqualValues(t, issue.ID, comment.IssueID) | ||||||
| 	assert.EqualValues(t, doer.ID, comment.PosterID) | 	assert.EqualValues(t, doer.ID, comment.PosterID) | ||||||
| 	AssertInt64InRange(t, now, then, comment.CreatedUnix) | 	AssertInt64InRange(t, now, then, int64(comment.CreatedUnix)) | ||||||
| 	AssertExistsAndLoadBean(t, comment) // assert actually added to DB | 	AssertExistsAndLoadBean(t, comment) // assert actually added to DB | ||||||
|  |  | ||||||
| 	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) | 	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) | ||||||
| 	AssertInt64InRange(t, now, then, updatedIssue.UpdatedUnix) | 	AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,9 +5,8 @@ | |||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| @@ -27,16 +26,14 @@ type Milestone struct { | |||||||
| 	Completeness    int  // Percentage(1-100). | 	Completeness    int  // Percentage(1-100). | ||||||
| 	IsOverDue       bool `xorm:"-"` | 	IsOverDue       bool `xorm:"-"` | ||||||
|  |  | ||||||
| 	DeadlineString string    `xorm:"-"` | 	DeadlineString string `xorm:"-"` | ||||||
| 	Deadline       time.Time `xorm:"-"` | 	DeadlineUnix   util.TimeStamp | ||||||
| 	DeadlineUnix   int64 | 	ClosedDateUnix util.TimeStamp | ||||||
| 	ClosedDate     time.Time `xorm:"-"` |  | ||||||
| 	ClosedDateUnix int64 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // BeforeInsert is invoked from XORM before inserting an object of this type. | // BeforeInsert is invoked from XORM before inserting an object of this type. | ||||||
| func (m *Milestone) BeforeInsert() { | func (m *Milestone) BeforeInsert() { | ||||||
| 	m.DeadlineUnix = m.Deadline.Unix() | 	m.DeadlineUnix = util.TimeStampNow() | ||||||
| } | } | ||||||
|  |  | ||||||
| // BeforeUpdate is invoked from XORM before updating this object. | // BeforeUpdate is invoked from XORM before updating this object. | ||||||
| @@ -46,26 +43,20 @@ func (m *Milestone) BeforeUpdate() { | |||||||
| 	} else { | 	} else { | ||||||
| 		m.Completeness = 0 | 		m.Completeness = 0 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.DeadlineUnix = m.Deadline.Unix() |  | ||||||
| 	m.ClosedDateUnix = m.ClosedDate.Unix() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the value of a field of | // AfterLoad is invoked from XORM after setting the value of a field of | ||||||
| // this object. | // this object. | ||||||
| func (m *Milestone) AfterLoad() { | func (m *Milestone) AfterLoad() { | ||||||
| 	m.NumOpenIssues = m.NumIssues - m.NumClosedIssues | 	m.NumOpenIssues = m.NumIssues - m.NumClosedIssues | ||||||
| 	m.Deadline = time.Unix(m.DeadlineUnix, 0).Local() | 	if m.DeadlineUnix.Year() == 9999 { | ||||||
| 	if m.Deadline.Year() == 9999 { |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.DeadlineString = m.Deadline.Format("2006-01-02") | 	m.DeadlineString = m.DeadlineUnix.Format("2006-01-02") | ||||||
| 	if time.Now().Local().After(m.Deadline) { | 	if util.TimeStampNow() >= m.DeadlineUnix { | ||||||
| 		m.IsOverDue = true | 		m.IsOverDue = true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.ClosedDate = time.Unix(m.ClosedDateUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // State returns string representation of milestone status. | // State returns string representation of milestone status. | ||||||
| @@ -87,10 +78,10 @@ func (m *Milestone) APIFormat() *api.Milestone { | |||||||
| 		ClosedIssues: m.NumClosedIssues, | 		ClosedIssues: m.NumClosedIssues, | ||||||
| 	} | 	} | ||||||
| 	if m.IsClosed { | 	if m.IsClosed { | ||||||
| 		apiMilestone.Closed = &m.ClosedDate | 		apiMilestone.Closed = m.ClosedDateUnix.AsTimePtr() | ||||||
| 	} | 	} | ||||||
| 	if m.Deadline.Year() < 9999 { | 	if m.DeadlineUnix.Year() < 9999 { | ||||||
| 		apiMilestone.Deadline = &m.Deadline | 		apiMilestone.Deadline = m.DeadlineUnix.AsTimePtr() | ||||||
| 	} | 	} | ||||||
| 	return apiMilestone | 	return apiMilestone | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| @@ -28,7 +29,7 @@ func TestMilestone_APIFormat(t *testing.T) { | |||||||
| 		IsClosed:        false, | 		IsClosed:        false, | ||||||
| 		NumOpenIssues:   5, | 		NumOpenIssues:   5, | ||||||
| 		NumClosedIssues: 6, | 		NumClosedIssues: 6, | ||||||
| 		Deadline:        time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC), | 		DeadlineUnix:    util.TimeStamp(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()), | ||||||
| 	} | 	} | ||||||
| 	assert.Equal(t, api.Milestone{ | 	assert.Equal(t, api.Milestone{ | ||||||
| 		ID:           milestone.ID, | 		ID:           milestone.ID, | ||||||
| @@ -37,7 +38,7 @@ func TestMilestone_APIFormat(t *testing.T) { | |||||||
| 		Description:  milestone.Content, | 		Description:  milestone.Content, | ||||||
| 		OpenIssues:   milestone.NumOpenIssues, | 		OpenIssues:   milestone.NumOpenIssues, | ||||||
| 		ClosedIssues: milestone.NumClosedIssues, | 		ClosedIssues: milestone.NumClosedIssues, | ||||||
| 		Deadline:     &milestone.Deadline, | 		Deadline:     milestone.DeadlineUnix.AsTimePtr(), | ||||||
| 	}, *milestone.APIFormat()) | 	}, *milestone.APIFormat()) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,9 +7,9 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"github.com/go-xorm/builder" | 	"github.com/go-xorm/builder" | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| @@ -17,19 +17,13 @@ import ( | |||||||
|  |  | ||||||
| // Reaction represents a reactions on issues and comments. | // Reaction represents a reactions on issues and comments. | ||||||
| type Reaction struct { | type Reaction struct { | ||||||
| 	ID          int64     `xorm:"pk autoincr"` | 	ID          int64          `xorm:"pk autoincr"` | ||||||
| 	Type        string    `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	Type        string         `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	IssueID     int64     `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	IssueID     int64          `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	CommentID   int64     `xorm:"INDEX UNIQUE(s)"` | 	CommentID   int64          `xorm:"INDEX UNIQUE(s)"` | ||||||
| 	UserID      int64     `xorm:"INDEX UNIQUE(s) NOT NULL"` | 	UserID      int64          `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||||||
| 	User        *User     `xorm:"-"` | 	User        *User          `xorm:"-"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (s *Reaction) AfterLoad() { |  | ||||||
| 	s.Created = time.Unix(s.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // FindReactionsOptions describes the conditions to Find reactions | // FindReactionsOptions describes the conditions to Find reactions | ||||||
|   | |||||||
| @@ -7,26 +7,16 @@ package models | |||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Stopwatch represents a stopwatch for time tracking. | // Stopwatch represents a stopwatch for time tracking. | ||||||
| type Stopwatch struct { | type Stopwatch struct { | ||||||
| 	ID          int64     `xorm:"pk autoincr"` | 	ID          int64          `xorm:"pk autoincr"` | ||||||
| 	IssueID     int64     `xorm:"INDEX"` | 	IssueID     int64          `xorm:"INDEX"` | ||||||
| 	UserID      int64     `xorm:"INDEX"` | 	UserID      int64          `xorm:"INDEX"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeInsert will be invoked by XORM before inserting a record |  | ||||||
| // representing this object. |  | ||||||
| func (s *Stopwatch) BeforeInsert() { |  | ||||||
| 	s.CreatedUnix = time.Now().Unix() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (s *Stopwatch) AfterLoad() { |  | ||||||
| 	s.Created = time.Unix(s.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { | func getStopwatch(e Engine, userID, issueID int64) (sw *Stopwatch, exists bool, err error) { | ||||||
| @@ -61,7 +51,7 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { | |||||||
| 	} | 	} | ||||||
| 	if exists { | 	if exists { | ||||||
| 		// Create tracked time out of the time difference between start date and actual date | 		// Create tracked time out of the time difference between start date and actual date | ||||||
| 		timediff := time.Now().Unix() - sw.CreatedUnix | 		timediff := time.Now().Unix() - int64(sw.CreatedUnix) | ||||||
|  |  | ||||||
| 		// Create TrackedTime | 		// Create TrackedTime | ||||||
| 		tt := &TrackedTime{ | 		tt := &TrackedTime{ | ||||||
| @@ -92,7 +82,6 @@ func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { | |||||||
| 		sw = &Stopwatch{ | 		sw = &Stopwatch{ | ||||||
| 			UserID:  user.ID, | 			UserID:  user.ID, | ||||||
| 			IssueID: issue.ID, | 			IssueID: issue.ID, | ||||||
| 			Created: time.Now(), |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if _, err := x.Insert(sw); err != nil { | 		if _, err := x.Insert(sw); err != nil { | ||||||
|   | |||||||
| @@ -2,7 +2,8 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| @@ -62,7 +63,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) { | |||||||
|  |  | ||||||
| 	assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) | 	assert.NoError(t, CreateOrStopIssueStopwatch(user3, issue1)) | ||||||
| 	sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) | 	sw := AssertExistsAndLoadBean(t, &Stopwatch{UserID: 3, IssueID: 1}).(*Stopwatch) | ||||||
| 	assert.Equal(t, true, sw.Created.Before(time.Now())) | 	assert.Equal(t, true, sw.CreatedUnix <= util.TimeStampNow()) | ||||||
|  |  | ||||||
| 	assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) | 	assert.NoError(t, CreateOrStopIssueStopwatch(user2, issue2)) | ||||||
| 	AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) | 	AssertNotExistsBean(t, &Stopwatch{UserID: 2, IssueID: 2}) | ||||||
|   | |||||||
| @@ -166,5 +166,5 @@ func TestUpdateIssueCols(t *testing.T) { | |||||||
| 	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) | 	updatedIssue := AssertExistsAndLoadBean(t, &Issue{ID: issue.ID}).(*Issue) | ||||||
| 	assert.EqualValues(t, newTitle, updatedIssue.Title) | 	assert.EqualValues(t, newTitle, updatedIssue.Title) | ||||||
| 	assert.EqualValues(t, prevContent, updatedIssue.Content) | 	assert.EqualValues(t, prevContent, updatedIssue.Content) | ||||||
| 	AssertInt64InRange(t, now, then, updatedIssue.UpdatedUnix) | 	AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,42 +4,16 @@ | |||||||
|  |  | ||||||
| package models | package models | ||||||
|  |  | ||||||
| import ( | import "code.gitea.io/gitea/modules/util" | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // IssueWatch is connection request for receiving issue notification. | // IssueWatch is connection request for receiving issue notification. | ||||||
| type IssueWatch struct { | type IssueWatch struct { | ||||||
| 	ID          int64     `xorm:"pk autoincr"` | 	ID          int64          `xorm:"pk autoincr"` | ||||||
| 	UserID      int64     `xorm:"UNIQUE(watch) NOT NULL"` | 	UserID      int64          `xorm:"UNIQUE(watch) NOT NULL"` | ||||||
| 	IssueID     int64     `xorm:"UNIQUE(watch) NOT NULL"` | 	IssueID     int64          `xorm:"UNIQUE(watch) NOT NULL"` | ||||||
| 	IsWatching  bool      `xorm:"NOT NULL"` | 	IsWatching  bool           `xorm:"NOT NULL"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"created NOT NULL"` | ||||||
| 	CreatedUnix int64     `xorm:"NOT NULL"` | 	UpdatedUnix util.TimeStamp `xorm:"updated NOT NULL"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"NOT NULL"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeInsert is invoked from XORM before inserting an object of this type. |  | ||||||
| func (iw *IssueWatch) BeforeInsert() { |  | ||||||
| 	var ( |  | ||||||
| 		t = time.Now() |  | ||||||
| 		u = t.Unix() |  | ||||||
| 	) |  | ||||||
| 	iw.Created = t |  | ||||||
| 	iw.CreatedUnix = u |  | ||||||
| 	iw.Updated = t |  | ||||||
| 	iw.UpdatedUnix = u |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeUpdate is invoked from XORM before updating an object of this type. |  | ||||||
| func (iw *IssueWatch) BeforeUpdate() { |  | ||||||
| 	var ( |  | ||||||
| 		t = time.Now() |  | ||||||
| 		u = t.Unix() |  | ||||||
| 	) |  | ||||||
| 	iw.Updated = t |  | ||||||
| 	iw.UpdatedUnix = u |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // CreateOrUpdateIssueWatch set watching for a user and issue | // CreateOrUpdateIssueWatch set watching for a user and issue | ||||||
|   | |||||||
| @@ -2,18 +2,18 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"time" |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // LFSMetaObject stores metadata for LFS tracked files. | // LFSMetaObject stores metadata for LFS tracked files. | ||||||
| type LFSMetaObject struct { | type LFSMetaObject struct { | ||||||
| 	ID           int64     `xorm:"pk autoincr"` | 	ID           int64          `xorm:"pk autoincr"` | ||||||
| 	Oid          string    `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	Oid          string         `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Size         int64     `xorm:"NOT NULL"` | 	Size         int64          `xorm:"NOT NULL"` | ||||||
| 	RepositoryID int64     `xorm:"UNIQUE(s) INDEX NOT NULL"` | 	RepositoryID int64          `xorm:"UNIQUE(s) INDEX NOT NULL"` | ||||||
| 	Existing     bool      `xorm:"-"` | 	Existing     bool           `xorm:"-"` | ||||||
| 	Created      time.Time `xorm:"-"` | 	CreatedUnix  util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix  int64     `xorm:"created"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // LFSTokenResponse defines the JSON structure in which the JWT token is stored. | // LFSTokenResponse defines the JSON structure in which the JWT token is stored. | ||||||
| @@ -105,8 +105,3 @@ func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) error { | |||||||
|  |  | ||||||
| 	return sess.Commit() | 	return sess.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad stores the LFSMetaObject creation time in the database as local time. |  | ||||||
| func (m *LFSMetaObject) AfterLoad() { |  | ||||||
| 	m.Created = time.Unix(m.CreatedUnix, 0).Local() |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -12,7 +12,6 @@ import ( | |||||||
| 	"net/smtp" | 	"net/smtp" | ||||||
| 	"net/textproto" | 	"net/textproto" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-macaron/binding" | 	"github.com/go-macaron/binding" | ||||||
| @@ -23,6 +22,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/auth/oauth2" | 	"code.gitea.io/gitea/modules/auth/oauth2" | ||||||
| 	"code.gitea.io/gitea/modules/auth/pam" | 	"code.gitea.io/gitea/modules/auth/pam" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // LoginType represents an login type. | // LoginType represents an login type. | ||||||
| @@ -147,10 +147,8 @@ type LoginSource struct { | |||||||
| 	IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"` | 	IsSyncEnabled bool            `xorm:"INDEX NOT NULL DEFAULT false"` | ||||||
| 	Cfg           core.Conversion `xorm:"TEXT"` | 	Cfg           core.Conversion `xorm:"TEXT"` | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` | 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Cell2Int64 converts a xorm.Cell type to int64, | // Cell2Int64 converts a xorm.Cell type to int64, | ||||||
| @@ -183,12 +181,6 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (source *LoginSource) AfterLoad() { |  | ||||||
| 	source.Created = time.Unix(source.CreatedUnix, 0).Local() |  | ||||||
| 	source.Updated = time.Unix(source.UpdatedUnix, 0).Local() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // TypeName return name of this login source type. | // TypeName return name of this login source type. | ||||||
| func (source *LoginSource) TypeName() string { | func (source *LoginSource) TypeName() string { | ||||||
| 	return LoginNames[source.Type] | 	return LoginNames[source.Type] | ||||||
|   | |||||||
| @@ -6,7 +6,8 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ( | type ( | ||||||
| @@ -51,32 +52,8 @@ type Notification struct { | |||||||
| 	Issue      *Issue      `xorm:"-"` | 	Issue      *Issue      `xorm:"-"` | ||||||
| 	Repository *Repository `xorm:"-"` | 	Repository *Repository `xorm:"-"` | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"created INDEX NOT NULL"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX NOT NULL"` | 	UpdatedUnix util.TimeStamp `xorm:"updated INDEX NOT NULL"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX NOT NULL"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeInsert runs while inserting a record |  | ||||||
| func (n *Notification) BeforeInsert() { |  | ||||||
| 	var ( |  | ||||||
| 		now     = time.Now() |  | ||||||
| 		nowUnix = now.Unix() |  | ||||||
| 	) |  | ||||||
| 	n.Created = now |  | ||||||
| 	n.CreatedUnix = nowUnix |  | ||||||
| 	n.Updated = now |  | ||||||
| 	n.UpdatedUnix = nowUnix |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeUpdate runs while updating a record |  | ||||||
| func (n *Notification) BeforeUpdate() { |  | ||||||
| 	var ( |  | ||||||
| 		now     = time.Now() |  | ||||||
| 		nowUnix = now.Unix() |  | ||||||
| 	) |  | ||||||
| 	n.Updated = now |  | ||||||
| 	n.UpdatedUnix = nowUnix |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // CreateOrUpdateIssueNotifications creates an issue notification | // CreateOrUpdateIssueNotifications creates an issue notification | ||||||
| @@ -212,6 +189,7 @@ func getIssueNotification(e Engine, userID, issueID int64) (*Notification, error | |||||||
| func NotificationsForUser(user *User, statuses []NotificationStatus, page, perPage int) ([]*Notification, error) { | func NotificationsForUser(user *User, statuses []NotificationStatus, page, perPage int) ([]*Notification, error) { | ||||||
| 	return notificationsForUser(x, user, statuses, page, perPage) | 	return notificationsForUser(x, user, statuses, page, perPage) | ||||||
| } | } | ||||||
|  |  | ||||||
| func notificationsForUser(e Engine, user *User, statuses []NotificationStatus, page, perPage int) (notifications []*Notification, err error) { | func notificationsForUser(e Engine, user *User, statuses []NotificationStatus, page, perPage int) (notifications []*Notification, err error) { | ||||||
| 	if len(statuses) == 0 { | 	if len(statuses) == 0 { | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| @@ -67,27 +68,11 @@ type PullRequest struct { | |||||||
| 	BaseBranch   string | 	BaseBranch   string | ||||||
| 	MergeBase    string `xorm:"VARCHAR(40)"` | 	MergeBase    string `xorm:"VARCHAR(40)"` | ||||||
|  |  | ||||||
| 	HasMerged      bool      `xorm:"INDEX"` | 	HasMerged      bool           `xorm:"INDEX"` | ||||||
| 	MergedCommitID string    `xorm:"VARCHAR(40)"` | 	MergedCommitID string         `xorm:"VARCHAR(40)"` | ||||||
| 	MergerID       int64     `xorm:"INDEX"` | 	MergerID       int64          `xorm:"INDEX"` | ||||||
| 	Merger         *User     `xorm:"-"` | 	Merger         *User          `xorm:"-"` | ||||||
| 	Merged         time.Time `xorm:"-"` | 	MergedUnix     util.TimeStamp `xorm:"updated INDEX"` | ||||||
| 	MergedUnix     int64     `xorm:"INDEX"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeUpdate is invoked from XORM before updating an object of this type. |  | ||||||
| func (pr *PullRequest) BeforeUpdate() { |  | ||||||
| 	pr.MergedUnix = pr.Merged.Unix() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| // Note: don't try to get Issue because will end up recursive querying. |  | ||||||
| func (pr *PullRequest) AfterLoad() { |  | ||||||
| 	if !pr.HasMerged { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	pr.Merged = time.Unix(pr.MergedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Note: don't try to get Issue because will end up recursive querying. | // Note: don't try to get Issue because will end up recursive querying. | ||||||
| @@ -194,8 +179,8 @@ func (pr *PullRequest) APIFormat() *api.PullRequest { | |||||||
| 		Base:      apiBaseBranchInfo, | 		Base:      apiBaseBranchInfo, | ||||||
| 		Head:      apiHeadBranchInfo, | 		Head:      apiHeadBranchInfo, | ||||||
| 		MergeBase: pr.MergeBase, | 		MergeBase: pr.MergeBase, | ||||||
| 		Created:   &pr.Issue.Created, | 		Created:   pr.Issue.CreatedUnix.AsTimePtr(), | ||||||
| 		Updated:   &pr.Issue.Updated, | 		Updated:   pr.Issue.UpdatedUnix.AsTimePtr(), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if pr.Status != PullRequestStatusChecking { | 	if pr.Status != PullRequestStatusChecking { | ||||||
| @@ -203,7 +188,7 @@ func (pr *PullRequest) APIFormat() *api.PullRequest { | |||||||
| 		apiPullRequest.Mergeable = mergeable | 		apiPullRequest.Mergeable = mergeable | ||||||
| 	} | 	} | ||||||
| 	if pr.HasMerged { | 	if pr.HasMerged { | ||||||
| 		apiPullRequest.Merged = &pr.Merged | 		apiPullRequest.Merged = pr.MergedUnix.AsTimePtr() | ||||||
| 		apiPullRequest.MergedCommitID = &pr.MergedCommitID | 		apiPullRequest.MergedCommitID = &pr.MergedCommitID | ||||||
| 		apiPullRequest.MergedBy = pr.Merger.APIFormat() | 		apiPullRequest.MergedBy = pr.Merger.APIFormat() | ||||||
| 	} | 	} | ||||||
| @@ -330,7 +315,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository) (err error | |||||||
| 		return fmt.Errorf("GetBranchCommit: %v", err) | 		return fmt.Errorf("GetBranchCommit: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	pr.Merged = time.Now() | 	pr.MergedUnix = util.TimeStampNow() | ||||||
| 	pr.Merger = doer | 	pr.Merger = doer | ||||||
| 	pr.MergerID = doer.ID | 	pr.MergerID = doer.ID | ||||||
|  |  | ||||||
| @@ -396,7 +381,7 @@ func (pr *PullRequest) setMerged() (err error) { | |||||||
| 	if pr.HasMerged { | 	if pr.HasMerged { | ||||||
| 		return fmt.Errorf("PullRequest[%d] already merged", pr.Index) | 		return fmt.Errorf("PullRequest[%d] already merged", pr.Index) | ||||||
| 	} | 	} | ||||||
| 	if pr.MergedCommitID == "" || pr.Merged.IsZero() || pr.Merger == nil { | 	if pr.MergedCommitID == "" || pr.MergedUnix == 0 || pr.Merger == nil { | ||||||
| 		return fmt.Errorf("Unable to merge PullRequest[%d], some required fields are empty", pr.Index) | 		return fmt.Errorf("Unable to merge PullRequest[%d], some required fields are empty", pr.Index) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -442,7 +427,7 @@ func (pr *PullRequest) manuallyMerged() bool { | |||||||
| 	} | 	} | ||||||
| 	if commit != nil { | 	if commit != nil { | ||||||
| 		pr.MergedCommitID = commit.ID.String() | 		pr.MergedCommitID = commit.ID.String() | ||||||
| 		pr.Merged = commit.Author.When | 		pr.MergedUnix = util.TimeStamp(commit.Author.When.Unix()) | ||||||
| 		pr.Status = PullRequestStatusManuallyMerged | 		pr.Status = PullRequestStatusManuallyMerged | ||||||
| 		merger, _ := GetUserByEmail(commit.Author.Email) | 		merger, _ := GetUserByEmail(commit.Author.Email) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,11 +8,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/git" | 	"code.gitea.io/git" | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
| 	"github.com/go-xorm/builder" | 	"github.com/go-xorm/builder" | ||||||
| ) | ) | ||||||
| @@ -30,28 +30,13 @@ type Release struct { | |||||||
| 	Title            string | 	Title            string | ||||||
| 	Sha1             string `xorm:"VARCHAR(40)"` | 	Sha1             string `xorm:"VARCHAR(40)"` | ||||||
| 	NumCommits       int64 | 	NumCommits       int64 | ||||||
| 	NumCommitsBehind int64  `xorm:"-"` | 	NumCommitsBehind int64          `xorm:"-"` | ||||||
| 	Note             string `xorm:"TEXT"` | 	Note             string         `xorm:"TEXT"` | ||||||
| 	IsDraft          bool   `xorm:"NOT NULL DEFAULT false"` | 	IsDraft          bool           `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsPrerelease     bool   `xorm:"NOT NULL DEFAULT false"` | 	IsPrerelease     bool           `xorm:"NOT NULL DEFAULT false"` | ||||||
| 	IsTag            bool   `xorm:"NOT NULL DEFAULT false"` | 	IsTag            bool           `xorm:"NOT NULL DEFAULT false"` | ||||||
|  | 	Attachments      []*Attachment  `xorm:"-"` | ||||||
| 	Attachments []*Attachment `xorm:"-"` | 	CreatedUnix      util.TimeStamp `xorm:"created INDEX"` | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` |  | ||||||
| 	CreatedUnix int64     `xorm:"INDEX"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeInsert is invoked from XORM before inserting an object of this type. |  | ||||||
| func (r *Release) BeforeInsert() { |  | ||||||
| 	if r.CreatedUnix == 0 { |  | ||||||
| 		r.CreatedUnix = time.Now().Unix() |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (r *Release) AfterLoad() { |  | ||||||
| 	r.Created = time.Unix(r.CreatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *Release) loadAttributes(e Engine) error { | func (r *Release) loadAttributes(e Engine) error { | ||||||
| @@ -104,8 +89,8 @@ func (r *Release) APIFormat() *api.Release { | |||||||
| 		ZipURL:       r.ZipURL(), | 		ZipURL:       r.ZipURL(), | ||||||
| 		IsDraft:      r.IsDraft, | 		IsDraft:      r.IsDraft, | ||||||
| 		IsPrerelease: r.IsPrerelease, | 		IsPrerelease: r.IsPrerelease, | ||||||
| 		CreatedAt:    r.Created, | 		CreatedAt:    r.CreatedUnix.AsTime(), | ||||||
| 		PublishedAt:  r.Created, | 		PublishedAt:  r.CreatedUnix.AsTime(), | ||||||
| 		Publisher:    r.Publisher.APIFormat(), | 		Publisher:    r.Publisher.APIFormat(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -144,7 +129,7 @@ func createTag(gitRepo *git.Repository, rel *Release) error { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		rel.Sha1 = commit.ID.String() | 		rel.Sha1 = commit.ID.String() | ||||||
| 		rel.CreatedUnix = commit.Author.When.Unix() | 		rel.CreatedUnix = util.TimeStamp(commit.Author.When.Unix()) | ||||||
| 		rel.NumCommits, err = commit.CommitsCount() | 		rel.NumCommits, err = commit.CommitsCount() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return fmt.Errorf("CommitsCount: %v", err) | 			return fmt.Errorf("CommitsCount: %v", err) | ||||||
| @@ -345,7 +330,7 @@ func (rs *releaseSorter) Less(i, j int) bool { | |||||||
| 	if diffNum != 0 { | 	if diffNum != 0 { | ||||||
| 		return diffNum > 0 | 		return diffNum > 0 | ||||||
| 	} | 	} | ||||||
| 	return rs.rels[i].Created.After(rs.rels[j].Created) | 	return rs.rels[i].CreatedUnix > rs.rels[j].CreatedUnix | ||||||
| } | } | ||||||
|  |  | ||||||
| func (rs *releaseSorter) Swap(i, j int) { | func (rs *releaseSorter) Swap(i, j int) { | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/cae/zip" | 	"github.com/Unknwon/cae/zip" | ||||||
| @@ -211,10 +212,8 @@ type Repository struct { | |||||||
| 	Size          int64              `xorm:"NOT NULL DEFAULT 0"` | 	Size          int64              `xorm:"NOT NULL DEFAULT 0"` | ||||||
| 	IndexerStatus *RepoIndexerStatus `xorm:"-"` | 	IndexerStatus *RepoIndexerStatus `xorm:"-"` | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` | 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| @@ -227,8 +226,6 @@ func (repo *Repository) AfterLoad() { | |||||||
| 	repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | 	repo.NumOpenIssues = repo.NumIssues - repo.NumClosedIssues | ||||||
| 	repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls | 	repo.NumOpenPulls = repo.NumPulls - repo.NumClosedPulls | ||||||
| 	repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones | 	repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones | ||||||
| 	repo.Created = time.Unix(repo.CreatedUnix, 0).Local() |  | ||||||
| 	repo.Updated = time.Unix(repo.UpdatedUnix, 0) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // MustOwner always returns a valid *User object to avoid | // MustOwner always returns a valid *User object to avoid | ||||||
| @@ -309,8 +306,8 @@ func (repo *Repository) innerAPIFormat(mode AccessMode, isParent bool) *api.Repo | |||||||
| 		Watchers:      repo.NumWatches, | 		Watchers:      repo.NumWatches, | ||||||
| 		OpenIssues:    repo.NumOpenIssues, | 		OpenIssues:    repo.NumOpenIssues, | ||||||
| 		DefaultBranch: repo.DefaultBranch, | 		DefaultBranch: repo.DefaultBranch, | ||||||
| 		Created:       repo.Created, | 		Created:       repo.CreatedUnix.AsTime(), | ||||||
| 		Updated:       repo.Updated, | 		Updated:       repo.UpdatedUnix.AsTime(), | ||||||
| 		Permissions:   permission, | 		Permissions:   permission, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -1011,10 +1008,10 @@ func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, err | |||||||
|  |  | ||||||
| 	if opts.IsMirror { | 	if opts.IsMirror { | ||||||
| 		if _, err = x.InsertOne(&Mirror{ | 		if _, err = x.InsertOne(&Mirror{ | ||||||
| 			RepoID:      repo.ID, | 			RepoID:         repo.ID, | ||||||
| 			Interval:    setting.Mirror.DefaultInterval, | 			Interval:       setting.Mirror.DefaultInterval, | ||||||
| 			EnablePrune: true, | 			EnablePrune:    true, | ||||||
| 			NextUpdate:  time.Now().Add(setting.Mirror.DefaultInterval), | 			NextUpdateUnix: util.TimeStampNow().AddDuration(setting.Mirror.DefaultInterval), | ||||||
| 		}); err != nil { | 		}); err != nil { | ||||||
| 			return repo, fmt.Errorf("InsertOne: %v", err) | 			return repo, fmt.Errorf("InsertOne: %v", err) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -31,10 +31,8 @@ type Mirror struct { | |||||||
| 	Interval    time.Duration | 	Interval    time.Duration | ||||||
| 	EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | 	EnablePrune bool `xorm:"NOT NULL DEFAULT true"` | ||||||
|  |  | ||||||
| 	Updated        time.Time `xorm:"-"` | 	UpdatedUnix    util.TimeStamp `xorm:"INDEX"` | ||||||
| 	UpdatedUnix    int64     `xorm:"INDEX"` | 	NextUpdateUnix util.TimeStamp `xorm:"INDEX"` | ||||||
| 	NextUpdate     time.Time `xorm:"-"` |  | ||||||
| 	NextUpdateUnix int64     `xorm:"INDEX"` |  | ||||||
|  |  | ||||||
| 	address string `xorm:"-"` | 	address string `xorm:"-"` | ||||||
| } | } | ||||||
| @@ -42,16 +40,8 @@ type Mirror struct { | |||||||
| // BeforeInsert will be invoked by XORM before inserting a record | // BeforeInsert will be invoked by XORM before inserting a record | ||||||
| func (m *Mirror) BeforeInsert() { | func (m *Mirror) BeforeInsert() { | ||||||
| 	if m != nil { | 	if m != nil { | ||||||
| 		m.UpdatedUnix = time.Now().Unix() | 		m.UpdatedUnix = util.TimeStampNow() | ||||||
| 		m.NextUpdateUnix = m.NextUpdate.Unix() | 		m.NextUpdateUnix = util.TimeStampNow() | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BeforeUpdate is invoked from XORM before updating this object. |  | ||||||
| func (m *Mirror) BeforeUpdate() { |  | ||||||
| 	if m != nil { |  | ||||||
| 		m.UpdatedUnix = m.Updated.Unix() |  | ||||||
| 		m.NextUpdateUnix = m.NextUpdate.Unix() |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -66,14 +56,11 @@ func (m *Mirror) AfterLoad(session *xorm.Session) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error(3, "getRepositoryByID[%d]: %v", m.ID, err) | 		log.Error(3, "getRepositoryByID[%d]: %v", m.ID, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.Updated = time.Unix(m.UpdatedUnix, 0).Local() |  | ||||||
| 	m.NextUpdate = time.Unix(m.NextUpdateUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // ScheduleNextUpdate calculates and sets next update time. | // ScheduleNextUpdate calculates and sets next update time. | ||||||
| func (m *Mirror) ScheduleNextUpdate() { | func (m *Mirror) ScheduleNextUpdate() { | ||||||
| 	m.NextUpdate = time.Now().Add(m.Interval) | 	m.NextUpdateUnix = util.TimeStampNow().AddDuration(m.Interval) | ||||||
| } | } | ||||||
|  |  | ||||||
| func remoteAddress(repoPath string) (string, error) { | func remoteAddress(repoPath string) (string, error) { | ||||||
| @@ -193,7 +180,7 @@ func (m *Mirror) runSync() bool { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.Updated = time.Now() | 	m.UpdatedUnix = util.TimeStampNow() | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,8 @@ package models | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"time" |  | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-xorm/core" | 	"github.com/go-xorm/core" | ||||||
| @@ -19,8 +20,7 @@ type RepoUnit struct { | |||||||
| 	RepoID      int64           `xorm:"INDEX(s)"` | 	RepoID      int64           `xorm:"INDEX(s)"` | ||||||
| 	Type        UnitType        `xorm:"INDEX(s)"` | 	Type        UnitType        `xorm:"INDEX(s)"` | ||||||
| 	Config      core.Conversion `xorm:"TEXT"` | 	Config      core.Conversion `xorm:"TEXT"` | ||||||
| 	CreatedUnix int64           `xorm:"INDEX CREATED"` | 	CreatedUnix util.TimeStamp  `xorm:"INDEX CREATED"` | ||||||
| 	Created     time.Time       `xorm:"-"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // UnitConfig describes common unit config | // UnitConfig describes common unit config | ||||||
| @@ -105,11 +105,6 @@ func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (r *RepoUnit) AfterLoad() { |  | ||||||
| 	r.Created = time.Unix(r.CreatedUnix, 0).Local() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Unit returns Unit | // Unit returns Unit | ||||||
| func (r *RepoUnit) Unit() Unit { | func (r *RepoUnit) Unit() Unit { | ||||||
| 	return Units[r.Type] | 	return Units[r.Type] | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/process" | 	"code.gitea.io/gitea/modules/process" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -54,20 +55,16 @@ type PublicKey struct { | |||||||
| 	Mode        AccessMode `xorm:"NOT NULL DEFAULT 2"` | 	Mode        AccessMode `xorm:"NOT NULL DEFAULT 2"` | ||||||
| 	Type        KeyType    `xorm:"NOT NULL DEFAULT 1"` | 	Type        KeyType    `xorm:"NOT NULL DEFAULT 1"` | ||||||
|  |  | ||||||
| 	Created           time.Time `xorm:"-"` | 	CreatedUnix       util.TimeStamp `xorm:"created"` | ||||||
| 	CreatedUnix       int64     `xorm:"created"` | 	UpdatedUnix       util.TimeStamp `xorm:"updated"` | ||||||
| 	Updated           time.Time `xorm:"-"` | 	HasRecentActivity bool           `xorm:"-"` | ||||||
| 	UpdatedUnix       int64     `xorm:"updated"` | 	HasUsed           bool           `xorm:"-"` | ||||||
| 	HasRecentActivity bool      `xorm:"-"` |  | ||||||
| 	HasUsed           bool      `xorm:"-"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| func (key *PublicKey) AfterLoad() { | func (key *PublicKey) AfterLoad() { | ||||||
| 	key.Created = time.Unix(key.CreatedUnix, 0).Local() | 	key.HasUsed = key.UpdatedUnix > key.CreatedUnix | ||||||
| 	key.Updated = time.Unix(key.UpdatedUnix, 0).Local() | 	key.HasRecentActivity = key.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() | ||||||
| 	key.HasUsed = key.Updated.After(key.Created) |  | ||||||
| 	key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now()) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // OmitEmail returns content of public key without email address. | // OmitEmail returns content of public key without email address. | ||||||
| @@ -484,7 +481,7 @@ func UpdatePublicKeyUpdated(id int64) error { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{ | 	_, err := x.ID(id).Cols("updated_unix").Update(&PublicKey{ | ||||||
| 		UpdatedUnix: time.Now().Unix(), | 		UpdatedUnix: util.TimeStampNow(), | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|   | |||||||
| @@ -8,11 +8,11 @@ import ( | |||||||
| 	"container/list" | 	"container/list" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"code.gitea.io/git" | 	"code.gitea.io/git" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| @@ -65,17 +65,8 @@ type CommitStatus struct { | |||||||
| 	Creator     *User             `xorm:"-"` | 	Creator     *User             `xorm:"-"` | ||||||
| 	CreatorID   int64 | 	CreatorID   int64 | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` | 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the value of a field of |  | ||||||
| // this object. |  | ||||||
| func (status *CommitStatus) AfterLoad() { |  | ||||||
| 	status.Created = time.Unix(status.CreatedUnix, 0).Local() |  | ||||||
| 	status.Updated = time.Unix(status.UpdatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (status *CommitStatus) loadRepo(e Engine) (err error) { | func (status *CommitStatus) loadRepo(e Engine) (err error) { | ||||||
| @@ -106,8 +97,8 @@ func (status *CommitStatus) APIURL() string { | |||||||
| func (status *CommitStatus) APIFormat() *api.Status { | func (status *CommitStatus) APIFormat() *api.Status { | ||||||
| 	status.loadRepo(x) | 	status.loadRepo(x) | ||||||
| 	apiStatus := &api.Status{ | 	apiStatus := &api.Status{ | ||||||
| 		Created:     status.Created, | 		Created:     status.CreatedUnix.AsTime(), | ||||||
| 		Updated:     status.Created, | 		Updated:     status.CreatedUnix.AsTime(), | ||||||
| 		State:       api.StatusState(status.State), | 		State:       api.StatusState(status.State), | ||||||
| 		TargetURL:   status.TargetURL, | 		TargetURL:   status.TargetURL, | ||||||
| 		Description: status.Description, | 		Description: status.Description, | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import ( | |||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // AccessToken represents a personal access token. | // AccessToken represents a personal access token. | ||||||
| @@ -19,20 +20,16 @@ type AccessToken struct { | |||||||
| 	Name string | 	Name string | ||||||
| 	Sha1 string `xorm:"UNIQUE VARCHAR(40)"` | 	Sha1 string `xorm:"UNIQUE VARCHAR(40)"` | ||||||
|  |  | ||||||
| 	Created           time.Time `xorm:"-"` | 	CreatedUnix       util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix       int64     `xorm:"INDEX created"` | 	UpdatedUnix       util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated           time.Time `xorm:"-"` | 	HasRecentActivity bool           `xorm:"-"` | ||||||
| 	UpdatedUnix       int64     `xorm:"INDEX updated"` | 	HasUsed           bool           `xorm:"-"` | ||||||
| 	HasRecentActivity bool      `xorm:"-"` |  | ||||||
| 	HasUsed           bool      `xorm:"-"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| func (t *AccessToken) AfterLoad() { | func (t *AccessToken) AfterLoad() { | ||||||
| 	t.Created = time.Unix(t.CreatedUnix, 0).Local() | 	t.HasUsed = t.UpdatedUnix > t.CreatedUnix | ||||||
| 	t.Updated = time.Unix(t.UpdatedUnix, 0).Local() | 	t.HasRecentActivity = t.UpdatedUnix.AddDuration(7*24*time.Hour) > util.TimeStampNow() | ||||||
| 	t.HasUsed = t.Updated.After(t.Created) |  | ||||||
| 	t.HasRecentActivity = t.Updated.Add(7 * 24 * time.Hour).After(time.Now()) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewAccessToken creates new access token. | // NewAccessToken creates new access token. | ||||||
|   | |||||||
| @@ -8,13 +8,13 @@ import ( | |||||||
| 	"crypto/md5" | 	"crypto/md5" | ||||||
| 	"crypto/subtle" | 	"crypto/subtle" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/pquerna/otp/totp" | 	"github.com/pquerna/otp/totp" | ||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // TwoFactor represents a two-factor authentication token. | // TwoFactor represents a two-factor authentication token. | ||||||
| @@ -23,17 +23,8 @@ type TwoFactor struct { | |||||||
| 	UID          int64 `xorm:"UNIQUE"` | 	UID          int64 `xorm:"UNIQUE"` | ||||||
| 	Secret       string | 	Secret       string | ||||||
| 	ScratchToken string | 	ScratchToken string | ||||||
|  | 	CreatedUnix  util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	Created     time.Time `xorm:"-"` | 	UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` |  | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. |  | ||||||
| func (t *TwoFactor) AfterLoad() { |  | ||||||
| 	t.Created = time.Unix(t.CreatedUnix, 0).Local() |  | ||||||
| 	t.Updated = time.Unix(t.UpdatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // GenerateScratchToken recreates the scratch token the user is using. | // GenerateScratchToken recreates the scratch token the user is using. | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ import ( | |||||||
| 	"code.gitea.io/git" | 	"code.gitea.io/git" | ||||||
| 	"code.gitea.io/gitea/modules/cache" | 	"code.gitea.io/gitea/modules/cache" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // env keys for git hooks need | // env keys for git hooks need | ||||||
| @@ -158,8 +159,7 @@ func pushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) | |||||||
| 			IsDraft:      false, | 			IsDraft:      false, | ||||||
| 			IsPrerelease: false, | 			IsPrerelease: false, | ||||||
| 			IsTag:        true, | 			IsTag:        true, | ||||||
| 			Created:      createdAt, | 			CreatedUnix:  util.TimeStamp(createdAt.Unix()), | ||||||
| 			CreatedUnix:  createdAt.Unix(), |  | ||||||
| 		} | 		} | ||||||
| 		if author != nil { | 		if author != nil { | ||||||
| 			rel.PublisherID = author.ID | 			rel.PublisherID = author.ID | ||||||
| @@ -170,8 +170,7 @@ func pushUpdateAddTag(repo *Repository, gitRepo *git.Repository, tagName string) | |||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		rel.Sha1 = commit.ID.String() | 		rel.Sha1 = commit.ID.String() | ||||||
| 		rel.Created = createdAt | 		rel.CreatedUnix = util.TimeStamp(createdAt.Unix()) | ||||||
| 		rel.CreatedUnix = createdAt.Unix() |  | ||||||
| 		rel.NumCommits = commitsCount | 		rel.NumCommits = commitsCount | ||||||
| 		rel.IsDraft = false | 		rel.IsDraft = false | ||||||
| 		if rel.IsTag && author != nil { | 		if rel.IsTag && author != nil { | ||||||
|   | |||||||
| @@ -94,12 +94,9 @@ type User struct { | |||||||
| 	Rands            string `xorm:"VARCHAR(10)"` | 	Rands            string `xorm:"VARCHAR(10)"` | ||||||
| 	Salt             string `xorm:"VARCHAR(10)"` | 	Salt             string `xorm:"VARCHAR(10)"` | ||||||
|  |  | ||||||
| 	Created       time.Time `xorm:"-"` | 	CreatedUnix   util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix   int64     `xorm:"INDEX created"` | 	UpdatedUnix   util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated       time.Time `xorm:"-"` | 	LastLoginUnix util.TimeStamp `xorm:"INDEX"` | ||||||
| 	UpdatedUnix   int64     `xorm:"INDEX updated"` |  | ||||||
| 	LastLogin     time.Time `xorm:"-"` |  | ||||||
| 	LastLoginUnix int64     `xorm:"INDEX"` |  | ||||||
|  |  | ||||||
| 	// Remember visibility choice for convenience, true for private | 	// Remember visibility choice for convenience, true for private | ||||||
| 	LastRepoVisibility bool | 	LastRepoVisibility bool | ||||||
| @@ -145,7 +142,7 @@ func (u *User) BeforeUpdate() { | |||||||
|  |  | ||||||
| // SetLastLogin set time to last login | // SetLastLogin set time to last login | ||||||
| func (u *User) SetLastLogin() { | func (u *User) SetLastLogin() { | ||||||
| 	u.LastLoginUnix = time.Now().Unix() | 	u.LastLoginUnix = util.TimeStampNow() | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdateDiffViewStyle updates the users diff view style | // UpdateDiffViewStyle updates the users diff view style | ||||||
| @@ -154,12 +151,13 @@ func (u *User) UpdateDiffViewStyle(style string) error { | |||||||
| 	return UpdateUserCols(u, "diff_view_style") | 	return UpdateUserCols(u, "diff_view_style") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
| // AfterLoad is invoked from XORM after setting the values of all fields of this object. | // AfterLoad is invoked from XORM after setting the values of all fields of this object. | ||||||
| func (u *User) AfterLoad() { | func (u *User) AfterLoad() { | ||||||
| 	u.Created = time.Unix(u.CreatedUnix, 0).Local() | 	u.Created = time.Unix(u.CreatedUnix, 0).Local() | ||||||
| 	u.Updated = time.Unix(u.UpdatedUnix, 0).Local() | 	u.Updated = time.Unix(u.UpdatedUnix, 0).Local() | ||||||
| 	u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local() | 	u.LastLogin = time.Unix(u.LastLoginUnix, 0).Local() | ||||||
| } | }*/ | ||||||
|  |  | ||||||
| // getEmail returns an noreply email, if the user has set to keep his | // getEmail returns an noreply email, if the user has set to keep his | ||||||
| // email address private, otherwise the primary email address. | // email address private, otherwise the primary email address. | ||||||
|   | |||||||
| @@ -17,6 +17,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/sync" | 	"code.gitea.io/gitea/modules/sync" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	api "code.gitea.io/sdk/gitea" | 	api "code.gitea.io/sdk/gitea" | ||||||
|  |  | ||||||
| 	gouuid "github.com/satori/go.uuid" | 	gouuid "github.com/satori/go.uuid" | ||||||
| @@ -105,10 +106,8 @@ type Webhook struct { | |||||||
| 	Meta         string     `xorm:"TEXT"` // store hook-specific attributes | 	Meta         string     `xorm:"TEXT"` // store hook-specific attributes | ||||||
| 	LastStatus   HookStatus // Last delivery status | 	LastStatus   HookStatus // Last delivery status | ||||||
|  |  | ||||||
| 	Created     time.Time `xorm:"-"` | 	CreatedUnix util.TimeStamp `xorm:"INDEX created"` | ||||||
| 	CreatedUnix int64     `xorm:"INDEX created"` | 	UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` | ||||||
| 	Updated     time.Time `xorm:"-"` |  | ||||||
| 	UpdatedUnix int64     `xorm:"INDEX updated"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // AfterLoad updates the webhook object upon setting a column | // AfterLoad updates the webhook object upon setting a column | ||||||
| @@ -117,9 +116,6 @@ func (w *Webhook) AfterLoad() { | |||||||
| 	if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { | 	if err := json.Unmarshal([]byte(w.Events), w.HookEvent); err != nil { | ||||||
| 		log.Error(3, "Unmarshal[%d]: %v", w.ID, err) | 		log.Error(3, "Unmarshal[%d]: %v", w.ID, err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	w.Created = time.Unix(w.CreatedUnix, 0).Local() |  | ||||||
| 	w.Updated = time.Unix(w.UpdatedUnix, 0).Local() |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetSlackHook returns slack metadata | // GetSlackHook returns slack metadata | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ package auth | |||||||
| import ( | import ( | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/go-macaron/binding" | 	"github.com/go-macaron/binding" | ||||||
| @@ -19,6 +18,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	"code.gitea.io/gitea/modules/validation" | 	"code.gitea.io/gitea/modules/validation" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -59,7 +59,7 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 { | |||||||
| 				} | 				} | ||||||
| 				return 0 | 				return 0 | ||||||
| 			} | 			} | ||||||
| 			t.Updated = time.Now() | 			t.UpdatedUnix = util.TimeStampNow() | ||||||
| 			if err = models.UpdateAccessToken(t); err != nil { | 			if err = models.UpdateAccessToken(t); err != nil { | ||||||
| 				log.Error(4, "UpdateAccessToken: %v", err) | 				log.Error(4, "UpdateAccessToken: %v", err) | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	"github.com/Unknwon/com" | 	"github.com/Unknwon/com" | ||||||
| 	"github.com/Unknwon/i18n" | 	"github.com/Unknwon/i18n" | ||||||
| 	"github.com/gogits/chardet" | 	"github.com/gogits/chardet" | ||||||
| @@ -357,11 +358,15 @@ func timeSincePro(then, now time.Time, lang string) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func timeSince(then, now time.Time, lang string) string { | func timeSince(then, now time.Time, lang string) string { | ||||||
|  | 	return timeSinceUnix(then.Unix(), now.Unix(), lang) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func timeSinceUnix(then, now int64, lang string) string { | ||||||
| 	lbl := "tool.ago" | 	lbl := "tool.ago" | ||||||
| 	diff := now.Unix() - then.Unix() | 	diff := now - then | ||||||
| 	if then.After(now) { | 	if then > now { | ||||||
| 		lbl = "tool.from_now" | 		lbl = "tool.from_now" | ||||||
| 		diff = then.Unix() - now.Unix() | 		diff = then - now | ||||||
| 	} | 	} | ||||||
| 	if diff <= 0 { | 	if diff <= 0 { | ||||||
| 		return i18n.Tr(lang, "tool.now") | 		return i18n.Tr(lang, "tool.now") | ||||||
| @@ -387,6 +392,17 @@ func htmlTimeSince(then, now time.Time, lang string) template.HTML { | |||||||
| 		timeSince(then, now, lang))) | 		timeSince(then, now, lang))) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // TimeSinceUnix calculates the time interval and generate user-friendly string. | ||||||
|  | func TimeSinceUnix(then util.TimeStamp, lang string) template.HTML { | ||||||
|  | 	return htmlTimeSinceUnix(then, util.TimeStamp(time.Now().Unix()), lang) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func htmlTimeSinceUnix(then, now util.TimeStamp, lang string) template.HTML { | ||||||
|  | 	return template.HTML(fmt.Sprintf(`<span class="time-since" title="%s">%s</span>`, | ||||||
|  | 		then.Format(setting.TimeFormat), | ||||||
|  | 		timeSinceUnix(int64(then), int64(now), lang))) | ||||||
|  | } | ||||||
|  |  | ||||||
| // Storage space size types | // Storage space size types | ||||||
| const ( | const ( | ||||||
| 	Byte  = 1 | 	Byte  = 1 | ||||||
|   | |||||||
| @@ -65,14 +65,15 @@ func NewFuncMap() []template.FuncMap { | |||||||
| 		"LoadTimes": func(startTime time.Time) string { | 		"LoadTimes": func(startTime time.Time) string { | ||||||
| 			return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" | 			return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" | ||||||
| 		}, | 		}, | ||||||
| 		"AvatarLink":   base.AvatarLink, | 		"AvatarLink":    base.AvatarLink, | ||||||
| 		"Safe":         Safe, | 		"Safe":          Safe, | ||||||
| 		"SafeJS":       SafeJS, | 		"SafeJS":        SafeJS, | ||||||
| 		"Str2html":     Str2html, | 		"Str2html":      Str2html, | ||||||
| 		"TimeSince":    base.TimeSince, | 		"TimeSince":     base.TimeSince, | ||||||
| 		"RawTimeSince": base.RawTimeSince, | 		"TimeSinceUnix": base.TimeSinceUnix, | ||||||
| 		"FileSize":     base.FileSize, | 		"RawTimeSince":  base.RawTimeSince, | ||||||
| 		"Subtract":     base.Subtract, | 		"FileSize":      base.FileSize, | ||||||
|  | 		"Subtract":      base.Subtract, | ||||||
| 		"Add": func(a, b int) int { | 		"Add": func(a, b int) int { | ||||||
| 			return a + b | 			return a + b | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
							
								
								
									
										57
									
								
								modules/util/time_stamp.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								modules/util/time_stamp.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // Copyright 2017 The Gitea Authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a MIT-style | ||||||
|  | // license that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | package util | ||||||
|  |  | ||||||
|  | import "time" | ||||||
|  |  | ||||||
|  | // TimeStamp defines a timestamp | ||||||
|  | type TimeStamp int64 | ||||||
|  |  | ||||||
|  | // TimeStampNow returns now int64 | ||||||
|  | func TimeStampNow() TimeStamp { | ||||||
|  | 	return TimeStamp(time.Now().Unix()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Add adds seconds and return sum | ||||||
|  | func (ts TimeStamp) Add(seconds int64) TimeStamp { | ||||||
|  | 	return ts + TimeStamp(seconds) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AddDuration adds time.Duration and return sum | ||||||
|  | func (ts TimeStamp) AddDuration(interval time.Duration) TimeStamp { | ||||||
|  | 	return ts + TimeStamp(interval/time.Second) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Year returns the time's year | ||||||
|  | func (ts TimeStamp) Year() int { | ||||||
|  | 	return ts.AsTime().Year() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AsTime convert timestamp as time.Time in Local locale | ||||||
|  | func (ts TimeStamp) AsTime() (tm time.Time) { | ||||||
|  | 	tm = time.Unix(int64(ts), 0).Local() | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AsTimePtr convert timestamp as *time.Time in Local locale | ||||||
|  | func (ts TimeStamp) AsTimePtr() *time.Time { | ||||||
|  | 	tm := time.Unix(int64(ts), 0).Local() | ||||||
|  | 	return &tm | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Format formats timestamp as | ||||||
|  | func (ts TimeStamp) Format(f string) string { | ||||||
|  | 	return ts.AsTime().Format(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FormatLong formats as RFC1123Z | ||||||
|  | func (ts TimeStamp) FormatLong() string { | ||||||
|  | 	return ts.Format(time.RFC1123Z) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // FormatShort formats as short | ||||||
|  | func (ts TimeStamp) FormatShort() string { | ||||||
|  | 	return ts.Format("Jan 02, 2006") | ||||||
|  | } | ||||||
| @@ -82,7 +82,7 @@ func ToPublicKey(apiLink string, key *models.PublicKey) *api.PublicKey { | |||||||
| 		URL:         apiLink + com.ToStr(key.ID), | 		URL:         apiLink + com.ToStr(key.ID), | ||||||
| 		Title:       key.Name, | 		Title:       key.Name, | ||||||
| 		Fingerprint: key.Fingerprint, | 		Fingerprint: key.Fingerprint, | ||||||
| 		Created:     key.Created, | 		Created:     key.CreatedUnix.AsTime(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -95,8 +95,8 @@ func ToGPGKey(key *models.GPGKey) *api.GPGKey { | |||||||
| 			PrimaryKeyID:      k.PrimaryKeyID, | 			PrimaryKeyID:      k.PrimaryKeyID, | ||||||
| 			KeyID:             k.KeyID, | 			KeyID:             k.KeyID, | ||||||
| 			PublicKey:         k.Content, | 			PublicKey:         k.Content, | ||||||
| 			Created:           k.Created, | 			Created:           k.CreatedUnix.AsTime(), | ||||||
| 			Expires:           k.Expired, | 			Expires:           k.ExpiredUnix.AsTime(), | ||||||
| 			CanSign:           k.CanSign, | 			CanSign:           k.CanSign, | ||||||
| 			CanEncryptComms:   k.CanEncryptComms, | 			CanEncryptComms:   k.CanEncryptComms, | ||||||
| 			CanEncryptStorage: k.CanEncryptStorage, | 			CanEncryptStorage: k.CanEncryptStorage, | ||||||
| @@ -112,8 +112,8 @@ func ToGPGKey(key *models.GPGKey) *api.GPGKey { | |||||||
| 		PrimaryKeyID:      key.PrimaryKeyID, | 		PrimaryKeyID:      key.PrimaryKeyID, | ||||||
| 		KeyID:             key.KeyID, | 		KeyID:             key.KeyID, | ||||||
| 		PublicKey:         key.Content, | 		PublicKey:         key.Content, | ||||||
| 		Created:           key.Created, | 		Created:           key.CreatedUnix.AsTime(), | ||||||
| 		Expires:           key.Expired, | 		Expires:           key.ExpiredUnix.AsTime(), | ||||||
| 		Emails:            emails, | 		Emails:            emails, | ||||||
| 		SubsKey:           subkeys, | 		SubsKey:           subkeys, | ||||||
| 		CanSign:           key.CanSign, | 		CanSign:           key.CanSign, | ||||||
| @@ -152,8 +152,8 @@ func ToHook(repoLink string, w *models.Webhook) *api.Hook { | |||||||
| 		Active:  w.IsActive, | 		Active:  w.IsActive, | ||||||
| 		Config:  config, | 		Config:  config, | ||||||
| 		Events:  w.EventsArray(), | 		Events:  w.EventsArray(), | ||||||
| 		Updated: w.Updated, | 		Updated: w.UpdatedUnix.AsTime(), | ||||||
| 		Created: w.Created, | 		Created: w.CreatedUnix.AsTime(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import ( | |||||||
|  |  | ||||||
| 	"code.gitea.io/gitea/models" | 	"code.gitea.io/gitea/models" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ListMilestones list all the milestones for a repository | // ListMilestones list all the milestones for a repository | ||||||
| @@ -118,10 +119,10 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	milestone := &models.Milestone{ | 	milestone := &models.Milestone{ | ||||||
| 		RepoID:   ctx.Repo.Repository.ID, | 		RepoID:       ctx.Repo.Repository.ID, | ||||||
| 		Name:     form.Title, | 		Name:         form.Title, | ||||||
| 		Content:  form.Description, | 		Content:      form.Description, | ||||||
| 		Deadline: *form.Deadline, | 		DeadlineUnix: util.TimeStamp(form.Deadline.Unix()), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.NewMilestone(milestone); err != nil { | 	if err := models.NewMilestone(milestone); err != nil { | ||||||
| @@ -175,7 +176,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { | |||||||
| 		milestone.Content = *form.Description | 		milestone.Content = *form.Description | ||||||
| 	} | 	} | ||||||
| 	if form.Deadline != nil && !form.Deadline.IsZero() { | 	if form.Deadline != nil && !form.Deadline.IsZero() { | ||||||
| 		milestone.Deadline = *form.Deadline | 		milestone.DeadlineUnix = util.TimeStamp(form.Deadline.Unix()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err := models.UpdateMilestone(milestone); err != nil { | 	if err := models.UpdateMilestone(milestone); err != nil { | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ func IsWatching(ctx *context.APIContext) { | |||||||
| 			Subscribed:    true, | 			Subscribed:    true, | ||||||
| 			Ignored:       false, | 			Ignored:       false, | ||||||
| 			Reason:        nil, | 			Reason:        nil, | ||||||
| 			CreatedAt:     ctx.Repo.Repository.Created, | 			CreatedAt:     ctx.Repo.Repository.CreatedUnix.AsTime(), | ||||||
| 			URL:           subscriptionURL(ctx.Repo.Repository), | 			URL:           subscriptionURL(ctx.Repo.Repository), | ||||||
| 			RepositoryURL: repositoryURL(ctx.Repo.Repository), | 			RepositoryURL: repositoryURL(ctx.Repo.Repository), | ||||||
| 		}) | 		}) | ||||||
| @@ -134,7 +134,7 @@ func Watch(ctx *context.APIContext) { | |||||||
| 		Subscribed:    true, | 		Subscribed:    true, | ||||||
| 		Ignored:       false, | 		Ignored:       false, | ||||||
| 		Reason:        nil, | 		Reason:        nil, | ||||||
| 		CreatedAt:     ctx.Repo.Repository.Created, | 		CreatedAt:     ctx.Repo.Repository.CreatedUnix.AsTime(), | ||||||
| 		URL:           subscriptionURL(ctx.Repo.Repository), | 		URL:           subscriptionURL(ctx.Repo.Repository), | ||||||
| 		RepositoryURL: repositoryURL(ctx.Repo.Repository), | 		RepositoryURL: repositoryURL(ctx.Repo.Repository), | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // HTTP implmentation git smart HTTP protocol | // HTTP implmentation git smart HTTP protocol | ||||||
| @@ -167,7 +168,7 @@ func HTTP(ctx *context.Context) { | |||||||
| 					return | 					return | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				token.Updated = time.Now() | 				token.UpdatedUnix = util.TimeStampNow() | ||||||
| 				if err = models.UpdateAccessToken(token); err != nil { | 				if err = models.UpdateAccessToken(token); err != nil { | ||||||
| 					ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err) | 					ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err) | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -1138,10 +1138,10 @@ func NewMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if err = models.NewMilestone(&models.Milestone{ | 	if err = models.NewMilestone(&models.Milestone{ | ||||||
| 		RepoID:   ctx.Repo.Repository.ID, | 		RepoID:       ctx.Repo.Repository.ID, | ||||||
| 		Name:     form.Title, | 		Name:         form.Title, | ||||||
| 		Content:  form.Content, | 		Content:      form.Content, | ||||||
| 		Deadline: deadline, | 		DeadlineUnix: util.TimeStamp(deadline.Unix()), | ||||||
| 	}); err != nil { | 	}); err != nil { | ||||||
| 		ctx.Handle(500, "NewMilestone", err) | 		ctx.Handle(500, "NewMilestone", err) | ||||||
| 		return | 		return | ||||||
| @@ -1210,7 +1210,7 @@ func EditMilestonePost(ctx *context.Context, form auth.CreateMilestoneForm) { | |||||||
| 	} | 	} | ||||||
| 	m.Name = form.Title | 	m.Name = form.Title | ||||||
| 	m.Content = form.Content | 	m.Content = form.Content | ||||||
| 	m.Deadline = deadline | 	m.DeadlineUnix = util.TimeStamp(deadline.Unix()) | ||||||
| 	if err = models.UpdateMilestone(m); err != nil { | 	if err = models.UpdateMilestone(m); err != nil { | ||||||
| 		ctx.Handle(500, "UpdateMilestone", err) | 		ctx.Handle(500, "UpdateMilestone", err) | ||||||
| 		return | 		return | ||||||
| @@ -1243,7 +1243,7 @@ func ChangeMilestonStatus(ctx *context.Context) { | |||||||
| 		ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open") | 		ctx.Redirect(ctx.Repo.RepoLink + "/milestones?state=open") | ||||||
| 	case "close": | 	case "close": | ||||||
| 		if !m.IsClosed { | 		if !m.IsClosed { | ||||||
| 			m.ClosedDate = time.Now() | 			m.ClosedDateUnix = util.TimeStampNow() | ||||||
| 			if err = models.ChangeMilestoneStatus(m, true); err != nil { | 			if err = models.ChangeMilestoneStatus(m, true); err != nil { | ||||||
| 				ctx.Handle(500, "ChangeMilestoneStatus", err) | 				ctx.Handle(500, "ChangeMilestoneStatus", err) | ||||||
| 				return | 				return | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/gitea/modules/util" | ||||||
| 	"code.gitea.io/gitea/routers/utils" | 	"code.gitea.io/gitea/routers/utils" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -119,7 +120,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) { | |||||||
| 		} else { | 		} else { | ||||||
| 			ctx.Repo.Mirror.EnablePrune = form.EnablePrune | 			ctx.Repo.Mirror.EnablePrune = form.EnablePrune | ||||||
| 			ctx.Repo.Mirror.Interval = interval | 			ctx.Repo.Mirror.Interval = interval | ||||||
| 			ctx.Repo.Mirror.NextUpdate = time.Now().Add(interval) | 			ctx.Repo.Mirror.NextUpdateUnix = util.TimeStampNow().AddDuration(interval) | ||||||
| 			if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil { | 			if err := models.UpdateMirror(ctx.Repo.Mirror); err != nil { | ||||||
| 				ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form) | 				ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form) | ||||||
| 				return | 				return | ||||||
|   | |||||||
| @@ -29,8 +29,8 @@ | |||||||
| 							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td> | 							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}">{{.Name}}</a></td> | ||||||
| 							<td>{{.TypeName}}</td> | 							<td>{{.TypeName}}</td> | ||||||
| 							<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td> | 							<td><i class="fa fa{{if .IsActived}}-check{{end}}-square-o"></i></td> | ||||||
| 							<td><span class="poping up" data-content="{{DateFmtLong .Updated}}" data-variation="tiny">{{DateFmtShort .Updated}}</span></td> | 							<td><span class="poping up" data-content="{{.UpdatedUnix.FormatShort}}" data-variation="tiny">{{.UpdatedUnix.FormatShort}}</span></td> | ||||||
| 							<td><span class="poping up" data-content="{{DateFmtLong .Created}}" data-variation="tiny">{{DateFmtShort .Created}}</span></td> | 							<td><span class="poping up" data-content="{{.CreatedUnix.FormatLong}}" data-variation="tiny">{{.CreatedUnix.FormatShort}}</span></td> | ||||||
| 							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}"><i class="fa fa-pencil-square-o"></i></a></td> | 							<td><a href="{{AppSubUrl}}/admin/auths/{{.ID}}"><i class="fa fa-pencil-square-o"></i></a></td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|   | |||||||
| @@ -49,8 +49,8 @@ | |||||||
| 						<tr> | 						<tr> | ||||||
| 							<td>{{.PID}}</td> | 							<td>{{.PID}}</td> | ||||||
| 							<td>{{.Description}}</td> | 							<td>{{.Description}}</td> | ||||||
| 							<td>{{DateFmtLong .Start}}</td> | 							<td>{{.Start.FormatLong}}</td> | ||||||
| 							<td>{{TimeSince .Start $.Lang}}</td> | 							<td>{{TimeSinceUnix .Start $.Lang}}</td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 				</tbody> | 				</tbody> | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| 							<td>{{.ID}}</td> | 							<td>{{.ID}}</td> | ||||||
| 							<td>{{$.i18n.Tr .TrStr}}</td> | 							<td>{{$.i18n.Tr .TrStr}}</td> | ||||||
| 							<td>{{SubStr .Description 0 120}}...</td> | 							<td>{{SubStr .Description 0 120}}...</td> | ||||||
| 							<td><span class="poping up" data-content="{{.Created}}" data-variation="inverted tiny">{{DateFmtShort .Created}}</span></td> | 							<td><span class="poping up" data-content="{{.CreatedUnix.AsTime}}" data-variation="inverted tiny">{{.CreatedUnix.FormatShort}}</span></td> | ||||||
| 							<td><a href="#"><i class="browser icon view-detail" data-content="{{.Description}}"></i></a></td> | 							<td><a href="#"><i class="browser icon view-detail" data-content="{{.Description}}"></i></a></td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|   | |||||||
| @@ -33,7 +33,7 @@ | |||||||
| 							<td>{{.NumTeams}}</td> | 							<td>{{.NumTeams}}</td> | ||||||
| 							<td>{{.NumMembers}}</td> | 							<td>{{.NumMembers}}</td> | ||||||
| 							<td>{{.NumRepos}}</td> | 							<td>{{.NumRepos}}</td> | ||||||
| 							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td> | 							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> | ||||||
| 							<td><a href="{{AppSubUrl}}/org/{{.Name}}/settings"><i class="fa fa-pencil-square-o"></i></a></td> | 							<td><a href="{{AppSubUrl}}/org/{{.Name}}/settings"><i class="fa fa-pencil-square-o"></i></a></td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
| 							<td>{{.NumStars}}</td> | 							<td>{{.NumStars}}</td> | ||||||
| 							<td>{{.NumIssues}}</td> | 							<td>{{.NumIssues}}</td> | ||||||
| 							<td>{{SizeFmt .Size}}</td> | 							<td>{{SizeFmt .Size}}</td> | ||||||
| 							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span></td> | 							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> | ||||||
| 							<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Current}}" data-id="{{.ID}}"><i class="trash icon text red"></i></a></td> | 							<td><a class="delete-button" href="" data-url="{{$.Link}}/delete?page={{$.Page.Current}}" data-id="{{.ID}}"><i class="trash icon text red"></i></a></td> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|   | |||||||
| @@ -36,9 +36,9 @@ | |||||||
| 							<td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td> | 							<td><i class="fa fa{{if .IsActive}}-check{{end}}-square-o"></i></td> | ||||||
| 							<td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td> | 							<td><i class="fa fa{{if .IsAdmin}}-check{{end}}-square-o"></i></td> | ||||||
| 							<td>{{.NumRepos}}</td> | 							<td>{{.NumRepos}}</td> | ||||||
| 							<td><span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created }}</span></td> | 							<td><span title="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</span></td> | ||||||
| 							{{if .LastLoginUnix}} | 							{{if .LastLoginUnix}} | ||||||
| 								<td><span title="{{DateFmtLong .LastLogin}}">{{DateFmtShort .LastLogin }}</span></td> | 								<td><span title="{{.LastLoginUnix.FormatLong}}">{{.LastLoginUnix.FormatShort}}</span></td> | ||||||
| 							{{else}} | 							{{else}} | ||||||
| 								<td><span>{{$.i18n.Tr "admin.users.never_login"}}</span></td> | 								<td><span>{{$.i18n.Tr "admin.users.never_login"}}</span></td> | ||||||
| 							{{end}} | 							{{end}} | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
| 								<i class="octicon octicon-link"></i> | 								<i class="octicon octicon-link"></i> | ||||||
| 								<a href="{{.Website}}" rel="nofollow">{{.Website}}</a> | 								<a href="{{.Website}}" rel="nofollow">{{.Website}}</a> | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} | 							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}} | ||||||
| 					</div> | 					</div> | ||||||
| 				  </div> | 				  </div> | ||||||
| 				</div> | 				</div> | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ | |||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 			{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}} | 			{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}} | ||||||
| 			<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Updated $.i18n.Lang}}</p> | 			<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSinceUnix .UpdatedUnix $.i18n.Lang}}</p> | ||||||
| 		</div> | 		</div> | ||||||
| 	{{else}} | 	{{else}} | ||||||
| 	<div> | 	<div> | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
| 								<i class="octicon octicon-mail"></i> | 								<i class="octicon octicon-mail"></i> | ||||||
| 								<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a> | 								<a href="mailto:{{.Email}}" rel="nofollow">{{.Email}}</a> | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} | 							<i class="octicon octicon-clock"></i> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}} | ||||||
| 					</div> | 					</div> | ||||||
| 				  </div> | 				  </div> | ||||||
| 				</div> | 				</div> | ||||||
|   | |||||||
| @@ -86,7 +86,7 @@ | |||||||
| 						{{if not .IsTag}} | 						{{if not .IsTag}} | ||||||
| 							<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/src/{{.TagName}}">{{.Title}}</a> | 							<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/src/{{.TagName}}">{{.Title}}</a> | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 						{{TimeSince .Created $.Lang}} | 						{{TimeSinceUnix .CreatedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| @@ -102,7 +102,7 @@ | |||||||
| 					<p class="desc"> | 					<p class="desc"> | ||||||
| 						<div class="ui purple label">{{$.i18n.Tr "repo.activity.merged_prs_label"}}</div> | 						<div class="ui purple label">{{$.i18n.Tr "repo.activity.merged_prs_label"}}</div> | ||||||
| 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a> | 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a> | ||||||
| 						{{TimeSince .Merged $.Lang}} | 						{{TimeSinceUnix .MergedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| @@ -118,7 +118,7 @@ | |||||||
| 					<p class="desc"> | 					<p class="desc"> | ||||||
| 						<div class="ui green label">{{$.i18n.Tr "repo.activity.opened_prs_label"}}</div> | 						<div class="ui green label">{{$.i18n.Tr "repo.activity.opened_prs_label"}}</div> | ||||||
| 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a> | 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/pulls/{{.Index}}">{{.Issue.Title}}</a> | ||||||
| 						{{TimeSince .Issue.Created $.Lang}} | 						{{TimeSinceUnix .Issue.CreatedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| @@ -134,7 +134,7 @@ | |||||||
| 					<p class="desc"> | 					<p class="desc"> | ||||||
| 						<div class="ui red label">{{$.i18n.Tr "repo.activity.closed_issue_label"}}</div> | 						<div class="ui red label">{{$.i18n.Tr "repo.activity.closed_issue_label"}}</div> | ||||||
| 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | ||||||
| 						{{TimeSince .Updated $.Lang}} | 						{{TimeSinceUnix .UpdatedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| @@ -150,7 +150,7 @@ | |||||||
| 					<p class="desc"> | 					<p class="desc"> | ||||||
| 						<div class="ui green label">{{$.i18n.Tr "repo.activity.new_issue_label"}}</div> | 						<div class="ui green label">{{$.i18n.Tr "repo.activity.new_issue_label"}}</div> | ||||||
| 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | 						#{{.Index}} <a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | ||||||
| 						{{TimeSince .Created $.Lang}} | 						{{TimeSinceUnix .CreatedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
| @@ -174,7 +174,7 @@ | |||||||
| 						{{else}} | 						{{else}} | ||||||
| 						<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | 						<a class="title has-emoji" href="{{$.Repository.HTMLURL}}/issues/{{.Index}}">{{.Title}}</a> | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 						{{TimeSince .Updated $.Lang}} | 						{{TimeSinceUnix .UpdatedUnix $.Lang}} | ||||||
| 					</p> | 					</p> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			</div> | 			</div> | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ | |||||||
| 									<td> | 									<td> | ||||||
| 									{{if .IsDeleted}} | 									{{if .IsDeleted}} | ||||||
| 										<s>{{.Name}}</s> | 										<s>{{.Name}}</s> | ||||||
| 										<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSince .DeletedBranch.Deleted $.i18n.Lang}}</p> | 										<p class="time">{{$.i18n.Tr "repo.branch.deleted_by" .DeletedBranch.DeletedBy.Name}} {{TimeSinceUnix .DeletedBranch.DeletedUnix $.i18n.Lang}}</p> | ||||||
| 									{{else}} | 									{{else}} | ||||||
| 										{{.Name}} | 										{{.Name}} | ||||||
| 										<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p> | 										<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSince .Commit.Committer.When $.i18n.Lang}}</p> | ||||||
|   | |||||||
| @@ -163,7 +163,7 @@ | |||||||
|  |  | ||||||
| 		<div class="issue list"> | 		<div class="issue list"> | ||||||
| 			{{range .Issues}} | 			{{range .Issues}} | ||||||
| 				{{ $timeStr:= TimeSince .Created $.Lang }} | 				{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }} | ||||||
| 				<li class="item"> | 				<li class="item"> | ||||||
| 					<div class="ui checkbox issue-checkbox"> | 					<div class="ui checkbox issue-checkbox"> | ||||||
| 						<input type="checkbox" data-issue-id={{.ID}}></input> | 						<input type="checkbox" data-issue-id={{.ID}}></input> | ||||||
|   | |||||||
| @@ -50,7 +50,7 @@ | |||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="meta"> | 					<div class="meta"> | ||||||
| 						{{ $closedDate:= TimeSince .ClosedDate $.Lang }} | 						{{ $closedDate:= TimeSinceUnix .ClosedDateUnix $.Lang }} | ||||||
| 						{{if .IsClosed}} | 						{{if .IsClosed}} | ||||||
| 							<span class="octicon octicon-clock"></span> {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}} | 							<span class="octicon octicon-clock"></span> {{$.i18n.Tr "repo.milestones.closed" $closedDate|Str2html}} | ||||||
| 						{{else}} | 						{{else}} | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 		{{template "repo/issue/view_title" .}} | 		{{template "repo/issue/view_title" .}} | ||||||
| 	{{end}} | 	{{end}} | ||||||
|  |  | ||||||
| 	{{ $createdStr:= TimeSince .Issue.Created $.Lang }} | 	{{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }} | ||||||
| 	<div class="twelve wide column comment-list"> | 	<div class="twelve wide column comment-list"> | ||||||
| 		<ui class="ui comments"> | 		<ui class="ui comments"> | ||||||
| 			<div class="comment"> | 			<div class="comment"> | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| {{range .Issue.Comments}} | {{range .Issue.Comments}} | ||||||
| 	{{ $createdStr:= TimeSince .Created $.Lang }} | 	{{ $createdStr:= TimeSinceUnix .CreatedUnix $.Lang }} | ||||||
|  |  | ||||||
| 	<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 12 = START_TRACKING, 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL --> | 	<!-- 0 = COMMENT, 1 = REOPEN, 2 = CLOSE, 3 = ISSUE_REF, 4 = COMMIT_REF, 5 = COMMENT_REF, 6 = PULL_REF, 7 = COMMENT_LABEL, 12 = START_TRACKING, 13 = STOP_TRACKING, 14 = ADD_TIME_MANUAL --> | ||||||
| 	{{if eq .Type 0}} | 	{{if eq .Type 0}} | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ | |||||||
|  |  | ||||||
| 	{{if .Issue.IsPull}} | 	{{if .Issue.IsPull}} | ||||||
| 		{{if .Issue.PullRequest.HasMerged}} | 		{{if .Issue.PullRequest.HasMerged}} | ||||||
| 			{{ $mergedStr:= TimeSince .Issue.PullRequest.Merged $.Lang }} | 			{{ $mergedStr:= TimeSinceUnix .Issue.PullRequest.MergedUnix $.Lang }} | ||||||
| 			<a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.Name}}</a> | 			<a {{if gt .Issue.PullRequest.Merger.ID 0}}href="{{.Issue.PullRequest.Merger.HomeLink}}"{{end}}>{{.Issue.PullRequest.Merger.Name}}</a> | ||||||
| 			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Str2html}}</span> | 			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.merged_title_desc" .NumCommits .HeadTarget .BaseTarget $mergedStr | Str2html}}</span> | ||||||
| 		{{else}} | 		{{else}} | ||||||
| @@ -34,7 +34,7 @@ | |||||||
| 			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.title_desc" .NumCommits .HeadTarget .BaseTarget | Str2html}}</span> | 			<span class="pull-desc">{{$.i18n.Tr "repo.pulls.title_desc" .NumCommits .HeadTarget .BaseTarget | Str2html}}</span> | ||||||
| 		{{end}} | 		{{end}} | ||||||
| 	{{else}} | 	{{else}} | ||||||
| 		{{ $createdStr:= TimeSince .Issue.Created $.Lang }} | 		{{ $createdStr:= TimeSinceUnix .Issue.CreatedUnix $.Lang }} | ||||||
| 		<span class="time-desc"> | 		<span class="time-desc"> | ||||||
| 			{{if gt .Issue.Poster.ID 0}} | 			{{if gt .Issue.Poster.ID 0}} | ||||||
| 				{{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.Name | Safe}} | 				{{$.i18n.Tr "repo.issues.opened_by" $createdStr .Issue.Poster.HomeLink .Issue.Poster.Name | Safe}} | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
| 				<li class="ui grid"> | 				<li class="ui grid"> | ||||||
| 					<div class="ui four wide column meta"> | 					<div class="ui four wide column meta"> | ||||||
| 						{{if .IsTag}} | 						{{if .IsTag}} | ||||||
| 							{{if .Created}}<span class="time">{{TimeSince .Created $.Lang}}</span>{{end}} | 							{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}} | ||||||
| 						{{else}} | 						{{else}} | ||||||
| 							{{if .IsDraft}} | 							{{if .IsDraft}} | ||||||
| 								<span class="ui yellow label">{{$.i18n.Tr "repo.release.draft"}}</span> | 								<span class="ui yellow label">{{$.i18n.Tr "repo.release.draft"}}</span> | ||||||
| @@ -55,7 +55,7 @@ | |||||||
| 									<img class="img-10" src="{{.Publisher.RelAvatarLink}}"> | 									<img class="img-10" src="{{.Publisher.RelAvatarLink}}"> | ||||||
| 									<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a> | 									<a href="{{AppSubUrl}}/{{.Publisher.Name}}">{{.Publisher.Name}}</a> | ||||||
| 								</span> | 								</span> | ||||||
| 								{{if .Created}}<span class="time">{{TimeSince .Created $.Lang}}</span>{{end}} | 								{{if .CreatedUnix}}<span class="time">{{TimeSinceUnix .CreatedUnix $.Lang}}</span>{{end}} | ||||||
| 								<span class="ahead">{{$.i18n.Tr "repo.release.ahead" .NumCommitsBehind .Target | Str2html}}</span> | 								<span class="ahead">{{$.i18n.Tr "repo.release.ahead" .NumCommitsBehind .Target | Str2html}}</span> | ||||||
| 							</p> | 							</p> | ||||||
| 							<div class="markdown desc"> | 							<div class="markdown desc"> | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ | |||||||
| 										{{.Fingerprint}} | 										{{.Fingerprint}} | ||||||
| 									</div> | 									</div> | ||||||
| 									<div class="activity meta"> | 									<div class="activity meta"> | ||||||
| 										<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> | 										<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> | ||||||
| 									</div> | 									</div> | ||||||
| 								</div> | 								</div> | ||||||
| 						</div> | 						</div> | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ | |||||||
| 					<input type="hidden" name="action" value="mirror-sync"> | 					<input type="hidden" name="action" value="mirror-sync"> | ||||||
| 					<div class="inline field"> | 					<div class="inline field"> | ||||||
| 						<label>{{.i18n.Tr "repo.mirror_last_synced"}}</label> | 						<label>{{.i18n.Tr "repo.mirror_last_synced"}}</label> | ||||||
| 						<span>{{.Mirror.Updated}}</span> | 						<span>{{.Mirror.UpdatedUnix.AsTime}}</span> | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="field"> | 					<div class="field"> | ||||||
| 						<button class="ui blue button">{{$.i18n.Tr "repo.settings.sync_mirror"}}</button> | 						<button class="ui blue button">{{$.i18n.Tr "repo.settings.sync_mirror"}}</button> | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ | |||||||
| 					{{else if .Location}} | 					{{else if .Location}} | ||||||
| 						<span class="octicon octicon-location"></span> {{.Location}} | 						<span class="octicon octicon-location"></span> {{.Location}} | ||||||
| 					{{else}} | 					{{else}} | ||||||
| 						<span class="octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}} | 						<span class="octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{.CreatedUnix.FormatShort}} | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 				</div> | 				</div> | ||||||
| 			</li> | 			</li> | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
| 							<i class="octicon octicon-file-text"></i> | 							<i class="octicon octicon-file-text"></i> | ||||||
| 							<a href="{{$.RepoLink}}/wiki/{{.SubURL}}">{{.Name}}</a> | 							<a href="{{$.RepoLink}}/wiki/{{.SubURL}}">{{.Name}}</a> | ||||||
| 						</td> | 						</td> | ||||||
| 						{{$timeSince := TimeSince .Updated $.Lang}} | 						{{$timeSince := TimeSinceUnix .UpdatedUnix $.Lang}} | ||||||
| 						<td class="text right grey">{{$.i18n.Tr "repo.wiki.last_updated" $timeSince | Safe}}</td> | 						<td class="text right grey">{{$.i18n.Tr "repo.wiki.last_updated" $timeSince | Safe}}</td> | ||||||
| 					</tr> | 					</tr> | ||||||
| 				{{end}} | 				{{end}} | ||||||
|   | |||||||
| @@ -59,7 +59,7 @@ | |||||||
|  |  | ||||||
| 				<div class="issue list"> | 				<div class="issue list"> | ||||||
| 					{{range .Issues}} | 					{{range .Issues}} | ||||||
| 						{{ $timeStr:= TimeSince .Created $.Lang }} | 						{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }} | ||||||
| 						<li class="item"> | 						<li class="item"> | ||||||
| 							<div class="ui label">{{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}</div> | 							<div class="ui label">{{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}</div> | ||||||
| 							<a class="title has-emoji" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Title}}</a> | 							<a class="title has-emoji" href="{{AppSubUrl}}/{{.Repo.Owner.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Title}}</a> | ||||||
|   | |||||||
| @@ -42,7 +42,7 @@ | |||||||
| 									</li> | 									</li> | ||||||
| 								{{end}} | 								{{end}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							<li><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{DateFmtShort .Owner.Created}}</li> | 							<li><i class="octicon octicon-clock"></i> {{.i18n.Tr "user.join_on"}} {{.Owner.CreatedUnix.FormatShort}}</li> | ||||||
| 							<li> | 							<li> | ||||||
| 								<i class="octicon octicon-person"></i> | 								<i class="octicon octicon-person"></i> | ||||||
| 								<a href="{{.Owner.HomeLink}}/followers"> | 								<a href="{{.Owner.HomeLink}}/followers"> | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ | |||||||
| 							<div class="content"> | 							<div class="content"> | ||||||
| 								<strong>{{.Name}}</strong> | 								<strong>{{.Name}}</strong> | ||||||
| 								<div class="activity meta"> | 								<div class="activity meta"> | ||||||
| 									<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> | 									<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —  <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> | ||||||
| 								</div> | 								</div> | ||||||
| 							</div> | 							</div> | ||||||
| 					</div> | 					</div> | ||||||
|   | |||||||
| @@ -24,9 +24,9 @@ | |||||||
| 						<b>{{$.i18n.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.KeyID}} {{end}} | 						<b>{{$.i18n.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.KeyID}} {{end}} | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="activity meta"> | 					<div class="activity meta"> | ||||||
| 						<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Added}}</span></i> | 						<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.AddedUnix.FormatShort}}</span></i> | ||||||
| 						- | 						- | ||||||
| 						<i>{{if not .Expired.IsZero }}{{$.i18n.Tr "settings.valid_until"}} <span>{{DateFmtShort .Expired}}</span>{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}}</i> | 						<i>{{if .ExpiredUnix}}{{$.i18n.Tr "settings.valid_until"}} <span>{{.ExpiredUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.valid_forever"}}{{end}}</i> | ||||||
| 					</div> | 					</div> | ||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ | |||||||
|                         {{.Fingerprint}} |                         {{.Fingerprint}} | ||||||
|                     </div> |                     </div> | ||||||
|                     <div class="activity meta"> |                     <div class="activity meta"> | ||||||
|                         <i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> —	<i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> |                         <i>{{$.i18n.Tr "settings.add_on"}} <span>{{.CreatedUnix.FormatShort}}</span> —	<i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}>{{.UpdatedUnix.FormatShort}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
| 			</div> | 			</div> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Lunny Xiao
					Lunny Xiao