This commit is contained in:
Konrad 2017-12-03 17:45:55 +01:00
commit 9af3aae2f3
No known key found for this signature in database
GPG Key ID: F40E70337AB24C9B
37 changed files with 1617 additions and 1487 deletions

2
docker/Makefile vendored
View File

@ -8,4 +8,4 @@ DOCKER_REF := $(DOCKER_IMAGE):$(DOCKER_TAG)
.PHONY: docker .PHONY: docker
docker: docker:
docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build docker run -ti --rm -v $(CURDIR):/srv/app/src/code.gitea.io/gitea -w /srv/app/src/code.gitea.io/gitea -e TAGS="bindata $(TAGS)" webhippie/golang:edge make clean generate build
docker build -t $(DOCKER_REF) . docker build --disable-content-trust=false -t $(DOCKER_REF) .

View File

@ -49,6 +49,8 @@ When you find the correct .tmpl file, you need to copy it in the `custom/templat
You can now customize the template you copied in `custom/templates`, being carefully to not break the Gitea syntax. You can now customize the template you copied in `custom/templates`, being carefully to not break the Gitea syntax.
Any statement contained inside `{{` and `}}` are Gitea templete's syntax and shouldn't be touch, unless you know what are you doing. Any statement contained inside `{{` and `}}` are Gitea templete's syntax and shouldn't be touch, unless you know what are you doing.
To add in custom HTML to the header or the footer of the page, in the `templates/custom` directory there are `header.tmpl` and `footer.tmpl` that can be modified. This is useful if you want to add in custom CSS files, or additional Javascript.
## Customizing gitignores, labels, licenses, locales, and readmes. ## Customizing gitignores, labels, licenses, locales, and readmes.
Place your own files in corresponding sub-folder under `custom/options`. Place your own files in corresponding sub-folder under `custom/options`.

View File

@ -14,15 +14,14 @@ import (
"time" "time"
"unicode" "unicode"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
"code.gitea.io/git" "code.gitea.io/git"
api "code.gitea.io/sdk/gitea"
"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"
api "code.gitea.io/sdk/gitea"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
) )
// ActionType represents the type of an action. // ActionType represents the type of an action.
@ -59,14 +58,16 @@ var (
issueReferenceKeywordsPat *regexp.Regexp issueReferenceKeywordsPat *regexp.Regexp
) )
const issueRefRegexpStr = `(?:\S+/\S=)?#\d+`
func assembleKeywordsPattern(words []string) string { func assembleKeywordsPattern(words []string) string {
return fmt.Sprintf(`(?i)(?:%s) \S+`, strings.Join(words, "|")) return fmt.Sprintf(`(?i)(?:%s) %s`, strings.Join(words, "|"), issueRefRegexpStr)
} }
func init() { func init() {
issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords)) issueCloseKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueCloseKeywords))
issueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueReopenKeywords)) issueReopenKeywordsPat = regexp.MustCompile(assembleKeywordsPattern(issueReopenKeywords))
issueReferenceKeywordsPat = regexp.MustCompile(`(?i)(?:)(^| )\S+`) issueReferenceKeywordsPat = regexp.MustCompile(issueRefRegexpStr)
} }
// Action represents user operation type and other information to // Action represents user operation type and other information to
@ -390,6 +391,49 @@ func (pc *PushCommits) AvatarLink(email string) string {
return pc.avatars[email] return pc.avatars[email]
} }
// getIssueFromRef returns the issue referenced by a ref. Returns a nil *Issue
// if the provided ref is misformatted or references a non-existent issue.
func getIssueFromRef(repo *Repository, ref string) (*Issue, error) {
ref = ref[strings.IndexByte(ref, ' ')+1:]
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
var refRepo *Repository
poundIndex := strings.IndexByte(ref, '#')
if poundIndex < 0 {
return nil, nil
} else if poundIndex == 0 {
refRepo = repo
} else {
slashIndex := strings.IndexByte(ref, '/')
if slashIndex < 0 || slashIndex >= poundIndex {
return nil, nil
}
ownerName := ref[:slashIndex]
repoName := ref[slashIndex+1 : poundIndex]
var err error
refRepo, err = GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
if IsErrRepoNotExist(err) {
return nil, nil
}
return nil, err
}
}
issueIndex, err := strconv.ParseInt(ref[poundIndex+1:], 10, 64)
if err != nil {
return nil, nil
}
issue, err := GetIssueByIndex(refRepo.ID, int64(issueIndex))
if err != nil {
if IsErrIssueNotExist(err) {
return nil, nil
}
return nil, err
}
return issue, nil
}
// UpdateIssuesCommit checks if issues are manipulated by commit message. // UpdateIssuesCommit checks if issues are manipulated by commit message.
func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) error { func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) error {
// Commits are appended in the reverse order. // Commits are appended in the reverse order.
@ -398,31 +442,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
refMarked := make(map[int64]bool) refMarked := make(map[int64]bool)
for _, ref := range issueReferenceKeywordsPat.FindAllString(c.Message, -1) { for _, ref := range issueReferenceKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:] issue, err := getIssueFromRef(repo, ref)
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// FIXME: We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil { if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err return err
} }
if refMarked[issue.ID] { if issue == nil || refMarked[issue.ID] {
continue continue
} }
refMarked[issue.ID] = true refMarked[issue.ID] = true
@ -436,31 +461,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
refMarked = make(map[int64]bool) refMarked = make(map[int64]bool)
// FIXME: can merge this one and next one to a common function. // FIXME: can merge this one and next one to a common function.
for _, ref := range issueCloseKeywordsPat.FindAllString(c.Message, -1) { for _, ref := range issueCloseKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:] issue, err := getIssueFromRef(repo, ref)
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil { if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err return err
} }
if refMarked[issue.ID] { if issue == nil || refMarked[issue.ID] {
continue continue
} }
refMarked[issue.ID] = true refMarked[issue.ID] = true
@ -484,31 +490,12 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
// It is conflict to have close and reopen at same time, so refsMarked doesn't need to reinit here. // It is conflict to have close and reopen at same time, so refsMarked doesn't need to reinit here.
for _, ref := range issueReopenKeywordsPat.FindAllString(c.Message, -1) { for _, ref := range issueReopenKeywordsPat.FindAllString(c.Message, -1) {
ref = ref[strings.IndexByte(ref, byte(' '))+1:] issue, err := getIssueFromRef(repo, ref)
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
if len(ref) == 0 {
continue
}
// Add repo name if missing
if ref[0] == '#' {
ref = fmt.Sprintf("%s%s", repo.FullName(), ref)
} else if !strings.Contains(ref, "/") {
// We don't support User#ID syntax yet
// return ErrNotImplemented
continue
}
issue, err := GetIssueByRef(ref)
if err != nil { if err != nil {
if IsErrIssueNotExist(err) || err == errMissingIssueNumber || err == errInvalidIssueNumber {
continue
}
return err return err
} }
if refMarked[issue.ID] { if issue == nil || refMarked[issue.ID] {
continue continue
} }
refMarked[issue.ID] = true refMarked[issue.ID] = true

View File

@ -1,6 +1,7 @@
package models package models
import ( import (
"fmt"
"path" "path"
"strings" "strings"
"testing" "testing"
@ -154,6 +155,35 @@ func TestPushCommits_AvatarLink(t *testing.T) {
pushCommits.AvatarLink("nonexistent@example.com")) pushCommits.AvatarLink("nonexistent@example.com"))
} }
func Test_getIssueFromRef(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
for _, test := range []struct {
Ref string
ExpectedIssueID int64
}{
{"#2", 2},
{"reopen #2", 2},
{"user2/repo2#1", 4},
{"fixes user2/repo2#1", 4},
} {
issue, err := getIssueFromRef(repo, test.Ref)
assert.NoError(t, err)
if assert.NotNil(t, issue) {
assert.EqualValues(t, test.ExpectedIssueID, issue.ID)
}
}
for _, badRef := range []string{
"doesnotexist/doesnotexist#1",
fmt.Sprintf("#%d", NonexistentID),
} {
issue, err := getIssueFromRef(repo, badRef)
assert.NoError(t, err)
assert.Nil(t, issue)
}
}
func TestUpdateIssuesCommit(t *testing.T) { func TestUpdateIssuesCommit(t *testing.T) {
assert.NoError(t, PrepareTestDatabase()) assert.NoError(t, PrepareTestDatabase())
pushCommits := []*PushCommit{ pushCommits := []*PushCommit{

View File

@ -5,7 +5,6 @@
package models package models
import ( import (
"errors"
"fmt" "fmt"
"path" "path"
"sort" "sort"
@ -22,11 +21,6 @@ import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
) )
var (
errMissingIssueNumber = errors.New("No issue number specified")
errInvalidIssueNumber = errors.New("Invalid issue number")
)
// Issue represents an issue or pull request of repository. // Issue represents an issue or pull request of repository.
type Issue struct { type Issue struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
@ -961,32 +955,6 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
return nil return nil
} }
// GetIssueByRef returns an Issue specified by a GFM reference.
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
func GetIssueByRef(ref string) (*Issue, error) {
n := strings.IndexByte(ref, '#')
if n == -1 {
return nil, errMissingIssueNumber
}
index, err := com.StrTo(ref[n+1:]).Int64()
if err != nil {
return nil, errInvalidIssueNumber
}
i := strings.IndexByte(ref[:n], '/')
if i < 2 {
return nil, ErrInvalidReference
}
repo, err := GetRepositoryByOwnerAndName(ref[:i], ref[i+1:n])
if err != nil {
return nil, err
}
return GetIssueByIndex(repo.ID, index)
}
// GetRawIssueByIndex returns raw issue without loading attributes by index in a repository. // GetRawIssueByIndex returns raw issue without loading attributes by index in a repository.
func GetRawIssueByIndex(repoID, index int64) (*Issue, error) { func GetRawIssueByIndex(repoID, index int64) (*Issue, error) {
issue := &Issue{ issue := &Issue{

View File

@ -605,9 +605,14 @@ func (repo *Repository) RepoPath() string {
return repo.repoPath(x) return repo.repoPath(x)
} }
// GitConfigPath returns the path to a repository's git config/ directory
func GitConfigPath(repoPath string) string {
return filepath.Join(repoPath, "config")
}
// GitConfigPath returns the repository git config path // GitConfigPath returns the repository git config path
func (repo *Repository) GitConfigPath() string { func (repo *Repository) GitConfigPath() string {
return filepath.Join(repo.RepoPath(), "config") return GitConfigPath(repo.RepoPath())
} }
// RelLink returns the repository relative link // RelLink returns the repository relative link

View File

@ -76,17 +76,23 @@ func (m *Mirror) ScheduleNextUpdate() {
m.NextUpdate = time.Now().Add(m.Interval) m.NextUpdate = time.Now().Add(m.Interval)
} }
func remoteAddress(repoPath string) (string, error) {
cfg, err := ini.Load(GitConfigPath(repoPath))
if err != nil {
return "", err
}
return cfg.Section("remote \"origin\"").Key("url").Value(), nil
}
func (m *Mirror) readAddress() { func (m *Mirror) readAddress() {
if len(m.address) > 0 { if len(m.address) > 0 {
return return
} }
var err error
cfg, err := ini.Load(m.Repo.GitConfigPath()) m.address, err = remoteAddress(m.Repo.RepoPath())
if err != nil { if err != nil {
log.Error(4, "Load: %v", err) log.Error(4, "remoteAddress: %v", err)
return
} }
m.address = cfg.Section("remote \"origin\"").Key("url").Value()
} }
// HandleCloneUserCredentials replaces user credentials from HTTP/HTTPS URL // HandleCloneUserCredentials replaces user credentials from HTTP/HTTPS URL
@ -107,6 +113,19 @@ func HandleCloneUserCredentials(url string, mosaics bool) string {
return url[:start+3] + url[i+1:] return url[:start+3] + url[i+1:]
} }
// sanitizeOutput sanitizes output of a command, replacing occurrences of the
// repository's remote address with a sanitized version.
func sanitizeOutput(output, repoPath string) (string, error) {
remoteAddr, err := remoteAddress(repoPath)
if err != nil {
// if we're unable to load the remote address, then we're unable to
// sanitize.
return "", err
}
sanitized := HandleCloneUserCredentials(remoteAddr, true)
return strings.Replace(output, remoteAddr, sanitized, -1), nil
}
// Address returns mirror address from Git repository config without credentials. // Address returns mirror address from Git repository config without credentials.
func (m *Mirror) Address() string { func (m *Mirror) Address() string {
m.readAddress() m.readAddress()
@ -145,7 +164,14 @@ func (m *Mirror) runSync() bool {
if _, stderr, err := process.GetManager().ExecDir( if _, stderr, err := process.GetManager().ExecDir(
timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath), timeout, repoPath, fmt.Sprintf("Mirror.runSync: %s", repoPath),
"git", gitArgs...); err != nil { "git", gitArgs...); err != nil {
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, stderr) // sanitize the output, since it may contain the remote address, which may
// contain a password
message, err := sanitizeOutput(stderr, repoPath)
if err != nil {
log.Error(4, "sanitizeOutput: %v", err)
return false
}
desc := fmt.Sprintf("Failed to update mirror repository '%s': %s", repoPath, message)
log.Error(4, desc) log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil { if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err) log.Error(4, "CreateRepositoryNotice: %v", err)
@ -170,7 +196,14 @@ func (m *Mirror) runSync() bool {
if _, stderr, err := process.GetManager().ExecDir( if _, stderr, err := process.GetManager().ExecDir(
timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath), timeout, wikiPath, fmt.Sprintf("Mirror.runSync: %s", wikiPath),
"git", "remote", "update", "--prune"); err != nil { "git", "remote", "update", "--prune"); err != nil {
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, stderr) // sanitize the output, since it may contain the remote address, which may
// contain a password
message, err := sanitizeOutput(stderr, wikiPath)
if err != nil {
log.Error(4, "sanitizeOutput: %v", err)
return false
}
desc := fmt.Sprintf("Failed to update mirror wiki repository '%s': %s", wikiPath, message)
log.Error(4, desc) log.Error(4, desc)
if err = CreateRepositoryNotice(desc); err != nil { if err = CreateRepositoryNotice(desc); err != nil {
log.Error(4, "CreateRepositoryNotice: %v", err) log.Error(4, "CreateRepositoryNotice: %v", err)

View File

@ -315,10 +315,9 @@ func (u *User) generateRandomAvatar(e Engine) error {
return nil return nil
} }
// RelAvatarLink returns relative avatar link to the site domain, // SizedRelAvatarLink returns a relative link to the user's avatar. When
// which includes app sub-url as prefix. However, it is possible // applicable, the link is for an avatar of the indicated size (in pixels).
// to return full URL if user enables Gravatar-like service. func (u *User) SizedRelAvatarLink(size int) string {
func (u *User) RelAvatarLink() string {
if u.ID == -1 { if u.ID == -1 {
return base.DefaultAvatarLink() return base.DefaultAvatarLink()
} }
@ -338,7 +337,14 @@ func (u *User) RelAvatarLink() string {
return setting.AppSubURL + "/avatars/" + u.Avatar return setting.AppSubURL + "/avatars/" + u.Avatar
} }
return base.AvatarLink(u.AvatarEmail) return base.SizedAvatarLink(u.AvatarEmail, size)
}
// RelAvatarLink returns a relative link to the user's avatar. The link
// may either be a sub-URL to this site, or a full URL to an external avatar
// service.
func (u *User) RelAvatarLink() string {
return u.SizedRelAvatarLink(base.DefaultAvatarSize)
} }
// AvatarLink returns user avatar absolute link. // AvatarLink returns user avatar absolute link.

View File

@ -16,6 +16,8 @@ import (
"math" "math"
"math/big" "math/big"
"net/http" "net/http"
"net/url"
"path"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -197,24 +199,59 @@ func DefaultAvatarLink() string {
return setting.AppSubURL + "/img/avatar_default.png" return setting.AppSubURL + "/img/avatar_default.png"
} }
// DefaultAvatarSize is a sentinel value for the default avatar size, as
// determined by the avatar-hosting service.
const DefaultAvatarSize = -1
// libravatarURL returns the URL for the given email. This function should only
// be called if a federated avatar service is enabled.
func libravatarURL(email string) (*url.URL, error) {
urlStr, err := setting.LibravatarService.FromEmail(email)
if err != nil {
log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
return nil, err
}
u, err := url.Parse(urlStr)
if err != nil {
log.Error(4, "Failed to parse libravatar url(%s): error %v", urlStr, err)
return nil, err
}
return u, nil
}
// SizedAvatarLink returns a sized link to the avatar for the given email
// address.
func SizedAvatarLink(email string, size int) string {
var avatarURL *url.URL
if setting.EnableFederatedAvatar && setting.LibravatarService != nil {
var err error
avatarURL, err = libravatarURL(email)
if err != nil {
return DefaultAvatarLink()
}
} else if !setting.DisableGravatar {
// copy GravatarSourceURL, because we will modify its Path.
copyOfGravatarSourceURL := *setting.GravatarSourceURL
avatarURL = &copyOfGravatarSourceURL
avatarURL.Path = path.Join(avatarURL.Path, HashEmail(email))
} else {
return DefaultAvatarLink()
}
vals := avatarURL.Query()
vals.Set("d", "identicon")
if size != DefaultAvatarSize {
vals.Set("s", strconv.Itoa(size))
}
avatarURL.RawQuery = vals.Encode()
return avatarURL.String()
}
// AvatarLink returns relative avatar link to the site domain by given email, // AvatarLink returns relative avatar link to the site domain by given email,
// which includes app sub-url as prefix. However, it is possible // which includes app sub-url as prefix. However, it is possible
// to return full URL if user enables Gravatar-like service. // to return full URL if user enables Gravatar-like service.
func AvatarLink(email string) string { func AvatarLink(email string) string {
if setting.EnableFederatedAvatar && setting.LibravatarService != nil { return SizedAvatarLink(email, DefaultAvatarSize)
url, err := setting.LibravatarService.FromEmail(email)
if err != nil {
log.Error(4, "LibravatarService.FromEmail(email=%s): error %v", email, err)
return DefaultAvatarLink()
}
return url
}
if !setting.DisableGravatar {
return setting.GravatarSource + HashEmail(email) + "?d=identicon"
}
return DefaultAvatarLink()
} }
// Seconds-based time units // Seconds-based time units

View File

@ -1,11 +1,13 @@
package base package base
import ( import (
"net/url"
"os" "os"
"testing" "testing"
"time" "time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/Unknwon/i18n" "github.com/Unknwon/i18n"
macaroni18n "github.com/go-macaron/i18n" macaroni18n "github.com/go-macaron/i18n"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -126,16 +128,40 @@ func TestHashEmail(t *testing.T) {
) )
} }
func TestAvatarLink(t *testing.T) { const gravatarSource = "https://secure.gravatar.com/avatar/"
func disableGravatar() {
setting.EnableFederatedAvatar = false setting.EnableFederatedAvatar = false
setting.LibravatarService = nil setting.LibravatarService = nil
setting.DisableGravatar = true setting.DisableGravatar = true
}
assert.Equal(t, "/img/avatar_default.png", AvatarLink("")) func enableGravatar(t *testing.T) {
setting.DisableGravatar = false setting.DisableGravatar = false
var err error
setting.GravatarSourceURL, err = url.Parse(gravatarSource)
assert.NoError(t, err)
}
func TestSizedAvatarLink(t *testing.T) {
disableGravatar()
assert.Equal(t, "/img/avatar_default.png",
SizedAvatarLink("gitea@example.com", 100))
enableGravatar(t)
assert.Equal(t, assert.Equal(t,
"353cbad9b58e69c96154ad99f92bedc7?d=identicon", "https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon&s=100",
SizedAvatarLink("gitea@example.com", 100),
)
}
func TestAvatarLink(t *testing.T) {
disableGravatar()
assert.Equal(t, "/img/avatar_default.png", AvatarLink("gitea@example.com"))
enableGravatar(t)
assert.Equal(t,
"https://secure.gravatar.com/avatar/353cbad9b58e69c96154ad99f92bedc7?d=identicon",
AvatarLink("gitea@example.com"), AvatarLink("gitea@example.com"),
) )
} }

View File

@ -326,6 +326,7 @@ var (
// Picture settings // Picture settings
AvatarUploadPath string AvatarUploadPath string
GravatarSource string GravatarSource string
GravatarSourceURL *url.URL
DisableGravatar bool DisableGravatar bool
EnableFederatedAvatar bool EnableFederatedAvatar bool
LibravatarService *libravatar.Libravatar LibravatarService *libravatar.Libravatar
@ -1027,18 +1028,22 @@ func NewContext() {
if DisableGravatar { if DisableGravatar {
EnableFederatedAvatar = false EnableFederatedAvatar = false
} }
if EnableFederatedAvatar || !DisableGravatar {
GravatarSourceURL, err = url.Parse(GravatarSource)
if err != nil {
log.Fatal(4, "Failed to parse Gravatar URL(%s): %v",
GravatarSource, err)
}
}
if EnableFederatedAvatar { if EnableFederatedAvatar {
LibravatarService = libravatar.New() LibravatarService = libravatar.New()
parts := strings.Split(GravatarSource, "/") if GravatarSourceURL.Scheme == "https" {
if len(parts) >= 3 { LibravatarService.SetUseHTTPS(true)
if parts[0] == "https:" { LibravatarService.SetSecureFallbackHost(GravatarSourceURL.Host)
LibravatarService.SetUseHTTPS(true) } else {
LibravatarService.SetSecureFallbackHost(parts[2]) LibravatarService.SetUseHTTPS(false)
} else { LibravatarService.SetFallbackHost(GravatarSourceURL.Host)
LibravatarService.SetUseHTTPS(false)
LibravatarService.SetFallbackHost(parts[2])
}
} }
} }

View File

@ -404,6 +404,7 @@ key_state_desc=該金鑰在 7 天內被使用過
token_state_desc=此 token 在過去七天內曾經被使用過 token_state_desc=此 token 在過去七天內曾經被使用過
show_openid=在設定檔顯示 show_openid=在設定檔顯示
hide_openid=從設定檔隱藏 hide_openid=從設定檔隱藏
ssh_disabled=已停用 SSH
manage_social=管理關聯社交帳戶 manage_social=管理關聯社交帳戶
social_desc=這是相關聯的社交帳戶清單。出於安全考量,請確保您識別所有項目,因為它們可用於登入到您的帳戶。 social_desc=這是相關聯的社交帳戶清單。出於安全考量,請確保您識別所有項目,因為它們可用於登入到您的帳戶。
@ -616,6 +617,7 @@ issues.new.closed_milestone=已關閉的里程碑
issues.new.assignee=指派成員 issues.new.assignee=指派成員
issues.new.clear_assignee=取消指派成員 issues.new.clear_assignee=取消指派成員
issues.new.no_assignee=未指派成員 issues.new.no_assignee=未指派成員
issues.no_ref=未指定分支或標籤
issues.create=建立問題 issues.create=建立問題
issues.new_label=建立標籤 issues.new_label=建立標籤
issues.new_label_placeholder=標籤名稱... issues.new_label_placeholder=標籤名稱...
@ -705,6 +707,9 @@ issues.attachment.open_tab=`在新的標籤頁中查看 '%s'`
issues.attachment.download=`點擊下載 '%s'` issues.attachment.download=`點擊下載 '%s'`
issues.subscribe=訂閱 issues.subscribe=訂閱
issues.unsubscribe=取消訂閱 issues.unsubscribe=取消訂閱
issues.add_time_hours=小時
issues.add_time_minutes=分鐘
issues.cancel_tracking=取消
pulls.desc=Pulls 管理你的程式碼審核及程式碼合併要求。 pulls.desc=Pulls 管理你的程式碼審核及程式碼合併要求。
pulls.new=建立合併請求 pulls.new=建立合併請求
@ -785,6 +790,11 @@ wiki.page_already_exists=相同名稱的 Wiki 頁面已經存在。
wiki.pages=所有頁面 wiki.pages=所有頁面
wiki.last_updated=最後更新於 %s wiki.last_updated=最後更新於 %s
activity.period.daily=1 天
activity.period.halfweekly=3 天
activity.period.weekly=1 星期
activity.period.monthly=1 個月
activity.overview=概覽
activity.closed_issue_label=已關閉 activity.closed_issue_label=已關閉
activity.title.releases_published_by=%s 由 %s 發佈 activity.title.releases_published_by=%s 由 %s 發佈
activity.published_release_label=已發佈 activity.published_release_label=已發佈
@ -989,12 +999,18 @@ release.tag_name_invalid=標記名稱不是有效的。
release.downloads=下載附件 release.downloads=下載附件
branch.delete=刪除分支 %s branch.delete=刪除分支 %s
branch.delete_html=刪除分支
branch.delete_desc=刪除分支將是永久的。沒有其它方法能復原。 branch.delete_desc=刪除分支將是永久的。沒有其它方法能復原。
branch.delete_notices_1=- 此操作<strong>不可以</strong>被還原。 branch.delete_notices_1=- 此操作<strong>不可以</strong>被還原。
branch.delete_notices_2=- 此操作將永久刪除在 %s 分支內的所有內容。 branch.delete_notices_2=- 此操作將永久刪除在 %s 分支內的所有內容。
branch.deletion_success=%s 已被刪除。 branch.deletion_success=%s 已被刪除。
branch.deletion_failed=刪除分支 %s 失敗。 branch.deletion_failed=刪除分支 %s 失敗。
branch.delete_branch_has_new_commits=不能刪除 %s因為合併後已新增了新的提交。 branch.delete_branch_has_new_commits=不能刪除 %s因為合併後已新增了新的提交。
branch.create_branch=建立分支 <strong>%s</strong>
branch.create_success=成功建立 '%s' 分支!
branch.branch_already_exists=分支 '%s' 已存在此儲存庫
branch.restore_failed=還原分支 %s 失敗
branch.protected_deletion_failed=不可能刪除已受保護的分支 %s。
[org] [org]
org_name_holder=組織名稱 org_name_holder=組織名稱
@ -1326,7 +1342,9 @@ config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱 config.mailer_name=發送者名稱
config.mailer_host=郵件主機地址 config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號 config.mailer_user=發送者帳號
config.mailer_use_sendmail=使用 Sendmail
config.mailer_sendmail_path=Sendmail 路徑 config.mailer_sendmail_path=Sendmail 路徑
config.mailer_sendmail_args=Sendmail 的額外參數
config.send_test_mail=發送測試郵件 config.send_test_mail=發送測試郵件
config.test_mail_failed=發送測試郵件至 '%s' 時失敗:%v config.test_mail_failed=發送測試郵件至 '%s' 時失敗:%v
config.test_mail_sent=測試電子郵件已發送到 '%s'。 config.test_mail_sent=測試電子郵件已發送到 '%s'。

File diff suppressed because one or more lines are too long

View File

@ -1,66 +1,66 @@
.admin { .admin {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
.table.segment { .table.segment {
padding: 0; padding: 0;
font-size: 13px; font-size: 13px;
&:not(.striped) { &:not(.striped) {
padding-top: 5px; padding-top: 5px;
thead { thead {
th:last-child { th:last-child {
padding-right: 5px !important; padding-right: 5px !important;
} }
} }
} }
th { th {
padding-top: 5px; padding-top: 5px;
padding-bottom: 5px; padding-bottom: 5px;
} }
&:not(.select) { &:not(.select) {
th, td { th, td {
&:first-of-type { &:first-of-type {
padding-left: 15px !important; padding-left: 15px !important;
} }
} }
} }
} }
.ui.header, .ui.header,
.ui.segment { .ui.segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15); box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
} }
&.user { &.user {
.email { .email {
max-width: 200px; max-width: 200px;
} }
} }
dl.admin-dl-horizontal { dl.admin-dl-horizontal {
padding: 20px; padding: 20px;
margin: 0; margin: 0;
dd { dd {
margin-left: 275px; margin-left: 275px;
} }
dt { dt {
font-weight: bolder; font-weight: bolder;
float: left; float: left;
width: 285px; width: 285px;
clear: left; clear: left;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
} }
&.config { &.config {
#test-mail-btn { #test-mail-btn {
margin-left: 5px; margin-left: 5px;
} }
} }
} }

View File

@ -146,6 +146,12 @@ pre, code {
} }
} }
&.menu,
&.vertical.menu,
&.segment {
box-shadow: none;
}
.text { .text {
&.red { &.red {
color: #d95c5c !important; color: #d95c5c !important;

View File

@ -1,158 +1,163 @@
.dashboard { .dashboard {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
&.feeds, &.feeds,
&.issues { &.issues {
.context.user.menu { .context.user.menu {
z-index: 101; z-index: 101;
min-width: 200px; min-width: 200px;
.ui.header { .ui.header {
font-size: 1rem; font-size: 1rem;
text-transform: none; text-transform: none;
} }
} }
.filter.menu { .filter.menu {
.item { .item {
text-align: left; text-align: left;
.text { .text {
height: 16px; height: 16px;
vertical-align: middle; vertical-align: middle;
&.truncate { &.truncate {
width: 85%; width: 85%;
} }
} }
.floating.label { .floating.label {
top: 7px; top: 7px;
left: 90%; left: 90%;
width: 15%; width: 15%;
} }
} }
// Sort // Sort
.jump.item { .jump.item {
margin: 1px; margin: 1px;
padding-right: 0; padding-right: 0;
} }
.menu { .menu {
max-height: 300px; max-height: 300px;
overflow-x: auto; overflow-x: auto;
right: 0!important; right: 0!important;
left: auto!important; left: auto!important;
} }
} }
.ui.right .head.menu { .ui.right .head.menu {
margin-top: -5px; margin-top: -5px;
.item.active { .item.active {
color: #d9453d; color: #d9453d;
} }
} }
} }
/* Accomodate for Semantic's 1px hacks on .attached elements */
.dashboard-repos {
margin: 0 1px;
}
} }
&.feeds { &.feeds {
.news { .news {
> .ui.grid { > .ui.grid {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
} }
.ui.avatar { .ui.avatar {
margin-top: 13px; margin-top: 13px;
} }
p { p {
line-height: 1em; line-height: 1em;
} }
.time-since { .time-since {
font-size: 13px; font-size: 13px;
} }
.issue.title { .issue.title {
width: 80%; width: 80%;
} }
.push.news .content ul { .push.news .content ul {
font-size: 13px; font-size: 13px;
list-style: none; list-style: none;
padding-left: 10px; padding-left: 10px;
img { img {
margin-bottom: -2px; margin-bottom: -2px;
} }
.text.truncate { .text.truncate {
width: 80%; width: 80%;
margin-bottom: -5px; margin-bottom: -5px;
} }
} }
.commit-id { .commit-id {
font-family: Consolas, monospace; font-family: Consolas, monospace;
} }
code { code {
padding: 1px; padding: 1px;
font-size: 85%; font-size: 85%;
background-color: rgba(0, 0, 0, 0.04); background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px; border-radius: 3px;
word-break: break-all; word-break: break-all;
} }
} }
.list { .list {
.header { .header {
.ui.label { .ui.label {
margin-top: -4px; margin-top: -4px;
padding: 4px 5px; padding: 4px 5px;
font-weight: normal; font-weight: normal;
} }
.plus.icon { .plus.icon {
margin-top: 5px; margin-top: 5px;
} }
} }
ul { ul {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding-left: 0; padding-left: 0;
li { li {
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid #EAEAEA; border-bottom: 1px solid #EAEAEA;
} }
&.private { &.private {
background-color: #fcf8e9; background-color: #fcf8e9;
} }
a { a {
padding: 6px 1.2em; padding: 6px 1.2em;
display: block; display: block;
.octicon { .octicon {
color: #888; color: #888;
&.rear { &.rear {
font-size: 15px; font-size: 15px;
} }
} }
.star-num { .star-num {
font-size: 12px; font-size: 12px;
} }
} }
} }
} }
.repo-owner-name-list { .repo-owner-name-list {
.item-name { .item-name {
max-width: 70%; max-width: 70%;
margin-bottom: -4px; margin-bottom: -4px;
} }
} }
#collaborative-repo-list { #collaborative-repo-list {
.owner-and-repo { .owner-and-repo {
max-width: 80%; max-width: 80%;
margin-bottom: -5px; margin-bottom: -5px;
} }
.owner-name { .owner-name {
max-width: 120px; max-width: 120px;
margin-bottom: -5px; margin-bottom: -5px;
} }
} }
} }
} }

View File

@ -1,12 +1,12 @@
.CodeMirror { .CodeMirror {
font: 14px Consolas, "Liberation Mono", Menlo, Courier, monospace; font: 14px Consolas, "Liberation Mono", Menlo, Courier, monospace;
&.cm-s-default { &.cm-s-default {
border-radius: 3px; border-radius: 3px;
padding: 0 !important; padding: 0 !important;
} }
.cm-comment { .cm-comment {
background: inherit !important; background: inherit !important;
} }
} }
.repository.file.editor .tab[data-tab="write"] { .repository.file.editor .tab[data-tab="write"] {
padding: 0 !important; padding: 0 !important;

View File

@ -1,6 +1,6 @@
.emoji { .emoji {
width: 1.5em; width: 1.5em;
height: 1.5em; height: 1.5em;
display: inline-block; display: inline-block;
background-size: contain; background-size: contain;
} }

View File

@ -1,8 +1,8 @@
.explore { .explore {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
.navbar { .navbar {
justify-content: center; justify-content: center;
padding-top: 15px !important; padding-top: 15px !important;
margin-top: -15px !important; margin-top: -15px !important;
@ -10,80 +10,80 @@
background-color: #FAFAFA !important; background-color: #FAFAFA !important;
border-width: 1px !important; border-width: 1px !important;
.octicon { .octicon {
width: 16px; width: 16px;
text-align: center; text-align: center;
} }
} }
} }
.ui.repository.list { .ui.repository.list {
.item { .item {
padding-bottom: 25px; padding-bottom: 25px;
&:not(:first-child) { &:not(:first-child) {
border-top: 1px solid #eee; border-top: 1px solid #eee;
padding-top: 25px; padding-top: 25px;
} }
.ui.header { .ui.header {
font-size: 1.5rem; font-size: 1.5rem;
padding-bottom: 10px; padding-bottom: 10px;
.name { .name {
word-break: break-all; word-break: break-all;
} }
.metas { .metas {
color: #888; color: #888;
font-size: 14px; font-size: 14px;
font-weight: normal; font-weight: normal;
span:not(:last-child) { span:not(:last-child) {
margin-right: 5px; margin-right: 5px;
} }
} }
} }
.time { .time {
font-size: 12px; font-size: 12px;
color: #808080; color: #808080;
} }
} }
} }
.ui.repository.branches { .ui.repository.branches {
.time{ .time{
font-size: 12px; font-size: 12px;
color: #808080; color: #808080;
} }
} }
.ui.user.list { .ui.user.list {
.item { .item {
padding-bottom: 25px; padding-bottom: 25px;
&:not(:first-child) { &:not(:first-child) {
border-top: 1px solid #eee; border-top: 1px solid #eee;
padding-top: 25px; padding-top: 25px;
} }
.ui.avatar.image { .ui.avatar.image {
width: 40px; width: 40px;
height: 40px; height: 40px;
} }
.description { .description {
margin-top: 5px; margin-top: 5px;
.octicon:not(:first-child) { .octicon:not(:first-child) {
margin-left: 5px; margin-left: 5px;
} }
a { a {
color: #333; color: #333;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
} }
} }
} }

View File

@ -1,144 +1,144 @@
.form { .form {
.help { .help {
color: #999999; color: #999999;
padding-top: .6em; padding-top: .6em;
padding-bottom: .6em; padding-bottom: .6em;
display: inline-block; display: inline-block;
} }
} }
.ui.attached.header { .ui.attached.header {
background: #f0f0f0; background: #f0f0f0;
.right { .right {
margin-top: -5px; margin-top: -5px;
.button { .button {
padding: 8px 10px; padding: 8px 10px;
font-weight: normal; font-weight: normal;
} }
} }
} }
@create-page-form-input-padding: 250px !important; @create-page-form-input-padding: 250px !important;
#create-page-form { #create-page-form {
form { form {
margin: auto; margin: auto;
width: 800px!important; width: 800px!important;
.ui.message { .ui.message {
text-align: center; text-align: center;
} }
.header { .header {
padding-left: @create-page-form-input-padding+30px; padding-left: @create-page-form-input-padding+30px;
} }
.inline.field > label { .inline.field > label {
text-align: right; text-align: right;
width: @create-page-form-input-padding; width: @create-page-form-input-padding;
word-wrap: break-word; word-wrap: break-word;
} }
.help { .help {
margin-left: @create-page-form-input-padding+15px; margin-left: @create-page-form-input-padding+15px;
} }
.optional .title { .optional .title {
margin-left: @create-page-form-input-padding; margin-left: @create-page-form-input-padding;
} }
input, input,
textarea { textarea {
width: 50%!important; width: 50%!important;
} }
} }
} }
.signin { .signin {
.oauth2{ .oauth2{
div { div {
display: inline-block; display: inline-block;
p { p {
margin: 10px 5px 0 0; margin: 10px 5px 0 0;
float: left; float: left;
} }
} }
a { a {
margin-right: 3px; margin-right: 3px;
&:last-child { &:last-child {
margin-right: 0px; margin-right: 0px;
} }
} }
img { img {
width: 32px; width: 32px;
height: 32px; height: 32px;
&.openidConnect { &.openidConnect {
width: auto; width: auto;
} }
} }
} }
} }
.user.activate, .user.activate,
.user.forgot.password, .user.forgot.password,
.user.reset.password, .user.reset.password,
.user.signin, .user.signin,
.user.signup { .user.signup {
@input-padding: 200px!important; @input-padding: 200px!important;
#create-page-form; #create-page-form;
form { form {
width: 700px!important; width: 700px!important;
.header { .header {
padding-left: 0 !important; padding-left: 0 !important;
text-align: center; text-align: center;
} }
.inline.field > label { .inline.field > label {
width: @input-padding; width: @input-padding;
} }
} }
} }
.repository { .repository {
&.new.repo, &.new.repo,
&.new.migrate, &.new.migrate,
&.new.fork { &.new.fork {
#create-page-form; #create-page-form;
form { form {
.dropdown { .dropdown {
.dropdown.icon { .dropdown.icon {
margin-top: -7px!important; margin-top: -7px!important;
} }
.text { .text {
margin-right: 0!important; margin-right: 0!important;
i { i {
margin-right: 0!important; margin-right: 0!important;
} }
} }
} }
.header { .header {
padding-left: 0 !important; padding-left: 0 !important;
text-align: center; text-align: center;
} }
} }
} }
&.new.repo { &.new.repo {
.ui.form { .ui.form {
.selection.dropdown:not(.owner) { .selection.dropdown:not(.owner) {
width: 50%!important; width: 50%!important;
} }
#auto-init { #auto-init {
margin-left: @create-page-form-input-padding+15px; margin-left: @create-page-form-input-padding+15px;
} }
} }
} }
} }
.new.webhook { .new.webhook {
form { form {
.help { .help {
margin-left: 25px; margin-left: 25px;
} }
} }
} }
.new.webhook { .new.webhook {
.events.fields { .events.fields {
.column { .column {
padding-left: 40px; padding-left: 40px;
} }
} }
} }
.githook { .githook {

View File

@ -1,39 +1,39 @@
.home { .home {
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
.logo { .logo {
max-width: 220px; max-width: 220px;
} }
.hero { .hero {
h1, h2 { h1, h2 {
font-family: 'PT Sans Narrow', sans-serif, 'Microsoft YaHei'; font-family: 'PT Sans Narrow', sans-serif, 'Microsoft YaHei';
} }
h1 { h1 {
font-size: 5.5em; font-size: 5.5em;
} }
h2 { h2 {
font-size: 3em; font-size: 3em;
} }
.octicon { .octicon {
color: #5aa509; color: #5aa509;
font-size: 40px; font-size: 40px;
width: 50px; width: 50px;
} }
&.header { &.header {
font-size: 20px; font-size: 20px;
} }
} }
p.large { p.large {
font-size: 16px font-size: 16px
} }
.stackable { .stackable {
padding-top: 30px; padding-top: 30px;
} }
a { a {
color: #5aa509; color: #5aa509;
} }
} }
.signup { .signup {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
} }

View File

@ -1,31 +1,31 @@
.install { .install {
padding-top: 45px; padding-top: 45px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
form { form {
@input-padding: 320px !important; @input-padding: 320px !important;
label { label {
text-align: right; text-align: right;
width: @input-padding; width: @input-padding;
} }
input { input {
width: 35% !important; width: 35% !important;
} }
.field { .field {
text-align: left; text-align: left;
.help { .help {
margin-left: @input-padding+15px; margin-left: @input-padding+15px;
} }
&.optional .title { &.optional .title {
margin-left: 38%; margin-left: 38%;
} }
} }
} }
.ui { .ui {
.checkbox { .checkbox {
margin-left: 40% !important; margin-left: 40% !important;
label { label {
width: auto !important; width: auto !important;
} }
} }
} }
} }

View File

@ -1,492 +1,492 @@
.markdown:not(code) { .markdown:not(code) {
overflow: hidden; overflow: hidden;
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif;
font-size: 16px; font-size: 16px;
line-height: 1.6 !important; line-height: 1.6 !important;
word-wrap: break-word; word-wrap: break-word;
&.file-view { &.file-view {
padding: 2em 2em 2em !important; padding: 2em 2em 2em !important;
} }
>*:first-child { >*:first-child {
margin-top: 0 !important; margin-top: 0 !important;
} }
>*:last-child { >*:last-child {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
a:not([href]) { a:not([href]) {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
.absent { .absent {
color: #c00; color: #c00;
} }
.anchor { .anchor {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
display: block; display: block;
padding-right: 6px; padding-right: 6px;
padding-left: 30px; padding-left: 30px;
margin-left: -30px; margin-left: -30px;
} }
.anchor:focus { .anchor:focus {
outline: none; outline: none;
} }
h1, h1,
h2, h2,
h3, h3,
h4, h4,
h5, h5,
h6 { h6 {
position: relative; position: relative;
margin-top: 1em; margin-top: 1em;
margin-bottom: 16px; margin-bottom: 16px;
font-weight: bold; font-weight: bold;
line-height: 1.4; line-height: 1.4;
&:first-of-type { &:first-of-type {
margin-top: 0 !important; margin-top: 0 !important;
} }
} }
h1 .octicon-link, h1 .octicon-link,
h2 .octicon-link, h2 .octicon-link,
h3 .octicon-link, h3 .octicon-link,
h4 .octicon-link, h4 .octicon-link,
h5 .octicon-link, h5 .octicon-link,
h6 .octicon-link { h6 .octicon-link {
display:none; display:none;
color:#000; color:#000;
vertical-align:middle; vertical-align:middle;
} }
h1:hover .anchor, h1:hover .anchor,
h2:hover .anchor, h2:hover .anchor,
h3:hover .anchor, h3:hover .anchor,
h4:hover .anchor, h4:hover .anchor,
h5:hover .anchor, h5:hover .anchor,
h6:hover .anchor { h6:hover .anchor {
padding-left:8px; padding-left:8px;
margin-left:-30px; margin-left:-30px;
text-decoration:none; text-decoration:none;
} }
h1:hover .anchor .octicon-link, h1:hover .anchor .octicon-link,
h2:hover .anchor .octicon-link, h2:hover .anchor .octicon-link,
h3:hover .anchor .octicon-link, h3:hover .anchor .octicon-link,
h4:hover .anchor .octicon-link, h4:hover .anchor .octicon-link,
h5:hover .anchor .octicon-link, h5:hover .anchor .octicon-link,
h6:hover .anchor .octicon-link { h6:hover .anchor .octicon-link {
display:inline-block; display:inline-block;
} }
h1 tt, h1 tt,
h1 code, h1 code,
h2 tt, h2 tt,
h2 code, h2 code,
h3 tt, h3 tt,
h3 code, h3 code,
h4 tt, h4 tt,
h4 code, h4 code,
h5 tt, h5 tt,
h5 code, h5 code,
h6 tt, h6 tt,
h6 code { h6 code {
font-size:inherit; font-size:inherit;
} }
h1 { h1 {
padding-bottom:0.3em; padding-bottom:0.3em;
font-size:2.25em; font-size:2.25em;
line-height:1.2; line-height:1.2;
border-bottom:1px solid #eee; border-bottom:1px solid #eee;
} }
h1 .anchor { h1 .anchor {
line-height:1; line-height:1;
} }
h2 { h2 {
padding-bottom:0.3em; padding-bottom:0.3em;
font-size:1.75em; font-size:1.75em;
line-height:1.225; line-height:1.225;
border-bottom:1px solid #eee; border-bottom:1px solid #eee;
} }
h2 .anchor { h2 .anchor {
line-height:1; line-height:1;
} }
h3 { h3 {
font-size:1.5em; font-size:1.5em;
line-height:1.43; line-height:1.43;
} }
h3 .anchor { h3 .anchor {
line-height:1.2; line-height:1.2;
} }
h4 { h4 {
font-size:1.25em; font-size:1.25em;
} }
h4 .anchor { h4 .anchor {
line-height:1.2; line-height:1.2;
} }
h5 { h5 {
font-size:1em; font-size:1em;
} }
h5 .anchor { h5 .anchor {
line-height:1.1; line-height:1.1;
} }
h6 { h6 {
font-size:1em;color:#777; font-size:1em;color:#777;
} }
h6 .anchor { h6 .anchor {
line-height:1.1; line-height:1.1;
} }
p, p,
blockquote, blockquote,
ul, ul,
ol, ol,
dl, dl,
table, table,
pre { pre {
margin-top: 0; margin-top: 0;
margin-bottom: 16px; margin-bottom: 16px;
} }
blockquote { blockquote {
margin-left: 0; margin-left: 0;
} }
hr { hr {
height:4px; height:4px;
padding:0; padding:0;
margin:16px 0; margin:16px 0;
background-color:#e7e7e7; background-color:#e7e7e7;
border:0 none; border:0 none;
} }
ul, ul,
ol { ol {
padding-left:2em; padding-left:2em;
} }
ul.no-list, ul.no-list,
ol.no-list { ol.no-list {
padding:0; padding:0;
list-style-type:none; list-style-type:none;
} }
ul ul, ul ul,
ul ol, ul ol,
ol ol, ol ol,
ol ul { ol ul {
margin-top:0; margin-top:0;
margin-bottom:0; margin-bottom:0;
} }
ol ol, ol ol,
ul ol { ul ol {
list-style-type: lower-roman; list-style-type: lower-roman;
} }
li>p { li>p {
margin-top:0; margin-top:0;
} }
dl { dl {
padding:0; padding:0;
} }
dl dt { dl dt {
padding:0; padding:0;
margin-top:16px; margin-top:16px;
font-size:1em; font-size:1em;
font-style:italic; font-style:italic;
font-weight:bold; font-weight:bold;
} }
dl dd { dl dd {
padding:0 16px; padding:0 16px;
margin-bottom:16px; margin-bottom:16px;
} }
blockquote { blockquote {
padding:0 15px; padding:0 15px;
color:#777; color:#777;
border-left:4px solid #ddd; border-left:4px solid #ddd;
} }
blockquote>:first-child { blockquote>:first-child {
margin-top:0; margin-top:0;
} }
blockquote>:last-child { blockquote>:last-child {
margin-bottom:0; margin-bottom:0;
} }
table { table {
width:auto; width:auto;
overflow:auto; overflow:auto;
word-break:normal; word-break:normal;
word-break:keep-all; word-break:keep-all;
} }
table th { table th {
font-weight:bold; font-weight:bold;
} }
table th, table th,
table td { table td {
padding: 6px 13px !important; padding: 6px 13px !important;
border: 1px solid #ddd !important; border: 1px solid #ddd !important;
} }
table tr { table tr {
background-color:#fff; background-color:#fff;
border-top:1px solid #ccc; border-top:1px solid #ccc;
} }
table tr:nth-child(2n) { table tr:nth-child(2n) {
background-color:#f8f8f8; background-color:#f8f8f8;
} }
img { img {
max-width:100%; max-width:100%;
box-sizing:border-box; box-sizing:border-box;
} }
.emoji { .emoji {
max-width:none; max-width:none;
} }
span.frame { span.frame {
display:block; display:block;
overflow:hidden; overflow:hidden;
} }
span.frame>span { span.frame>span {
display:block; display:block;
float:left; float:left;
width:auto; width:auto;
padding:7px; padding:7px;
margin:13px 0 0; margin:13px 0 0;
overflow:hidden; overflow:hidden;
border:1px solid #ddd; border:1px solid #ddd;
} }
span.frame span img { span.frame span img {
display:block; display:block;
float:left; float:left;
} }
span.frame span span { span.frame span span {
display:block; display:block;
padding:5px 0 0; padding:5px 0 0;
clear:both; clear:both;
color:#333; color:#333;
} }
span.align-center { span.align-center {
display:block; display:block;
overflow:hidden; overflow:hidden;
clear:both; clear:both;
} }
span.align-center>span { span.align-center>span {
display:block; display:block;
margin:13px auto 0; margin:13px auto 0;
overflow:hidden; overflow:hidden;
text-align:center; text-align:center;
} }
span.align-center span img { span.align-center span img {
margin:0 auto; margin:0 auto;
text-align:center; text-align:center;
} }
span.align-right { span.align-right {
display:block; display:block;
overflow:hidden; overflow:hidden;
clear:both; clear:both;
} }
span.align-right>span { span.align-right>span {
display:block; display:block;
margin:13px 0 0; margin:13px 0 0;
overflow:hidden; overflow:hidden;
text-align:right; text-align:right;
} }
span.align-right span img { span.align-right span img {
margin:0; margin:0;
text-align:right; text-align:right;
} }
span.float-left { span.float-left {
display:block; display:block;
float:left; float:left;
margin-right:13px; margin-right:13px;
overflow:hidden; overflow:hidden;
} }
span.float-left span { span.float-left span {
margin:13px 0 0; margin:13px 0 0;
} }
span.float-right { span.float-right {
display:block; display:block;
float:right; float:right;
margin-left:13px; margin-left:13px;
overflow:hidden; overflow:hidden;
} }
span.float-right>span { span.float-right>span {
display:block; display:block;
margin:13px auto 0; margin:13px auto 0;
overflow:hidden; overflow:hidden;
text-align:right; text-align:right;
} }
code, code,
tt { tt {
padding:0; padding:0;
padding-top:0.2em; padding-top:0.2em;
padding-bottom:0.2em; padding-bottom:0.2em;
margin:0; margin:0;
font-size:85%; font-size:85%;
background-color:rgba(0,0,0,0.04); background-color:rgba(0,0,0,0.04);
border-radius:3px; border-radius:3px;
} }
code:before, code:before,
code:after, code:after,
tt:before, tt:before,
tt:after { tt:after {
letter-spacing:-0.2em; letter-spacing:-0.2em;
content:"\00a0"; content:"\00a0";
} }
code br, code br,
tt br { tt br {
display:none; display:none;
} }
del code { del code {
text-decoration:inherit; text-decoration:inherit;
} }
pre>code { pre>code {
padding:0; padding:0;
margin:0; margin:0;
font-size:100%; font-size:100%;
word-break:normal; word-break:normal;
white-space:pre; white-space:pre;
background:transparent; background:transparent;
border:0; border:0;
} }
.highlight { .highlight {
margin-bottom:16px; margin-bottom:16px;
} }
.highlight pre, .highlight pre,
pre { pre {
padding:16px; padding:16px;
overflow:auto; overflow:auto;
font-size:85%; font-size:85%;
line-height:1.45; line-height:1.45;
background-color:#f7f7f7; background-color:#f7f7f7;
border-radius:3px; border-radius:3px;
} }
.highlight pre { .highlight pre {
margin-bottom:0; margin-bottom:0;
word-break:normal; word-break:normal;
} }
pre { pre {
word-wrap:normal; word-wrap:normal;
} }
pre code, pre code,
pre tt { pre tt {
display:inline; display:inline;
max-width:initial; max-width:initial;
padding:0; padding:0;
margin:0; margin:0;
overflow:initial; overflow:initial;
line-height:inherit; line-height:inherit;
word-wrap:normal; word-wrap:normal;
background-color:transparent; background-color:transparent;
border:0; border:0;
} }
pre code:before, pre code:before,
pre code:after, pre code:after,
pre tt:before, pre tt:before,
pre tt:after { pre tt:after {
content:normal; content:normal;
} }
kbd { kbd {
display:inline-block; display:inline-block;
padding:3px 5px; padding:3px 5px;
font-size:11px; font-size:11px;
line-height:10px; line-height:10px;
color:#555; color:#555;
vertical-align:middle; vertical-align:middle;
background-color:#fcfcfc; background-color:#fcfcfc;
border:solid 1px #ccc; border:solid 1px #ccc;
border-bottom-color:#bbb; border-bottom-color:#bbb;
border-radius:3px; border-radius:3px;
box-shadow:inset 0 -1px 0 #bbb; box-shadow:inset 0 -1px 0 #bbb;
} }
input[type="checkbox"] { input[type="checkbox"] {
vertical-align: middle !important; vertical-align: middle !important;
} }
.csv-data td, .csv-data td,
.csv-data th { .csv-data th {
padding:5px; padding:5px;
overflow:hidden; overflow:hidden;
font-size:12px; font-size:12px;
line-height:1; line-height:1;
text-align:left; text-align:left;
white-space:nowrap; white-space:nowrap;
} }
.csv-data .blob-num { .csv-data .blob-num {
padding:10px 8px 9px; padding:10px 8px 9px;
text-align:right; text-align:right;
background:#fff;border:0; background:#fff;border:0;
} }
.csv-data tr { .csv-data tr {
border-top:0; border-top:0;
} }
.csv-data th { .csv-data th {
font-weight:bold; font-weight:bold;
background:#f8f8f8;border-top:0; background:#f8f8f8;border-top:0;
} }
.ui.list .list, ol.ui.list ol, ul.ui.list ul { .ui.list .list, ol.ui.list ol, ul.ui.list ul {
padding-left: 2em; padding-left: 2em;
} }
} }

View File

@ -1,162 +1,162 @@
.organization { .organization {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
.head { .head {
.ui.header { .ui.header {
.text { .text {
vertical-align: middle; vertical-align: middle;
font-size: 1.6rem; font-size: 1.6rem;
margin-left: 15px; margin-left: 15px;
} }
.ui.right { .ui.right {
margin-top: 5px; margin-top: 5px;
} }
} }
} }
&.new.org { &.new.org {
#create-page-form; #create-page-form;
form { form {
.header { .header {
padding-left: 0 !important; padding-left: 0 !important;
text-align: center; text-align: center;
} }
} }
} }
&.options { &.options {
input { input {
min-width: 300px; min-width: 300px;
} }
} }
&.profile { &.profile {
#org-avatar { #org-avatar {
width: 100px; width: 100px;
height: 100px; height: 100px;
margin-right: 15px; margin-right: 15px;
} }
#org-info { #org-info {
.ui.header { .ui.header {
font-size: 36px; font-size: 36px;
margin-bottom: 0; margin-bottom: 0;
} }
.desc { .desc {
font-size: 16px; font-size: 16px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.meta { .meta {
.item { .item {
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
.icon { .icon {
margin-right: 5px; margin-right: 5px;
} }
} }
} }
} }
.ui.top.header { .ui.top.header {
.ui.right { .ui.right {
margin-top: 0; margin-top: 0;
} }
} }
.teams { .teams {
.item { .item {
padding: 10px 15px; padding: 10px 15px;
} }
} }
} }
&.teams, &.teams,
&.profile { &.profile {
.members { .members {
.ui.avatar { .ui.avatar {
width: 48px; width: 48px;
height: 48px; height: 48px;
margin-right: 5px; margin-right: 5px;
} }
} }
} }
&.invite { &.invite {
#invite-box { #invite-box {
margin: auto; margin: auto;
margin-top: 50px; margin-top: 50px;
width: 500px !important; width: 500px !important;
#search-user-box { #search-user-box {
input { input {
margin-left: 0; margin-left: 0;
width: 300px; width: 300px;
} }
} }
.ui.button { .ui.button {
margin-left: 5px; margin-left: 5px;
margin-top: -3px; margin-top: -3px;
} }
} }
} }
&.members { &.members {
.list { .list {
.item { .item {
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
.ui.avatar { .ui.avatar {
width: 48px; width: 48px;
height: 48px; height: 48px;
} }
.meta { .meta {
line-height: 24px; line-height: 24px;
} }
} }
} }
} }
&.teams { &.teams {
.detail { .detail {
.item { .item {
padding: 10px 15px; padding: 10px 15px;
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
} }
} }
.repositories, .repositories,
.members { .members {
.item { .item {
padding: 10px 20px; padding: 10px 20px;
line-height: 32px; line-height: 32px;
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
} }
.button { .button {
padding: 9px 10px; padding: 9px 10px;
} }
} }
} }
#add-repo-form, #add-repo-form,
#add-member-form { #add-member-form {
input { input {
margin-left: 0; margin-left: 0;
} }
.ui.button { .ui.button {
margin-left: 5px; margin-left: 5px;
margin-top: -3px; margin-top: -3px;
} }
} }
} }
} }

