| @@ -1,102 +1,114 @@ | |||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||
| <style> | <style> | ||||
| .repository.file.list #repo-desc { | |||||
| font-size: 1.0em; | |||||
| margin-bottom: 1.0rem; | |||||
| } | |||||
| #contributorInfo > a:nth-child(n+26){ | |||||
| display:none; | |||||
| } | |||||
| #contributorInfo > a{ | |||||
| width: 2.0em; | |||||
| float: left; | |||||
| margin: .25em; | |||||
| } | |||||
| .edit-link{ | |||||
| vertical-align: top; | |||||
| display: inline-block; | |||||
| overflow: hidden; | |||||
| word-break: keep-all; | |||||
| white-space: nowrap; | |||||
| text-overflow: ellipsis; | |||||
| width: 16.5em; | |||||
| } | |||||
| #contributorInfo > a.circular{ | |||||
| height: 2.0em; | |||||
| padding: 0; | |||||
| overflow: hidden; | |||||
| letter-spacing:1.0em; | |||||
| text-indent: 0.6em; | |||||
| line-height: 2.0em; | |||||
| text-transform:capitalize; | |||||
| color: #FFF; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+1){ | |||||
| background-color: #4ccdec; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+2){ | |||||
| background-color: #e0b265; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+3){ | |||||
| background-color: #d884b7; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+4){ | |||||
| background-color: #8c6bdc; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+5){ | |||||
| background-color: #3cb99f; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+6){ | |||||
| background-color: #6995b9; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+7){ | |||||
| background-color: #ab91a7; | |||||
| } | |||||
| #contributorInfo > a.circular:nth-child(9n+8){ | |||||
| background-color: #bfd0aa; | |||||
| } | |||||
| .vue_menu { | |||||
| cursor: auto; | |||||
| position: absolute; | |||||
| outline: none; | |||||
| top: 100%; | |||||
| margin: 0em; | |||||
| padding: 0em 0em; | |||||
| background: #fff; | |||||
| font-size: 1em; | |||||
| text-shadow: none; | |||||
| text-align: left; | |||||
| /* -webkit-box-shadow: 0px 2px 3px 0px rgb(34 36 38 / 15%); */ | |||||
| box-shadow: 0px 2px 3px 0px rgba(34, 36, 38, 0.15); | |||||
| border: 1px solid rgba(34,36,38,0.15); | |||||
| border-radius: 0.28571429rem; | |||||
| -webkit-transition: opacity 0.1s ease; | |||||
| transition: opacity 0.1s ease; | |||||
| z-index: 11; | |||||
| will-change: transform, opacity; | |||||
| width: 100% !important; | |||||
| -webkit-animation-iteration-count: 1; | |||||
| animation-iteration-count: 1; | |||||
| -webkit-animation-duration: 300ms; | |||||
| animation-duration: 300ms; | |||||
| -webkit-animation-timing-function: ease; | |||||
| animation-timing-function: ease; | |||||
| -webkit-animation-fill-mode: both; | |||||
| animation-fill-mode: both; | |||||
| } | |||||
| .repository.file.list #repo-desc { | |||||
| font-size: 1.0em; | |||||
| margin-bottom: 1.0rem; | |||||
| } | |||||
| #contributorInfo>a:nth-child(n+26) { | |||||
| display: none; | |||||
| } | |||||
| #contributorInfo>a { | |||||
| width: 2.0em; | |||||
| float: left; | |||||
| margin: .25em; | |||||
| } | |||||
| .edit-link { | |||||
| vertical-align: top; | |||||
| display: inline-block; | |||||
| overflow: hidden; | |||||
| word-break: keep-all; | |||||
| white-space: nowrap; | |||||
| text-overflow: ellipsis; | |||||
| width: 16.5em; | |||||
| } | |||||
| #contributorInfo>a.circular { | |||||
| height: 2.0em; | |||||
| padding: 0; | |||||
| overflow: hidden; | |||||
| letter-spacing: 1.0em; | |||||
| text-indent: 0.6em; | |||||
| line-height: 2.0em; | |||||
| text-transform: capitalize; | |||||
| color: #FFF; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+1) { | |||||
| background-color: #4ccdec; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+2) { | |||||
| background-color: #e0b265; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+3) { | |||||
| background-color: #d884b7; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+4) { | |||||
| background-color: #8c6bdc; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+5) { | |||||
| background-color: #3cb99f; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+6) { | |||||
| background-color: #6995b9; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+7) { | |||||
| background-color: #ab91a7; | |||||
| } | |||||
| #contributorInfo>a.circular:nth-child(9n+8) { | |||||
| background-color: #bfd0aa; | |||||
| } | |||||
| .vue_menu { | |||||
| cursor: auto; | |||||
| position: absolute; | |||||
| outline: none; | |||||
| top: 100%; | |||||
| margin: 0em; | |||||
| padding: 0em 0em; | |||||
| background: #fff; | |||||
| font-size: 1em; | |||||
| text-shadow: none; | |||||
| text-align: left; | |||||
| /* -webkit-box-shadow: 0px 2px 3px 0px rgb(34 36 38 / 15%); */ | |||||
| box-shadow: 0px 2px 3px 0px rgba(34, 36, 38, 0.15); | |||||
| border: 1px solid rgba(34, 36, 38, 0.15); | |||||
| border-radius: 0.28571429rem; | |||||
| -webkit-transition: opacity 0.1s ease; | |||||
| transition: opacity 0.1s ease; | |||||
| z-index: 11; | |||||
| will-change: transform, opacity; | |||||
| width: 100% !important; | |||||
| -webkit-animation-iteration-count: 1; | |||||
| animation-iteration-count: 1; | |||||
| -webkit-animation-duration: 300ms; | |||||
| animation-duration: 300ms; | |||||
| -webkit-animation-timing-function: ease; | |||||
| animation-timing-function: ease; | |||||
| -webkit-animation-fill-mode: both; | |||||
| animation-fill-mode: both; | |||||
| } | |||||
| </style> | </style> | ||||
| <div class="repository file list"> | <div class="repository file list"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| <div class="ui negative message" style="display: none;"> | |||||
| </div> | |||||
| {{template "base/alert" .}} | {{template "base/alert" .}} | ||||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} | {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} | ||||
| <!-- <div class="ui repo-topic-edit grid form segment error" id="topic_edit" style="display:none"> | |||||
| <!-- <div class="ui repo-topic-edit grid form segment error" id="topic_edit" style="display:none"> | |||||
| <div class="fourteen wide column"> | <div class="fourteen wide column"> | ||||
| <div class="field"> | <div class="field"> | ||||
| <div class="ui fluid multiple search selection dropdown"> | <div class="ui fluid multiple search selection dropdown"> | ||||
| @@ -114,157 +126,182 @@ | |||||
| </div> | </div> | ||||
| </div> --> | </div> --> | ||||
| {{end}} | |||||
| <div class="hide" id="validate_prompt"> | |||||
| <span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span> | |||||
| <span id="format_prompt">{{.i18n.Tr "repo.topic.format_prompt"}}</span> | |||||
| </div> | |||||
| {{end}} | |||||
| <div class="hide" id="validate_prompt"> | |||||
| <span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span> | |||||
| <span id="format_prompt">{{.i18n.Tr "repo.topic.format_prompt"}}</span> | |||||
| </div> | |||||
| <div class="ui repo-description stackable grid"> | <div class="ui repo-description stackable grid"> | ||||
| {{if .RepoSearchEnabled}} | {{if .RepoSearchEnabled}} | ||||
| <div class="ui repo-search four wide column"> | |||||
| <form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get"> | |||||
| <div class="field"> | |||||
| <div class="ui action input"> | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> | |||||
| <button class="ui icon button" type="submit"> | |||||
| <i class="search icon"></i> | |||||
| </button> | |||||
| </div> | |||||
| <div class="ui repo-search four wide column"> | |||||
| <form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get"> | |||||
| <div class="field"> | |||||
| <div class="ui action input"> | |||||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> | |||||
| <button class="ui icon button" type="submit"> | |||||
| <i class="search icon"></i> | |||||
| </button> | |||||
| </div> | </div> | ||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| {{if .Repository.IsArchived}} | {{if .Repository.IsArchived}} | ||||
| <div class="ui warning message"> | |||||
| {{.i18n.Tr "repo.archive.title"}} | |||||
| </div> | |||||
| <div class="ui warning message"> | |||||
| {{.i18n.Tr "repo.archive.title"}} | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| {{template "repo/sub_menu" .}} | {{template "repo/sub_menu" .}} | ||||
| <div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins"> | <div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins"> | ||||
| {{template "repo/branch_dropdown" .}} | {{template "repo/branch_dropdown" .}} | ||||
| {{ $n := len .TreeNames}} | {{ $n := len .TreeNames}} | ||||
| {{ $l := Subtract $n 1}} | {{ $l := Subtract $n 1}} | ||||
| {{.TreePath}} | |||||
| <!-- If home page, show new PR. If not, show breadcrumb --> | <!-- If home page, show new PR. If not, show breadcrumb --> | ||||
| {{if eq $n 0}} | {{if eq $n 0}} | ||||
| {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} | |||||
| <div class="fitted item"> | |||||
| <a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button">{{if .PullRequestCtx.Allowed}}{{.i18n.Tr "repo.pulls.compare_changes"}}{{else}}{{.i18n.Tr "action.compare_branch"}}{{end}}</button> | |||||
| </a> | |||||
| {{if and .Repository.IsFork .PullRequestCtx.Allowed}} | |||||
| {{if gt .FetchUpstreamCnt 0 }} | |||||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" title="{{$.i18n.Tr (TrN $.i18n.Lang .FetchUpstreamCnt "repo.pulls.commits_count_1" "repo.pulls.commits_count_n") .FetchUpstreamCnt}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{else if lt .FetchUpstreamCnt 0}} | |||||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_error"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{else}} | |||||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_up_to_date"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} | |||||
| <div class="fitted item"> | |||||
| <a | |||||
| href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}"> | |||||
| <button id="new-pull-request" | |||||
| class="ui compact basic button">{{if .PullRequestCtx.Allowed}}{{.i18n.Tr "repo.pulls.compare_changes"}}{{else}}{{.i18n.Tr "action.compare_branch"}}{{end}}</button> | |||||
| </a> | |||||
| {{if and .Repository.IsFork .PullRequestCtx.Allowed}} | |||||
| {{if gt .FetchUpstreamCnt 0 }} | |||||
| <a | |||||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" | |||||
| title="{{$.i18n.Tr (TrN $.i18n.Lang .FetchUpstreamCnt "repo.pulls.commits_count_1" "repo.pulls.commits_count_n") .FetchUpstreamCnt}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{else if lt .FetchUpstreamCnt 0}} | |||||
| <a | |||||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" | |||||
| title="{{.i18n.Tr "repo.pulls.upstream_error"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{else}} | |||||
| <a | |||||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||||
| <button id="new-pull-request" class="ui compact basic button" | |||||
| title="{{.i18n.Tr "repo.pulls.upstream_up_to_date"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||||
| </a> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </div> | |||||
| {{end}} | |||||
| {{else}} | {{else}} | ||||
| <div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div> | |||||
| <div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" | |||||
| href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" | |||||
| title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span | |||||
| class="divider">/</span>{{if eq $i $l}}<span class="active section" | |||||
| title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span | |||||
| class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" | |||||
| title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div> | |||||
| {{end}} | {{end}} | ||||
| <div class="right fitted item" id="file-buttons"> | <div class="right fitted item" id="file-buttons"> | ||||
| <div class="ui tiny blue buttons"> | <div class="ui tiny blue buttons"> | ||||
| {{if .Repository.CanEnableEditor}} | {{if .Repository.CanEnableEditor}} | ||||
| {{if .CanAddFile}} | |||||
| <a href="{{.RepoLink}}/_new/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button"> | |||||
| {{.i18n.Tr "repo.editor.new_file"}} | |||||
| </a> | |||||
| {{end}} | |||||
| {{if .CanUploadFile}} | |||||
| <a href="{{.RepoLink}}/_upload/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button"> | |||||
| {{.i18n.Tr "repo.editor.upload_file"}} | |||||
| </a> | |||||
| {{end}} | |||||
| {{if .CanAddFile}} | |||||
| <a href="{{.RepoLink}}/_new/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" | |||||
| class="ui button"> | |||||
| {{.i18n.Tr "repo.editor.new_file"}} | |||||
| </a> | |||||
| {{end}} | |||||
| {{if .CanUploadFile}} | |||||
| <a href="{{.RepoLink}}/_upload/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" | |||||
| class="ui button"> | |||||
| {{.i18n.Tr "repo.editor.upload_file"}} | |||||
| </a> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| {{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }} | {{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }} | ||||
| <a href="{{.RepoLink}}/commits/{{EscapePound .BranchNameSubURL}}/{{EscapePound .TreePath}}" class="ui button"> | |||||
| {{.i18n.Tr "repo.file_history"}} | |||||
| </a> | |||||
| <a href="{{.RepoLink}}/commits/{{EscapePound .BranchNameSubURL}}/{{EscapePound .TreePath}}" | |||||
| class="ui button"> | |||||
| {{.i18n.Tr "repo.file_history"}} | |||||
| </a> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="fitted item"> | <div class="fitted item"> | ||||
| {{if eq $n 0}} | {{if eq $n 0}} | ||||
| {{if .Repository.IsTemplate}} | |||||
| <div class="ui tiny blue buttons"> | |||||
| <a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button"> | |||||
| {{.i18n.Tr "repo.use_template"}} | |||||
| </a> | |||||
| </div> | |||||
| {{end}} | |||||
| {{if .Repository.IsTemplate}} | |||||
| <div class="ui tiny blue buttons"> | |||||
| <a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button"> | |||||
| {{.i18n.Tr "repo.use_template"}} | |||||
| </a> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="fitted item"> | <div class="fitted item"> | ||||
| <!-- Only show clone panel in repository home page --> | <!-- Only show clone panel in repository home page --> | ||||
| {{if eq $n 0}} | {{if eq $n 0}} | ||||
| <div class="ui action tiny input" id="clone-panel"> | |||||
| {{if not $.DisableHTTP}} | |||||
| <button class="ui basic clone button" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}"> | |||||
| {{if UseHTTPS}}HTTPS{{else}}HTTP{{end}} | |||||
| </button> | |||||
| {{end}} | |||||
| {{if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||||
| <button class="ui basic clone button" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}"> | |||||
| SSH | |||||
| </button> | |||||
| {{end}} | |||||
| {{if not $.DisableHTTP}} | |||||
| <input id="repo-clone-url" value="{{$.CloneLink.HTTPS}}" readonly> | |||||
| {{else if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||||
| <input id="repo-clone-url" value="{{$.CloneLink.SSH}}" readonly> | |||||
| {{end}} | |||||
| {{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}} | |||||
| <button class="ui basic icon button poping up clipboard" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}" data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-target="#repo-clone-url"> | |||||
| {{svg "octicon-clippy" 16}} | |||||
| </button> | |||||
| {{end}} | |||||
| <div class="ui basic jump dropdown icon button poping up" data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted" data-position="top right"> | |||||
| <i class="download icon"></i> | |||||
| <div class="menu"> | |||||
| <a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip" 16}} ZIP</a> | |||||
| <a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip" 16}} TAR.GZ</a> | |||||
| </div> | |||||
| <div class="ui action tiny input" id="clone-panel"> | |||||
| {{if not $.DisableHTTP}} | |||||
| <button class="ui basic clone button" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}"> | |||||
| {{if UseHTTPS}}HTTPS{{else}}HTTP{{end}} | |||||
| </button> | |||||
| {{end}} | |||||
| {{if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||||
| <button class="ui basic clone button" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}"> | |||||
| SSH | |||||
| </button> | |||||
| {{end}} | |||||
| {{if not $.DisableHTTP}} | |||||
| <input id="repo-clone-url" value="{{$.CloneLink.HTTPS}}" readonly> | |||||
| {{else if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||||
| <input id="repo-clone-url" value="{{$.CloneLink.SSH}}" readonly> | |||||
| {{end}} | |||||
| {{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}} | |||||
| <button class="ui basic icon button poping up clipboard" id="clipboard-btn" | |||||
| data-original="{{.i18n.Tr "repo.copy_link"}}" | |||||
| data-success="{{.i18n.Tr "repo.copy_link_success"}}" | |||||
| data-error="{{.i18n.Tr "repo.copy_link_error"}}" data-content="{{.i18n.Tr "repo.copy_link"}}" | |||||
| data-variation="inverted tiny" data-clipboard-target="#repo-clone-url"> | |||||
| {{svg "octicon-clippy" 16}} | |||||
| </button> | |||||
| {{end}} | |||||
| <div class="ui basic jump dropdown icon button poping up" | |||||
| data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted" | |||||
| data-position="top right"> | |||||
| <i class="download icon"></i> | |||||
| <div class="menu"> | |||||
| <a class="item" | |||||
| href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip" 16}} ZIP</a> | |||||
| <a class="item" | |||||
| href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip" 16}} TAR.GZ</a> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| <div class="ui mobile reversed stackable grid"> | <div class="ui mobile reversed stackable grid"> | ||||
| <div class="ui ten wide tablet twelve wide computer column"> | <div class="ui ten wide tablet twelve wide computer column"> | ||||
| {{.CanEditFile}} | |||||
| {{if .IsViewFile}} | {{if .IsViewFile}} | ||||
| {{template "repo/view_file" .}} | |||||
| {{template "repo/view_file" .}} | |||||
| {{else if .IsBlame}} | {{else if .IsBlame}} | ||||
| {{template "repo/blame" .}} | |||||
| {{template "repo/blame" .}} | |||||
| {{else}} | {{else}} | ||||
| {{template "repo/view_list" .}} | |||||
| {{template "repo/view_list" .}} | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div class="ui six wide tablet four wide computer column"> | <div class="ui six wide tablet four wide computer column"> | ||||
| <div id="repo-desc" data-IsAdmin= "{{.Permission.IsAdmin}}" data-IsArchived="{{.Repository.IsArchived}}" > | |||||
| <h4 id="about-desc" class="ui header">简介</h4> | |||||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||||
| <div id="repo-desc" data-IsAdmin="{{.Permission.IsAdmin}}" | |||||
| data-IsArchived="{{.Repository.IsArchived}}"> | |||||
| <h4 id="about-desc" class="ui header">简介</h4> | |||||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||||
| <p> | <p> | ||||
| {{if .Repository.DescriptionHTML}} | {{if .Repository.DescriptionHTML}} | ||||
| <span class="description" style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | |||||
| <span class="description" | |||||
| style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | |||||
| {{else}} | {{else}} | ||||
| <span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span> | |||||
| <span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span> | |||||
| {{end}} | {{end}} | ||||
| </p> | </p> | ||||
| @@ -276,7 +313,8 @@ | |||||
| {{if .Repository.Website}} | {{if .Repository.Website}} | ||||
| <p class="ui"> | <p class="ui"> | ||||
| <i class="gray linkify icon"></i> | <i class="gray linkify icon"></i> | ||||
| <a class="link edit-link" target="_blank" title="{{.Repository.Website}}" href="{{.Repository.Website}}">{{.Repository.Website}}</a> | |||||
| <a class="link edit-link" target="_blank" title="{{.Repository.Website}}" | |||||
| href="{{.Repository.Website}}">{{.Repository.Website}}</a> | |||||
| </p> | </p> | ||||
| {{end}} | {{end}} | ||||
| @@ -286,11 +324,13 @@ | |||||
| <div id="repo-topics1" style="flex: 1;"> | <div id="repo-topics1" style="flex: 1;"> | ||||
| {{range .Topics}} | {{range .Topics}} | ||||
| <a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=">{{.Name}}</a> | |||||
| <a class="ui repo-topic small label topic" | |||||
| href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=">{{.Name}}</a> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div> | <div> | ||||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i id="manage_topic" style="cursor: pointer;" class="plus icon"></i>{{end}} | |||||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i id="manage_topic" | |||||
| style="cursor: pointer;" class="plus icon"></i>{{end}} | |||||
| </div> | </div> | ||||
| <div id="topic_edit" class="vue_menu" style="display:none"> | <div id="topic_edit" class="vue_menu" style="display:none"> | ||||
| <div id="topic_edit1"> | <div id="topic_edit1"> | ||||
| @@ -304,7 +344,7 @@ | |||||
| <p class="ui"> | <p class="ui"> | ||||
| <i class="grey code icon"></i> | <i class="grey code icon"></i> | ||||
| {{range .LanguageStats}} | {{range .LanguageStats}} | ||||
| {{.Language}} | |||||
| {{.Language}} | |||||
| {{end}} | {{end}} | ||||
| </p> | </p> | ||||
| @@ -313,7 +353,7 @@ | |||||
| {{if .LICENSE}} | {{if .LICENSE}} | ||||
| <p class="ui"> | <p class="ui"> | ||||
| <i class="grey clone icon"></i> | <i class="grey clone icon"></i> | ||||
| {{.LICENSE}} | |||||
| {{.LICENSE}} | |||||
| </p> | </p> | ||||
| {{end}} | {{end}} | ||||
| @@ -328,19 +368,22 @@ | |||||
| {{else}} | {{else}} | ||||
| <strong>贡献者 ({{len .ContributorInfo}}+)</strong> | <strong>贡献者 ({{len .ContributorInfo}}+)</strong> | ||||
| {{end}} | {{end}} | ||||
| <div class="ui right"> | <div class="ui right"> | ||||
| <!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a> --> | <!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a> --> | ||||
| <a class="membersmore text grey" href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部 {{svg "octicon-chevron-right" 16}}</a> | |||||
| <a class="membersmore text grey" | |||||
| href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部 | |||||
| {{svg "octicon-chevron-right" 16}}</a> | |||||
| </div> | </div> | ||||
| </h4> | </h4> | ||||
| <div class="ui members" id="contributorInfo"> | <div class="ui members" id="contributorInfo"> | ||||
| {{range .ContributorInfo}} | {{range .ContributorInfo}} | ||||
| {{if .UserInfo}} | |||||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" src="{{.UserInfo.RelAvatarLink}}"></a> | |||||
| {{else if .Email}} | |||||
| <a href="mailto:{{.Email}}" class="circular ui button">{{.Email}}</a> | |||||
| {{end}} | |||||
| {{if .UserInfo}} | |||||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" | |||||
| src="{{.UserInfo.RelAvatarLink}}"></a> | |||||
| {{else if .Email}} | |||||
| <a href="mailto:{{.Email}}" class="circular ui button">{{.Email}}</a> | |||||
| {{end}} | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -359,4 +402,4 @@ | |||||
| // }); | // }); | ||||
| // }); | // }); | ||||
| </script> | </script> | ||||
| {{template "base/footer" .}} | |||||
| {{template "base/footer" .}} | |||||
| @@ -1,53 +1,29 @@ | |||||
| <style> | <style> | ||||
| .menu1 { | |||||
| border: 1px solid white; | |||||
| background-color: rgba(0, 0, 0, 0.5); | |||||
| color: white; | |||||
| position: fixed; | |||||
| width: 150px; | |||||
| } | |||||
| .menu1 > .item:hover { | |||||
| background-color: rgba(0, 0, 0, 0.5); | |||||
| .context-menu { | |||||
| z-index: 99; | |||||
| position: absolute; | |||||
| padding: 0; | |||||
| border-radius: 4px; | |||||
| border: 1px solid #e3e9ed; | |||||
| -webkit-box-shadow: none; | |||||
| box-shadow: none; | |||||
| background: #fff; | |||||
| display: none !important; | |||||
| } | |||||
| } | |||||
| .context-menu.active { | |||||
| display: block !important; | |||||
| } | |||||
| .menu1 > .item { | |||||
| user-select: none; | |||||
| line-height: 30px; | |||||
| vertical-align: middle; | |||||
| padding-inline-start: 20px; | |||||
| } | |||||
| .menu1.active { | |||||
| display: block; | |||||
| } | |||||
| .context-menu-operation { | |||||
| padding: 5px !important; | |||||
| line-height: 1.78 !important; | |||||
| } | |||||
| .menu1 > .item.disabled { | |||||
| pointer-events: none; | |||||
| opacity: .5; | |||||
| } | |||||
| .context-menu { | |||||
| z-index: 99; | |||||
| position: absolute; | |||||
| padding: 0; | |||||
| border-radius: 4px; | |||||
| border: 1px solid #e3e9ed; | |||||
| -webkit-box-shadow: none; | |||||
| box-shadow: none; | |||||
| background: #fff; | |||||
| display: none !important; | |||||
| } | |||||
| .context-menu.active { | |||||
| display: block !important; | |||||
| } | |||||
| .context-menu-operation { | |||||
| padding: 5px !important; | |||||
| line-height: 1.78 !important; | |||||
| } | |||||
| .context-menu-icon{ | |||||
| float: left !important; | |||||
| margin: 0px 5px 0px 0px !important; | |||||
| } | |||||
| .context-menu-icon { | |||||
| float: left !important; | |||||
| margin: 0px 5px 0px 0px !important; | |||||
| } | |||||
| </style> | </style> | ||||
| <div id="mask"> | <div id="mask"> | ||||
| <div id="loadingPage"> | <div id="loadingPage"> | ||||
| @@ -58,131 +34,148 @@ | |||||
| <div class="rect5"></div> | <div class="rect5"></div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <table id="repo-files-table" class="ui single line table"> | |||||
| <table id="repo-files-table" class="ui single line table can-context-menu" data-can-editfile="{{.CanEditFile}}"> | |||||
| {{.CsrfTokenHtml}} | {{.CsrfTokenHtml}} | ||||
| <thead> | <thead> | ||||
| <tr class="commit-list"> | <tr class="commit-list"> | ||||
| <th colspan="2"> | <th colspan="2"> | ||||
| {{if .LatestCommitUser}} | {{if .LatestCommitUser}} | ||||
| <img class="ui avatar image img-12" src="{{.LatestCommitUser.RelAvatarLink}}" /> | |||||
| {{if .LatestCommitUser.FullName}} | |||||
| <a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> | |||||
| {{else}} | |||||
| <a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> | |||||
| {{end}} | |||||
| <img class="ui avatar image img-12" src="{{.LatestCommitUser.RelAvatarLink}}" /> | |||||
| {{if .LatestCommitUser.FullName}} | |||||
| <a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> | |||||
| {{else}} | {{else}} | ||||
| {{if .LatestCommit.Author}} | |||||
| <img class="ui avatar image img-12" src="{{AvatarLink .LatestCommit.Author.Email}}" /> | |||||
| <strong>{{.LatestCommit.Author.Name}}</strong> | |||||
| {{end}} | |||||
| <a | |||||
| href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> | |||||
| {{end}} | {{end}} | ||||
| <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}"> | |||||
| {{else}} | |||||
| {{if .LatestCommit.Author}} | |||||
| <img class="ui avatar image img-12" src="{{AvatarLink .LatestCommit.Author.Email}}" /> | |||||
| <strong>{{.LatestCommit.Author.Name}}</strong> | |||||
| {{end}} | |||||
| {{end}} | |||||
| <a rel="nofollow" | |||||
| class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" | |||||
| href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}"> | |||||
| <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span> | <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span> | ||||
| {{if .LatestCommit.Signature}} | {{if .LatestCommit.Signature}} | ||||
| <div class="ui detail icon button"> | |||||
| {{if .LatestCommitVerification.Verified}} | |||||
| <div title="{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.LatestCommitVerification.Reason}}"> | |||||
| {{if ne .LatestCommitVerification.SigningUser.ID 0}} | |||||
| <i class="lock icon"></i> | |||||
| <img class="ui signature avatar image" src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" /> | |||||
| {{else}} | |||||
| <i title="{{.LatestCommitVerification.Reason}}" class="icons"> | |||||
| <i class="lock icon"></i> | |||||
| <i class="tiny inverted cog icon centerlock"></i> | |||||
| </i> | |||||
| <img class="ui signature avatar image" src="{{AvatarLink .LatestCommitVerification.SigningEmail}}" /> | |||||
| {{end}} | |||||
| </div> | |||||
| <div class="ui detail icon button"> | |||||
| {{if .LatestCommitVerification.Verified}} | |||||
| <div | |||||
| title="{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.LatestCommitVerification.Reason}}"> | |||||
| {{if ne .LatestCommitVerification.SigningUser.ID 0}} | |||||
| <i class="lock icon"></i> | |||||
| <img class="ui signature avatar image" | |||||
| src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" /> | |||||
| {{else}} | {{else}} | ||||
| <i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i> | |||||
| <i title="{{.LatestCommitVerification.Reason}}" class="icons"> | |||||
| <i class="lock icon"></i> | |||||
| <i class="tiny inverted cog icon centerlock"></i> | |||||
| </i> | |||||
| <img class="ui signature avatar image" | |||||
| src="{{AvatarLink .LatestCommitVerification.SigningEmail}}" /> | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| {{else}} | |||||
| <i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i> | |||||
| {{end}} | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| </a> | </a> | ||||
| {{template "repo/commit_status" .LatestCommitStatus}} | {{template "repo/commit_status" .LatestCommitStatus}} | ||||
| {{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }} | {{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }} | ||||
| <span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span class="message-wrapper">{{RenderCommitMessageLinkSubject .LatestCommit.Message $.RepoLink $commitLink $.Repository.ComposeMetas}}</span> | |||||
| {{if IsMultilineCommitMessage .LatestCommit.Message}} | |||||
| <button class="basic compact mini ui icon button commit-button"><i class="ellipsis horizontal icon"></i></button> | |||||
| <pre class="commit-body" style="display: none;">{{RenderCommitBody .LatestCommit.Message $.RepoLink $.Repository.ComposeMetas}}</pre> | |||||
| {{end}} | |||||
| <span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span | |||||
| class="message-wrapper">{{RenderCommitMessageLinkSubject .LatestCommit.Message $.RepoLink $commitLink $.Repository.ComposeMetas}}</span> | |||||
| {{if IsMultilineCommitMessage .LatestCommit.Message}} | |||||
| <button class="basic compact mini ui icon button commit-button"><i | |||||
| class="ellipsis horizontal icon"></i></button> | |||||
| <pre class="commit-body" | |||||
| style="display: none;">{{RenderCommitBody .LatestCommit.Message $.RepoLink $.Repository.ComposeMetas}}</pre> | |||||
| {{end}} | |||||
| </span> | </span> | ||||
| </th> | </th> | ||||
| <th class="text grey right age">{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}</th> | |||||
| <th class="text grey right age"> | |||||
| {{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}</th> | |||||
| </tr> | </tr> | ||||
| </thead> | </thead> | ||||
| <tbody> | <tbody> | ||||
| {{if .HasParentPath}} | {{if .HasParentPath}} | ||||
| <tr class="has-parent"> | |||||
| <td colspan="3">{{svg "octicon-mail-reply" 16}}<a href="{{EscapePound .BranchLink}}{{.ParentPath}}">..</a></td> | |||||
| </tr> | |||||
| <tr class="has-parent"> | |||||
| <td colspan="3">{{svg "octicon-mail-reply" 16}}<a href="{{EscapePound .BranchLink}}{{.ParentPath}}">..</a> | |||||
| </td> | |||||
| </tr> | |||||
| {{end}} | {{end}} | ||||
| {{range $item := .Files}} | {{range $item := .Files}} | ||||
| {{$entry := index $item 0}} | |||||
| {{$commit := index $item 1}} | |||||
| {{$entry := index $item 0}} | |||||
| {{$commit := index $item 1}} | |||||
| <tr> | |||||
| {{if $entry.IsSubModule}} | |||||
| <td> | |||||
| <span class="truncate"> | |||||
| {{svg "octicon-inbox" 16}} | |||||
| {{$refURL := $commit.RefURL AppUrl $.Repository.FullName}} | |||||
| {{if $refURL}} | |||||
| <a href="{{$refURL}}">{{$entry.Name}}</a> @ <a | |||||
| href="{{$refURL}}/commit/{{$commit.RefID}}">{{ShortSha $commit.RefID}}</a> | |||||
| {{else}} | |||||
| {{$entry.Name}} @ {{ShortSha $commit.RefID}} | |||||
| {{end}} | |||||
| </span> | |||||
| </td> | |||||
| {{else}} | |||||
| <td class="name four wide modified-contextmenu"> | |||||
| <span class="truncate"> | |||||
| {{if $entry.IsDir}} | |||||
| {{$subJumpablePathName := $entry.GetSubJumpablePathName}} | |||||
| {{$subJumpablePath := SubJumpablePath $subJumpablePathName}} | |||||
| {{svg "octicon-file-directory" 16}} | |||||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $subJumpablePathName}}" | |||||
| title="{{$subJumpablePathName}}"> | |||||
| {{if eq (len $subJumpablePath) 2}} | |||||
| <span class="jumpable-path">{{index $subJumpablePath 0}}</span>{{index $subJumpablePath 1}} | |||||
| {{else}} | |||||
| {{index $subJumpablePath 0}} | |||||
| {{end}} | |||||
| </a> | |||||
| {{else}} | |||||
| {{svg (printf "octicon-%s" (EntryIcon $entry)) 16}} | |||||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $entry.Name}}" | |||||
| title="{{$entry.Name}}">{{$entry.Name}}</a> | |||||
| {{end}} | |||||
| </span> | |||||
| </td> | |||||
| {{end}} | |||||
| <tr> | |||||
| {{if $entry.IsSubModule}} | |||||
| <td> | |||||
| <span class="truncate"> | |||||
| {{svg "octicon-inbox" 16}} | |||||
| {{$refURL := $commit.RefURL AppUrl $.Repository.FullName}} | |||||
| {{if $refURL}} | |||||
| <a href="{{$refURL}}">{{$entry.Name}}</a> @ <a href="{{$refURL}}/commit/{{$commit.RefID}}">{{ShortSha $commit.RefID}}</a> | |||||
| {{else}} | |||||
| {{$entry.Name}} @ {{ShortSha $commit.RefID}} | |||||
| {{end}} | |||||
| </span> | |||||
| </td> | |||||
| {{else}} | |||||
| <td class="name four wide" id="menu"> | |||||
| <span class="truncate"> | |||||
| {{if $entry.IsDir}} | |||||
| {{$subJumpablePathName := $entry.GetSubJumpablePathName}} | |||||
| {{$subJumpablePath := SubJumpablePath $subJumpablePathName}} | |||||
| {{svg "octicon-file-directory" 16}} | |||||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $subJumpablePathName}}" title="{{$subJumpablePathName}}"> | |||||
| {{if eq (len $subJumpablePath) 2}} | |||||
| <span class="jumpable-path">{{index $subJumpablePath 0}}</span>{{index $subJumpablePath 1}} | |||||
| {{else}} | |||||
| {{index $subJumpablePath 0}} | |||||
| {{end}} | |||||
| </a> | |||||
| {{else}} | |||||
| {{svg (printf "octicon-%s" (EntryIcon $entry)) 16}} | |||||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $entry.Name}}" title="{{$entry.Name}}">{{$entry.Name}}</a> | |||||
| {{end}} | |||||
| </span> | |||||
| </td> | |||||
| {{end}} | |||||
| <td class="message nine wide"> | |||||
| <span class="truncate"> | |||||
| <a href="{{$.RepoLink}}/commit/{{$commit.ID}}" title="{{$commit.Summary}}">{{$commit.Summary | RenderEmoji}}</a> | |||||
| </span> | |||||
| </td> | |||||
| <td class="text right age three wide">{{TimeSince $commit.Committer.When $.Lang}}</td> | |||||
| </tr> | |||||
| <tr style="display: none !important;" class="context-menu-one"> | |||||
| <td colspan="12"> | |||||
| <div class="ui column form" method="POST"> | |||||
| <div class="two fields" style="margin: 0;"> | |||||
| <div class="five wide field"> | |||||
| <input class="ui input" name="new_filename" type="text" value=""> | |||||
| </div> | |||||
| <div class="five wide field"> | |||||
| <button class="ui blue button popup-save" type="button" data-postBasePath="{{$.RepoLink}}/_rename/{{EscapePound $.BranchName}}{{if $.TreePath}}/{{EscapePound $.TreePath}}{{end}}/{{$entry.Name}}" data-commit="{{$.LatestCommit.ID}}" data-treepath="{{if $.TreePath}}{{EscapePound $.TreePath}}/{{end}}">保存</button> | |||||
| <button class="ui basic button popup-close" type="button">取消</button> | |||||
| </div> | |||||
| <td class="message nine wide"> | |||||
| <span class="truncate"> | |||||
| <a href="{{$.RepoLink}}/commit/{{$commit.ID}}" | |||||
| title="{{$commit.Summary}}">{{$commit.Summary | RenderEmoji}}</a> | |||||
| </span> | |||||
| </td> | |||||
| <td class="text right age three wide">{{TimeSince $commit.Committer.When $.Lang}}</td> | |||||
| </tr> | |||||
| <tr style="display: none !important;" class="context-menu-one"> | |||||
| <td colspan="12"> | |||||
| <div class="ui column form" method="POST"> | |||||
| <div class="two fields" style="margin: 0;"> | |||||
| <div class="five wide field"> | |||||
| <input class="ui input" name="new_filename" type="text" value=""> | |||||
| </div> | |||||
| <div class="five wide field"> | |||||
| <button class="ui blue button popup-save" type="button" | |||||
| data-postBasePath="{{$.RepoLink}}/_rename/{{EscapePound $.BranchName}}{{if $.TreePath}}/{{EscapePound $.TreePath}}{{end}}/{{$entry.Name}}" | |||||
| data-commit="{{$.LatestCommit.ID}}" | |||||
| data-treepath="{{if $.TreePath}}{{EscapePound $.TreePath}}/{{end}}">保存</button> | |||||
| <button class="ui basic button popup-close" type="button">取消</button> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </td> | |||||
| </tr> | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| {{end}} | {{end}} | ||||
| </tbody> | </tbody> | ||||
| </table> | </table> | ||||
| {{if .ReadmeExist}} | {{if .ReadmeExist}} | ||||
| {{template "repo/view_file" .}} | |||||
| {{template "repo/view_file" .}} | |||||
| {{end}} | {{end}} | ||||
| <!-- 确认模态框 --> | <!-- 确认模态框 --> | ||||
| @@ -204,260 +197,4 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | |||||
| <script> | |||||
| $('.popup-close').on('click',function(e){ | |||||
| $(this).parents('tr').prev().css('display','table-row') | |||||
| $(this).closest('tr').css('cssText','display:none !important') | |||||
| }) | |||||
| function test(){ | |||||
| $('.name.four.wide').on('contextmenu',function(e){ | |||||
| let ev = window.event || e; | |||||
| ev.preventDefault(); | |||||
| menu.show(e) | |||||
| }) | |||||
| // if({{.CanEditFile}}){ | |||||
| // $('.name.four.wide').on('contextmenu',function(e){ | |||||
| // let ev = window.event || e; | |||||
| // ev.preventDefault(); | |||||
| // menu.show(e) | |||||
| // }) | |||||
| // }else{ | |||||
| // return | |||||
| // } | |||||
| } | |||||
| test() | |||||
| // const ContextMenu = function (options) { | |||||
| // // 唯一实例 | |||||
| // let instance; | |||||
| // // 创建实例方法 | |||||
| // function createMenu() { | |||||
| // const ul = document.createElement("ul"); | |||||
| // ul.classList.add("custom-context-menu"); | |||||
| // const { menus } = options; | |||||
| // if (menus && menus.length > 0) { | |||||
| // for (let menu of menus) { | |||||
| // const li = document.createElement("li"); | |||||
| // li.textContent = menu.name; | |||||
| // li.onclick = menu.onClick; | |||||
| // ul.appendChild(li); | |||||
| // } | |||||
| // } | |||||
| // const body = document.querySelector("body"); | |||||
| // body.appendChild(ul); | |||||
| // return ul; | |||||
| // } | |||||
| // return { | |||||
| // // 获取实例的唯一方式 | |||||
| // getInstance: function () { | |||||
| // if (!instance) { | |||||
| // instance = createMenu(); | |||||
| // } | |||||
| // return instance; | |||||
| // }, | |||||
| // }; | |||||
| // }; | |||||
| // const menuSinglton = ContextMenu({ | |||||
| // menus: [ | |||||
| // { | |||||
| // name: "重命名", | |||||
| // onClick: function (e) { | |||||
| // console.log("menu1 clicked",e); | |||||
| // }, | |||||
| // }, | |||||
| // { | |||||
| // name: "删除", | |||||
| // onClick: function (e,a) { | |||||
| // console.log("menu2 clicked"); | |||||
| // }, | |||||
| // }, | |||||
| // ], | |||||
| // }); | |||||
| // function showMenu(e) { | |||||
| // const menus = menuSinglton.getInstance(); | |||||
| // menus.style.top = `${e.clientY}px`; | |||||
| // menus.style.left = `${e.clientX}px`; | |||||
| // menus.style.display = "block"; | |||||
| // } | |||||
| // function hideMenu(e) { | |||||
| // const menus = menuSinglton.getInstance(); | |||||
| // menus.style.display = "none"; | |||||
| // } | |||||
| // document.addEventListener("click", hideMenu); | |||||
| // function doNothing(e) { | |||||
| // window.event.returnValue = false | |||||
| // menu.show(e) | |||||
| // return false | |||||
| // } | |||||
| class Menu { | |||||
| constructor(param) { | |||||
| this.target = document.createElement('div') | |||||
| this.target.classList.add("ui","menu","compact","vertical","context-menu") | |||||
| this.data = param.data | |||||
| this.active = false | |||||
| this.clickZ = this.click.bind(this) | |||||
| this.closeZ = this.close2.bind(this) | |||||
| document.addEventListener('click', this.closeZ) | |||||
| for (let i = 0; i < this.data.length; i++) { | |||||
| let div = document.createElement('a') | |||||
| div.classList.add('item','context-menu-operation') | |||||
| if (this.data[i].disabled) { | |||||
| div.classList.add('disabled') | |||||
| } | |||||
| div.dataset.index = i.toString() | |||||
| // div.innerText = this.data[i].label | |||||
| div.innerHTML = `<i class="${this.data[i].icon}"></i>${this.data[i].label}` | |||||
| div.addEventListener('click', this.clickZ) | |||||
| this.target.append(div) | |||||
| } | |||||
| document.body.append(this.target) | |||||
| } | |||||
| click(e) { | |||||
| let index = parseInt(e.target.dataset.index) | |||||
| if (this.data[index].active) { | |||||
| this.data[index].active(e, this.acEvent) | |||||
| } | |||||
| this.close() | |||||
| } | |||||
| show(e) { | |||||
| this.active = true | |||||
| this.nodeList = this.target.querySelectorAll('.item') | |||||
| for (let i = 0; i < this.data.length; i++) { | |||||
| if (this.data[i].beforeDisabled) { | |||||
| let t = this.data[i].beforeDisabled(e) | |||||
| this.data[i].disabled = t | |||||
| if (t) { | |||||
| this.nodeList[i].classList.add('disabled') | |||||
| } else { | |||||
| this.nodeList[i].classList.remove('disabled') | |||||
| } | |||||
| } | |||||
| } | |||||
| this.acEvent = e | |||||
| this.target.style.top = `${e.pageY}px` | |||||
| this.target.style.left = `${e.pageX}px` | |||||
| this.target.style.minWidth = '90px' | |||||
| this.target.classList.add('active') | |||||
| } | |||||
| close() { | |||||
| this.active = false | |||||
| this.target.classList.remove('active') | |||||
| } | |||||
| close2(e) { | |||||
| if (!this.target.contains(e.target) && this.active) { | |||||
| this.active = false | |||||
| this.target.classList.remove('active') | |||||
| } | |||||
| } | |||||
| } | |||||
| const menu = new Menu({ | |||||
| data: [ | |||||
| { | |||||
| label: '新标签打开', | |||||
| icon:"file outline icon context-menu-icon", | |||||
| active: (e, a) => { | |||||
| console.log(a.currentTarget.getElementsByTagName("a")[0].getAttribute('href')) | |||||
| window.open(a.currentTarget.getElementsByTagName("a")[0].getAttribute('href')) | |||||
| } | |||||
| }, | |||||
| { | |||||
| label: '重命名', | |||||
| icon:"edit icon context-menu-icon", | |||||
| active: (e, a) => { | |||||
| // if (a.target.nodeName === 'LI') { | |||||
| // a.target.remove() | |||||
| // } | |||||
| console.log(e,a) | |||||
| document.querySelectorAll(".context-menu-one").forEach((ele)=>{ | |||||
| if(ele.style.display==='table-row'){ | |||||
| ele.style.display='none' | |||||
| ele.previousElementSibling.style.display='table-row' | |||||
| } | |||||
| }) | |||||
| if(a.currentTarget.parentNode.nextElementSibling){ | |||||
| a.currentTarget.parentNode.style.setProperty('display','none','important') | |||||
| a.currentTarget.parentNode.nextElementSibling.style.display='table-row' | |||||
| // a.target.parentNode.nextElementSibling = | |||||
| a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("input")[0].setAttribute("value", a.currentTarget.getElementsByTagName("a")[0].getAttribute('title')) | |||||
| } | |||||
| console.log(a.currentTarget.parentNode.nextElementSibling) | |||||
| let btn = a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("button")[0] | |||||
| console.log(btn) | |||||
| btn.addEventListener('click',function(e) { | |||||
| console.log('ckilc',e.target.parentNode.previousElementSibling.getElementsByTagName("input")[0]) | |||||
| let postUrl = btn.getAttribute('data-postbasepath') | |||||
| let last_commit = btn.getAttribute('data-commit') | |||||
| let tree_path = btn.getAttribute('data-treepath') + e.target.parentNode.previousElementSibling.getElementsByTagName("input")[0].value | |||||
| console.log(postUrl,last_commit) | |||||
| let csrf = $("input[name='_csrf']").val() | |||||
| $.ajax({ | |||||
| url:postUrl, | |||||
| type: "POST", | |||||
| contentType: "application/x-www-form-urlencoded", | |||||
| data:{last_commit:last_commit,tree_path:tree_path,_csrf:csrf}, | |||||
| success:function(res){ | |||||
| console.log(res) | |||||
| document.getElementById("mask").style.display = "block" | |||||
| location.reload() | |||||
| } | |||||
| }) | |||||
| }) | |||||
| }, | |||||
| // beforeDisabled: (e) => { | |||||
| // console.log(e,e.target) | |||||
| // return e.target.nodeName !== 'TD' | |||||
| // } | |||||
| }, | |||||
| { | |||||
| label: '删除', | |||||
| icon:"trash icon context-menu-icon", | |||||
| active: (e, a) => { | |||||
| console.dir(a) | |||||
| $('.context-menu-delete.modal') | |||||
| .modal({ | |||||
| onApprove() { | |||||
| // $('.edit-label.form').trigger('submit'); | |||||
| console.log(33333333) | |||||
| } | |||||
| }) | |||||
| .modal('show'); | |||||
| } | |||||
| }, | |||||
| // { | |||||
| // label: '啧啧', | |||||
| // disabled: true | |||||
| // } | |||||
| ] | |||||
| }) | |||||
| console.log({{$.CanEditFile}}) | |||||
| </script> | |||||
| </div> | |||||
| @@ -0,0 +1,153 @@ | |||||
| export default async function initContextMenu() { | |||||
| $('.popup-close').on('click', function (e) { | |||||
| $(this).parents('tr').prev().css('display', 'table-row') | |||||
| $(this).closest('tr').css('cssText', 'display:none !important') | |||||
| }) | |||||
| function contextMenu() { | |||||
| let canContextMenu = $('.ui.single.line.table.can-context-menu').data('can-editfile') | |||||
| if (canContextMenu) { | |||||
| $('.name.four.wide').on('contextmenu', function (e) { | |||||
| let ev = window.event || e; | |||||
| ev.preventDefault(); | |||||
| menu.show(e) | |||||
| }) | |||||
| } else { | |||||
| return | |||||
| } | |||||
| } | |||||
| contextMenu() | |||||
| const menu = new Menu({ | |||||
| data: [ | |||||
| { | |||||
| label: '新标签打开', | |||||
| icon: "file outline icon context-menu-icon", | |||||
| active: (e, a) => { | |||||
| window.open(a.currentTarget.getElementsByTagName("a")[0].getAttribute('href')) | |||||
| } | |||||
| }, | |||||
| { | |||||
| label: '重命名', | |||||
| icon: "edit icon context-menu-icon", | |||||
| active: (e, a) => { | |||||
| document.querySelectorAll(".context-menu-one").forEach((ele) => { | |||||
| if (ele.style.display === 'table-row') { | |||||
| ele.style.display = 'none' | |||||
| ele.previousElementSibling.style.display = 'table-row' | |||||
| } | |||||
| }) | |||||
| if (a.currentTarget.parentNode.nextElementSibling) { | |||||
| a.currentTarget.parentNode.style.setProperty('display', 'none', 'important') | |||||
| a.currentTarget.parentNode.nextElementSibling.style.display = 'table-row' | |||||
| a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("input")[0].setAttribute("value", a.currentTarget.getElementsByTagName("a")[0].getAttribute('title')) | |||||
| } | |||||
| let btn = a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("button")[0] | |||||
| btn.addEventListener('click', function (e) { | |||||
| let postUrl = btn.getAttribute('data-postbasepath') | |||||
| let last_commit = btn.getAttribute('data-commit') | |||||
| let tree_path = btn.getAttribute('data-treepath') + e.target.parentNode.previousElementSibling.getElementsByTagName("input")[0].value | |||||
| let csrf = $("input[name='_csrf']").val() | |||||
| $.ajax({ | |||||
| url: postUrl, | |||||
| type: "POST", | |||||
| contentType: "application/x-www-form-urlencoded", | |||||
| data: { last_commit: last_commit, tree_path: tree_path, _csrf: csrf }, | |||||
| success: function (res) { | |||||
| console.log("--------------") | |||||
| console.log(res.Code) | |||||
| console.log(res.Message) | |||||
| if (res.Code === 0) { | |||||
| document.getElementById("mask").style.display = "block" | |||||
| location.reload() | |||||
| } | |||||
| else { | |||||
| $('.ui.negative.message').text(res.Msg).show().delay(10000).fadeOut(); | |||||
| } | |||||
| } | |||||
| }) | |||||
| }) | |||||
| }, | |||||
| }, | |||||
| // { | |||||
| // label: '删除', | |||||
| // icon: "trash icon context-menu-icon", | |||||
| // active: (e, a) => { | |||||
| // console.dir(a) | |||||
| // $('.context-menu-delete.modal') | |||||
| // .modal({ | |||||
| // onApprove() { | |||||
| // } | |||||
| // }) | |||||
| // .modal('show'); | |||||
| // } | |||||
| // }, | |||||
| ] | |||||
| }) | |||||
| } | |||||
| class Menu { | |||||
| constructor(param) { | |||||
| this.target = document.createElement('div') | |||||
| this.target.classList.add("ui", "menu", "compact", "vertical", "context-menu") | |||||
| this.data = param.data | |||||
| this.active = false | |||||
| this.clickZ = this.click.bind(this) | |||||
| this.closeZ = this.close2.bind(this) | |||||
| document.addEventListener('click', this.closeZ) | |||||
| for (let i = 0; i < this.data.length; i++) { | |||||
| let div = document.createElement('a') | |||||
| div.classList.add('item', 'context-menu-operation') | |||||
| if (this.data[i].disabled) { | |||||
| div.classList.add('disabled') | |||||
| } | |||||
| div.dataset.index = i.toString() | |||||
| div.innerHTML = `<i class="${this.data[i].icon}"></i>${this.data[i].label}` | |||||
| div.addEventListener('click', this.clickZ) | |||||
| this.target.append(div) | |||||
| } | |||||
| document.body.append(this.target) | |||||
| } | |||||
| click(e) { | |||||
| let index = parseInt(e.target.dataset.index) | |||||
| if (this.data[index].active) { | |||||
| this.data[index].active(e, this.acEvent) | |||||
| } | |||||
| this.close() | |||||
| } | |||||
| show(e) { | |||||
| this.active = true | |||||
| this.nodeList = this.target.querySelectorAll('.item') | |||||
| for (let i = 0; i < this.data.length; i++) { | |||||
| if (this.data[i].beforeDisabled) { | |||||
| let t = this.data[i].beforeDisabled(e) | |||||
| this.data[i].disabled = t | |||||
| if (t) { | |||||
| this.nodeList[i].classList.add('disabled') | |||||
| } else { | |||||
| this.nodeList[i].classList.remove('disabled') | |||||
| } | |||||
| } | |||||
| } | |||||
| this.acEvent = e | |||||
| this.target.style.top = `${e.pageY}px` | |||||
| this.target.style.left = `${e.pageX}px` | |||||
| this.target.style.minWidth = '90px' | |||||
| this.target.classList.add('active') | |||||
| } | |||||
| close() { | |||||
| this.active = false | |||||
| this.target.classList.remove('active') | |||||
| } | |||||
| close2(e) { | |||||
| if (!this.target.contains(e.target) && this.active) { | |||||
| this.active = false | |||||
| this.target.classList.remove('active') | |||||
| } | |||||
| } | |||||
| } | |||||