diff --git a/.gitignore b/.gitignore index ac88d5ca1a..e8b5ee1f93 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,8 @@ _testmain.go *.exe *.exe~ -gogs +/gogs +profile/ __pycache__ *.pem output* diff --git a/cmd/web.go b/cmd/web.go index 995aeb04a9..40ae760280 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -19,7 +19,9 @@ import ( "github.com/macaron-contrib/csrf" "github.com/macaron-contrib/i18n" "github.com/macaron-contrib/session" + "github.com/macaron-contrib/toolbox" + "github.com/gogits/gogs/models" "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/auth/apiv1" "github.com/gogits/gogs/modules/avatar" @@ -62,20 +64,20 @@ func newMacaron() *macaron.Macaron { m := macaron.New() m.Use(macaron.Logger()) m.Use(macaron.Recovery()) - if setting.EnableGzip { - m.Use(macaron.Gzip()) - } m.Use(macaron.Static("public", macaron.StaticOptions{ SkipLogging: !setting.DisableRouterLog, }, )) + if setting.EnableGzip { + m.Use(macaron.Gzip()) + } m.Use(macaron.Renderer(macaron.RenderOptions{ Directory: path.Join(setting.StaticRootPath, "templates"), Funcs: []template.FuncMap{base.TemplateFuncs}, IndentJSON: macaron.Env != macaron.PROD, })) - m.Use(i18n.I18n(i18n.LocaleOptions{ + m.Use(i18n.I18n(i18n.Options{ Langs: setting.Langs, Names: setting.Names, Redirect: true, @@ -94,6 +96,14 @@ func newMacaron() *macaron.Macaron { Secret: setting.SecretKey, SetCookie: true, })) + m.Use(toolbox.Toolboxer(m, toolbox.Options{ + HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{ + &toolbox.HealthCheckFuncDesc{ + Desc: "Database connection", + Func: models.Ping, + }, + }, + })) m.Use(middleware.Contexter()) return m } @@ -208,7 +218,6 @@ func runWeb(*cli.Context) { if macaron.Env == macaron.DEV { m.Get("/template/*", dev.TemplatePreview) - dev.RegisterDebugRoutes(m) } reqTrueOwner := middleware.RequireTrueOwner() @@ -245,8 +254,7 @@ func runWeb(*cli.Context) { r.Get("/settings", repo.Settings) r.Post("/settings", bindIgnErr(auth.RepoSettingForm{}), repo.SettingsPost) m.Group("/settings", func(r *macaron.Router) { - r.Get("/collaboration", repo.Collaboration) - r.Post("/collaboration", repo.CollaborationPost) + r.Route("/collaboration", "GET,POST", repo.SettingsCollaboration) r.Get("/hooks", repo.WebHooks) r.Get("/hooks/add", repo.WebHooksAdd) r.Post("/hooks/add", bindIgnErr(auth.NewWebhookForm{}), repo.WebHooksAddPost) diff --git a/conf/locale/locale_en-US.ini b/conf/locale/locale_en-US.ini index 29a61e7f5a..5ecf913900 100644 --- a/conf/locale/locale_en-US.ini +++ b/conf/locale/locale_en-US.ini @@ -86,6 +86,7 @@ username_password_incorrect = Username or password is not correct. enterred_invalid_repo_name = Please make sure you entered repository name is correct. enterred_invalid_owner_name = Please make sure you entered owner name is correct. enterred_invalid_password = Please make sure you entered passord is correct. +user_not_exist = Given user does not exist. invalid_ssh_key = Sorry, we're not able to verify your SSH key: %s auth_failed = Authentication failed: %v @@ -174,6 +175,9 @@ settings.update_settings_success = Repository options has been successfully upda settings.transfer_owner = New Owner settings.make_transfer = Make Transfer settings.confirm_delete = Confirm Deletion +settings.add_collaborator = Add New Collaborator +settings.add_collaborator_success = New collaborator has been added. +settings.remove_collaborator_success = Collaborator has been removed. [org] org_name_holder = Organization Name diff --git a/conf/locale/locale_zh-CN.ini b/conf/locale/locale_zh-CN.ini index a2b1840187..4c65812523 100644 --- a/conf/locale/locale_zh-CN.ini +++ b/conf/locale/locale_zh-CN.ini @@ -86,6 +86,7 @@ username_password_incorrect = 用户名或密码不正确。 enterred_invalid_repo_name = 请检查您输入的仓库名称是正确。 enterred_invalid_owner_name = 请检查您输入的新所有者用户名是否正确。 enterred_invalid_password = 请检查您输入的密码是否正确。 +user_not_exist = 被操作的用户不存在! invalid_ssh_key = 很抱歉,我们无法验证您输入的 SSH 密钥:%s auth_failed = 授权验证失败:%v @@ -174,6 +175,9 @@ settings.update_settings_success = 仓库设置更新成功! settings.transfer_owner = 新拥有者 settings.make_transfer = 确认转移仓库 settings.confirm_delete = 确认删除仓库 +settings.add_collaborator = 增加新的协作者 +settings.add_collaborator_success = 成功添加新的协作者! +settings.remove_collaborator_success = 被操作的协作者已经被收回权限! [org] org_name_holder = 组织名称 diff --git a/gogs.go b/gogs.go index 42d15db43c..d40f1a02d1 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.7.0802 Alpha" +const APP_VER = "0.4.7.0807 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/models.go b/models/models.go index 31509ed349..af9529f40a 100644 --- a/models/models.go +++ b/models/models.go @@ -165,6 +165,10 @@ func GetStatistic() (stats Statistic) { return } +func Ping() error { + return x.Ping() +} + // DumpDatabase dumps all data from database to file system. func DumpDatabase(filePath string) error { return x.DumpAllToFile(filePath) diff --git a/models/publickey.go b/models/publickey.go index baf381778e..f9880c74cd 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -69,7 +69,7 @@ func init() { // Determine and create .ssh path. SshPath = filepath.Join(homeDir(), ".ssh") - if err = os.MkdirAll(SshPath, os.ModePerm); err != nil { + if err = os.MkdirAll(SshPath, 0700); err != nil { log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err) } } @@ -156,6 +156,16 @@ func saveAuthorizedKeyFile(key *PublicKey) error { return err } defer f.Close() + finfo, err := f.Stat() + if err != nil { + return err + } + if finfo.Mode().Perm() > 0600 { + log.Error(4, "authorized_keys file has unusual permission flags: %s - setting to -rw-------", finfo.Mode().Perm().String()) + if err = f.Chmod(0600); err != nil { + return err + } + } _, err = f.WriteString(key.GetAuthorizedString()) return err diff --git a/models/repo.go b/models/repo.go index a68757af31..c2398fe7da 100644 --- a/models/repo.go +++ b/models/repo.go @@ -446,7 +446,9 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa } if len(fileName) == 0 { - return nil + repo.IsBare = true + repo.DefaultBranch = "master" + return UpdateRepository(repo) } // Apply changes and commit. @@ -479,10 +481,6 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror LowerName: strings.ToLower(name), Description: desc, IsPrivate: private, - IsBare: lang == "" && license == "" && !initReadme, - } - if !repo.IsBare { - repo.DefaultBranch = "master" } if _, err = sess.Insert(repo); err != nil { @@ -550,11 +548,11 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror if u.IsOrganization() { ous, err := GetOrgUsersByOrgId(u.Id) if err != nil { - log.Error(4, "repo.CreateRepository(GetOrgUsersByOrgId): %v", err) + log.Error(4, "GetOrgUsersByOrgId: %v", err) } else { for _, ou := range ous { if err = WatchRepo(ou.Uid, repo.Id, true); err != nil { - log.Error(4, "repo.CreateRepository(WatchRepo): %v", err) + log.Error(4, "WatchRepo: %v", err) } } } diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index bc52cdb628..16bd7defb8 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -245,8 +245,6 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount } - log.Debug("displayBare: %v; IsBare: %v", displayBare, ctx.Repo.Repository.IsBare) - // repo is bare and display enable if displayBare && ctx.Repo.Repository.IsBare { log.Debug("Bare repository: %s", ctx.Repo.RepoLink) diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css index 938610af76..244d6531d6 100644 --- a/public/ng/css/gogs.css +++ b/public/ng/css/gogs.css @@ -30,6 +30,16 @@ img.avatar-30 { height: 30px; vertical-align: middle; } +img.avatar-40 { + width: 40px; + height: 40px; + vertical-align: middle; +} +img.avatar-48 { + width: 48px; + height: 48px; + vertical-align: middle; +} #wrapper { padding: 0; margin: 0 0 -55px 0; @@ -188,15 +198,65 @@ img.avatar-30 { .main-wrapper { padding: 20px 0 40px; } +.user-list { + width: auto; + min-width: 180px; + max-width: 300px; +} +.user-list img { + width: 28px; + height: 28px; + margin-right: 1em; + margin-top: 1px; + vertical-align: middle; +} +.user-list li { + cursor: pointer; + font-weight: bold; +} .markdown { background-color: white; - font-size: 14px; + font-size: 16px; line-height: 24px; } .markdown .markdown-body { padding-left: 24px; padding-right: 16px; } +.markdown h5, +.markdown h6 { + font-size: 1em; +} +.markdown ul { + padding: 10px 0 0 15px; +} +.markdown ul li { + list-style: inside; +} +.markdown ol li { + list-style: decimal inside; +} +.markdown li { + line-height: 1.6; + margin-top: 6px; +} +.markdown li:first-child { + margin-top: 0; +} +.markdown > pre { + font-size: 14px; + line-height: 1.6; + overflow: auto; + border: 1px solid #ddd; + border-radius: .25em; + margin: 5px 0; + padding: 10px; + background-color: #f8f8f8; +} +.markdown img { + padding: 10px 0; + max-width: 100%; +} .markdown a { color: #428BCA; } @@ -233,12 +293,6 @@ img.avatar-30 { .markdown h4 { font-size: 18px; } -.markdown h5 { - font-size: 14px; -} -.markdown h6 { - font-size: 14px; -} .markdown table { border-collapse: collapse; border-spacing: 0; @@ -262,19 +316,6 @@ img.avatar-30 { .markdown table tr:nth-child(2n) { background-color: #f8f8f8; } -.markdown ul li { - list-style: inside; -} -.markdown ol li { - list-style: decimal inside; -} -.markdown li { - line-height: 1.6; - margin-top: 6px; -} -.markdown li:first-child { - margin-top: 0; -} .markdown dl dt { font-style: italic; margin-top: 9px; @@ -288,15 +329,6 @@ img.avatar-30 { font-size: 14px; background-color: #f5f5f5; } -.markdown > pre { - line-height: 1.6; - overflow: auto; - border: 1px solid #ddd; - border-radius: .25em; - margin: 5px 0; - padding: 10px; - background-color: #f8f8f8; -} .markdown > pre.linenums { padding: 0; } @@ -345,9 +377,6 @@ img.avatar-30 { .markdown p:last-child { margin-bottom: 0; } -.markdown img { - max-width: 100%; -} .markdown .btn { color: #fff; } @@ -740,9 +769,24 @@ The dashboard page style margin-right: 6px; font-size: 1.1em; } +#dashboard-selection-menu { + width: auto; + max-width: 300px; +} #dashboard-selection-menu > .drop-down { top: 56px; } +#dashboard-selection-menu li { + white-space: nowrap; +} +#dashboard-selection-menu li.checked .octicon { + opacity: 1; +} +#dashboard-selection-menu li a { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; +} #dashboard-switch-menu { border-bottom-left-radius: .3em; border-bottom-right-radius: .3em; @@ -1145,6 +1189,8 @@ The register and sign-in page style #repo-create-owner-list { top: 30px; left: 0; + width: auto; + max-width: 300px; } #repo-create-owner-list .octicon { margin-right: 12px; @@ -1154,9 +1200,17 @@ The register and sign-in page style width: 20px; height: 20px; } +#repo-create-owner-list li { + white-space: nowrap; +} #repo-create-owner-list li.checked .octicon { opacity: 1; } +#repo-create-owner-list li a { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; +} .file-name { margin-left: 1em; } @@ -1215,6 +1269,34 @@ The register and sign-in page style .repo-setting-zone { padding: 30px; } +#repo-collab-list { + list-style: none; + padding: 10px 0 5px 0; +} +#repo-collab-list li.collab { + clear: both; + height: 50px; + padding: 0 15px 0 15px; +} +#repo-collab-list a.member { + color: #444; + height: 50px; + line-height: 50px; +} +#repo-collab-list a.member:hover { + color: #4183C4; +} +#repo-collab-list .avatar { + margin-right: 1em; + width: 40px; +} +#repo-collab-list .remove-collab { + color: #DD4B39; +} +.repo-user-list-block { + position: relative; + top: 5px; +} #setting-wrapper { padding-bottom: 100px; } @@ -1368,6 +1450,7 @@ The register and sign-in page style .pr-nav { border-bottom: 1px solid #DDD; margin-top: 16px; + margin-bottom: 16px; } .pr-nav .octicon { margin-right: 4px; @@ -1384,7 +1467,7 @@ The register and sign-in page style font-size: 12px; margin-left: 4px; } -.pr-nav li.current > a { +.pr-nav li.js-tab-nav-show > a { background-color: #FFF; border-color: #E6E6E6; } @@ -1410,3 +1493,122 @@ The register and sign-in page style border-top-left-radius: .2em; border-bottom-left-radius: .2em; } +#pr-commit, +#pr-file-diff, +#issue-add-comment-preview { + display: none; +} +#pr-conversation-list { + padding-right: 30px; + box-sizing: border-box; +} +.issue-comment, +.issue-commit, +.issue-line, +.issue-merge, +.issue-add-comment { + margin-bottom: 16px; +} +.issue-comment .author-avatar img { + margin-right: 12px; +} +.issue-comment .panel { + margin-left: 60px; + margin-top: -40px; +} +.issue-comment .panel-header { + font-size: 13px; +} +.issue-comment .author-name { + font-weight: bold; +} +.issue-comment .date { + margin-left: 4px; + font-style: italic; + color: #888; +} +.issue-comment .action > * { + margin-left: 4px; + font-size: 12px; +} +.issue-comment .action i { + font-size: 13px; +} +.issue-commit { + line-height: 32px; +} +.issue-commit i, +.issue-commit .author-avatar img { + margin-right: 16px; +} +.issue-commit .sha { + margin-left: 24px; +} +.issue-commit .message { + display: block; + margin-left: 88px; + padding-top: 4px; + line-height: 24px; +} +.issue-merge .ico { + width: 40px; + height: 40px; + text-align: center; + color: #FFF; + margin-right: 12px; +} +.issue-merge .ico i { + margin-top: 8px; + font-size: 24px; +} +.issue-merge .panel { + margin-left: 60px; + margin-top: -40px; +} +.issue-merge .panel-header { + font-size: 13px; +} +.issue-merge-ok .ico { + background-color: #65AD4E; +} +.issue-merge-ok .panel, +.issue-merge-ok .panel-content, +.issue-merge-ok .panel-header { + border-color: #65AD4E; + background-color: #FFF; +} +.issue-merge-ok .panel-header { + color: #508a3e; +} +.issue-line { + height: 4px; + background-color: #E6E6E6; +} +.issue-add-comment .panel { + margin-left: 60px; + margin-top: -40px; +} +.issue-add-comment .panel-header { + font-size: 13px; + padding-bottom: 0; +} +.issue-add-comment .add-nav > li > a { + padding: 4px 12px; + color: #444; + border: 1px solid #CCC; + margin-bottom: -1px; + font-size: 14px; + border-top-left-radius: .3em; + border-top-right-radius: .3em; +} +.issue-add-comment .add-nav > li > a:hover { + background-color: #FFF; +} +.issue-add-comment .add-nav > li.js-tab-nav-show > a { + background-color: #FFF; +} +textarea#issue-add-content { + width: 100%; + box-sizing: border-box; + height: 120px; +} diff --git a/public/ng/css/ui.css b/public/ng/css/ui.css index 5a5f7dc90a..d30e137dbc 100644 --- a/public/ng/css/ui.css +++ b/public/ng/css/ui.css @@ -59,7 +59,8 @@ audio:not([controls]) { height: 0; } [hidden], -template .hidden { +template, +.hidden { display: none; } .opacity { @@ -72,6 +73,7 @@ a, .text-link { color: #428bca; text-decoration: none; + cursor: pointer; } a:hover, .text-link:hover { @@ -604,6 +606,12 @@ ul.menu-down { box-shadow: 0 0 2px #666666; background-color: #ffffff; } +ul.menu-down-show { + position: absolute; + z-index: 99; + box-shadow: 0 0 2px #666666; + background-color: #ffffff; +} ul.menu-radius { border-radius: .3em; } @@ -681,6 +689,10 @@ ul.menu-radius > li:last-child > a { border-bottom-left-radius: .3em; border-bottom-right-radius: .3em; } +.panel.panel-radius .panel-content { + border-bottom-left-radius: .3em; + border-bottom-right-radius: .3em; +} .panel.panel-warning { border-color: #F0C36D; } diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js index 37144ce99e..473997e9ee 100644 --- a/public/ng/js/gogs.js +++ b/public/ng/js/gogs.js @@ -52,6 +52,59 @@ var Gogs = {}; } } }); + $.fn.extend({ + toggleHide: function () { + $(this).addClass("hidden"); + }, + toggleShow: function () { + $(this).removeClass("hidden"); + }, + toggleAjax: function (successCallback, errorCallback) { + var url = $(this).data("ajax"); + var method = $(this).data('ajax-method') || 'get'; + var ajaxName = $(this).data('ajax-name'); + var data = {}; + + if (ajaxName.endsWith("preview")) { + data["mode"] = "gfm"; + data["context"] = $(this).data('ajax-context'); + } + + $('[data-ajax-rel=' + ajaxName + ']').each(function () { + var field = $(this).data("ajax-field"); + var t = $(this).data("ajax-val"); + if (t == "val") { + data[field] = $(this).val(); + return true; + } + if (t == "txt") { + data[field] = $(this).text(); + return true; + } + if (t == "html") { + data[field] = $(this).html(); + return true; + } + if (t == "data") { + data[field] = $(this).data("ajax-data"); + return true; + } + return true; + }); + console.log("toggleAjax:", method, url, data); + $.ajax({ + url: url, + method: method.toUpperCase(), + data: data, + error: errorCallback, + success: function (d) { + if (successCallback) { + successCallback(d); + } + } + }) + } + }); }(jQuery)); (function ($) { @@ -145,6 +198,26 @@ var Gogs = {}; } }).trigger('hashchange'); }; + + // Search users by keyword. + Gogs.searchUsers = function (val, $target) { + $.ajax({ + url: '/api/v1/users/search?q=' + val, + dataType: "json", + success: function (json) { + if (json.ok && json.data.length) { + var html = ''; + $.each(json.data, function (i, item) { + html += '
  • ' + item.username + '
  • '; + }); + $target.html(html); + $target.toggleShow(); + } else { + $target.toggleHide(); + } + } + }); + } })(jQuery); function initCore() { @@ -175,6 +248,7 @@ function initRepoCreate() { } function initRepoSetting() { + // Options. // Confirmation of changing repository name. $('#repo-setting-form').submit(function (e) { var $reponame = $('#repo_name'); @@ -189,6 +263,27 @@ function initRepoSetting() { $('#delete-button').click(function () { $('#delete-form').show(); }); + + // Collaboration. + $('#repo-collab-list hr:last-child').remove(); + var $ul = $('#repo-collaborator').next().next().find('ul'); + $('#repo-collaborator').on('keyup', function () { + var $this = $(this); + if (!$this.val()) { + $ul.toggleHide(); + return; + } + Gogs.searchUsers($this.val(), $ul); + }).on('focus', function () { + if (!$(this).val()) { + $ul.toggleHide(); + } else { + $ul.toggleShow(); + } + }).next().next().find('ul').on("click", 'li', function () { + $('#repo-collaborator').val($(this).text()); + $ul.toggleHide(); + }); } $(document).ready(function () { diff --git a/public/ng/less/gogs/base.less b/public/ng/less/gogs/base.less new file mode 100644 index 0000000000..0cadabe869 --- /dev/null +++ b/public/ng/less/gogs/base.less @@ -0,0 +1,233 @@ +@import "../ui/var"; +@headerBgColor: #428BCA; +@headerLinkFontColor: #FFF; +@headerLinkHoverColor: #fff65f; +@headerLinkCurrentColor: #fff65f; +@headerSignOutColor: #ff908b; +@footerBorderColor: #D6D6D6; +@footerFontColor: #888; +@langNum: 2px; +// means 2 items +html, +body { + height: 100%; +} +.octicon, +.fa { + width: 16px; + text-align: center; +} +.fa { + font-size: 14px; +} +.container { + max-width: 1170px; + padding: 0 1.5em; + margin: auto; +} +img.avatar-16 { + width: 16px; + height: 16px; + vertical-align: middle; +} +img.avatar-24 { + width: 24px; + height: 24px; + vertical-align: middle; +} +img.avatar-30 { + width: 30px; + height: 30px; + vertical-align: middle; +} +img.avatar-40 { + width: 40px; + height: 40px; + vertical-align: middle; +} +img.avatar-48{ + width: 48px; + height: 48px; + vertical-align: middle; +} +#wrapper { + padding: 0; + margin: 0 0 -55px 0; + min-height: 100%; +} +#footer { + background-color: white; + border-top: 1px solid@footerBorderColor; + +clear: both; + width: 100%; + .container { + padding: 15px; + } + color:@footerFontColor; +.official, + .version { + color: @footerFontColor; + } +} +#footer-links { + > * { + border-left: 1px solid@footerBorderColor; + padding-left: 8px; + margin-left: 5px; + &:first-child { + border-left: none; + } + } +} +#footer-lang { + position: relative; + .drop-down { + top: -2-31*@langNum; + left: -2px; + position: absolute; + height: -3+31*@langNum; + z-index: 100; + font-size: 12px; + width: 120%; + li > a { + padding: 3px 9px; + } + } +} +#header { + background-color: @headerBgColor; + height: 44px; + > .menu-line { + > li > a { + display: inline-block; + color:@headerLinkFontColor; + &:hover { + background-color: transparent; + color: @headerLinkHoverColor; + } + } + > li.head { + color: @headerLinkFontColor; + } + > li.hover a:after { + bottom: -9px; + color: @headerLinkFontColor; + } + > li.current > a { + color: @headerLinkCurrentColor; + font-weight: bold; + } + } +} +#header-nav-user { + height: 44px; + img { + margin: -4px 10px 0 0; + border-radius: 3px; + } +} +#header-nav-sign-out > a:hover { + color: @headerSignOutColor !important; +} +#header-nav-logo { + padding: 6px 1.2em; +} +#header-nav-explore, +#header-nav-help { + font-size: 14px; +} +#header-new-repo-menu { + width: 180px; + background-color: #FFF; + top: 44px; + border-top: none; + .octicon { + margin-right: 6px; + font-size: 1.1em; + } + left:-66px; +} +.switching-list { + width: 100%; + list-style: none; + > li { + border-bottom: 1px solid #eaeaea; + &:last-child { + border-bottom: none; + } + > a { + padding: .4em 1.2em; + display: block; + color: #444; + &:hover { + background-color: #428bca !important; + color: #fff !important; + } + } + } +} +.social-buttons { + .btn { + border: none; + font-size: 16px; + border-radius: 4px; + margin-right: 12px; + font-family: 'PT Sans Narrow', sans-serif; + padding: 5px 12px; + color: #FFF; + .fa { + margin-right: 6px; + font-size: 16px; + } + } + .twitter { + background-color: #1c6399; + &:hover { + background-color: #1c5487; + } + } + .github { + background-color: #444; + &:hover { + background-color: #333; + } + } + .google { + background-color: #C03D20; + &:hover { + background-color: #D56060; + } + } + .weibo { + background-color: #bf1324; + &:hover { + background-color: #b94c4a; + } + } + .qq { + background-color: #03a2ef; + &:hover { + background-color: #3cb3ff; + } + } +} +.main-wrapper { + padding: 20px 0 40px; +} +.user-list { + width: auto; + min-width: 180px; + max-width: 300px; + img { + width: 28px; + height: 28px; + margin-right: 1em; + margin-top: 1px; + vertical-align: middle; + } + li { + cursor: pointer; + font-weight: bold; + } +} \ No newline at end of file diff --git a/public/ng/less/gogs/dashboard.less b/public/ng/less/gogs/dashboard.less new file mode 100644 index 0000000000..f8838ae6fd --- /dev/null +++ b/public/ng/less/gogs/dashboard.less @@ -0,0 +1,259 @@ +@import "../ui/var"; + +/* +The dashboard page style +*/ + +@dashboardHeaderBorderColor: #D6D6D6; +@dashboardHeaderLinkColor: #444; +@dashboardHeaderLinkHoverColor: #D9453D; +@dashboardSwitchMenuHoverBgColor: @linkColor; +@dashboardSwitchMenuHoverFontColor: #FFF; + +// dashboard header, contains dashboard selection menu and nav of Feed/PR/Issues. +#dashboard-header { + border-bottom: 1px solid @dashboardHeaderBorderColor; + height: 69px; + > .menu-line { + > li { + padding: 12px 0; + } + > li.right { + > a { + font-size: 1.2em; + color: @dashboardHeaderLinkColor; + &:hover { + background-color: transparent; + color: @dashboardHeaderLinkHoverColor; + } + .octicon { + margin-right: 6px; + } + } + .current { + border-bottom: 2px solid #D26911; + } + } + } +} + +// dashboard context switch selection +#dashboard-selection-menu { + a img { + margin: -4px 10px 0 0; + } +} + +#dashboard { + padding: 24px 0; +} + +// dashboard sidebar contains contributed repositories panel, +// and my repositories panel +#dashboard-sidebar { + .panel-header h4 { + margin: 0; + } + > .panel { + margin-bottom: 24px; + border-bottom-left-radius: .3em; + border-bottom-right-radius: .3em; + } +} + +#dashboard-sidebar-menu { + border-top-left-radius: .3em; + border-top-right-radius: .3em; + > li { + border: 1px solid #d6d6d6; + float: left; + margin-right: -1px; + border-bottom: none; + > a { + padding-top: .4em; + padding-bottom: .4em; + } + } + > li.first { + border-top-left-radius: .3em; + > a { + border-top-left-radius: .3em; + } + } + > li.drop { + border: none; + float: right; + } + width: 100%; + height: 35px; + > li.js-tab-nav-show { + background-color: #EEEEEE; + } + > li.last { + border-top-right-radius: .3em; + > a { + border-top-right-radius: .3em; + } + } +} + +#dashboard-my-mirror, +#dashboard-my-org, +#dashboard-my-repo { + li { + &.private { + background-color: #fcf8e9; + } + border-bottom: 1px solid #EAEAEA; + &:last-child { + border-bottom: none; + } + a { + padding: 6px 1.2em; + display: block; + .octicon { + margin-right: 6px; + color: #888; + } + &:hover { + .repo-name { + text-decoration: underline; + } + } + } + } + .repo-name { + font-size: 1.1em; + } + .repo-star { + color: #888; + } + .repo-contrib-header { + border-top: 1px solid #d6d6d6; + } +} + +#dashboard-my-repo { + .panel-header { + .octicon { + margin-right: 6px; + font-size: 12px; + } + } + .repo-count { + margin-left: 4px; + } +} + +#dashboard-my-org, +#dashboard-my-mirror { + display: none; +} + +// the button of new repository in my repositories panel +#dashboard-new-repo { + width: 50px; + height: 35px; + padding-top: 6px; + margin-right: 1px; + .octicon { + font-size: 2em; + } + border-top-left-radius: .3em; + border-top-right-radius: .3em; +} + +// the drop-down menu of #dashboard-new-repo +#dashboard-new-repo-menu { + top: 35px; + width: 180px; + background-color: #FFF; + left: -132px; + .octicon { + margin-right: 6px; + font-size: 1.1em; + } +} + +#dashboard-selection-menu { + width: auto; + max-width: 300px; + > .drop-down { + top: 56px; + } + li { + white-space: nowrap; + &.checked { + .octicon { + opacity: 1; + } + } + a { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + } + } +} + +// the drop-down menu of #dashboard-selection-menu +#dashboard-switch-menu { + > li { + > a { + img { + margin-top: 0; + } + .octicon { + margin-right: 12px; + } + } + &:last-child { + > a { + border-bottom-left-radius: .3em; + border-bottom-right-radius: .3em; + } + } + } + > li.org > a { + .octicon { + opacity: 0; + } + } + > li.checked > a { + .octicon { + opacity: 1; + } + font-weight: bold; + } + border-bottom-left-radius: .3em; + border-bottom-right-radius: .3em; +} + +#dashboard-news { + .news { + margin-right: 2.4em; + .mega-octicon { + color: #CCC; + } + .avatar { + margin: 0 1.2em; + } + .news-content, + .news-time { + color: #888; + } + padding-bottom: 1em; + margin-bottom: 1em; + border-bottom: 1px solid #E6E6E6; + min-height: 30px; + } + .push-news { + .news-content li { + margin-left: 1em; + img { + margin-bottom: -2px; + } + } + } +} + diff --git a/public/ng/less/gogs/external.less b/public/ng/less/gogs/external.less new file mode 100644 index 0000000000..b8d2e55156 --- /dev/null +++ b/public/ng/less/gogs/external.less @@ -0,0 +1,97 @@ +@import "base"; +@import "../ui/var"; +#promo-wrapper { + padding-top: 50px; + background-color: @headerBgColor; +} + +#promo-logo { + img { + max-width: 250px; + } + margin-right: 50px; + padding-bottom: 50px; +} + +#promo-content { + color: #FFF; + margin-left: 300px; + h1, + h2 { + font-family: 'PT Sans Narrow', sans-serif; + line-height: 60px; + margin-bottom: 0; + text-shadow: 0 2px 1px rgba(0, 0, 0, 0.5); + } + h1 { + font-size: 96px; + line-height: 96px; + margin-bottom: 30px; + } + h2 { + font-size: 52px; + line-height: 70px; + font-weight: normal; + } +} + +#promo-form { + padding: 40px 0; + .ipt-large { + border: none; + border-radius: 4px; + font-size: 18px; + &:focus { + box-shadow: 0 0 3px #FFF; + } + margin-right: 12px; + } + .btn-large { + border-radius: 4px; + font-size: 18px; + margin-right: 12px; + } +} + +#promo-social { + padding-bottom: 60px; + .qq{ + box-shadow: 0 0 1px #1c6399; + } +} + +#feature-wrapper { + font-family: Lato, sans-serif; + font-size: 18px; + padding: 50px 0 100px 0; + .octicon { + color: @btnRedColor; + font-size: 60px; + height: 60px; + width: 60px; + line-height: 60px; + margin-right: 12px; + vertical-align: middle; + display: inline-block; + } + b { + color: #000; + font-size: 24px; + display: inline-block; + line-height: 60px; + } + p { + margin: 1em 0; + line-height: 40px; + padding-right: 30px; + } + a { + color: @btnRedColor; + &:hover { + color: @btnHoverRedColor; + } + } + .grid-1-2 { + margin-bottom: 30px; + } +} \ No newline at end of file diff --git a/public/ng/less/gogs/issue.less b/public/ng/less/gogs/issue.less new file mode 100644 index 0000000000..ae481f0e20 --- /dev/null +++ b/public/ng/less/gogs/issue.less @@ -0,0 +1,262 @@ +@import "../ui/var"; + +.repo-issue-wrapper { + padding: 18px 0; +} + +.pr-main { + padding-right: 40px; + box-sizing: border-box; +} + +.pr-sidebar { + border-left: 1px solid #DDD; + box-sizing: border-box; +} + +#pr-sidebar-nav { + margin-top: 6px; + li { + margin-bottom: 4px; + } + li > a { + border: 1px solid transparent; + border-left: none; + &:hover { + background-color: #FFF; + border-color: #DDD; + } + } + .label { + font-size: 12px; + line-height: 1.4em; + margin-top: 1px; + } + li.current { + a { + background-color: #FFF; + border-color: #DDD; + } + } +} + +.pr-title { + .pr-num { + font-weight: normal; + color: #888; + } +} + +.pr-meta { + color: #888; + .pr-author { + margin: 0 8px; + color: #444; + &:hover { + text-decoration: underline; + } + } + .pr-branch { + margin: 0 4px; + font-size: 12px; + padding: 4px 6px; + } +} + +.pr-nav { + border-bottom: 1px solid #DDD; + margin-top: 16px; + margin-bottom: 16px; + .octicon { + margin-right: 4px; + } + li > a { + padding: 3px 9px !important; + border: 1px solid transparent; + border-bottom: none; + .label { + padding: 1px 5px; + font-size: 12px; + margin-left: 4px; + } + border-top-left-radius: .2em; + border-top-right-radius: .2em; + } + li.js-tab-nav-show { + > a { + background-color: #FFF; + border-color: #E6E6E6; + } + } +} + +.diff-bar { + .diff-add { + color: @btnGreenColor; + } + .diff-delete { + color: @btnRedColor; + } + .diff-status { + width: 50px; + background-color: @btnRedColor; + height: 10px; + margin-top: 7px; + margin-left: 4px; + margin-right: 4px; + border-radius: .2em; + } + .diff-status-inner { + width: 45%; + background-color: @btnGreenColor; + height: 10px; + border-top-left-radius: .2em; + border-bottom-left-radius: .2em; + } +} + +#pr-commit, +#pr-file-diff, +#issue-add-comment-preview { + display: none; +} + +#pr-conversation-list { + padding-right: 30px; + box-sizing: border-box; +} + +.issue-comment, +.issue-commit, +.issue-line, +.issue-merge, +.issue-add-comment { + margin-bottom: 16px; +} + +.issue-comment { + .author-avatar { + img { + margin-right: 12px; + } + } + .panel { + margin-left: 60px; + margin-top: -40px; + } + .panel-header { + font-size: 13px; + } + .author-name { + font-weight: bold; + } + .date { + margin-left: 4px; + font-style: italic; + color: #888; + } + .action { + > * { + margin-left: 4px; + font-size: 12px; + } + i { + font-size: 13px; + } + } +} + +.issue-commit { + line-height: 32px; + i, .author-avatar img { + margin-right: 16px; + } + .sha { + margin-left: 24px; + } + .message { + display: block; + margin-left: 88px; + padding-top: 4px; + line-height: 24px; + } +} + +.issue-merge { + .ico { + width: 40px; + height: 40px; + text-align: center; + color: #FFF; + i { + margin-top: 8px; + font-size: 24px; + } + margin-right: 12px; + } + .panel { + margin-left: 60px; + margin-top: -40px; + } + .panel-header { + font-size: 13px; + } +} + +.issue-merge-ok { + .ico { + background-color: #65AD4E; + } + .panel, + .panel-content, + .panel-header { + border-color: #65AD4E; + background-color: #FFF; + } + .panel-header { + color: darken(#65AD4E, 10%); + } +} + +.issue-line { + height: 4px; + background-color: #E6E6E6; +} + +.issue-add-comment { + .panel { + margin-left: 60px; + margin-top: -40px; + } + .panel-header { + font-size: 13px; + padding-bottom: 0; + } + .add-nav { + > li { + > a { + padding: 4px 12px; + color: #444; + border: 1px solid #CCC; + margin-bottom: -1px; + font-size: 14px; + border-top-left-radius: .3em; + border-top-right-radius: .3em; + &:hover { + background-color: #FFF; + } + } + &.js-tab-nav-show { + > a { + background-color: #FFF; + } + } + } + } +} + +textarea#issue-add-content { + width: 100%; + box-sizing: border-box; + height: 120px; +} \ No newline at end of file diff --git a/public/ng/less/gogs/markdown.less b/public/ng/less/gogs/markdown.less new file mode 100644 index 0000000000..898f8e774d --- /dev/null +++ b/public/ng/less/gogs/markdown.less @@ -0,0 +1,322 @@ +.markdown { + background-color: white; + font-size: 16px; + line-height: 24px; + .markdown-body { + padding-left: 24px; + padding-right: 16px; + } + h5, + h6 { + font-size: 1em; + } + ul { + padding: 10px 0 0 15px; + li { + list-style: inside; + } + } + ol li { + list-style: decimal inside; + } + li { + line-height: 1.6; + margin-top: 6px; + &:first-child { + margin-top: 0; + } + } + > pre { + font-size: 14px; + line-height: 1.6; + overflow: auto; + border: 1px solid #ddd; + border-radius: .25em; + margin: 5px 0; + padding: 10px; + background-color: #f8f8f8; + } + img { + padding: 10px 0; + max-width: 100%; + } +} +.markdown a { + color: #428BCA; +} +.markdown h1, +.markdown h2, +.markdown h3, +.markdown h4, +.markdown h5, +.markdown h6 { + line-height: 1.7; + padding: 15px 0 0; + margin: 0 0 15px; + color: #444; + font-weight: bold; +} +.markdown h1, +.markdown h2 { + border-bottom: 1px solid #E0E0E0; +} +.markdown h2 { + border-bottom: 1px solid #E0E0E0; +} +.markdown h1 { + color: #000; + font-size: 33px +} +.markdown h2 { + color: #333; + font-size: 28px +} +.markdown h3 { + font-size: 22px +} +.markdown h4 { + font-size: 18px +} +.markdown table { + border-collapse: collapse; + border-spacing: 0; + display: block; + overflow: auto; + width: 100%; + margin: 0 0 9px; +} +.markdown table th { + font-weight: 700 +} +.markdown table th, +.markdown table td { + border: 1px solid #DDD; + padding: 6px 13px; +} +.markdown table tr { + background-color: #FFF; + border-top: 1px solid #CCC; +} +.markdown table tr:nth-child(2n) { + background-color: #F8F8F8 +} +.markdown dl dt { + font-style: italic; + margin-top: 9px; +} +.markdown dl dd { + margin: 0 0 9px; + padding: 0 9px; +} +.markdown blockquote, +.markdown blockquote p { + font-size: 14px; + background-color: #f5f5f5; +} +.markdown > pre.linenums { + padding: 0; +} +.markdown > pre > ol.linenums { + list-style: none; + padding: 0; +} +.markdown > pre > ol.linenums > li { + margin-top: 2px; +} +.markdown > pre.nums-style > ol.linenums { + list-style-type: decimal; + padding: 0 0 0 40px; + -webkit-box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc; + box-shadow: inset 40px 0 0 #f5f5f5, inset 41px 0 0 #ccc; +} +.markdown > pre > code { + white-space: pre; + word-wrap: normal; +} +.markdown > pre > ol.linenums > li { + padding: 0 10px; +} +.markdown > pre > ol.linenums > li:first-child { + padding-top: 12px; +} +.markdown > pre > ol.linenums > li:last-child { + padding-bottom: 12px; +} +.markdown > pre.nums-style > ol.linenums > li { + border-left: 1px solid #ddd; +} +.markdown hr { + border: none; + color: #ccc; + height: 4px; + padding: 0; + margin: 15px 0; + border-bottom: 2px solid #EEE; +} +.markdown blockquote:last-child, +.markdown ul:last-child, +.markdown ol:last-child, +.markdown > pre:last-child, +.markdown > pre:last-child, +.markdown p:last-child { + margin-bottom: 0; +} +.markdown .btn { + color: #fff; +} +.markdown h1 a, +.markdown h2 a, +.markdown h3 a { + text-decoration: none; +} +.markdown h1 a.anchor, +.markdown h2 a.anchor, +.markdown h3 a.anchor, +.markdown h4 a.anchor, +.markdown h5 a.anchor, +.markdown h6 a.anchor { + text-decoration: none; + line-height: 1; + padding-left: 0; + margin-left: -24px; + top: 15%; +} +.markdown a span.octicon { + font-size: 16px; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + margin-left: 30px; +} +.markdown a span.octicon-link { + opacity: 0; + color: #444; +} +.markdown h1:hover .octicon-link, +.markdown h2:hover .octicon-link, +.markdown h3:hover .octicon-link, +.markdown h4:hover .octicon-link, +.markdown h5:hover .octicon-link, +.markdown h6:hover .octicon-link { + display: inline-block; + opacity: 1; +} +/* Author: jmblog */ + +/* Project: https://github.com/jmblog/color-themes-for-google-code-prettify */ + +/* GitHub Theme */ + +/* Pretty printing styles. Used with prettify.js. */ + +/* SPAN elements with the classes below are added by prettyprint. */ + +/* plain text */ + +.pln { + color: #333333; +} +@media screen { + /* string content */ + .str { + color: #dd1144; + } + /* a keyword */ + .kwd { + color: #333333; + } + /* a comment */ + .com { + color: #999988; + font-style: italic; + } + /* a type name */ + .typ { + color: #445588; + } + /* a literal value */ + .lit { + color: #445588; + } + /* punctuation */ + .pun { + color: #333333; + } + /* lisp open bracket */ + .opn { + color: #333333; + } + /* lisp close bracket */ + .clo { + color: #333333; + } + /* a markup tag name */ + .tag { + color: navy; + } + /* a markup attribute name */ + .atn { + color: teal; + } + /* a markup attribute value */ + .atv { + color: #dd1144; + } + /* a declaration */ + .dec { + color: #333333; + } + /* a variable name */ + .var { + color: teal; + } + /* a function name */ + .fun { + color: #990000; + } +} +/* Use higher contrast and text-weight for printable form. */ + +@media print, +projection { + .str { + color: #006600; + } + .kwd { + color: #006; + font-weight: bold; + } + .com { + color: #600; + font-style: italic; + } + .typ { + color: #404; + font-weight: bold; + } + .lit { + color: #004444; + } + .pun, + .opn, + .clo { + color: #444400; + } + .tag { + color: #006; + font-weight: bold; + } + .atn { + color: #440044; + } + .atv { + color: #006600; + } +} +/* Specify class=linenums on a pre to get line numbering */ + +ol.linenums { + margin-top: 0; + margin-bottom: 0; +} \ No newline at end of file diff --git a/public/ng/less/gogs/repository.less b/public/ng/less/gogs/repository.less new file mode 100644 index 0000000000..1847c44e53 --- /dev/null +++ b/public/ng/less/gogs/repository.less @@ -0,0 +1,472 @@ +@import "../ui/var"; + +@repoHeaderBorderColor: #D6D6D6; +@repoHeaderBgColor: #FFF; +@repoHeaderNameColor: #888; + +/* repository main */ +#repo-wrapper { + padding-bottom: 100px; +} +#repo-header { + height: 69px; + border-bottom: 1px solid @repoHeaderBorderColor; + background-color: @repoHeaderBgColor; +} +#repo-header-name { + line-height: 66px; + color: @repoHeaderNameColor; + font-size: 1.6em; + font-weight: normal; + margin-bottom: 0; + i { + margin-right: 12px; + vertical-align: middle; + } + .divider { + margin: 0 4px; + } +} + +#repo-header-meta { + line-height: 66px; + li { + > a { + padding: 0; + &:hover { + background-color: transparent; + } + } + } + a > .btn { + font-size: 1.05em; + margin-left: 16px; + i { + margin-right: 6px; + } + line-height: 16px; + .num { + margin-left: 6px; + } + } +} + +#repo-header-download-btn { + > .btn > i { + margin-right: 0 !important; + } + &:hover { + &:after, + .btn { + background-color: @btnHoverBlackColor; + color: #FFF; + } + } + &:after { + background-color: @btnBlackColor; + padding: 9px 16px 8px 0; + margin-left: -8px !important; + color: #FFF; + border-top: 1px solid @btnBlackColor; + border-bottom: 1px solid @btnBlackColor; + border-top-right-radius: .25em; + border-bottom-right-radius: .25em; + } +} + +#repo-header-download-drop { + line-height: 24px; + width: 440px; + top: 50px; + left: -354px; + padding: 20px; + box-sizing: border-box; + .btn > i { + margin-right: 6px; + } +} + +#repo-content { + padding: 18px 0; +} + +#repo-clone-url { + border-right: none; + width: 196px; + border-left: none; +} + +#repo-clone-help { + line-height: 48px; +} + +#repo-clone-zip { + line-height: 48px; + a { + cursor: pointer; + color: white; + overflow: visible; + padding: .6em 1.2em; + } + .btn { + margin: 0 6px; + } +} + +#repo-desc { + font-size: 1.2em; +} + +#repo-sidebar-nav { + .label { + font-size: 12px; + line-height: 1.4em; + margin-top: 2px; + } + i { + margin-right: 6px; + } +} + +#repo-file-nav { + padding: .6em 0 1em 0; + > li > a { + padding-left: 0; + &:hover { + background-color: transparent; + } + } + li.repo-jump > a { + padding-right: 0; + .btn { + margin-left: -1px; + } + } +} + +#repo-branch-switch { + > a { + .btn { + padding-right: 30px; + } + &:after { + position: absolute; + top: 12px; + right: 30px; + margin-left: 0; + color: @baseFontColor; + } + } + > .drop-down { + top: 40px; + left: 0; + } +} + +#repo-branch-filter-ipt { + width: 100%; + border-left: none; + border-right: none; + box-sizing: border-box; +} + +#repo-branch-tag { + .tab-nav { + border-bottom: 1px solid #EAEAEA; + a { + padding: .3em .8em; + } + .js-tab-nav-show { + background-color: #EEE; + font-weight: bold; + } + } +} + +#repo-branch-list, +#repo-tag-list { + li { + i { + margin-right: 12px; + opacity: 0; + } + } + li.checked { + i { + opacity: 1; + } + } +} + +#repo-tag-list { + display: none; +} + +#repo-bread { + .bread { + padding-right: 0; + font-size: 16px; + font-weight: bold; + } +} + +#repo-main { + padding-right: 40px; + box-sizing: border-box; +} + +#repo-files-table { + margin-bottom: 20px; + th, + td { + text-align: left; + line-height: 32px; + } + td.icon { + width: 16px; + padding-right: .1em; + padding-left: 1em; + } + td.name { + max-width: 120px; + .text-truncate { + max-width: 100%; + } + } + td.age { + max-width: 120px; + text-align: right; + } + td.msg { + max-width: 440px; + .text-truncate { + max-width: 100%; + } + } + td.age, + td.size, + td.msg a { + color: #888; + } + td.msg a:hover { + color: #428BCA; + text-decoration: underline; + } + tbody { + background-color: #FFF; + tr:hover { + background-color: #ffffEE; + } + } + thead { + background-color: #F0F0F0; + .author { + a { + margin: 0 .4em; + } + } + .last-commit { + strong { + color: #444; + } + .text-truncate { + margin-left: .4em; + } + } + .last-commit .text-truncate, + .age { + font-weight: normal; + color: #888; + } + } +} + +#repo-readme { + margin-bottom: 80px; +} + +#repo-bare-start { + margin-bottom: 100px; + .panel-content { + background-color: #FFF; + } + pre { + margin: 0 40px; + padding: 6px 10px; + border: 1px solid #ddd; + background: #f8f8f8; + } +} + +.repo-bare { + #repo-bare-start { + h2 { + margin-top: 30px; + margin-bottom: 24px; + } + } + #repo-header-meta { + display: none; + } + #repo-clone-ssh { + margin-left: 200px; + } + #repo-clone-copy { + margin-right: 200px; + } + #repo-clone-help { + clear: both; + width: 100%; + } + #repo-clone-url { + width: 520px; + } +} + +/* repository create */ + +#repo-migrate-form, +#repo-create-form { + width: 800px; + margin: 60px auto auto auto; + background: white; + h2 { + margin: .5em 1em; + } + .field { + margin: 1.2em 0 2em 0; + } + .ipt { + width: 540px; + } + textarea { + height: 120px; + } + .avatar { + vertical-align: middle; + margin-right: .6em; + width: 28px; + height: 28px; + } + &:hover { + box-shadow: 0px 0px 6px #CCC; + } +} + +#repo-create-cancel { + margin-left: 4em; +} + +#repo-create-owner-list { + top: 30px; + left: 0; + width: auto; + max-width: 300px; + .octicon { + margin-right: 12px; + opacity: 0; + } + .avatar { + width: 20px; + height: 20px; + } + li { + white-space: nowrap; + &.checked { + .octicon { + opacity: 1; + } + } + a { + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + overflow: hidden; + } + } +} +.file-name { + margin-left: 1em; +} +.file-size { + font-size: 13px; + color: #888; + margin-left: 1em; +} +.code-view { + overflow: auto; + overflow-x: auto; + overflow-y: hidden; + background: white; + .view-raw { + min-height: 40px; + text-align: center; + padding-top: 20px; + .btn { + font-size: 1.05em; + line-height: 16px; + padding: 6px 8px; + } + } + table { + width: 100%; + td { + padding: 0; + } + } + .lines-num { + text-align: right; + color: #999; + background: #f5f5f5; + width: 1%; + span { + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + line-height: 18px; + padding: 0 8px 0 10px; + cursor: pointer; + display: block; + margin-top: 2px; + font-size: 12px; + } + } + .lines-code > pre { + border: none; + border-left: 1px solid #ddd; + > ol.linenums > li { + padding: 0 10px; + &.active { + background: #ffffdd; + } + } + } +} +.repo-setting-zone { + padding: 30px; +} +#repo-collab-list { + list-style: none; + padding: 10px 0 5px 0; + li.collab { + clear: both; + height: 50px; + padding: 0 15px 0 15px; + } + a.member { + color: #444; + height: 50px; + line-height: 50px; + &:hover { + color: #4183C4; + } + } + .avatar { + margin-right: 1em; + width: 40px; + } + .remove-collab { + color: #DD4B39; + } +} +.repo-user-list-block { + position: relative; + top: 5px; +} \ No newline at end of file diff --git a/public/ng/less/gogs/settings.less b/public/ng/less/gogs/settings.less new file mode 100644 index 0000000000..076c30bb6b --- /dev/null +++ b/public/ng/less/gogs/settings.less @@ -0,0 +1,103 @@ +@import "../ui/var"; + +#setting-wrapper { + padding-bottom: 100px; +} + +#setting-menu { + box-sizing: border-box; + li > a { + border-left: 2px solid #FFF; + background-color: #FFF; + } + li:hover { + a { + border-left: 2px solid #EFEFEF; + background-color: #EFEFEF !important; + color: #000 !important; + } + border-color: #EAEAEA; + } + li.current { + a { + color: #000 !important; + font-weight: bold; + border-left: 2px solid #d26911; + } + } +} + +.setting-content { + margin-left: 32px; +} + +#repo-setting-form, +#user-profile-form { + background-color: #FFF; + padding: 30px 0; + textarea { + margin-left: 4px; + height: 100px; + } + label, + .form-label { + width: 240px; + } + .ipt { + width: 360px; + } + .field { + margin-bottom: 24px; + } +} + +#user-ssh-panel { + margin-bottom: 20px; + .switching-list { + background-color: #FFF; + li { + padding: 8px 20px; + &.ssh:hover { + background-color: #ffffEE; + } + } + } + .active-icon { + width: 10px; + height: 10px; + border-radius: 6px; + padding: 0; + margin-right: 20px; + margin-top: 10px; + } + .ssh-content { + margin-left: 24px; + .octicon { + margin-right: 4px; + } + .print, + .activity { + color: #888; + } + } + .ssh-delete-btn { + margin-top: 6px; + } +} + +#user-ssh-add-form { + .panel-body { + background-color: #FFF; + padding: 30px 0; + } + .ipt { + width: 500px; + } + textarea { + height: 120px; + margin-left: 3px; + } + .field { + margin-bottom: 24px; + } +} \ No newline at end of file diff --git a/public/ng/less/gogs/sign.less b/public/ng/less/gogs/sign.less new file mode 100644 index 0000000000..55a9ffbbd9 --- /dev/null +++ b/public/ng/less/gogs/sign.less @@ -0,0 +1,63 @@ +@import "../ui/var"; + +/* +The register and sign-in page style +*/ + +@signPanelBgColor: #FFF; + +#sign-wrapper { + padding: 60px 0; +} + +.sign-panel { + background-color: @signPanelBgColor; +} + +.sign-form.form-align { + .field { + margin: 1.2em 0 2em 0; + } + .ipt-large { + width: 300px; + } + label, + .form-label { + width: 160px; + } + .alert{ + margin:0 30px 24px 30px; + } + &:hover{ + box-shadow: 0 0 6px #CCC; + } +} + +.sign-form.container{ + padding: 0; + width: 600px; + margin-bottom: 80px; +} + +// register form element +#sign-up-form { + .panel-content{ + margin-top: 1.2em; + } + h2 { + margin: .5em 1em; + } +} + +#sign-social{ + position: relative; + margin: 40px 0; + .or{ + position: absolute; + width: 30px; + top: -52px; + left: 50%; + background-color: #FFF; + margin-left: -15px; + } +} \ No newline at end of file diff --git a/public/ng/less/ui/menu.less b/public/ng/less/ui/menu.less index e36667ce26..a1daefb365 100644 --- a/public/ng/less/ui/menu.less +++ b/public/ng/less/ui/menu.less @@ -94,12 +94,20 @@ ul.menu-down { } } -ul.menu-down { - position: absolute; - display: none; - z-index: 99; - box-shadow: 0 0 2px @menuShadowColor; - background-color: @menuDownBgColor; +ul { + &.menu-down { + position: absolute; + display: none; + z-index: 99; + box-shadow: 0 0 2px @menuShadowColor; + background-color: @menuDownBgColor; + } + &.menu-down-show { + position: absolute; + z-index: 99; + box-shadow: 0 0 2px @menuShadowColor; + background-color: @menuDownBgColor; + } } ul.menu-radius { diff --git a/public/ng/less/ui/panel.less b/public/ng/less/ui/panel.less index b3e2dec95f..f05f0c16ac 100644 --- a/public/ng/less/ui/panel.less +++ b/public/ng/less/ui/panel.less @@ -31,6 +31,10 @@ border-bottom-left-radius: .3em; border-bottom-right-radius: .3em; } + .panel-content{ + border-bottom-left-radius: .3em; + border-bottom-right-radius: .3em; + } } &.panel-warning { border-color: #F0C36D; diff --git a/public/ng/less/ui/reset.less b/public/ng/less/ui/reset.less index f58e1a4730..04d1198969 100644 --- a/public/ng/less/ui/reset.less +++ b/public/ng/less/ui/reset.less @@ -81,17 +81,15 @@ audio:not([controls]) { // display hidden elements [hidden], -template +template, .hidden { - display: none; + display: none; } - .opacity { - opacity: 0; + opacity: 0; } - .opacity-half { - opacity: .5; + opacity: .5; } // links element @@ -100,6 +98,7 @@ a, .text-link { color: @linkColor; text-decoration: none; + cursor: pointer; &:hover { color: @linkHoverColor; text-decoration: none; diff --git a/routers/dev/debug.go b/routers/dev/debug.go deleted file mode 100644 index 6ef40a6226..0000000000 --- a/routers/dev/debug.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package dev - -import ( - "net/http/pprof" - - "github.com/Unknwon/macaron" -) - -func RegisterDebugRoutes(r *macaron.Macaron) { - r.Any("/debug/pprof/cmdline", pprof.Cmdline) - r.Any("/debug/pprof/profile", pprof.Profile) - r.Any("/debug/pprof/symbol", pprof.Symbol) - r.Any("/debug/pprof/**", pprof.Index) -} diff --git a/routers/home.go b/routers/home.go index 770aca034b..4f7abea7a3 100644 --- a/routers/home.go +++ b/routers/home.go @@ -28,6 +28,11 @@ func Home(ctx *middleware.Context) { return } + if setting.OauthService != nil { + ctx.Data["OauthEnabled"] = true + ctx.Data["OauthService"] = setting.OauthService + } + ctx.Data["PageIsHome"] = true ctx.HTML(200, HOME) } diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 3dc3bc5687..484cefb621 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -22,7 +22,7 @@ import ( const ( SETTINGS_OPTIONS base.TplName = "repo/settings/options" - COLLABORATION base.TplName = "repo/collaboration" + COLLABORATION base.TplName = "repo/settings/collaboration" HOOKS base.TplName = "repo/hooks" HOOK_ADD base.TplName = "repo/hook_add" @@ -134,26 +134,71 @@ func SettingsPost(ctx *middleware.Context, form auth.RepoSettingForm) { } } -func Collaboration(ctx *middleware.Context) { +func SettingsCollaboration(ctx *middleware.Context) { + ctx.Data["Title"] = ctx.Tr("repo.settings") + ctx.Data["PageIsSettingsCollaboration"] = true + repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") - ctx.Data["IsRepoToolbarCollaboration"] = true - ctx.Data["Title"] = repoLink + " - collaboration" + + if ctx.Req.Method == "POST" { + name := strings.ToLower(ctx.Query("collaborator")) + if len(name) == 0 || ctx.Repo.Owner.LowerName == name { + ctx.Redirect(ctx.Req.URL.Path) + return + } + has, err := models.HasAccess(name, repoLink, models.WRITABLE) + if err != nil { + ctx.Handle(500, "HasAccess", err) + return + } else if has { + ctx.Redirect(ctx.Req.URL.Path) + return + } + + u, err := models.GetUserByName(name) + if err != nil { + if err == models.ErrUserNotExist { + ctx.Flash.Error(ctx.Tr("form.user_not_exist")) + ctx.Redirect(ctx.Req.URL.Path) + } else { + ctx.Handle(500, "GetUserByName", err) + } + return + } + + if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink, + Mode: models.WRITABLE}); err != nil { + ctx.Handle(500, "AddAccess2", err) + return + } + + if setting.Service.EnableNotifyMail { + if err = mailer.SendCollaboratorMail(ctx.Render, u, ctx.User, ctx.Repo.Repository); err != nil { + ctx.Handle(500, "SendCollaboratorMail", err) + return + } + } + + ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success")) + ctx.Redirect(ctx.Req.URL.Path) + return + } // Delete collaborator. remove := strings.ToLower(ctx.Query("remove")) if len(remove) > 0 && remove != ctx.Repo.Owner.LowerName { if err := models.DeleteAccess(&models.Access{UserName: remove, RepoName: repoLink}); err != nil { - ctx.Handle(500, "setting.Collaboration(DeleteAccess)", err) + ctx.Handle(500, "DeleteAccess", err) return } - ctx.Flash.Success("Collaborator has been removed.") + ctx.Flash.Success(ctx.Tr("repo.settings.remove_collaborator_success")) ctx.Redirect(ctx.Repo.RepoLink + "/settings/collaboration") return } names, err := models.GetCollaboratorNames(repoLink) if err != nil { - ctx.Handle(500, "setting.Collaboration(GetCollaborators)", err) + ctx.Handle(500, "GetCollaborators", err) return } @@ -161,7 +206,7 @@ func Collaboration(ctx *middleware.Context) { for i, name := range names { us[i], err = models.GetUserByName(name) if err != nil { - ctx.Handle(500, "setting.Collaboration(GetUserByName)", err) + ctx.Handle(500, "GetUserByName", err) return } } @@ -170,7 +215,7 @@ func Collaboration(ctx *middleware.Context) { ctx.HTML(200, COLLABORATION) } -func CollaborationPost(ctx *middleware.Context) { +func SettingsCollaborationPost(ctx *middleware.Context) { repoLink := strings.TrimPrefix(ctx.Repo.RepoLink, "/") name := strings.ToLower(ctx.Query("collaborator")) if len(name) == 0 || ctx.Repo.Owner.LowerName == name { diff --git a/routers/user/auth.go b/routers/user/auth.go index 90194e0c46..710d048f39 100644 --- a/routers/user/auth.go +++ b/routers/user/auth.go @@ -31,16 +31,16 @@ const ( func SignIn(ctx *middleware.Context) { ctx.Data["Title"] = ctx.Tr("sign_in") - // if _, ok := ctx.Session.Get("socialId").(int64); ok { - // ctx.Data["IsSocialLogin"] = true - // ctx.HTML(200, SIGNIN) - // return - // } + if _, ok := ctx.Session.Get("socialId").(int64); ok { + ctx.Data["IsSocialLogin"] = true + ctx.HTML(200, SIGNIN) + return + } - // if setting.OauthService != nil { - // ctx.Data["OauthEnabled"] = true - // ctx.Data["OauthService"] = setting.OauthService - // } + if setting.OauthService != nil { + ctx.Data["OauthEnabled"] = true + ctx.Data["OauthService"] = setting.OauthService + } // Check auto-login. uname := ctx.GetCookie(setting.CookieUserName) @@ -89,13 +89,13 @@ func SignIn(ctx *middleware.Context) { func SignInPost(ctx *middleware.Context, form auth.SignInForm) { ctx.Data["Title"] = ctx.Tr("sign_in") - // sid, isOauth := ctx.Session.Get("socialId").(int64) - // if isOauth { - // ctx.Data["IsSocialLogin"] = true - // } else if setting.OauthService != nil { - // ctx.Data["OauthEnabled"] = true - // ctx.Data["OauthService"] = setting.OauthService - // } + sid, isOauth := ctx.Session.Get("socialId").(int64) + if isOauth { + ctx.Data["IsSocialLogin"] = true + } else if setting.OauthService != nil { + ctx.Data["OauthEnabled"] = true + ctx.Data["OauthService"] = setting.OauthService + } if ctx.HasError() { ctx.HTML(200, SIGNIN) @@ -121,18 +121,18 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) { } // Bind with social account. - // if isOauth { - // if err = models.BindUserOauth2(user.Id, sid); err != nil { - // if err == models.ErrOauth2RecordNotExist { - // ctx.Handle(404, "user.SignInPost(GetOauth2ById)", err) - // } else { - // ctx.Handle(500, "user.SignInPost(GetOauth2ById)", err) - // } - // return - // } - // ctx.Session.Delete("socialId") - // log.Trace("%s OAuth binded: %s -> %d", ctx.Req.RequestURI, form.UserName, sid) - // } + if isOauth { + if err = models.BindUserOauth2(u.Id, sid); err != nil { + if err == models.ErrOauth2RecordNotExist { + ctx.Handle(404, "GetOauth2ById", err) + } else { + ctx.Handle(500, "GetOauth2ById", err) + } + return + } + ctx.Session.Delete("socialId") + log.Trace("%s OAuth binded: %s -> %d", ctx.Req.RequestURI, form.UserName, sid) + } ctx.Session.Set("uid", u.Id) ctx.Session.Set("uname", u.Name) @@ -148,14 +148,34 @@ func SignInPost(ctx *middleware.Context, form auth.SignInForm) { func SignOut(ctx *middleware.Context) { ctx.Session.Delete("uid") ctx.Session.Delete("uname") - // ctx.Session.Delete("socialId") - // ctx.Session.Delete("socialName") - // ctx.Session.Delete("socialEmail") + ctx.Session.Delete("socialId") + ctx.Session.Delete("socialName") + ctx.Session.Delete("socialEmail") ctx.SetCookie(setting.CookieUserName, "", -1) ctx.SetCookie(setting.CookieRememberName, "", -1) ctx.Redirect("/") } +func oauthSignUp(ctx *middleware.Context, sid int64) { + // ctx.Data["Title"] = "OAuth Sign Up" + // ctx.Data["PageIsSignUp"] = true + + // if _, err := models.GetOauth2ById(sid); err != nil { + // if err == models.ErrOauth2RecordNotExist { + // ctx.Handle(404, "user.oauthSignUp(GetOauth2ById)", err) + // } else { + // ctx.Handle(500, "user.oauthSignUp(GetOauth2ById)", err) + // } + // return + // } + + // ctx.Data["IsSocialLogin"] = true + // ctx.Data["username"] = strings.Replace(ctx.Session.Get("socialName").(string), " ", "", -1) + // ctx.Data["email"] = ctx.Session.Get("socialEmail") + // log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId")) + // ctx.HTML(200, SIGNUP) +} + func SignUp(ctx *middleware.Context) { ctx.Data["Title"] = ctx.Tr("sign_up") @@ -165,34 +185,14 @@ func SignUp(ctx *middleware.Context) { return } - // if sid, ok := ctx.Session.Get("socialId").(int64); ok { - // oauthSignUp(ctx, sid) - // return - // } + if sid, ok := ctx.Session.Get("socialId").(int64); ok { + oauthSignUp(ctx, sid) + return + } ctx.HTML(200, SIGNUP) } -// func oauthSignUp(ctx *middleware.Context, sid int64) { -// ctx.Data["Title"] = "OAuth Sign Up" -// ctx.Data["PageIsSignUp"] = true - -// if _, err := models.GetOauth2ById(sid); err != nil { -// if err == models.ErrOauth2RecordNotExist { -// ctx.Handle(404, "user.oauthSignUp(GetOauth2ById)", err) -// } else { -// ctx.Handle(500, "user.oauthSignUp(GetOauth2ById)", err) -// } -// return -// } - -// ctx.Data["IsSocialLogin"] = true -// ctx.Data["username"] = strings.Replace(ctx.Session.Get("socialName").(string), " ", "", -1) -// ctx.Data["email"] = ctx.Session.Get("socialEmail") -// log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId")) -// ctx.HTML(200, SIGNUP) -// } - func SignUpPost(ctx *middleware.Context, cpt *captcha.Captcha, form auth.RegisterForm) { ctx.Data["Title"] = ctx.Tr("sign_up") diff --git a/routers/user/home.go b/routers/user/home.go index 706c16d91f..177fa38be3 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -119,12 +119,19 @@ func Profile(ctx *middleware.Context) { ctx.Data["Title"] = "Profile" ctx.Data["PageIsUserProfile"] = true - u, err := models.GetUserByName(ctx.Params(":username")) + uname := ctx.Params(":username") + // Special handle for FireFox requests favicon.ico. + if uname == "favicon.ico" { + ctx.Redirect("/img/favicon.png") + return + } + + u, err := models.GetUserByName(uname) if err != nil { if err == models.ErrUserNotExist { - ctx.Handle(404, "user.Profile(GetUserByName)", err) + ctx.Handle(404, "GetUserByName", err) } else { - ctx.Handle(500, "user.Profile(GetUserByName)", err) + ctx.Handle(500, "GetUserByName", err) } return } @@ -146,13 +153,13 @@ func Profile(ctx *middleware.Context) { case "activity": ctx.Data["Feeds"], err = models.GetFeeds(u.Id, 0, true) if err != nil { - ctx.Handle(500, "user.Profile(GetFeeds)", err) + ctx.Handle(500, "GetFeeds", err) return } default: ctx.Data["Repos"], err = models.GetRepositories(u.Id, ctx.IsSigned && ctx.User.Id == u.Id) if err != nil { - ctx.Handle(500, "user.Profile(GetRepositories)", err) + ctx.Handle(500, "GetRepositories", err) return } } diff --git a/templates/.VERSION b/templates/.VERSION index bdaabb3ffa..0621825f4b 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.4.7.0802 Alpha \ No newline at end of file +0.4.7.0807 Alpha \ No newline at end of file diff --git a/templates/.brackets.json b/templates/.brackets.json new file mode 100644 index 0000000000..f358faa62e --- /dev/null +++ b/templates/.brackets.json @@ -0,0 +1,5 @@ +{ + "language.fileExtensions": { + "tmpl": "html" + } +} \ No newline at end of file diff --git a/templates/home.tmpl b/templates/home.tmpl index 249bce314d..47d1e69017 100644 --- a/templates/home.tmpl +++ b/templates/home.tmpl @@ -1,17 +1,16 @@ -{{template "ng/base/head" .}} -{{template "ng/base/header" .}} +{{template "ng/base/head" .}} {{template "ng/base/header" .}}

    Gogs

    {{.i18n.Tr "app_desc"}}

    {{.CsrfTokenHtml}} - - + + diff --git a/templates/ng/base/social.tmpl b/templates/ng/base/social.tmpl index 153239f743..97f71b4e99 100644 --- a/templates/ng/base/social.tmpl +++ b/templates/ng/base/social.tmpl @@ -1,4 +1,4 @@ - - - - \ No newline at end of file +{{if .OauthService.GitHub}}GitHub{{end}} +{{if .OauthService.Google}}Google +{{end}} +{{if .OauthService.Weibo}}新浪微博{{end}} +{{if .OauthService.Tencent}}腾讯 QQ {{end}} \ No newline at end of file diff --git a/templates/repo/collaboration.tmpl b/templates/repo/collaboration.tmpl deleted file mode 100644 index 564c99eca2..0000000000 --- a/templates/repo/collaboration.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
    - {{template "repo/setting_nav" .}} -
    - {{template "base/alert" .}} -
    -
    - Collaborators -
    - -
    - -
    - - -
    - -
    -
    -{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index a789d13fee..5e9c3ea2db 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -1,10 +1,11 @@

    - + {{.Owner.Name}} / {{.Repository.Name}} + {{if .Repository.IsMirror}}{{.i18n.Tr "mirror"}}{{end}}