mirror of
https://github.com/go-gitea/gitea
synced 2024-11-25 04:35:00 +01:00
commit
50cd67cd4b
28 changed files with 668 additions and 333 deletions
|
@ -272,8 +272,9 @@ func runWeb(ctx *cli.Context) {
|
|||
m.Post("/email", bindIgnErr(auth.AddEmailForm{}), user.SettingsEmailPost)
|
||||
m.Get("/password", user.SettingsPassword)
|
||||
m.Post("/password", bindIgnErr(auth.ChangePasswordForm{}), user.SettingsPasswordPost)
|
||||
m.Get("/ssh", user.SettingsSSHKeys)
|
||||
m.Post("/ssh", bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
|
||||
m.Combo("/ssh").Get(user.SettingsSSHKeys).
|
||||
Post(bindIgnErr(auth.AddSSHKeyForm{}), user.SettingsSSHKeysPost)
|
||||
m.Post("/ssh/delete", user.DeleteSSHKey)
|
||||
m.Get("/social", user.SettingsSocial)
|
||||
m.Combo("/applications").Get(user.SettingsApplications).
|
||||
Post(bindIgnErr(auth.NewAccessTokenForm{}), user.SettingsApplicationsPost)
|
||||
|
|
|
@ -276,6 +276,9 @@ key_name = Key Name
|
|||
key_content = Content
|
||||
add_key_success = New SSH key '%s' has been added successfully!
|
||||
delete_key = Delete
|
||||
ssh_key_deletion = SSH Key Deletion
|
||||
ssh_key_deletion_desc = Delete this SSH key will remove all related accesses for your account. Do you want to continue?
|
||||
ssh_key_deletion_success = SSH key has been deleted successfully!
|
||||
add_on = Added on
|
||||
last_used = Last used on
|
||||
no_activity = No recent activity
|
||||
|
|
|
@ -169,6 +169,12 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
|
|||
beg := len(DIFF_HEAD)
|
||||
a := line[beg : (len(line)-beg)/2+beg]
|
||||
|
||||
// In case file name is surrounded by double quotes(it happens only in git-shell).
|
||||
if a[0] == '"' {
|
||||
a = a[1 : len(a)-1]
|
||||
a = strings.Replace(a, `\"`, `"`, -1)
|
||||
}
|
||||
|
||||
curFile = &DiffFile{
|
||||
Name: a[strings.Index(a, "/")+1:],
|
||||
Index: len(diff.Files) + 1,
|
||||
|
|
|
@ -466,7 +466,15 @@ func deletePublicKey(e *xorm.Session, key *PublicKey) error {
|
|||
}
|
||||
|
||||
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
|
||||
func DeletePublicKey(key *PublicKey) (err error) {
|
||||
func DeletePublicKey(id int64) (err error) {
|
||||
key := &PublicKey{ID: id}
|
||||
has, err := x.Id(key.ID).Get(key)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return nil
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sessionRelease(sess)
|
||||
if err = sess.Begin(); err != nil {
|
||||
|
|
|
@ -166,6 +166,13 @@ type Repository struct {
|
|||
Updated time.Time `xorm:"UPDATED"`
|
||||
}
|
||||
|
||||
func (repo *Repository) AfterSet(colName string, _ xorm.Cell) {
|
||||
switch colName {
|
||||
case "updated":
|
||||
repo.Updated = regulateTimeZone(repo.Updated)
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *Repository) getOwner(e Engine) (err error) {
|
||||
if repo.Owner == nil {
|
||||
repo.Owner, err = getUserByID(e, repo.OwnerID)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -275,9 +275,11 @@ func (repo *Repository) searchCommits(id sha1, keyword string) (*list.List, erro
|
|||
return parsePrettyFormatLog(repo, stdout)
|
||||
}
|
||||
|
||||
var CommitsRangeSize = 50
|
||||
|
||||
func (repo *Repository) commitsByRange(id sha1, page int) (*list.List, error) {
|
||||
stdout, stderr, err := com.ExecCmdDirBytes(repo.Path, "git", "log", id.String(),
|
||||
"--skip="+com.ToStr((page-1)*50), "--max-count=50", prettyLogFormat)
|
||||
"--skip="+com.ToStr((page-1)*CommitsRangeSize), "--max-count="+com.ToStr(CommitsRangeSize), prettyLogFormat)
|
||||
if err != nil {
|
||||
return nil, errors.New(string(stderr))
|
||||
}
|
||||
|
|
|
@ -71,6 +71,13 @@ func parseTreeData(tree *Tree, data []byte) ([]*TreeEntry, error) {
|
|||
|
||||
step = bytes.IndexByte(data[pos:], '\n')
|
||||
entry.name = string(data[pos : pos+step])
|
||||
|
||||
// In case entry name is surrounded by double quotes(it happens only in git-shell).
|
||||
if entry.name[0] == '"' {
|
||||
entry.name = string(data[pos+1 : pos+step-1])
|
||||
entry.name = strings.Replace(entry.name, `\"`, `"`, -1)
|
||||
}
|
||||
|
||||
pos += step + 1
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
|
|
@ -17,6 +17,33 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
type loginAuth struct {
|
||||
username, password string
|
||||
}
|
||||
|
||||
// SMTP AUTH LOGIN Auth Handler
|
||||
func LoginAuth(username, password string) smtp.Auth {
|
||||
return &loginAuth{username, password}
|
||||
}
|
||||
|
||||
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
|
||||
return "LOGIN", []byte{}, nil
|
||||
}
|
||||
|
||||
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
|
||||
if more {
|
||||
switch string(fromServer) {
|
||||
case "Username:":
|
||||
return []byte(a.username), nil
|
||||
case "Password:":
|
||||
return []byte(a.password), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknwon fromServer: %s", string(fromServer))
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
To []string
|
||||
From string
|
||||
|
@ -135,6 +162,9 @@ func sendMail(settings *setting.Mailer, recipients []string, msgContent []byte)
|
|||
auth = smtp.CRAMMD5Auth(settings.User, settings.Passwd)
|
||||
} else if strings.Contains(options, "PLAIN") {
|
||||
auth = smtp.PlainAuth("", settings.User, settings.Passwd, host)
|
||||
} else if strings.Contains(options, "LOGIN") {
|
||||
// Patch for AUTH LOGIN
|
||||
auth = LoginAuth(settings.User, settings.Passwd)
|
||||
}
|
||||
|
||||
if auth != nil {
|
||||
|
|
2
public/css/gogs.min.css
vendored
2
public/css/gogs.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -339,6 +339,25 @@ function initRepository() {
|
|||
})
|
||||
}
|
||||
|
||||
// Diff
|
||||
if ($('.repository.diff').length > 0) {
|
||||
$('.diff-detail-box .toggle.button').click(function () {
|
||||
$($(this).data('target')).slideToggle(100);
|
||||
})
|
||||
|
||||
var $counter = $('.diff-counter');
|
||||
if ($counter.length < 1) {
|
||||
return;
|
||||
}
|
||||
$counter.each(function (i, item) {
|
||||
var $item = $(item);
|
||||
var addLine = $item.find('span[data-line].add').data("line");
|
||||
var delLine = $item.find('span[data-line].del').data("line");
|
||||
var addPercent = parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine)) * 100;
|
||||
$item.find(".bar .add").css("width", addPercent + "%");
|
||||
});
|
||||
}
|
||||
|
||||
// Pull request
|
||||
if ($('.repository.compare.pull').length > 0) {
|
||||
var $branch_dropdown = $('.choose.branch .dropdown')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.admin {
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 3;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
|
||||
.table.segment {
|
||||
padding: 0;
|
||||
|
|
|
@ -92,6 +92,13 @@ img {
|
|||
&.small {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
&.truncate {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
|
@ -111,6 +118,19 @@ img {
|
|||
border-color: #F0C36D;
|
||||
}
|
||||
}
|
||||
.info {
|
||||
&.header {
|
||||
background-color: #d9edf7!important;
|
||||
border-color: #85c5e5;
|
||||
}
|
||||
&.segment {
|
||||
border-color: #85c5e5;
|
||||
}
|
||||
}
|
||||
|
||||
.normal.header {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.avatar.image {
|
||||
border-radius: 3px;
|
||||
|
|
|
@ -9,7 +9,11 @@
|
|||
.ui.attached.header {
|
||||
background: #f0f0f0;
|
||||
.right {
|
||||
margin-top: -6px;
|
||||
margin-top: -5px;
|
||||
.button {
|
||||
padding: 8px 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
.repository {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.home {
|
||||
padding-bottom: @footer-margin * 3;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
.logo {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.install {
|
||||
padding-top: 45px;
|
||||
padding-bottom: @footer-margin * 3;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
form {
|
||||
@input-padding: 320px !important;
|
||||
label {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@mega-octicon-width: 30px;
|
||||
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 3;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
|
||||
.head {
|
||||
.column {
|
||||
|
@ -424,6 +424,187 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.commits {
|
||||
.header {
|
||||
.ui.right {
|
||||
.search {
|
||||
input {
|
||||
font-weight: normal;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
.button {
|
||||
float: right;
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.commits.table {
|
||||
font-size: 13px;
|
||||
th, td {
|
||||
&:first-child {
|
||||
padding-left: 15px;
|
||||
}
|
||||
}
|
||||
td {
|
||||
line-height: 15px;
|
||||
}
|
||||
.author {
|
||||
min-width: 180px;
|
||||
}
|
||||
.message span {
|
||||
max-width: 500px;
|
||||
}
|
||||
.date {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
.sha.label {
|
||||
font-family: Consolas, Menlo, Monaco, "Lucida Console", monospace;
|
||||
font-size: 14px;
|
||||
padding: 6px 10px 4px 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.diff-detail-box {
|
||||
margin: 15px 0;
|
||||
line-height: 30px;
|
||||
ol {
|
||||
clear: both;
|
||||
padding-left: 0;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 28px;
|
||||
li {
|
||||
list-style: none;
|
||||
padding-bottom: 4px;
|
||||
margin-bottom: 4px;
|
||||
border-bottom: 1px dashed #DDD;
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
span.status{
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
&.modify {
|
||||
background-color: #f0db88;
|
||||
}
|
||||
&.add {
|
||||
background-color: #b4e2b4;
|
||||
}
|
||||
&.del {
|
||||
background-color: #e9aeae;
|
||||
}
|
||||
&.rename {
|
||||
background-color: #dad8ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
.diff-box {
|
||||
.count {
|
||||
margin-right: 12px;
|
||||
.bar {
|
||||
background-color: #e75316;
|
||||
height: 12px;
|
||||
width: 40px;
|
||||
display: inline-block;
|
||||
margin: 2px 4px 0 4px;
|
||||
vertical-align: text-top;
|
||||
.add {
|
||||
background-color: #77c64a;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.file {
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
.diff-file-box {
|
||||
.header {
|
||||
border-bottom: 1px solid #d4d4d5!important;
|
||||
}
|
||||
.file-body.file-code {
|
||||
.lines-num {
|
||||
text-align: right;
|
||||
color: #999;
|
||||
background: #fafafa;
|
||||
width: 1%;
|
||||
}
|
||||
.lines-num-old {
|
||||
border-right: 1px solid #DDD;
|
||||
}
|
||||
}
|
||||
.code-diff {
|
||||
font-size: 13px;
|
||||
td {
|
||||
padding: 0;
|
||||
border-top: none;
|
||||
}
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
.lines-num {
|
||||
border-right: 1px solid #d4d4d5;
|
||||
padding: 0 5px;
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
&.tag-code {
|
||||
td, pre {
|
||||
background-color: #E0E0E0 !important;
|
||||
border-color: #ADADAD!important;
|
||||
}
|
||||
// td.selected-line, td.selected-line pre {
|
||||
// background-color: #ffffdd !important;
|
||||
// }
|
||||
}
|
||||
// &.same-code {
|
||||
// td.selected-line, td.selected-line pre {
|
||||
// background-color: #ffffdd !important;
|
||||
// }
|
||||
// }
|
||||
&.del-code {
|
||||
td, pre {
|
||||
background-color: #ffe2dd !important;
|
||||
border-color: #e9aeae !important;
|
||||
}
|
||||
// td.selected-line, td.selected-line pre {
|
||||
// background-color: #ffffdd !important;
|
||||
// }
|
||||
}
|
||||
&.add-code {
|
||||
td, pre {
|
||||
background-color: #d1ffd6 !important;
|
||||
border-color: #b4e2b4 !important;
|
||||
}
|
||||
// td.selected-line, td.selected-line pre {
|
||||
// background-color: #ffffdd !important;
|
||||
// }
|
||||
}
|
||||
&:hover {
|
||||
td {
|
||||
background-color: #FFF8D2 !important;
|
||||
border-color: #F0DB88 !important;
|
||||
}
|
||||
pre {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.code-view {
|
||||
overflow: auto;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.ui.comments {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.user {
|
||||
padding-top: 15px;
|
||||
padding-bottom: @footer-margin * 3;
|
||||
padding-bottom: @footer-margin * 2;
|
||||
|
||||
&.settings {
|
||||
.key.list {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"path"
|
||||
|
||||
"github.com/Unknwon/com"
|
||||
"github.com/Unknwon/paginater"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
|
@ -44,7 +45,7 @@ func RenderIssueLinks(oldCommits *list.List, repoLink string) *list.List {
|
|||
}
|
||||
|
||||
func Commits(ctx *middleware.Context) {
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["PageIsCommits"] = true
|
||||
|
||||
userName := ctx.Repo.Owner.Name
|
||||
repoName := ctx.Repo.Repository.Name
|
||||
|
@ -64,19 +65,11 @@ func Commits(ctx *middleware.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Calculate and validate page number.
|
||||
page, _ := com.StrTo(ctx.Query("p")).Int()
|
||||
if page < 1 {
|
||||
page := ctx.QueryInt("page")
|
||||
if page <= 1 {
|
||||
page = 1
|
||||
}
|
||||
lastPage := page - 1
|
||||
if lastPage < 0 {
|
||||
lastPage = 0
|
||||
}
|
||||
nextPage := page + 1
|
||||
if page*50 > commitsCount {
|
||||
nextPage = 0
|
||||
}
|
||||
ctx.Data["Page"] = paginater.New(commitsCount, git.CommitsRangeSize, page, 5)
|
||||
|
||||
// Both `git log branchName` and `git log commitId` work.
|
||||
commits, err := ctx.Repo.Commit.CommitsByRange(page)
|
||||
|
@ -91,14 +84,11 @@ func Commits(ctx *middleware.Context) {
|
|||
ctx.Data["Username"] = userName
|
||||
ctx.Data["Reponame"] = repoName
|
||||
ctx.Data["CommitCount"] = commitsCount
|
||||
ctx.Data["LastPageNum"] = lastPage
|
||||
ctx.Data["NextPageNum"] = nextPage
|
||||
ctx.HTML(200, COMMITS)
|
||||
}
|
||||
|
||||
func SearchCommits(ctx *middleware.Context) {
|
||||
ctx.Data["IsSearchPage"] = true
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["PageIsCommits"] = true
|
||||
|
||||
keyword := ctx.Query("q")
|
||||
if len(keyword) == 0 {
|
||||
|
@ -199,7 +189,7 @@ func FileHistory(ctx *middleware.Context) {
|
|||
}
|
||||
|
||||
func Diff(ctx *middleware.Context) {
|
||||
ctx.Data["IsRepoToolbarCommits"] = true
|
||||
ctx.Data["PageIsDiff"] = true
|
||||
|
||||
userName := ctx.Repo.Owner.Name
|
||||
repoName := ctx.Repo.Repository.Name
|
||||
|
@ -253,7 +243,7 @@ func Diff(ctx *middleware.Context) {
|
|||
ctx.Data["Parents"] = parents
|
||||
ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
|
||||
ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitId)
|
||||
if (commit.ParentCount() > 0) {
|
||||
if commit.ParentCount() > 0 {
|
||||
ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", parents[0])
|
||||
}
|
||||
ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitId)
|
||||
|
|
|
@ -677,6 +677,13 @@ func SettingsDeployKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
|||
ctx.Data["Title"] = ctx.Tr("repo.settings")
|
||||
ctx.Data["PageIsSettingsKeys"] = true
|
||||
|
||||
keys, err := models.ListDeployKeys(ctx.Repo.Repository.ID)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ListDeployKeys", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Deploykeys"] = keys
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, DEPLOY_KEYS)
|
||||
return
|
||||
|
|
|
@ -269,12 +269,12 @@ func SettingsSSHKeys(ctx *middleware.Context) {
|
|||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSSHKeys"] = true
|
||||
|
||||
var err error
|
||||
ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
|
||||
keys, err := models.ListPublicKeys(ctx.User.Id)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ssh.ListPublicKey", err)
|
||||
ctx.Handle(500, "ListPublicKeys", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Keys"] = keys
|
||||
|
||||
ctx.HTML(200, SETTINGS_SSH_KEYS)
|
||||
}
|
||||
|
@ -283,66 +283,58 @@ func SettingsSSHKeysPost(ctx *middleware.Context, form auth.AddSSHKeyForm) {
|
|||
ctx.Data["Title"] = ctx.Tr("settings")
|
||||
ctx.Data["PageIsSettingsSSHKeys"] = true
|
||||
|
||||
var err error
|
||||
ctx.Data["Keys"], err = models.ListPublicKeys(ctx.User.Id)
|
||||
keys, err := models.ListPublicKeys(ctx.User.Id)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ssh.ListPublicKey", err)
|
||||
ctx.Handle(500, "ListPublicKeys", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Keys"] = keys
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, SETTINGS_SSH_KEYS)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete SSH key.
|
||||
if ctx.Query("_method") == "DELETE" {
|
||||
id := com.StrTo(ctx.Query("id")).MustInt64()
|
||||
if id <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if err = models.DeletePublicKey(&models.PublicKey{ID: id}); err != nil {
|
||||
ctx.Handle(500, "DeletePublicKey", err)
|
||||
content, err := models.CheckPublicKeyString(form.Content)
|
||||
if err != nil {
|
||||
if err == models.ErrKeyUnableVerify {
|
||||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
|
||||
} else {
|
||||
log.Trace("SSH key deleted: %s", ctx.User.Name)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Add new SSH key.
|
||||
if ctx.Req.Method == "POST" {
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, SETTINGS_SSH_KEYS)
|
||||
return
|
||||
}
|
||||
|
||||
content, err := models.CheckPublicKeyString(form.Content)
|
||||
if err != nil {
|
||||
if err == models.ErrKeyUnableVerify {
|
||||
ctx.Flash.Info(ctx.Tr("form.unable_verify_ssh_key"))
|
||||
} else {
|
||||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = models.AddPublicKey(ctx.User.Id, form.Title, content); err != nil {
|
||||
switch {
|
||||
case models.IsErrKeyAlreadyExist(err):
|
||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
|
||||
case models.IsErrKeyNameAlreadyUsed(err):
|
||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &form)
|
||||
default:
|
||||
ctx.Handle(500, "AddPublicKey", err)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
log.Trace("SSH key added: %s", ctx.User.Name)
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
|
||||
ctx.Flash.Error(ctx.Tr("form.invalid_ssh_key", err.Error()))
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.HTML(200, SETTINGS_SSH_KEYS)
|
||||
if err = models.AddPublicKey(ctx.User.Id, form.Title, content); err != nil {
|
||||
ctx.Data["HasError"] = true
|
||||
switch {
|
||||
case models.IsErrKeyAlreadyExist(err):
|
||||
ctx.Data["Err_Content"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_been_used"), SETTINGS_SSH_KEYS, &form)
|
||||
case models.IsErrKeyNameAlreadyUsed(err):
|
||||
ctx.Data["Err_Title"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("settings.ssh_key_name_used"), SETTINGS_SSH_KEYS, &form)
|
||||
default:
|
||||
ctx.Handle(500, "AddPublicKey", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("settings.add_key_success", form.Title))
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/settings/ssh")
|
||||
}
|
||||
|
||||
func DeleteSSHKey(ctx *middleware.Context) {
|
||||
if err := models.DeletePublicKey(ctx.QueryInt64("id")); err != nil {
|
||||
ctx.Flash.Error("DeletePublicKey: " + err.Error())
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("settings.ssh_key_deletion_success"))
|
||||
}
|
||||
|
||||
ctx.JSON(200, map[string]interface{}{
|
||||
"redirect": setting.AppSubUrl + "/user/settings/ssh",
|
||||
})
|
||||
}
|
||||
|
||||
func SettingsSocial(ctx *middleware.Context) {
|
||||
|
@ -389,6 +381,12 @@ func SettingsApplicationsPost(ctx *middleware.Context, form auth.NewAccessTokenF
|
|||
ctx.Data["PageIsSettingsApplications"] = true
|
||||
|
||||
if ctx.HasError() {
|
||||
tokens, err := models.ListAccessTokens(ctx.User.Id)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "ListAccessTokens", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["Tokens"] = tokens
|
||||
ctx.HTML(200, SETTINGS_APPLICATIONS)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="repo-wrapper">
|
||||
{{template "repo/header_old" .}}
|
||||
<div class="container clear">
|
||||
{{template "repo/commits_table" .}}
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="repository commits">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{template "repo/commits_table" .}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
@ -1,48 +1,68 @@
|
|||
<div id="commits-list">
|
||||
<div class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
{{if not .IsDiffCompare}}
|
||||
<form class="search pull-right" action="{{.RepoLink}}/commits/{{.BranchName}}/search" method="get" id="commits-search-form">
|
||||
<input class="ipt ipt-radius" type="search" name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" />
|
||||
<button class="btn btn-black btn-small btn-radius">{{.i18n.Tr "repo.commits.find"}}</button>
|
||||
</form>
|
||||
{{end}}
|
||||
<h4>{{.CommitCount}} {{.i18n.Tr "repo.commits.commits"}}</h4>
|
||||
</div>
|
||||
<table class="panel-body table commit-list table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="author">{{.i18n.Tr "repo.commits.author"}}</th>
|
||||
<th class="sha">SHA1</th>
|
||||
<th class="message">{{.i18n.Tr "repo.commits.message"}}</th>
|
||||
<th class="date">{{.i18n.Tr "repo.commits.date"}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ $username := .Username}}
|
||||
{{ $reponame := .Reponame}}
|
||||
{{$r := List .Commits}}
|
||||
{{range $r}}
|
||||
<tr>
|
||||
<td class="author">
|
||||
{{if .User}}
|
||||
<img class="avatar-20" src="{{.User.AvatarLink}}" alt=""/> <a href="{{AppSubUrl}}/{{.User.Name}}">{{.Author.Name}}</a>
|
||||
{{else}}
|
||||
<img class="avatar-20" src="{{AvatarLink .Author.Email}}" alt=""/> {{.Author.Name}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="sha"><a rel="nofollow" class="label label-green" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td>
|
||||
<td class="message"><span class="text-truncate">{{RenderCommitMessage .Summary $.RepoLink}}</span></td>
|
||||
<td class="date">{{TimeSince .Author.When $.Lang}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{if and (not .IsSearchPage) (not .IsDiffCompare)}}
|
||||
<ul class="pagination">
|
||||
{{if .LastPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.LastPageNum}}" rel="nofollow">« {{.i18n.Tr "repo.commits.newer"}}</a></li>{{end}}
|
||||
{{if .NextPageNum}}<li><a class="btn btn-medium btn-gray btn-radius" href="{{.RepoLink}}/commits/{{.BranchName}}{{if .FileName}}/{{.FileName}}{{end}}?p={{.NextPageNum}}" rel="nofollow">» {{.i18n.Tr "repo.commits.older"}}</a></li>{{end}}
|
||||
</ul>
|
||||
<h4 class="ui top attached header">
|
||||
{{.CommitCount}} {{.i18n.Tr "repo.commits.commits"}}
|
||||
{{if .PageIsCommits}}
|
||||
<div class="ui right">
|
||||
<form action="{{.RepoLink}}/commits/{{.BranchName}}/search">
|
||||
<div class="ui tiny search input">
|
||||
<input name="q" placeholder="{{.i18n.Tr "repo.commits.search"}}" value="{{.Keyword}}" autofocus>
|
||||
</div>
|
||||
<button class="ui black tiny button" data-panel="#add-deploy-key-panel">{{.i18n.Tr "repo.commits.find"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
{{else if .IsDiffCompare}}
|
||||
<a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="ui green sha label">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="ui green sha label">{{ShortSha .AfterCommitId}}</a>
|
||||
{{end}}
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
<table class="ui very basic striped commits table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{.i18n.Tr "repo.commits.author"}}</th>
|
||||
<th>SHA1</th>
|
||||
<th>{{.i18n.Tr "repo.commits.message"}}</th>
|
||||
<th>{{.i18n.Tr "repo.commits.date"}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ $username := .Username}}
|
||||
{{ $reponame := .Reponame}}
|
||||
{{ $r:= List .Commits}}
|
||||
{{range $r}}
|
||||
<tr>
|
||||
<td class="author">
|
||||
{{if .User}}
|
||||
<img class="ui avatar image" src="{{.User.AvatarLink}}" alt=""/> <a href="{{AppSubUrl}}/{{.User.Name}}">{{.Author.Name}}</a>
|
||||
{{else}}
|
||||
<img class="ui avatar image" src="{{AvatarLink .Author.Email}}" alt=""/> {{.Author.Name}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td class="sha"><a rel="nofollow" class="ui green sha label" href="{{AppSubUrl}}/{{$username}}/{{$reponame}}/commit/{{.Id}} ">{{SubStr .Id.String 0 10}} </a></td>
|
||||
<td class="message"><span class="text truncate">{{RenderCommitMessage .Summary $.RepoLink}}</span></td>
|
||||
<td class="date">{{TimeSince .Author.When $.Lang}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{with .Page}}
|
||||
{{if gt .TotalPages 1}}
|
||||
<div class="center page buttons">
|
||||
<div class="ui borderless pagination menu">
|
||||
<a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.RepoLink}}/commits/{{$.BranchName}}{{if $.FileName}}/{{$.FileName}}{{end}}?page={{.Previous}}"{{end}}>
|
||||
<i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
|
||||
</a>
|
||||
{{range .Pages}}
|
||||
{{if eq .Num -1}}
|
||||
<a class="disabled item">...</a>
|
||||
{{else}}
|
||||
<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.RepoLink}}/commits/{{$.BranchName}}{{if $.FileName}}/{{$.FileName}}{{end}}?page={{.Num}}"{{end}}>{{.Num}}</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.RepoLink}}/commits/{{$.BranchName}}{{if $.FileName}}/{{$.FileName}}{{end}}?page={{.Next}}"{{end}}>
|
||||
{{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
|
@ -1,134 +1,136 @@
|
|||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="repo-wrapper">
|
||||
{{template "repo/header_old" .}}
|
||||
<div class="container clear" id="diff-page">
|
||||
{{if .IsDiffCompare }}
|
||||
<div class="panel panel-info panel-radius compare-head-box">
|
||||
<div class="panel-header">
|
||||
<a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{EscapePound .SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a>
|
||||
<h4><a href="{{$.RepoLink}}/commit/{{.BeforeCommitId}}" class="label label-green">{{ShortSha .BeforeCommitId}}</a> ... <a href="{{$.RepoLink}}/commit/{{.AfterCommitId}}" class="label label-green">{{ShortSha .AfterCommitId}}</a></h4>
|
||||
</div>
|
||||
<div class="panel-body compare">
|
||||
{{template "repo/commits_table" .}}
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="repository diff">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container">
|
||||
{{if .IsDiffCompare }}
|
||||
{{template "repo/commits_table" .}}
|
||||
{{else}}
|
||||
<h4 class="ui top attached info header">
|
||||
{{RenderCommitMessage .Commit.Message $.RepoLink}}
|
||||
<div class="ui right">
|
||||
<a class="ui blue tiny button" href="{{EscapePound .SourcePath}}">
|
||||
{{.i18n.Tr "repo.diff.browse_source"}}
|
||||
</a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached info segment">
|
||||
{{if .Author}}
|
||||
<img class="ui avatar image" src="{{.Author.AvatarLink}}" />
|
||||
<a href="{{.Author.HomeLink}}"><strong>{{.Commit.Author.Name}}</strong></a>
|
||||
{{else}}
|
||||
<img class="ui avatar image" src="{{AvatarLink .Commit.Author.Email}}" />
|
||||
<strong>{{.Commit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
<span class="text grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span>
|
||||
<div class="ui right">
|
||||
<div class="ui horizontal list">
|
||||
<div class="item">
|
||||
{{.i18n.Tr "repo.diff.parent"}}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{range .Parents}}
|
||||
<a class="ui blue sha label" href="{{$.RepoLink}}/commit/{{.}}">{{ShortSha .}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="item">{{.i18n.Tr "repo.diff.commit"}}</div>
|
||||
<div class="item"><span class="ui blue sha label">{{ShortSha .CommitId}}</span></div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="panel panel-info panel-radius diff-head-box">
|
||||
<div class="panel-header">
|
||||
<a class="pull-right btn btn-blue btn-header btn-medium btn-radius" rel="nofollow" href="{{EscapePound .SourcePath}}">{{.i18n.Tr "repo.diff.browse_source"}}</a>
|
||||
<h4 class="commit-message">{{RenderCommitMessage .Commit.Message $.RepoLink}}</h4>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<span class="pull-right">
|
||||
<ul class="list-unstyled">
|
||||
<li class="inline">{{.i18n.Tr "repo.diff.parent"}}</li>
|
||||
{{range .Parents}}
|
||||
<li class="inline"><a href="{{$.RepoLink}}/commit/{{.}}"><span class="label label-blue">{{ShortSha .}}</span></a></li>
|
||||
{{end}}
|
||||
<li class="inline">{{.i18n.Tr "repo.diff.commit"}} <span class="label label-blue">{{ShortSha .CommitId}}</span></li>
|
||||
</ul>
|
||||
</span>
|
||||
<p class="author">
|
||||
{{if .Author}}
|
||||
<img class="avatar-30" src="{{.Author.AvatarLink}}" />
|
||||
<a href="{{AppSubUrl}}/{{.Author.Name}}"><strong>{{.Commit.Author.Name}}</strong></a>
|
||||
{{else}}
|
||||
<img class="avatar-30" src="{{AvatarLink .Commit.Author.Email}}" />
|
||||
<strong>{{.Commit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
<span class="text-grey" id="authored-time">{{TimeSince .Commit.Author.When $.Lang}}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .DiffNotAvailable}}
|
||||
<h4>{{.i18n.Tr "repo.diff.data_not_available"}}</h4>
|
||||
{{else}}
|
||||
<div class="diff-detail-box diff-box">
|
||||
<a class="pull-right btn btn-gray btn-header btn-radius text-black" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a>
|
||||
<p class="showing">
|
||||
<i class="fa fa-retweet"></i>
|
||||
{{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
|
||||
</p>
|
||||
<ol class="detail-files collapse hide" id="diff-files">
|
||||
{{range .Diff.Files}}
|
||||
<li>
|
||||
<div class="diff-counter count pull-right">
|
||||
{{if not .IsBin}}
|
||||
<span class="add" data-line="{{.Addition}}">{{.Addition}}</span>
|
||||
<span class="bar">
|
||||
<span class="pull-left add"></span>
|
||||
<span class="pull-left del"></span>
|
||||
</span>
|
||||
<span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span>
|
||||
{{else}}
|
||||
<span>{{$.i18n.Tr "repo.diff.bin"}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
<!-- todo finish all file status, now modify, add, delete and rename -->
|
||||
<span class="status {{DiffTypeToStr .Type}}" data-toggle="tooltip" data-placement="right" title="{{DiffTypeToStr .Type}}"> </span>
|
||||
<a class="file" href="#diff-{{.Index}}">{{.Name}}</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{range $i, $file := .Diff.Files}}
|
||||
<div class="panel panel-radius diff-file-box diff-box file-content" id="diff-{{.Index}}">
|
||||
<div class="panel-header">
|
||||
<div class="diff-counter count pull-left">
|
||||
{{if not $file.IsBin}}
|
||||
<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
|
||||
<span class="bar">
|
||||
<span class="pull-left add"></span>
|
||||
<span class="pull-left del"></span>
|
||||
</span>
|
||||
<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.diff.bin"}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{if $file.IsDeleted}}
|
||||
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
|
||||
{{else}}
|
||||
<a class="btn btn-gray btn-header btn-radius text-black pull-right" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
|
||||
{{end}}
|
||||
<span class="file">{{$file.Name}}</span>
|
||||
</div>
|
||||
{{$isImage := (call $.IsImageFile $file.Name)}}
|
||||
<div class="panel-body file-body file-code code-view code-diff">
|
||||
{{if $isImage}}
|
||||
<div class="text-center">
|
||||
<img src="{{$.RawPath}}/{{EscapePound .Name}}">
|
||||
</div>
|
||||
{{else}}
|
||||
<table>
|
||||
<tbody>
|
||||
{{range .Sections}}
|
||||
{{range $k, $line := .Lines}}
|
||||
<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
|
||||
<td class="lines-num lines-num-old">
|
||||
<span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span>
|
||||
</td>
|
||||
<td class="lines-num lines-num-new">
|
||||
<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span>
|
||||
</td>
|
||||
|
||||
<td class="lines-code">
|
||||
<pre>{{$line.Content}}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if .DiffNotAvailable}}
|
||||
<h4>{{.i18n.Tr "repo.diff.data_not_available"}}</h4>
|
||||
{{else}}
|
||||
<div class="diff-detail-box diff-box">
|
||||
<div>
|
||||
<i class="fa fa-retweet"></i>
|
||||
{{.i18n.Tr "repo.diff.stats_desc" .Diff.NumFiles .Diff.TotalAddition .Diff.TotalDeletion | Str2html}}
|
||||
<div class="ui right">
|
||||
<a class="ui tiny basic black toggle button" data-target="#diff-files">{{.i18n.Tr "repo.diff.show_diff_stats"}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="detail-files hide" id="diff-files">
|
||||
{{range .Diff.Files}}
|
||||
<li>
|
||||
<div class="diff-counter count pull-right">
|
||||
{{if not .IsBin}}
|
||||
<span class="add" data-line="{{.Addition}}">{{.Addition}}</span>
|
||||
<span class="bar">
|
||||
<span class="pull-left add"></span>
|
||||
<span class="pull-left del"></span>
|
||||
</span>
|
||||
<span class="del" data-line="{{.Deletion}}">{{.Deletion}}</span>
|
||||
{{else}}
|
||||
<span>{{$.i18n.Tr "repo.diff.bin"}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
<!-- todo finish all file status, now modify, add, delete and rename -->
|
||||
<span class="status {{DiffTypeToStr .Type}} poping up" data-content="{{DiffTypeToStr .Type}}" data-variation="inverted tiny" data-position="right center"> </span>
|
||||
<a class="file" href="#diff-{{.Index}}">{{.Name}}</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{{range $i, $file := .Diff.Files}}
|
||||
<div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
|
||||
<h4 class="ui top attached normal header">
|
||||
<div class="diff-counter count ui left">
|
||||
{{if not $file.IsBin}}
|
||||
<span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
|
||||
<span class="bar">
|
||||
<span class="pull-left add"></span>
|
||||
<span class="pull-left del"></span>
|
||||
</span>
|
||||
<span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
|
||||
{{else}}
|
||||
{{$.i18n.Tr "repo.diff.bin"}}
|
||||
{{end}}
|
||||
</div>
|
||||
<span class="file">{{$file.Name}}</span>
|
||||
<div class="ui right">
|
||||
{{if $file.IsDeleted}}
|
||||
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
|
||||
{{else}}
|
||||
<a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.SourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached table segment">
|
||||
{{$isImage := (call $.IsImageFile $file.Name)}}
|
||||
{{if $isImage}}
|
||||
<div class="center">
|
||||
<img src="{{$.RawPath}}/{{EscapePound .Name}}">
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="file-body file-code code-view code-diff">
|
||||
<table>
|
||||
<tbody>
|
||||
{{range .Sections}}
|
||||
{{range $k, $line := .Lines}}
|
||||
<tr class="{{DiffLineTypeToStr .Type}}-code nl-{{$k}} ol-{{$k}}">
|
||||
<td class="lines-num lines-num-old">
|
||||
<span rel="{{if $line.LeftIdx}}diff-{{Sha1 $file.Name}}L{{$line.LeftIdx}}{{end}}">{{if $line.LeftIdx}}{{$line.LeftIdx}}{{end}}</span>
|
||||
</td>
|
||||
<td class="lines-num lines-num-new">
|
||||
<span rel="{{if $line.RightIdx}}diff-{{Sha1 $file.Name}}R{{$line.RightIdx}}{{end}}">{{if $line.RightIdx}}{{$line.RightIdx}}{{end}}</span>
|
||||
</td>
|
||||
<td class="lines-code">
|
||||
<pre>{{$line.Content}}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
{{template "base/footer" .}}
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
</div>
|
||||
{{end}}
|
||||
{{if or $.IsRepositoryAdmin (eq .Poster.Id $.SignedUserID)}}
|
||||
<a class="edit-content item" href="#" data-type="comment"><i class="octicon octicon-pencil"></i></a>
|
||||
<a class="edit-content item" href="#"><i class="octicon octicon-pencil"></i></a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -53,12 +53,12 @@
|
|||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label>{{.i18n.Tr "repo.settings.title"}}</label>
|
||||
<input name="title" value="{{.title}}" autofocus required>
|
||||
<label for="title">{{.i18n.Tr "repo.settings.title"}}</label>
|
||||
<input id="title" name="title" value="{{.title}}" autofocus required>
|
||||
</div>
|
||||
<div class="field {{if .Err_Content}}error{{end}}">
|
||||
<label>{{.i18n.Tr "repo.settings.deploy_key_content"}}</label>
|
||||
<textarea name="content" required>{{.content}}</textarea>
|
||||
<label for="content">{{.i18n.Tr "repo.settings.deploy_key_content"}}</label>
|
||||
<textarea id="content" name="content" required>{{.content}}</textarea>
|
||||
</div>
|
||||
<button class="ui green button">
|
||||
{{.i18n.Tr "repo.settings.add_deploy_key"}}
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
<li {{if .PageIsSettingsPassword}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/password">{{.i18n.Tr "settings.password"}}</a></li>
|
||||
<li {{if .PageIsSettingsEmails}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/email">{{.i18n.Tr "settings.emails"}}</a></li>
|
||||
<li {{if .PageIsSettingsSSHKeys}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/ssh">{{.i18n.Tr "settings.ssh_keys"}}</a></li>
|
||||
{{if .HasOAuthService}}
|
||||
<li {{if .PageIsSettingsSocial}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/social">{{.i18n.Tr "settings.social"}}</a></li>
|
||||
{{end}}
|
||||
<li {{if .PageIsSettingsApplications}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/applications">{{.i18n.Tr "settings.applications"}}</a></li>
|
||||
<li {{if .PageIsSettingsDelete}}class="current"{{end}}><a href="{{AppSubUrl}}/user/settings/delete">{{.i18n.Tr "settings.delete"}}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -1,63 +1,92 @@
|
|||
{{template "ng/base/head" .}}
|
||||
{{template "ng/base/header" .}}
|
||||
<div id="setting-wrapper" class="main-wrapper">
|
||||
<div id="user-profile-setting" class="container clear">
|
||||
{{template "user/settings/nav" .}}
|
||||
<div class="grid-4-5 left">
|
||||
<div class="setting-content">
|
||||
{{template "ng/base/alert" .}}
|
||||
<div id="user-ssh-setting-content">
|
||||
<div id="user-ssh-panel" class="panel panel-radius">
|
||||
<div class="panel-header">
|
||||
<a class="show-form-btn" data-target-form="#user-ssh-add-form">
|
||||
<button class="btn btn-medium btn-black btn-radius right">{{.i18n.Tr "settings.add_key"}}</button>
|
||||
</a>
|
||||
<strong>{{.i18n.Tr "settings.manage_ssh_keys"}}</strong>
|
||||
</div>
|
||||
<ul class="panel-body setting-list">
|
||||
<li>{{.i18n.Tr "settings.ssh_desc"}}</li>
|
||||
{{range .Keys}}
|
||||
<li class="ssh clear">
|
||||
<span class="active-icon left label label-{{if .HasRecentActivity}}green{{else}}gray{{end}} label-radius"></span>
|
||||
<i class="mega-octicon octicon-key left"></i>
|
||||
<div class="ssh-content left">
|
||||
<p><strong>{{.Name}}</strong></p>
|
||||
<p class="print">{{.Fingerprint}}</p>
|
||||
<p class="activity"><i>{{$.i18n.Tr "settings.add_on"}} <span title="{{DateFmtLong .Created}}">{{DateFmtShort .Created}}</span> — <i class="octicon octicon-info"></i>{{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span title="{{DateFmtLong .Updated}}">{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i></p>
|
||||
</div>
|
||||
<form action="{{AppSubUrl}}/user/settings/ssh" method="post">
|
||||
{{$.CsrfTokenHtml}}
|
||||
<input name="_method" type="hidden" value="DELETE">
|
||||
<input name="id" type="hidden" value="{{.ID}}">
|
||||
<button class="right ssh-btn btn btn-red btn-radius btn-small">{{$.i18n.Tr "settings.delete_key"}}</button>
|
||||
</form>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
<p>{{.i18n.Tr "settings.ssh_helper" "https://help.github.com/articles/generating-ssh-keys" "https://help.github.com/ssh-issues/" | Str2html}}</p>
|
||||
<br>
|
||||
<form class="panel panel-radius form form-align form-settings-add hide" id="user-ssh-add-form" action="{{AppSubUrl}}/user/settings/ssh" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<p class="panel-header"><strong>{{.i18n.Tr "settings.add_new_key"}}</strong></p>
|
||||
<div class="panel-body">
|
||||
<p class="field">
|
||||
<label class="req" for="ssh-title">{{.i18n.Tr "settings.key_name"}}</label>
|
||||
<input class="ipt ipt-radius" id="ssh-title" name="title" type="text" required />
|
||||
</p>
|
||||
<p class="field clear">
|
||||
<label class="left req" for="ssh-key">{{.i18n.Tr "settings.key_content"}}</label>
|
||||
<textarea class="ipt ipt-radius left" name="content" id="ssh-key" required></textarea>
|
||||
</p>
|
||||
<p class="field">
|
||||
<label></label>
|
||||
<button class="btn btn-green btn-radius" id="ssh-add-btn">{{.i18n.Tr "settings.add_key"}}</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{template "base/head" .}}
|
||||
<div class="user settings">
|
||||
<div class="ui container">
|
||||
<div class="ui grid">
|
||||
{{template "user/settings/navbar" .}}
|
||||
<div class="twelve wide column content">
|
||||
{{template "base/alert" .}}
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "settings.manage_ssh_keys"}}
|
||||
<div class="ui right">
|
||||
<div class="ui blue tiny show-panel button" data-panel="#add-ssh-key-panel">{{.i18n.Tr "settings.add_key"}}</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<div class="ui key list">
|
||||
<div class="item">
|
||||
{{.i18n.Tr "settings.ssh_desc"}}
|
||||
</div>
|
||||
{{range .Keys}}
|
||||
<div class="item ui grid">
|
||||
<div class="one wide column">
|
||||
<i class="ssh-key-state-indicator fa fa-circle{{if .HasRecentActivity}} active invert poping up{{else}}-o{{end}}" {{if .HasRecentActivity}}data-content="{{$.i18n.Tr "settings.key_state_desc"}}" data-variation="inverted"{{end}}></i>
|
||||
</div>
|
||||
<div class="one wide column">
|
||||
<i class="mega-octicon octicon-key left"></i>
|
||||
</div>
|
||||
<div class="eleven wide column">
|
||||
<strong>{{.Name}}</strong>
|
||||
<div class="print meta">
|
||||
{{.Fingerprint}}
|
||||
</div>
|
||||
<div class="activity meta">
|
||||
<i>{{$.i18n.Tr "settings.add_on"}} <span>{{DateFmtShort .Created}}</span> — <i class="octicon octicon-info"></i> {{if .HasUsed}}{{$.i18n.Tr "settings.last_used"}} <span>{{DateFmtShort .Updated}}</span>{{else}}{{$.i18n.Tr "settings.no_activity"}}{{end}}</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two wide column">
|
||||
<button class="ui red tiny button delete-button" data-url="{{$.Link}}/delete" data-id="{{.ID}}">
|
||||
{{$.i18n.Tr "settings.delete_key"}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<p>{{.i18n.Tr "settings.ssh_helper" "https://help.github.com/articles/generating-ssh-keys" "https://help.github.com/ssh-issues/" | Str2html}}</p>
|
||||
<div {{if not .HasError}}class="hide"{{end}} id="add-ssh-key-panel">
|
||||
<h4 class="ui top attached header">
|
||||
{{.i18n.Tr "settings.add_new_key"}}
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
<form class="ui form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
<div class="field {{if .Err_Title}}error{{end}}">
|
||||
<label for="title">{{.i18n.Tr "settings.key_name"}}</label>
|
||||
<input id="title" name="title" value="{{.title}}" autofocus required>
|
||||
</div>
|
||||
<div class="field {{if .Err_Content}}error{{end}}">
|
||||
<label for="content">{{.i18n.Tr "settings.key_content"}}</label>
|
||||
<textarea id="content" name="content" required>{{.content}}</textarea>
|
||||
</div>
|
||||
<button class="ui green button">
|
||||
{{.i18n.Tr "settings.add_key"}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "ng/base/footer" .}}
|
||||
|
||||
<div class="ui small basic delete modal">
|
||||
<div class="ui icon header">
|
||||
<i class="trash icon"></i>
|
||||
{{.i18n.Tr "settings.ssh_key_deletion"}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>{{.i18n.Tr "settings.ssh_key_deletion_desc"}}</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui red basic inverted cancel button">
|
||||
<i class="remove icon"></i>
|
||||
{{.i18n.Tr "modal.no"}}
|
||||
</div>
|
||||
<div class="ui green basic inverted ok button">
|
||||
<i class="checkmark icon"></i>
|
||||
{{.i18n.Tr "modal.yes"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
Loading…
Reference in a new issue