View File

@ -1354,257 +1354,257 @@
// End of .repository // End of .repository
&.user-cards { &.user-cards {
.list { .list {
padding: 0; padding: 0;
.item { .item {
list-style: none; list-style: none;
width: 32%; width: 32%;
margin: 10px 10px 10px 0; margin: 10px 10px 10px 0;
padding-bottom: 14px; padding-bottom: 14px;
float: left; float: left;
.avatar { .avatar {
width: 48px; width: 48px;
height: 48px; height: 48px;
float: left; float: left;
display: block; display: block;
margin-right: 10px; margin-right: 10px;
} }
.name { .name {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
font-weight: normal; font-weight: normal;
} }
.meta { .meta {
margin-top: 5px; margin-top: 5px;
} }
} }
} }
} }
#search-repo-box, #search-repo-box,
#search-user-box { #search-user-box {
.results { .results {
.result { .result {
.image { .image {
float: left; float: left;
margin-right: 8px; margin-right: 8px;
width: 2em; width: 2em;
height: 2em; height: 2em;
} }
.content { .content {
margin: 6px 0; margin: 6px 0;
} }
} }
} }
} }
.issue-actions { .issue-actions {
display: none; display: none;
} }
.issue.list { .issue.list {
list-style: none; list-style: none;
padding-top: 15px; padding-top: 15px;
>.item { >.item {
padding-top: 15px; padding-top: 15px;
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px dashed #AAA; border-bottom: 1px dashed #AAA;
.title { .title {
color: #444; color: #444;
font-size: 15px; font-size: 15px;
font-weight: bold; font-weight: bold;
margin: 0 6px; margin: 0 6px;
&:hover { &:hover {
color: #000; color: #000;
} }
} }
.comment { .comment {
padding-right: 10px; padding-right: 10px;
color: #666; color: #666;
} }
.desc { .desc {
padding-top: 5px; padding-top: 5px;
color: #999; color: #999;
a.milestone { a.milestone {
padding-left: 5px; padding-left: 5px;
color: #999!important; color: #999!important;
&:hover { &:hover {
color: #000!important; color: #000!important;
} }
} }
.assignee { .assignee {
margin-top: -5px; margin-top: -5px;
margin-right: 5px; margin-right: 5px;
} }
} }
} }
} }
.page.buttons { .page.buttons {
padding-top: 15px; padding-top: 15px;
} }
.ui.form { .ui.form {
.dropzone { .dropzone {
width: 100%; width: 100%;
margin-bottom: 10px; margin-bottom: 10px;
border: 2px dashed #0087F7; border: 2px dashed #0087F7;
box-shadow: none!important; box-shadow: none!important;
.dz-error-message { .dz-error-message {
top: 140px; top: 140px;
} }
} }
} }
.settings { .settings {
.content { .content {
margin-top: 2px; margin-top: 2px;
>.header, >.header,
.segment { .segment {
box-shadow: 0 1px 2px 0 rgba(34,36,38,.15); box-shadow: 0 1px 2px 0 rgba(34,36,38,.15);
} }
} }
.list { .list {
> .item { > .item {
.green { .green {
color: #21BA45 !important; color: #21BA45 !important;
} }
&:not(:first-child) { &:not(:first-child) {
border-top: 1px solid #eaeaea; border-top: 1px solid #eaeaea;
padding:1rem; padding:1rem;
margin: 15px -1rem -1rem -1rem; margin: 15px -1rem -1rem -1rem;
} }
> .mega-octicon { > .mega-octicon {
display: table-cell; display: table-cell;
} }
> .mega-octicon + .content { > .mega-octicon + .content {
display: table-cell; display: table-cell;
padding: 0 0 0 .5em; padding: 0 0 0 .5em;
vertical-align: top; vertical-align: top;
} }
.info { .info {
margin-top: 10px; margin-top: 10px;
.tab.segment { .tab.segment {
border: none; border: none;
padding: 10px 0 0; padding: 10px 0 0;
} }
} }
} }
&.key{ &.key{
.meta { .meta {
padding-top: 5px; padding-top: 5px;
color: #666; color: #666;
} }
} }
&.email { &.email {
> .item:not(:first-child) { > .item:not(:first-child) {
min-height: 60px; min-height: 60px;
} }
} }
&.collaborator { &.collaborator {
> .item { > .item {
padding: 0; padding: 0;
} }
} }
} }
} }
.ui.vertical.menu { .ui.vertical.menu {
.header.item { .header.item {
font-size: 1.1em; font-size: 1.1em;
background: #f0f0f0; background: #f0f0f0;
} }
} }
.edit-label.modal, .edit-label.modal,
.new-label.segment { .new-label.segment {
.form { .form {
.column { .column {
padding-right: 0; padding-right: 0;
} }
.buttons { .buttons {
margin-left: auto; margin-left: auto;
padding-top: 15px; padding-top: 15px;
} }
.color.picker.column { .color.picker.column {
width: auto; width: auto;
.color-picker { .color-picker {
height: 35px; height: 35px;
width: auto; width: auto;
padding-left: 30px; padding-left: 30px;
} }
} }
.minicolors-swatch.minicolors-sprite { .minicolors-swatch.minicolors-sprite {
top: 10px; top: 10px;
left: 10px; left: 10px;
width: 15px; width: 15px;
height: 15px; height: 15px;
} }
.precolors { .precolors {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
margin: 3px 10px auto 10px; margin: 3px 10px auto 10px;
width: 120px; width: 120px;
.color { .color {
float: left; float: left;
width: 15px; width: 15px;
height: 15px; height: 15px;
} }
} }
} }
} }
#avatar-arrow { #avatar-arrow {
&:before, &:after { &:before, &:after {
right: 100%; right: 100%;
top: 20px; top: 20px;
border: solid transparent; border: solid transparent;
content: " "; content: " ";
height: 0; height: 0;
width: 0; width: 0;
position: absolute; position: absolute;
pointer-events: none; pointer-events: none;
} }
&:before { &:before {
border-right-color: #D4D4D5; border-right-color: #D4D4D5;
border-width: 9px; border-width: 9px;
margin-top: -9px; margin-top: -9px;
} }
&:after { &:after {
border-right-color: #f7f7f7; border-right-color: #f7f7f7;
border-width: 8px; border-width: 8px;
margin-top: -8px; margin-top: -8px;
} }
} }
#transfer-repo-modal, #transfer-repo-modal,
#delete-repo-modal { #delete-repo-modal {
.ui.message { .ui.message {
width: 100%!important; width: 100%!important;
} }
} }
// generate .tab-size-{i} from 1 to 16 // generate .tab-size-{i} from 1 to 16
.generate-tab-size(16); .generate-tab-size(16);
.generate-tab-size(@n, @i: 1) when (@i =< @n) { .generate-tab-size(@n, @i: 1) when (@i =< @n) {
.tab-size-@{i} { .tab-size-@{i} {
tab-size: @i !important; tab-size: @i !important;
-moz-tab-size: @i !important; -moz-tab-size: @i !important;
} }
.generate-tab-size(@n, (@i + 1)); .generate-tab-size(@n, (@i + 1));
} }
.stats-table { .stats-table {
display: table; display: table;
width: 100%; width: 100%;
.table-cell { .table-cell {
display: table-cell; display: table-cell;
&.tiny { &.tiny {
height: .5em; height: .5em;
} }
} }
} }
tbody.commit-list { tbody.commit-list {
@ -1612,5 +1612,5 @@ tbody.commit-list {
} }
.commit-body { .commit-body {
white-space: pre-wrap; white-space: pre-wrap;
} }

View File

@ -1,62 +1,62 @@
.user { .user {
&:not(.icon) { &:not(.icon) {
padding-top: 15px; padding-top: 15px;
padding-bottom: @footer-margin * 2; padding-bottom: @footer-margin * 2;
} }
&.profile { &.profile {
.ui.card { .ui.card {
.username { .username {
display: block; display: block;
} }
.extra.content { .extra.content {
padding: 0; padding: 0;
ul { ul {
margin: 0; margin: 0;
padding: 0; padding: 0;
li { li {
padding: 10px; padding: 10px;
list-style: none; list-style: none;
&:not(:last-child) { &:not(:last-child) {
border-bottom: 1px solid #eaeaea; border-bottom: 1px solid #eaeaea;
} }
.octicon { .octicon {
margin-left: 1px; margin-left: 1px;
margin-right: 5px; margin-right: 5px;
} }
&.follow { &.follow {
.ui.button { .ui.button {
width: 100%; width: 100%;
} }
} }
} }
} }
} }
} }
.ui.repository.list { .ui.repository.list {
margin-top: 25px; margin-top: 25px;
} }
} }
&.followers { &.followers {
.header.name { .header.name {
font-size: 20px; font-size: 20px;
line-height: 24px; line-height: 24px;
vertical-align: middle; vertical-align: middle;
} }
.follow { .follow {
.ui.button { .ui.button {
padding: 8px 15px; padding: 8px 15px;
} }
} }
} }
&.notification { &.notification {
.octicon { .octicon {

View File

@ -66,5 +66,6 @@
<!-- JavaScript --> <!-- JavaScript -->
<script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script> <script src="{{AppSubUrl}}/vendor/plugins/semantic/semantic.min.js"></script>
<script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script> <script src="{{AppSubUrl}}/js/index.js?v={{MD5 AppVer}}"></script>
{{template "custom/footer" .}}
</body> </body>
</html> </html>

View File

@ -122,6 +122,7 @@
<meta property="og:url" content="{{AppUrl}}" /> <meta property="og:url" content="{{AppUrl}}" />
<meta property="og:description" content="{{MetaDescription}}"> <meta property="og:description" content="{{MetaDescription}}">
{{end}} {{end}}
{{template "custom/header" .}}
</head> </head>
<body> <body>
<div class="full height"> <div class="full height">

View File

View File

View File

@ -3,7 +3,7 @@
<div class="ui vertically grid head"> <div class="ui vertically grid head">
<div class="column"> <div class="column">
<div class="ui header"> <div class="ui header">
<img class="ui image" src="{{.RelAvatarLink}}?s=100"> <img class="ui image" src="{{.SizedRelAvatarLink 100}}">
<span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span> <span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span>
<div class="ui right"> <div class="ui right">

View File

@ -3,7 +3,7 @@
<div class="ui container"> <div class="ui container">
<div class="ui grid"> <div class="ui grid">
<div class="ui sixteen wide column"> <div class="ui sixteen wide column">
<img class="ui left" id="org-avatar" src="{{.Org.RelAvatarLink}}?s=140"/> <img class="ui left" id="org-avatar" src="{{.Org.SizedRelAvatarLink 140}}"/>
<div id="org-info"> <div id="org-info">
<div class="ui header"> <div class="ui header">
{{.Org.DisplayName}} {{.Org.DisplayName}}

View File

@ -8,7 +8,7 @@
{{range .Members}} {{range .Members}}
<div class="item ui grid"> <div class="item ui grid">
<div class="ui one wide column"> <div class="ui one wide column">
<img class="ui avatar" src="{{.RelAvatarLink}}?s=48"> <img class="ui avatar" src="{{.SizedRelAvatarLink 48}}">
</div> </div>
<div class="ui three wide column"> <div class="ui three wide column">
<div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div> <div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div>

View File

@ -1,6 +1,6 @@
<div class="fitted item choose reference"> <div class="fitted item choose reference">
<div class="ui floating filter dropdown custom" data-can-create-branch="{{.CanCreateBranch}}" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}"> <div class="ui floating filter dropdown custom" data-can-create-branch="{{.CanCreateBranch}}" data-no-results="{{.i18n.Tr "repo.pulls.no_results"}}">
<div class="ui basic small button" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible"> <div class="ui basic small compact button" @click="menuVisible = !menuVisible" @keyup.enter="menuVisible = !menuVisible">
<span class="text"> <span class="text">
<i class="octicon octicon-git-branch"></i> <i class="octicon octicon-git-branch"></i>
{{if .IsViewBranch}}{{.i18n.Tr "repo.branch"}}{{else}}{{.i18n.Tr "repo.tree"}}{{end}}: {{if .IsViewBranch}}{{.i18n.Tr "repo.branch"}}{{else}}{{.i18n.Tr "repo.tree"}}{{end}}:

View File

@ -172,7 +172,7 @@
<a class="title has-emoji" href="{{$.Link}}/{{.Index}}">{{.Title}}</a> <a class="title has-emoji" href="{{$.Link}}/{{.Index}}">{{.Title}}</a>
{{if .Ref}} {{if .Ref}}
<a class="ui label" href="{{$.RepoLink}}/src/commit/{{.Ref}}">{{.Ref}}</a> <a class="ui label" href="{{$.RepoLink}}/src/branch/{{.Ref}}">{{.Ref}}</a>
{{end}} {{end}}
{{range .Labels}} {{range .Labels}}
<a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a> <a class="ui label" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&state={{$.State}}&labels={{.ID}}&milestone={{$.MilestoneID}}&assignee={{$.AssigneeID}}" style="color: {{.ForegroundColor}}; background-color: {{.Color}}">{{.Name}}</a>

View File

@ -31,7 +31,7 @@
<a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a> <a :class="{item: true, active: tab === 'repos'}" @click="changeTab('repos')">{{.i18n.Tr "repository"}}</a>
<a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a> <a :class="{item: true, active: tab === 'organizations'}" @click="changeTab('organizations')">{{.i18n.Tr "organization"}}</a>
</div> </div>
<div v-show="tab === 'repos'" class="ui tab active list"> <div v-show="tab === 'repos'" class="ui tab active list dashboard-repos">
<h4 class="ui top attached header"> <h4 class="ui top attached header">
{{.i18n.Tr "home.my_repos"}} <span class="ui grey label">${reposTotalCount}</span> {{.i18n.Tr "home.my_repos"}} <span class="ui grey label">${reposTotalCount}</span>
<div class="ui right"> <div class="ui right">

View File

@ -6,11 +6,11 @@
<div class="ui card"> <div class="ui card">
{{if eq .SignedUserName .Owner.Name}} {{if eq .SignedUserName .Owner.Name}}
<a class="image poping up" href="{{AppSubUrl}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center"> <a class="image poping up" href="{{AppSubUrl}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center">
<img src="{{.Owner.RelAvatarLink}}?s=290" title="{{.Owner.Name}}"/> <img src="{{.Owner.SizedRelAvatarLink 290}}" title="{{.Owner.Name}}"/>
</a> </a>
{{else}} {{else}}
<span class="image"> <span class="image">
<img src="{{.Owner.RelAvatarLink}}?s=290" title="{{.Owner.Name}}"/> <img src="{{.Owner.SizedRelAvatarLink 290}}" title="{{.Owner.Name}}"/>
</span> </span>
{{end}} {{end}}
<div class="content"> <div class="content">