mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Merge template functions "dict/Dict/mergeinto" (#23932)
One of the steps in #23328 Before there were 3 different but similar functions: dict/Dict/mergeinto The code was just copied & pasted, no test. This PR defines a new stable `dict` function, it covers all the 3 old functions behaviors, only +160 -171 Future developers do not need to think about or guess the different dict functions, just use one: `dict` Why use `dict` but not `Dict`? Because there are far more `dict` than `Dict` in code already ......
This commit is contained in:
		| @@ -8,7 +8,6 @@ import ( | |||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/hex" | 	"encoding/hex" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"html" | 	"html" | ||||||
| 	"html/template" | 	"html/template" | ||||||
| @@ -219,20 +218,6 @@ func NewFuncMap() []template.FuncMap { | |||||||
| 		"DisableImportLocal": func() bool { | 		"DisableImportLocal": func() bool { | ||||||
| 			return !setting.ImportLocalPaths | 			return !setting.ImportLocalPaths | ||||||
| 		}, | 		}, | ||||||
| 		"Dict": func(values ...interface{}) (map[string]interface{}, error) { |  | ||||||
| 			if len(values)%2 != 0 { |  | ||||||
| 				return nil, errors.New("invalid dict call") |  | ||||||
| 			} |  | ||||||
| 			dict := make(map[string]interface{}, len(values)/2) |  | ||||||
| 			for i := 0; i < len(values); i += 2 { |  | ||||||
| 				key, ok := values[i].(string) |  | ||||||
| 				if !ok { |  | ||||||
| 					return nil, errors.New("dict keys must be strings") |  | ||||||
| 				} |  | ||||||
| 				dict[key] = values[i+1] |  | ||||||
| 			} |  | ||||||
| 			return dict, nil |  | ||||||
| 		}, |  | ||||||
| 		"Printf":   fmt.Sprintf, | 		"Printf":   fmt.Sprintf, | ||||||
| 		"Escape":   Escape, | 		"Escape":   Escape, | ||||||
| 		"Sec2Time": util.SecToTime, | 		"Sec2Time": util.SecToTime, | ||||||
| @@ -242,35 +227,7 @@ func NewFuncMap() []template.FuncMap { | |||||||
| 		"DefaultTheme": func() string { | 		"DefaultTheme": func() string { | ||||||
| 			return setting.UI.DefaultTheme | 			return setting.UI.DefaultTheme | ||||||
| 		}, | 		}, | ||||||
| 		// pass key-value pairs to a partial template which receives them as a dict | 		"dict":                dict, | ||||||
| 		"dict": func(values ...interface{}) (map[string]interface{}, error) { |  | ||||||
| 			if len(values) == 0 { |  | ||||||
| 				return nil, errors.New("invalid dict call") |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			dict := make(map[string]interface{}) |  | ||||||
| 			return util.MergeInto(dict, values...) |  | ||||||
| 		}, |  | ||||||
| 		/* like dict but merge key-value pairs into the first dict and return it */ |  | ||||||
| 		"mergeinto": func(root map[string]interface{}, values ...interface{}) (map[string]interface{}, error) { |  | ||||||
| 			if len(values) == 0 { |  | ||||||
| 				return nil, errors.New("invalid mergeinto call") |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			dict := make(map[string]interface{}) |  | ||||||
| 			for key, value := range root { |  | ||||||
| 				dict[key] = value |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return util.MergeInto(dict, values...) |  | ||||||
| 		}, |  | ||||||
| 		"percentage": func(n int, values ...int) float32 { |  | ||||||
| 			sum := 0 |  | ||||||
| 			for i := 0; i < len(values); i++ { |  | ||||||
| 				sum += values[i] |  | ||||||
| 			} |  | ||||||
| 			return float32(n) * 100 / float32(sum) |  | ||||||
| 		}, |  | ||||||
| 		"CommentMustAsDiff":   gitdiff.CommentMustAsDiff, | 		"CommentMustAsDiff":   gitdiff.CommentMustAsDiff, | ||||||
| 		"MirrorRemoteAddress": mirrorRemoteAddress, | 		"MirrorRemoteAddress": mirrorRemoteAddress, | ||||||
| 		"NotificationSettings": func() map[string]interface{} { | 		"NotificationSettings": func() map[string]interface{} { | ||||||
| @@ -413,52 +370,13 @@ func NewTextFuncMap() []texttmpl.FuncMap { | |||||||
| 		}, | 		}, | ||||||
| 		"EllipsisString": base.EllipsisString, | 		"EllipsisString": base.EllipsisString, | ||||||
| 		"URLJoin":        util.URLJoin, | 		"URLJoin":        util.URLJoin, | ||||||
| 		"Dict": func(values ...interface{}) (map[string]interface{}, error) { |  | ||||||
| 			if len(values)%2 != 0 { |  | ||||||
| 				return nil, errors.New("invalid dict call") |  | ||||||
| 			} |  | ||||||
| 			dict := make(map[string]interface{}, len(values)/2) |  | ||||||
| 			for i := 0; i < len(values); i += 2 { |  | ||||||
| 				key, ok := values[i].(string) |  | ||||||
| 				if !ok { |  | ||||||
| 					return nil, errors.New("dict keys must be strings") |  | ||||||
| 				} |  | ||||||
| 				dict[key] = values[i+1] |  | ||||||
| 			} |  | ||||||
| 			return dict, nil |  | ||||||
| 		}, |  | ||||||
| 		"Printf":         fmt.Sprintf, | 		"Printf":         fmt.Sprintf, | ||||||
| 		"Escape":         Escape, | 		"Escape":         Escape, | ||||||
| 		"Sec2Time":       util.SecToTime, | 		"Sec2Time":       util.SecToTime, | ||||||
| 		"ParseDeadline": func(deadline string) []string { | 		"ParseDeadline": func(deadline string) []string { | ||||||
| 			return strings.Split(deadline, "|") | 			return strings.Split(deadline, "|") | ||||||
| 		}, | 		}, | ||||||
| 		"dict": func(values ...interface{}) (map[string]interface{}, error) { | 		"dict":        dict, | ||||||
| 			if len(values) == 0 { |  | ||||||
| 				return nil, errors.New("invalid dict call") |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			dict := make(map[string]interface{}) |  | ||||||
|  |  | ||||||
| 			for i := 0; i < len(values); i++ { |  | ||||||
| 				switch key := values[i].(type) { |  | ||||||
| 				case string: |  | ||||||
| 					i++ |  | ||||||
| 					if i == len(values) { |  | ||||||
| 						return nil, errors.New("specify the key for non array values") |  | ||||||
| 					} |  | ||||||
| 					dict[key] = values[i] |  | ||||||
| 				case map[string]interface{}: |  | ||||||
| 					m := values[i].(map[string]interface{}) |  | ||||||
| 					for i, v := range m { |  | ||||||
| 						dict[i] = v |  | ||||||
| 					} |  | ||||||
| 				default: |  | ||||||
| 					return nil, errors.New("dict values must be maps") |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			return dict, nil |  | ||||||
| 		}, |  | ||||||
| 		"QueryEscape": url.QueryEscape, | 		"QueryEscape": url.QueryEscape, | ||||||
| 		"Eval":        Eval, | 		"Eval":        Eval, | ||||||
| 	}} | 	}} | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								modules/templates/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								modules/templates/util.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | // Copyright 2023 The Gitea Authors. All rights reserved. | ||||||
|  | // SPDX-License-Identifier: MIT | ||||||
|  |  | ||||||
|  | package templates | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"reflect" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func dictMerge(base map[string]any, arg any) bool { | ||||||
|  | 	if arg == nil { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	rv := reflect.ValueOf(arg) | ||||||
|  | 	if rv.Kind() == reflect.Map { | ||||||
|  | 		for _, k := range rv.MapKeys() { | ||||||
|  | 			base[k.String()] = rv.MapIndex(k).Interface() | ||||||
|  | 		} | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // dict is a helper function for creating a map[string]any from a list of key-value pairs. | ||||||
|  | // If the key is dot ".", the value is merged into the base map, just like Golang template's dot syntax: dot means current | ||||||
|  | // The dot syntax is highly discouraged because it might cause unclear key conflicts. It's always good to use explicit keys. | ||||||
|  | func dict(args ...any) (map[string]any, error) { | ||||||
|  | 	if len(args)%2 != 0 { | ||||||
|  | 		return nil, fmt.Errorf("invalid dict constructor syntax: must have key-value pairs") | ||||||
|  | 	} | ||||||
|  | 	m := make(map[string]any, len(args)/2) | ||||||
|  | 	for i := 0; i < len(args); i += 2 { | ||||||
|  | 		key, ok := args[i].(string) | ||||||
|  | 		if !ok { | ||||||
|  | 			return nil, fmt.Errorf("invalid dict constructor syntax: unable to merge args[%d]", i) | ||||||
|  | 		} | ||||||
|  | 		if key == "." { | ||||||
|  | 			if ok = dictMerge(m, args[i+1]); !ok { | ||||||
|  | 				return nil, fmt.Errorf("invalid dict constructor syntax: dot arg[%d] must be followed by a dict", i) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			m[key] = args[i+1] | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return m, nil | ||||||
|  | } | ||||||
							
								
								
									
										43
									
								
								modules/templates/util_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								modules/templates/util_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | // Copyright 2023 The Gitea Authors. All rights reserved. | ||||||
|  | // SPDX-License-Identifier: MIT | ||||||
|  |  | ||||||
|  | package templates | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestDict(t *testing.T) { | ||||||
|  | 	type M map[string]any | ||||||
|  | 	cases := []struct { | ||||||
|  | 		args []any | ||||||
|  | 		want map[string]any | ||||||
|  | 	}{ | ||||||
|  | 		{[]any{"a", 1, "b", 2}, M{"a": 1, "b": 2}}, | ||||||
|  | 		{[]any{".", M{"base": 1}, "b", 2}, M{"base": 1, "b": 2}}, | ||||||
|  | 		{[]any{"a", 1, ".", M{"extra": 2}}, M{"a": 1, "extra": 2}}, | ||||||
|  | 		{[]any{"a", 1, ".", map[string]int{"int": 2}}, M{"a": 1, "int": 2}}, | ||||||
|  | 		{[]any{".", nil, "b", 2}, M{"b": 2}}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, c := range cases { | ||||||
|  | 		got, err := dict(c.args...) | ||||||
|  | 		if assert.NoError(t, err) { | ||||||
|  | 			assert.EqualValues(t, c.want, got) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bads := []struct { | ||||||
|  | 		args []any | ||||||
|  | 	}{ | ||||||
|  | 		{[]any{"a", 1, "b"}}, | ||||||
|  | 		{[]any{1}}, | ||||||
|  | 		{[]any{struct{}{}}}, | ||||||
|  | 	} | ||||||
|  | 	for _, c := range bads { | ||||||
|  | 		_, err := dict(c.args...) | ||||||
|  | 		assert.Error(t, err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -6,7 +6,6 @@ package util | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"crypto/rand" | 	"crypto/rand" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @@ -117,29 +116,6 @@ func NormalizeEOL(input []byte) []byte { | |||||||
| 	return tmp[:pos] | 	return tmp[:pos] | ||||||
| } | } | ||||||
|  |  | ||||||
| // MergeInto merges pairs of values into a "dict" |  | ||||||
| func MergeInto(dict map[string]interface{}, values ...interface{}) (map[string]interface{}, error) { |  | ||||||
| 	for i := 0; i < len(values); i++ { |  | ||||||
| 		switch key := values[i].(type) { |  | ||||||
| 		case string: |  | ||||||
| 			i++ |  | ||||||
| 			if i == len(values) { |  | ||||||
| 				return nil, errors.New("specify the key for non array values") |  | ||||||
| 			} |  | ||||||
| 			dict[key] = values[i] |  | ||||||
| 		case map[string]interface{}: |  | ||||||
| 			m := values[i].(map[string]interface{}) |  | ||||||
| 			for i, v := range m { |  | ||||||
| 				dict[i] = v |  | ||||||
| 			} |  | ||||||
| 		default: |  | ||||||
| 			return nil, errors.New("dict values must be maps") |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return dict, nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // CryptoRandomInt returns a crypto random integer between 0 and limit, inclusive | // CryptoRandomInt returns a crypto random integer between 0 and limit, inclusive | ||||||
| func CryptoRandomInt(limit int64) (int64, error) { | func CryptoRandomInt(limit int64) (int64, error) { | ||||||
| 	rInt, err := rand.Int(rand.Reader, big.NewInt(limit)) | 	rInt, err := rand.Int(rand.Reader, big.NewInt(limit)) | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ | |||||||
| 					</div> | 					</div> | ||||||
| 					<div class="ui attached segment members"> | 					<div class="ui attached segment members"> | ||||||
| 						{{range .Members}} | 						{{range .Members}} | ||||||
| 							{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .}} | 							{{template "shared/user/avatarlink" dict "Context" $.Context "user" .}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</div> | 					</div> | ||||||
| 					<div class="ui bottom attached header"> | 					<div class="ui bottom attached header"> | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| 	{{if .OriginalAuthor}} | 	{{if .OriginalAuthor}} | ||||||
| 		<span class="avatar"><img src="{{AppSubUrl}}/assets/img/avatar_default.png"></span> | 		<span class="avatar"><img src="{{AppSubUrl}}/assets/img/avatar_default.png"></span> | ||||||
| 	{{else}} | 	{{else}} | ||||||
| 		{{template "shared/user/avatarlink" Dict "Context" $.root.Context "user" .Poster}} | 		{{template "shared/user/avatarlink" dict "Context" $.root.Context "user" .Poster}} | ||||||
| 	{{end}} | 	{{end}} | ||||||
| 	<div class="content comment-container"> | 	<div class="content comment-container"> | ||||||
| 		<div class="ui top attached header comment-header gt-df gt-ac gt-sb"> | 		<div class="ui top attached header comment-header gt-df gt-ac gt-sb"> | ||||||
| @@ -42,8 +42,8 @@ | |||||||
| 						</div> | 						</div> | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 				{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}} | 				{{template "repo/issue/view_content/add_reaction" dict "ctxData" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID)}} | ||||||
| 				{{template "repo/issue/view_content/context_menu" Dict "ctxData" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}} | 				{{template "repo/issue/view_content/context_menu" dict "ctxData" $.root "item" . "delete" true "issue" false "diff" true "IsCommentPoster" (and $.root.IsSigned (eq $.root.SignedUserID .PosterID))}} | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		<div class="ui attached segment comment-body"> | 		<div class="ui attached segment comment-body"> | ||||||
| @@ -60,7 +60,7 @@ | |||||||
| 		{{$reactions := .Reactions.GroupByType}} | 		{{$reactions := .Reactions.GroupByType}} | ||||||
| 		{{if $reactions}} | 		{{if $reactions}} | ||||||
| 			<div class="ui attached segment reactions"> | 			<div class="ui attached segment reactions"> | ||||||
| 			{{template "repo/issue/view_content/reactions" Dict "ctxData" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) "Reactions" $reactions}} | 			{{template "repo/issue/view_content/reactions" dict "ctxData" $.root "ActionURL" (Printf "%s/comments/%d/reactions" $.root.RepoLink .ID) "Reactions" $reactions}} | ||||||
| 			</div> | 			</div> | ||||||
| 		{{end}} | 		{{end}} | ||||||
| 	</div> | 	</div> | ||||||
|   | |||||||
| @@ -111,22 +111,22 @@ | |||||||
| 						<td class="add-comment-left" colspan="4"> | 						<td class="add-comment-left" colspan="4"> | ||||||
| 							{{if gt (len $line.Comments) 0}} | 							{{if gt (len $line.Comments) 0}} | ||||||
| 								{{if eq $line.GetCommentSide "previous"}} | 								{{if eq $line.GetCommentSide "previous"}} | ||||||
| 									{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} | 									{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}} | ||||||
| 								{{end}} | 								{{end}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							{{if gt (len $match.Comments) 0}} | 							{{if gt (len $match.Comments) 0}} | ||||||
| 								{{if eq $match.GetCommentSide "previous"}} | 								{{if eq $match.GetCommentSide "previous"}} | ||||||
| 									{{template "repo/diff/conversation" mergeinto $.root "comments" $match.Comments}} | 									{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}} | ||||||
| 								{{end}} | 								{{end}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</td> | 						</td> | ||||||
| 						<td class="add-comment-right" colspan="4"> | 						<td class="add-comment-right" colspan="4"> | ||||||
| 							{{if eq $line.GetCommentSide "proposed"}} | 							{{if eq $line.GetCommentSide "proposed"}} | ||||||
| 								{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} | 								{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							{{if gt (len $match.Comments) 0}} | 							{{if gt (len $match.Comments) 0}} | ||||||
| 								{{if eq $match.GetCommentSide "proposed"}} | 								{{if eq $match.GetCommentSide "proposed"}} | ||||||
| 									{{template "repo/diff/conversation" mergeinto $.root "comments" $match.Comments}} | 									{{template "repo/diff/conversation" dict "." $.root "comments" $match.Comments}} | ||||||
| 								{{end}} | 								{{end}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</td> | 						</td> | ||||||
| @@ -137,13 +137,13 @@ | |||||||
| 					<td class="add-comment-left" colspan="4"> | 					<td class="add-comment-left" colspan="4"> | ||||||
| 						{{if gt (len $line.Comments) 0}} | 						{{if gt (len $line.Comments) 0}} | ||||||
| 							{{if eq $line.GetCommentSide "previous"}} | 							{{if eq $line.GetCommentSide "previous"}} | ||||||
| 								{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} | 								{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</td> | 					</td> | ||||||
| 					<td class="add-comment-right" colspan="4"> | 					<td class="add-comment-right" colspan="4"> | ||||||
| 						{{if eq $line.GetCommentSide "proposed"}} | 						{{if eq $line.GetCommentSide "proposed"}} | ||||||
| 							{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} | 							{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</td> | 					</td> | ||||||
| 				</tr> | 				</tr> | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ | |||||||
| 		{{if gt (len $line.Comments) 0}} | 		{{if gt (len $line.Comments) 0}} | ||||||
| 			<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}"> | 			<tr class="add-comment" data-line-type="{{DiffLineTypeToStr .GetType}}"> | ||||||
| 				<td class="add-comment-left add-comment-right" colspan="5"> | 				<td class="add-comment-left add-comment-right" colspan="5"> | ||||||
| 					{{template "repo/diff/conversation" mergeinto $.root "comments" $line.Comments}} | 					{{template "repo/diff/conversation" dict "." $.root "comments" $line.Comments}} | ||||||
| 				</td> | 				</td> | ||||||
| 			</tr> | 			</tr> | ||||||
| 		{{end}} | 		{{end}} | ||||||
|   | |||||||
| @@ -307,7 +307,7 @@ | |||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		{{template "shared/issuelist" mergeinto . "listType" "repo"}} | 		{{template "shared/issuelist" dict "." . "listType" "repo"}} | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||||
|   | |||||||
| @@ -198,7 +198,7 @@ | |||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 		{{template "shared/issuelist" mergeinto . "listType" "milestone"}} | 		{{template "shared/issuelist" dict "." . "listType" "milestone"}} | ||||||
| 	</div> | 	</div> | ||||||
| </div> | </div> | ||||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| 	<div class="twelve wide column"> | 	<div class="twelve wide column"> | ||||||
| 		<div class="ui comments"> | 		<div class="ui comments"> | ||||||
| 			<div class="comment"> | 			<div class="comment"> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .SignedUser}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .SignedUser}} | ||||||
| 				<div class="ui segment content"> | 				<div class="ui segment content"> | ||||||
| 					<div class="field"> | 					<div class="field"> | ||||||
| 						<input name="title" id="issue_title" placeholder="{{.locale.Tr "repo.milestones.title"}}" value="{{if .TitleQuery}}{{.TitleQuery}}{{else if .IssueTemplateTitle}}{{.IssueTemplateTitle}}{{else}}{{.title}}{{end}}" tabindex="3" autofocus required maxlength="255" autocomplete="off"> | 						<input name="title" id="issue_title" placeholder="{{.locale.Tr "repo.milestones.title"}}" value="{{if .TitleQuery}}{{.TitleQuery}}{{else if .IssueTemplateTitle}}{{.IssueTemplateTitle}}{{else}}{{.title}}{{end}}" tabindex="3" autofocus required maxlength="255" autocomplete="off"> | ||||||
| @@ -20,15 +20,15 @@ | |||||||
| 						<input type="hidden" name="template-file" value="{{.TemplateFile}}"> | 						<input type="hidden" name="template-file" value="{{.TemplateFile}}"> | ||||||
| 						{{range .Fields}} | 						{{range .Fields}} | ||||||
| 							{{if eq .Type "input"}} | 							{{if eq .Type "input"}} | ||||||
| 								{{template "repo/issue/fields/input" Dict "Context" $.Context "item" .}} | 								{{template "repo/issue/fields/input" dict "Context" $.Context "item" .}} | ||||||
| 							{{else if eq .Type "markdown"}} | 							{{else if eq .Type "markdown"}} | ||||||
| 								{{template "repo/issue/fields/markdown" Dict "Context" $.Context "item" .}} | 								{{template "repo/issue/fields/markdown" dict "Context" $.Context "item" .}} | ||||||
| 							{{else if eq .Type "textarea"}} | 							{{else if eq .Type "textarea"}} | ||||||
| 								{{template "repo/issue/fields/textarea" Dict "Context" $.Context "item" .}} | 								{{template "repo/issue/fields/textarea" dict "Context" $.Context "item" .}} | ||||||
| 							{{else if eq .Type "dropdown"}} | 							{{else if eq .Type "dropdown"}} | ||||||
| 								{{template "repo/issue/fields/dropdown" Dict "Context" $.Context "item" .}} | 								{{template "repo/issue/fields/dropdown" dict "Context" $.Context "item" .}} | ||||||
| 							{{else if eq .Type "checkboxes"}} | 							{{else if eq .Type "checkboxes"}} | ||||||
| 								{{template "repo/issue/fields/checkboxes" Dict "Context" $.Context "item" .}} | 								{{template "repo/issue/fields/checkboxes" dict "Context" $.Context "item" .}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 						{{if .IsAttachmentEnabled}} | 						{{if .IsAttachmentEnabled}} | ||||||
|   | |||||||
| @@ -64,8 +64,8 @@ | |||||||
| 								{{end}} | 								{{end}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							{{if not $.Repository.IsArchived}} | 							{{if not $.Repository.IsArchived}} | ||||||
| 								{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}} | 								{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index)}} | ||||||
| 								{{template "repo/issue/view_content/context_menu" Dict "ctxData" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}} | 								{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" .Issue "delete" false "issue" true "diff" false "IsCommentPoster" $.IsIssuePoster}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| @@ -80,13 +80,13 @@ | |||||||
| 						<div id="issue-{{.Issue.ID}}-raw" class="raw-content gt-hidden">{{.Issue.Content}}</div> | 						<div id="issue-{{.Issue.ID}}-raw" class="raw-content gt-hidden">{{.Issue.Content}}</div> | ||||||
| 						<div class="edit-content-zone gt-hidden" data-write="issue-{{.Issue.ID}}-write" data-preview="issue-{{.Issue.ID}}-preview" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/content" data-context="{{.RepoLink}}" data-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/attachments" data-view-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/view-attachments"></div> | 						<div class="edit-content-zone gt-hidden" data-write="issue-{{.Issue.ID}}-write" data-preview="issue-{{.Issue.ID}}-preview" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/content" data-context="{{.RepoLink}}" data-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/attachments" data-view-attachment-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/view-attachments"></div> | ||||||
| 						{{if .Issue.Attachments}} | 						{{if .Issue.Attachments}} | ||||||
| 							{{template "repo/issue/view_content/attachments" Dict "ctxData" $ "Attachments" .Issue.Attachments "Content" .Issue.RenderedContent}} | 							{{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Issue.Attachments "Content" .Issue.RenderedContent}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</div> | 					</div> | ||||||
| 					{{$reactions := .Issue.Reactions.GroupByType}} | 					{{$reactions := .Issue.Reactions.GroupByType}} | ||||||
| 					{{if $reactions}} | 					{{if $reactions}} | ||||||
| 						<div class="ui attached segment reactions" role="note"> | 						<div class="ui attached segment reactions" role="note"> | ||||||
| 							{{template "repo/issue/view_content/reactions" Dict "ctxData" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}} | 							{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" $reactions}} | ||||||
| 						</div> | 						</div> | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 				</div> | 				</div> | ||||||
|   | |||||||
| @@ -64,8 +64,8 @@ | |||||||
| 								</div> | 								</div> | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 							{{if not $.Repository.IsArchived}} | 							{{if not $.Repository.IsArchived}} | ||||||
| 								{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | 								{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | ||||||
| 								{{template "repo/issue/view_content/context_menu" Dict "ctxData" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | 								{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</div> | 						</div> | ||||||
| 					</div> | 					</div> | ||||||
| @@ -80,13 +80,13 @@ | |||||||
| 						<div id="issuecomment-{{.ID}}-raw" class="raw-content gt-hidden">{{.Content}}</div> | 						<div id="issuecomment-{{.ID}}-raw" class="raw-content gt-hidden">{{.Content}}</div> | ||||||
| 						<div class="edit-content-zone gt-hidden" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div> | 						<div class="edit-content-zone gt-hidden" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div> | ||||||
| 						{{if .Attachments}} | 						{{if .Attachments}} | ||||||
| 							{{template "repo/issue/view_content/attachments" Dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} | 							{{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</div> | 					</div> | ||||||
| 					{{$reactions := .Reactions.GroupByType}} | 					{{$reactions := .Reactions.GroupByType}} | ||||||
| 					{{if $reactions}} | 					{{if $reactions}} | ||||||
| 						<div class="ui attached segment reactions" role="note"> | 						<div class="ui attached segment reactions" role="note"> | ||||||
| 							{{template "repo/issue/view_content/reactions" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | 							{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | ||||||
| 						</div> | 						</div> | ||||||
| 					{{end}} | 					{{end}} | ||||||
| 				</div> | 				</div> | ||||||
| @@ -94,7 +94,7 @@ | |||||||
| 		{{else if eq .Type 1}} | 		{{else if eq .Type 1}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge gt-bg-green gt-text-white">{{svg "octicon-dot-fill"}}</span> | 				<span class="badge gt-bg-green gt-text-white">{{svg "octicon-dot-fill"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if .Issue.IsPull}} | 					{{if .Issue.IsPull}} | ||||||
| @@ -107,7 +107,7 @@ | |||||||
| 		{{else if eq .Type 2}} | 		{{else if eq .Type 2}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge gt-bg-red gt-text-white">{{svg "octicon-circle-slash"}}</span> | 				<span class="badge gt-bg-red gt-text-white">{{svg "octicon-circle-slash"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if .Issue.IsPull}} | 					{{if .Issue.IsPull}} | ||||||
| @@ -120,7 +120,7 @@ | |||||||
| 		{{else if eq .Type 28}} | 		{{else if eq .Type 28}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge gt-bg-purple gt-text-white">{{svg "octicon-git-merge"}}</span> | 				<span class="badge gt-bg-purple gt-text-white">{{svg "octicon-git-merge"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}} | 					{{$link := printf "%s/commit/%s" $.Repository.Link ($.Issue.PullRequest.MergedCommitID|PathEscape)}} | ||||||
| @@ -147,7 +147,7 @@ | |||||||
| 			{{$createdStr:= TimeSinceUnix .CreatedUnix $.locale}} | 			{{$createdStr:= TimeSinceUnix .CreatedUnix $.locale}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-bookmark"}}</span> | 				<span class="badge">{{svg "octicon-bookmark"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				{{if eq .RefAction 3}}<del>{{end}} | 				{{if eq .RefAction 3}}<del>{{end}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| @@ -162,7 +162,7 @@ | |||||||
| 		{{else if eq .Type 4}} | 		{{else if eq .Type 4}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-bookmark"}}</span> | 				<span class="badge">{{svg "octicon-bookmark"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.commit_ref_at" .EventTag $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.commit_ref_at" .EventTag $createdStr | Safe}} | ||||||
| @@ -176,7 +176,7 @@ | |||||||
| 			{{if or .AddedLabels .RemovedLabels}} | 			{{if or .AddedLabels .RemovedLabels}} | ||||||
| 				<div class="timeline-item event" id="{{.HashTag}}"> | 				<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 					<span class="badge">{{svg "octicon-tag"}}</span> | 					<span class="badge">{{svg "octicon-tag"}}</span> | ||||||
| 					{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 					{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 					<span class="text grey muted-links"> | 					<span class="text grey muted-links"> | ||||||
| 						{{template "shared/user/authorlink" .Poster}} | 						{{template "shared/user/authorlink" .Poster}} | ||||||
| 						{{if and .AddedLabels (not .RemovedLabels)}} | 						{{if and .AddedLabels (not .RemovedLabels)}} | ||||||
| @@ -192,7 +192,7 @@ | |||||||
| 		{{else if eq .Type 8}} | 		{{else if eq .Type 8}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-milestone"}}</span> | 				<span class="badge">{{svg "octicon-milestone"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if gt .OldMilestoneID 0}}{{if gt .MilestoneID 0}}{{$.locale.Tr "repo.issues.change_milestone_at" (.OldMilestone.Name|Escape) (.Milestone.Name|Escape) $createdStr | Safe}}{{else}}{{$.locale.Tr "repo.issues.remove_milestone_at" (.OldMilestone.Name|Escape) $createdStr | Safe}}{{end}}{{else if gt .MilestoneID 0}}{{$.locale.Tr "repo.issues.add_milestone_at" (.Milestone.Name|Escape) $createdStr | Safe}}{{end}} | 					{{if gt .OldMilestoneID 0}}{{if gt .MilestoneID 0}}{{$.locale.Tr "repo.issues.change_milestone_at" (.OldMilestone.Name|Escape) (.Milestone.Name|Escape) $createdStr | Safe}}{{else}}{{$.locale.Tr "repo.issues.remove_milestone_at" (.OldMilestone.Name|Escape) $createdStr | Safe}}{{end}}{{else if gt .MilestoneID 0}}{{$.locale.Tr "repo.issues.add_milestone_at" (.Milestone.Name|Escape) $createdStr | Safe}}{{end}} | ||||||
| @@ -203,7 +203,7 @@ | |||||||
| 				<span class="badge">{{svg "octicon-person"}}</span> | 				<span class="badge">{{svg "octicon-person"}}</span> | ||||||
| 				{{if gt .AssigneeID 0}} | 				{{if gt .AssigneeID 0}} | ||||||
| 					{{if .RemovedAssignee}} | 					{{if .RemovedAssignee}} | ||||||
| 						{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Assignee}} | 						{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Assignee}} | ||||||
| 						<span class="text grey muted-links"> | 						<span class="text grey muted-links"> | ||||||
| 							{{template "shared/user/authorlink" .Assignee}} | 							{{template "shared/user/authorlink" .Assignee}} | ||||||
| 							{{if eq .Poster.ID .Assignee.ID}} | 							{{if eq .Poster.ID .Assignee.ID}} | ||||||
| @@ -213,7 +213,7 @@ | |||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</span> | 						</span> | ||||||
| 					{{else}} | 					{{else}} | ||||||
| 						{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Assignee}} | 						{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Assignee}} | ||||||
| 						<span class="text grey muted-links"> | 						<span class="text grey muted-links"> | ||||||
| 							{{template "shared/user/authorlink" .Assignee}} | 							{{template "shared/user/authorlink" .Assignee}} | ||||||
| 							{{if eq .Poster.ID .AssigneeID}} | 							{{if eq .Poster.ID .AssigneeID}} | ||||||
| @@ -228,7 +228,7 @@ | |||||||
| 		{{else if eq .Type 10}} | 		{{else if eq .Type 10}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-pencil"}}</span> | 				<span class="badge">{{svg "octicon-pencil"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.change_title_at" (.OldTitle|RenderEmoji $.Context) (.NewTitle|RenderEmoji $.Context) $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.change_title_at" (.OldTitle|RenderEmoji $.Context) (.NewTitle|RenderEmoji $.Context) $createdStr | Safe}} | ||||||
| @@ -237,7 +237,7 @@ | |||||||
| 		{{else if eq .Type 11}} | 		{{else if eq .Type 11}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-git-branch"}}</span> | 				<span class="badge">{{svg "octicon-git-branch"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.delete_branch_at" (.OldRef|Escape) $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.delete_branch_at" (.OldRef|Escape) $createdStr | Safe}} | ||||||
| @@ -246,7 +246,7 @@ | |||||||
| 		{{else if eq .Type 12}} | 		{{else if eq .Type 12}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.start_tracking_history"  $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.start_tracking_history"  $createdStr | Safe}} | ||||||
| @@ -255,12 +255,12 @@ | |||||||
| 		{{else if eq .Type 13}} | 		{{else if eq .Type 13}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.stop_tracking_history"  $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.stop_tracking_history"  $createdStr | Safe}} | ||||||
| 				</span> | 				</span> | ||||||
| 				{{template "repo/issue/view_content/comments_delete_time" Dict "ctxData" $ "comment" .}} | 				{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} | ||||||
| 				<div class="detail"> | 				<div class="detail"> | ||||||
| 					{{svg "octicon-clock"}} | 					{{svg "octicon-clock"}} | ||||||
| 					<span class="text grey muted-links">{{.Content}}</span> | 					<span class="text grey muted-links">{{.Content}}</span> | ||||||
| @@ -269,12 +269,12 @@ | |||||||
| 		{{else if eq .Type 14}} | 		{{else if eq .Type 14}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.add_time_history"  $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.add_time_history"  $createdStr | Safe}} | ||||||
| 				</span> | 				</span> | ||||||
| 				{{template "repo/issue/view_content/comments_delete_time" Dict "ctxData" $ "comment" .}} | 				{{template "repo/issue/view_content/comments_delete_time" dict "ctxData" $ "comment" .}} | ||||||
| 				<div class="detail"> | 				<div class="detail"> | ||||||
| 					{{svg "octicon-clock"}} | 					{{svg "octicon-clock"}} | ||||||
| 					<span class="text grey muted-links">{{.Content}}</span> | 					<span class="text grey muted-links">{{.Content}}</span> | ||||||
| @@ -283,7 +283,7 @@ | |||||||
| 		{{else if eq .Type 15}} | 		{{else if eq .Type 15}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.cancel_tracking_history"  $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.cancel_tracking_history"  $createdStr | Safe}} | ||||||
| @@ -292,7 +292,7 @@ | |||||||
| 		{{else if eq .Type 16}} | 		{{else if eq .Type 16}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.due_date_added" .Content $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.due_date_added" .Content $createdStr | Safe}} | ||||||
| @@ -301,7 +301,7 @@ | |||||||
| 		{{else if eq .Type 17}} | 		{{else if eq .Type 17}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$parsedDeadline := .Content | ParseDeadline}} | 					{{$parsedDeadline := .Content | ParseDeadline}} | ||||||
| @@ -311,7 +311,7 @@ | |||||||
| 		{{else if eq .Type 18}} | 		{{else if eq .Type 18}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.due_date_remove" .Content $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.due_date_remove" .Content $createdStr | Safe}} | ||||||
| @@ -320,7 +320,7 @@ | |||||||
| 		{{else if eq .Type 19}} | 		{{else if eq .Type 19}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-package-dependents"}}</span> | 				<span class="badge">{{svg "octicon-package-dependents"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.dependency.added_dependency" $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.dependency.added_dependency" $createdStr | Safe}} | ||||||
| @@ -343,7 +343,7 @@ | |||||||
| 		{{else if eq .Type 20}} | 		{{else if eq .Type 20}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-package-dependents"}}</span> | 				<span class="badge">{{svg "octicon-package-dependents"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.dependency.removed_dependency" $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.dependency.removed_dependency" $createdStr | Safe}} | ||||||
| @@ -436,8 +436,8 @@ | |||||||
| 										</div> | 										</div> | ||||||
| 									{{end}} | 									{{end}} | ||||||
| 									{{if not $.Repository.IsArchived}} | 									{{if not $.Repository.IsArchived}} | ||||||
| 											{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | 											{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | ||||||
| 											{{template "repo/issue/view_content/context_menu" Dict "ctxData" $ "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | 											{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" false "issue" true "diff" false "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | ||||||
| 									{{end}} | 									{{end}} | ||||||
| 							</div> | 							</div> | ||||||
| 						</div> | 						</div> | ||||||
| @@ -452,13 +452,13 @@ | |||||||
| 							<div id="issuecomment-{{.ID}}-raw" class="raw-content gt-hidden">{{.Content}}</div> | 							<div id="issuecomment-{{.ID}}-raw" class="raw-content gt-hidden">{{.Content}}</div> | ||||||
| 							<div class="edit-content-zone gt-hidden" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div> | 							<div class="edit-content-zone gt-hidden" data-write="issuecomment-{{.ID}}-write" data-preview="issuecomment-{{.ID}}-preview" data-update-url="{{$.RepoLink}}/comments/{{.ID}}" data-context="{{$.RepoLink}}" data-attachment-url="{{$.RepoLink}}/comments/{{.ID}}/attachments"></div> | ||||||
| 							{{if .Attachments}} | 							{{if .Attachments}} | ||||||
| 								{{template "repo/issue/view_content/attachments" Dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} | 								{{template "repo/issue/view_content/attachments" dict "ctxData" $ "Attachments" .Attachments "Content" .RenderedContent}} | ||||||
| 							{{end}} | 							{{end}} | ||||||
| 						</div> | 						</div> | ||||||
| 						{{$reactions := .Reactions.GroupByType}} | 						{{$reactions := .Reactions.GroupByType}} | ||||||
| 						{{if $reactions}} | 						{{if $reactions}} | ||||||
| 							<div class="ui attached segment reactions"> | 							<div class="ui attached segment reactions"> | ||||||
| 									{{template "repo/issue/view_content/reactions" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | 									{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | ||||||
| 							</div> | 							</div> | ||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</div> | 					</div> | ||||||
| @@ -563,8 +563,8 @@ | |||||||
| 																	</div> | 																	</div> | ||||||
| 																{{end}} | 																{{end}} | ||||||
| 																{{if not $.Repository.IsArchived}} | 																{{if not $.Repository.IsArchived}} | ||||||
| 																	{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | 																	{{template "repo/issue/view_content/add_reaction" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID)}} | ||||||
| 																	{{template "repo/issue/view_content/context_menu" Dict "ctxData" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | 																	{{template "repo/issue/view_content/context_menu" dict "ctxData" $ "item" . "delete" true "issue" true "diff" true "IsCommentPoster" (and $.IsSigned (eq $.SignedUserID .PosterID))}} | ||||||
| 																{{end}} | 																{{end}} | ||||||
| 															</div> | 															</div> | ||||||
| 														</div> | 														</div> | ||||||
| @@ -582,7 +582,7 @@ | |||||||
| 														{{$reactions := .Reactions.GroupByType}} | 														{{$reactions := .Reactions.GroupByType}} | ||||||
| 														{{if $reactions}} | 														{{if $reactions}} | ||||||
| 															<div class="ui attached segment reactions"> | 															<div class="ui attached segment reactions"> | ||||||
| 																{{template "repo/issue/view_content/reactions" Dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | 																{{template "repo/issue/view_content/reactions" dict "ctxData" $ "ActionURL" (Printf "%s/comments/%d/reactions" $.RepoLink .ID) "Reactions" $reactions}} | ||||||
| 															</div> | 															</div> | ||||||
| 														{{end}} | 														{{end}} | ||||||
| 													</div> | 													</div> | ||||||
| @@ -626,7 +626,7 @@ | |||||||
| 		{{else if eq .Type 23}} | 		{{else if eq .Type 23}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-lock"}}</span> | 				<span class="badge">{{svg "octicon-lock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				{{if .Content}} | 				{{if .Content}} | ||||||
| 					<span class="text grey muted-links"> | 					<span class="text grey muted-links"> | ||||||
| 						{{template "shared/user/authorlink" .Poster}} | 						{{template "shared/user/authorlink" .Poster}} | ||||||
| @@ -642,7 +642,7 @@ | |||||||
| 		{{else if eq .Type 24}} | 		{{else if eq .Type 24}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-key"}}</span> | 				<span class="badge">{{svg "octicon-key"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{$.locale.Tr "repo.issues.unlock_comment" $createdStr | Safe}} | 					{{$.locale.Tr "repo.issues.unlock_comment" $createdStr | Safe}} | ||||||
| @@ -651,7 +651,7 @@ | |||||||
| 		{{else if eq .Type 25}} | 		{{else if eq .Type 25}} | ||||||
| 			<div class="timeline-item event"> | 			<div class="timeline-item event"> | ||||||
| 				<span class="badge">{{svg "octicon-git-branch"}}</span> | 				<span class="badge">{{svg "octicon-git-branch"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					<a{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.Name}}</a> | 					<a{{if gt .Poster.ID 0}} href="{{.Poster.HomeLink}}"{{end}}>{{.Poster.Name}}</a> | ||||||
| 					{{$.locale.Tr "repo.pulls.change_target_branch_at" (.OldRef|Escape) (.NewRef|Escape) $createdStr | Safe}} | 					{{$.locale.Tr "repo.pulls.change_target_branch_at" (.OldRef|Escape) (.NewRef|Escape) $createdStr | Safe}} | ||||||
| @@ -660,7 +660,7 @@ | |||||||
| 		{{else if eq .Type 26}} | 		{{else if eq .Type 26}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-clock"}}</span> | 				<span class="badge">{{svg "octicon-clock"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
|  |  | ||||||
| @@ -674,7 +674,7 @@ | |||||||
| 		{{else if eq .Type 27}} | 		{{else if eq .Type 27}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-eye"}}</span> | 				<span class="badge">{{svg "octicon-eye"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if (gt .AssigneeID 0)}} | 					{{if (gt .AssigneeID 0)}} | ||||||
| @@ -724,7 +724,7 @@ | |||||||
| 			{{if not $.UnitProjectsGlobalDisabled}} | 			{{if not $.UnitProjectsGlobalDisabled}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-project"}}</span> | 				<span class="badge">{{svg "octicon-project"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if gt .OldProjectID 0}} | 					{{if gt .OldProjectID 0}} | ||||||
| @@ -781,7 +781,7 @@ | |||||||
| 		{{else if eq .Type 33}} | 		{{else if eq .Type 33}} | ||||||
| 			<div class="timeline-item event" id="{{.HashTag}}"> | 			<div class="timeline-item event" id="{{.HashTag}}"> | ||||||
| 				<span class="badge">{{svg "octicon-git-branch"}}</span> | 				<span class="badge">{{svg "octicon-git-branch"}}</span> | ||||||
| 				{{template "shared/user/avatarlink" Dict "Context" $.Context "user" .Poster}} | 				{{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} | ||||||
| 				<span class="text grey muted-links"> | 				<span class="text grey muted-links"> | ||||||
| 					{{template "shared/user/authorlink" .Poster}} | 					{{template "shared/user/authorlink" .Poster}} | ||||||
| 					{{if and .OldRef .NewRef}} | 					{{if and .OldRef .NewRef}} | ||||||
|   | |||||||
| @@ -5,5 +5,5 @@ | |||||||
| 	</a> | 	</a> | ||||||
| {{end}} | {{end}} | ||||||
| {{if AllowedReactions}} | {{if AllowedReactions}} | ||||||
| 	{{template "repo/issue/view_content/add_reaction" Dict "ctxData" $.ctxData "ActionURL" .ActionURL}} | 	{{template "repo/issue/view_content/add_reaction" dict "ctxData" $.ctxData "ActionURL" .ActionURL}} | ||||||
| {{end}} | {{end}} | ||||||
|   | |||||||
| @@ -112,7 +112,7 @@ | |||||||
| 						{{end}} | 						{{end}} | ||||||
| 					</div> | 					</div> | ||||||
| 				</div> | 				</div> | ||||||
| 				{{template "shared/issuelist" mergeinto . "listType" "dashboard"}} | 				{{template "shared/issuelist" dict "." . "listType" "dashboard"}} | ||||||
| 			</div> | 			</div> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ | |||||||
| 					<div class="ui divider"></div> | 					<div class="ui divider"></div> | ||||||
| 					{{.locale.Tr "notification.no_subscriptions"}} | 					{{.locale.Tr "notification.no_subscriptions"}} | ||||||
| 				{{else}} | 				{{else}} | ||||||
| 					{{template "shared/issuelist" mergeinto . "listType" "dashboard"}} | 					{{template "shared/issuelist" dict "." . "listType" "dashboard"}} | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 			{{else}} | 			{{else}} | ||||||
| 				{{template "explore/repo_search" .}} | 				{{template "explore/repo_search" .}} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user