]> source.dussan.org Git - gitea.git/commitdiff
Finish new collaboration page
authorUnknwon <joe2010xtmf@163.com>
Thu, 7 Aug 2014 10:40:05 +0000 (06:40 -0400)
committerUnknwon <joe2010xtmf@163.com>
Thu, 7 Aug 2014 10:40:05 +0000 (06:40 -0400)
23 files changed:
cmd/web.go
conf/locale/locale_en-US.ini
conf/locale/locale_zh-CN.ini
gogs.go
public/ng/css/gogs.css
public/ng/css/ui.css
public/ng/js/gogs.js
public/ng/less/gogs/base.less
public/ng/less/gogs/dashboard.less
public/ng/less/gogs/repository.less
public/ng/less/ui/menu.less
public/ng/less/ui/reset.less
routers/home.go
routers/repo/setting.go
routers/user/auth.go
templates/.VERSION
templates/.brackets.json [new file with mode: 0644]
templates/home.tmpl
templates/ng/base/social.tmpl
templates/repo/collaboration.tmpl [deleted file]
templates/repo/header.tmpl
templates/repo/settings/collaboration.tmpl [new file with mode: 0644]
templates/user/signin.tmpl

index 8d39ce64c8567071e0add77b654275c6d1fe17fb..40ae760280178637085f709345c8f6dc6d47b0ba 100644 (file)
@@ -96,7 +96,6 @@ func newMacaron() *macaron.Macaron {
                Secret:    setting.SecretKey,
                SetCookie: true,
        }))
-       m.Use(middleware.Contexter())
        m.Use(toolbox.Toolboxer(m, toolbox.Options{
                HealthCheckFuncs: []*toolbox.HealthCheckFuncDesc{
                        &toolbox.HealthCheckFuncDesc{
@@ -105,6 +104,7 @@ func newMacaron() *macaron.Macaron {
                        },
                },
        }))
+       m.Use(middleware.Contexter())
        return m
 }
 
@@ -254,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)
index 29a61e7f5a413c82ef50e2105c1c4e02c6b4689e..5ecf9139000d0605c26e28c4ed4768c4710c3193 100644 (file)
@@ -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
index a2b1840187a1121fc0ea55654a794332d6afd5af..4c658125233c2b34b95c1d8d58f2586b4b59c517 100644 (file)
@@ -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 b08dbd5a5f9a7ad7575b4358a2311a27a02263ff..d40f1a02d1fa8aec5668acbac04acc8a0ec78bf9 100644 (file)
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
        "github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.4.7.0806 Alpha"
+const APP_VER = "0.4.7.0807 Alpha"
 
 func init() {
        runtime.GOMAXPROCS(runtime.NumCPU())
index 148df5eb4363dfc0549a75b2975a8196fb8d9c89..244d6531d6c2e0ddd3604c8ff41f9dba8c10aaaa 100644 (file)
@@ -198,6 +198,22 @@ img.avatar-48 {
 .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: 16px;
@@ -753,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;
@@ -1155,32 +1186,26 @@ The register and sign-in page style
 #repo-create-cancel {
   margin-left: 4em;
 }
-#dashboard-switch-menu,
 #repo-create-owner-list {
   top: 30px;
   left: 0;
   width: auto;
   max-width: 300px;
 }
-#dashboard-switch-menu .octicon,
 #repo-create-owner-list .octicon {
   margin-right: 12px;
   opacity: 0;
 }
-#dashboard-switch-menu .avatar,
 #repo-create-owner-list .avatar {
   width: 20px;
   height: 20px;
 }
-#dashboard-switch-menu li,
 #repo-create-owner-list li {
   white-space: nowrap;
 }
-#dashboard-switch-menu li.checked .octicon,
 #repo-create-owner-list li.checked .octicon {
   opacity: 1;
 }
-#dashboard-switch-menu li a,
 #repo-create-owner-list li a {
   text-overflow: ellipsis;
   -o-text-overflow: ellipsis;
@@ -1244,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;
 }
index 908f4e70fbaf38b93a9676a1f118f17dc2947dfe..d30e137dbc1c0805bcbad11ef4079cf8be6ba55f 100644 (file)
@@ -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;
 }
index 37144ce99ef361f0baa351b38e883b598825dec7..473997e9ee96996539bfc9857ae4b3e7bcb918c4 100644 (file)
@@ -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 += '<li><a><img src="' + item.avatar + '">' + item.username + '</a></li>';
+                    });
+                    $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 () {
index f9405499ad81af8b7195e993884899295289aba4..0cadabe8691410c8a13367da04fe0f20ee2abd48 100644 (file)
@@ -214,4 +214,20 @@ clear: both;
 }
 .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
index 3929f2d00d5744cd1eb3fa640bb03fdb7fb20812..f8838ae6fddc258382a2166adb1c12695d78d2ed 100644 (file)
@@ -176,9 +176,24 @@ The dashboard page style
 }
 
 #dashboard-selection-menu {
-  > .drop-down {
-    top: 56px;
-  }
+    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
index 13f5a42e53778474dc44293b20a23d38724ea24c..1847c44e53c3b097c8858a7af805db9c847691fb 100644 (file)
   margin-left: 4em;
 }
 
-#dashboard-switch-menu,
 #repo-create-owner-list {
     top: 30px;
     left: 0;
 }
 .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
index e36667ce26fa79efeadcd5393f13ab0af96dd4db..a1daefb36593cf1cf44e43890a8629a65635ab23 100644 (file)
@@ -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 {
index f58e1a4730fb69557be635c4e1a932cb72cd6941..04d1198969b2125254fe079d6d330059a63ccfe8 100644 (file)
@@ -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;
index 770aca034b92b84a475c2a6b8aaee698af28562e..4f7abea7a34d8d2e8afdc80a51ac9b572956d8cc 100644 (file)
@@ -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)
 }
index 3dc3bc568773f3a213f6ec862486282a6ddff9ea..484cefb6211b77e893cb25e6514ec4eac1589da4 100644 (file)
@@ -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 {
index 90194e0c46198d157dce496c2f4cf825dd4ff26d..710d048f39d00aa4c65e8add897c9ad925784508 100644 (file)
@@ -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")
 
index 04e73b67f7db3f586290300650896c1ff5c7f232..0621825f4bcc6e6611bae48d1d2fd2685af25c28 100644 (file)
@@ -1 +1 @@
-0.4.7.0806 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 (file)
index 0000000..f358faa
--- /dev/null
@@ -0,0 +1,5 @@
+{
+    "language.fileExtensions": {
+        "tmpl": "html"
+    }
+}
\ No newline at end of file
index 249bce314d2a6cce4eebb457a903dddf917b07f7..47d1e69017e961065f67e38e1ffd6e76e2a87d20 100644 (file)
@@ -1,17 +1,16 @@
-{{template "ng/base/head" .}}
-{{template "ng/base/header" .}}
+{{template "ng/base/head" .}} {{template "ng/base/header" .}}
 <div id="promo-wrapper">
     <div class="container clear">
         <div id="promo-logo" class="left">
-            <img src="/img/gogs-lg.png" alt="logo"/>
+            <img src="/img/gogs-lg.png" alt="logo" />
         </div>
         <div id="promo-content">
             <h1>Gogs</h1>
             <h2>{{.i18n.Tr "app_desc"}}</h2>
             <form id="promo-form" action="/user/login" method="post">
                 {{.CsrfTokenHtml}}
-                <input class="ipt ipt-large" id="username" name="uname" type="text" placeholder="{{.i18n.Tr "home.uname_holder"}}"/>
-                <input class="ipt ipt-large" name="password" type="password" placeholder="{{.i18n.Tr "home.password_holder"}}"/>
+                <input class="ipt ipt-large" id="username" name="uname" type="text" placeholder="{{.i18n.Tr " home.uname_holder "}}"/>
+                <input class="ipt ipt-large" name="password" type="password" placeholder="{{.i18n.Tr " home.password_holder "}}"/>
                 <input name="from" type="hidden" value="home">
                 <button class="btn btn-black btn-large">{{.i18n.Tr "sign_in"}}</button>
                 <button class="btn btn-green btn-large" id="register-button">{{.i18n.Tr "register"}}</button>
index 153239f743d29434a933daea2af4202953dd7681..97f71b4e9973f4d4728e63daaeeae6efa0dcf254 100644 (file)
@@ -1,4 +1,4 @@
-<button class="btn github"><i class="fa fa-github"></i>GitHub</button>
-<button class="btn google"><i class="fa fa-google"></i>Google +</button>
-<button class="btn weibo"><i class="fa fa-weibo"></i>新浪微博</button>
-<button class="btn qq"><i class="fa fa-qq"></i>腾讯 QQ&nbsp;</button>
\ No newline at end of file
+{{if .OauthService.GitHub}}<a class="btn github" href="/user/login/github?next=/user/sign_up"><i class="fa fa-github"></i>GitHub</a>{{end}}
+{{if .OauthService.Google}}<a class="btn google" href="/user/login/google?next=/user/sign_up"><i class="fa fa-google"></i>Google +</a>{{end}}
+{{if .OauthService.Weibo}}<a class="btn weibo" href="/user/login/weibo?next=/user/sign_up"><i class="fa fa-weibo"></i>新浪微博</a>{{end}}
+{{if .OauthService.Tencent}}<a class="btn qq" href="/user/login/qq?next=/user/sign_up"><i class="fa fa-qq"></i>腾讯 QQ&nbsp;</a>{{end}}
\ No newline at end of file
diff --git a/templates/repo/collaboration.tmpl b/templates/repo/collaboration.tmpl
deleted file mode 100644 (file)
index 564c99e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{{template "base/head" .}}
-{{template "base/navbar" .}}
-{{template "repo/nav" .}}
-{{template "repo/toolbar" .}}
-<div id="body" class="container">
-    {{template "repo/setting_nav" .}}
-    <div id="repo-setting-container" class="col-md-10">
-        {{template "base/alert" .}}
-        <div class="panel panel-default">
-            <div class="panel-heading">
-                Collaborators
-            </div>
-            
-            <div class="panel-body">
-                <ul id="repo-collab-list" class="list-unstyled">
-                    {{range .Collaborators}}
-                    <li class="collab">
-                        {{if not (eq .LowerName $.Owner.LowerName)}}<a href="{{$.RepoLink}}/settings/collaboration?remove={{.Name}}" class="remove-collab pull-right"><i class="fa fa-times"></i></a>{{end}}
-                        <a class="member" href="/user/{{.Name}}">
-                            <img alt="{{.Name}}" class="pull-left avatar" src="{{.AvatarLink}}">
-                            <strong class="access-member-fullname">{{.FullName}}</strong><br/>
-                            {{.Name}}
-                        </a>
-                    </li>
-                    {{end}}
-                </ul>
-            </div>
-
-            <div class="panel-footer">
-                <form action="{{.RepoLink}}/settings/collaboration" method="post" class="form-horizontal" id="repo-collab-form">
-                    {{.CsrfTokenHtml}}
-                    <div class="form-group" style="margin-bottom: 0">
-                        <div class="col-md-4">
-                            <input type="text" name="collaborator" class="form-control dropdown-toggle" id="repo-collaborator" autocomplete="off" required="required" data-toggle="dropdown"/>
-                            <div class="dropdown-menu">
-                                <ul class="list-unstyled"></ul>
-                            </div>
-                        </div>
-                        <button class="col-md-2 btn btn-primary">Add collaborator</button>
-                    </div>
-                </form>
-            </div>
-        </div>
-
-    </div>
-</div>
-{{template "base/footer" .}}
\ No newline at end of file
index a789d13fee72cb18547f22d738de13d1fc5d9d53..5e9c3ea2db09863a84597902c335d79c60e514c0 100644 (file)
@@ -1,10 +1,11 @@
 <div id="repo-header" class="clear">
     <div class="container clear">
         <h1 id="repo-header-name" class="left public">
-            <i class="mega-octicon octicon-{{if .Repository.IsPrivate}}lock{{else}}repo{{end}}"></i>
+            <i class="mega-octicon octicon-{{if .Repository.IsPrivate}}lock{{else if .Repository.IsMirror}}repo-clone{{else}}repo{{end}}"></i>
             <a class="author" href="/{{.Owner.Name}}">{{.Owner.Name}}</a>
             <span class="divider">/</span>
             <a class="repo text-bold" href="{{.RepoLink}}">{{.Repository.Name}}</a>
+            {{if .Repository.IsMirror}}<span class="label label-gray">{{.i18n.Tr "mirror"}}</span>{{end}}
         </h1>
         <ul id="repo-header-meta" class="right menu menu-line">
             <li id="repo-header-download" class="inline-block down drop">
diff --git a/templates/repo/settings/collaboration.tmpl b/templates/repo/settings/collaboration.tmpl
new file mode 100644 (file)
index 0000000..deb09e1
--- /dev/null
@@ -0,0 +1,47 @@
+{{template "ng/base/head" .}}
+{{template "ng/base/header" .}}
+<div id="repo-wrapper">
+    {{template "repo/header" .}}
+       <div id="setting-wrapper" class="main-wrapper">
+           <div id="repo-setting" class="container clear">
+               {{template "repo/settings/nav" .}}
+               <div class="grid-4-5 left">
+                   <div class="setting-content">
+                       {{template "ng/base/alert" .}}
+                       <div id="setting-content">
+                           <div id="user-profile-setting-content" class="panel panel-radius">
+                               <div class="panel-header">
+                                       <strong>{{.i18n.Tr "repo.settings.collaboration"}}</strong>
+                               </div>
+                               <div class="panel-body">
+                                       <ul id="repo-collab-list">
+                                               {{range .Collaborators}}
+                                               <li class="collab">
+                                                       {{if not (eq .Id $.Owner.Id)}}<a href="{{$.RepoLink}}/settings/collaboration?remove={{.Name}}" class="remove-collab right"><i class="fa fa-times"></i></a>{{end}}
+                                                                               <a class="member" href="/{{.Name}}">
+                                                                                   <img alt="{{.Name}}" class="pull-left avatar" src="{{.AvatarLink}}">
+                                                                                   <strong>{{.FullName}}</strong> ({{.Name}})
+                                                                               </a>
+                                               </li>
+                                               <hr>
+                                               {{end}}
+                                       </ul>
+                                                       </div>
+                                           <div class="panel-footer">
+                                               <form class="form form-align" action="{{.RepoLink}}/settings/collaboration" method="post" id="repo-collab-form">
+                                                   {{.CsrfTokenHtml}}
+                                       <input class="ipt ipt-large ipt-radius" id="repo-collaborator" name="collaborator" autocomplete="off" required />
+                                       <button class="btn btn-blue btn-large btn-radius">{{.i18n.Tr "repo.settings.add_collaborator"}}</button>
+                                                                       <div class="repo-user-list-block">
+                                                                               <ul class="menu-down-show menu-vertical menu-radius switching-list user-list" id="repo-collaborator-list"></ul>
+                                                                       </div>
+                                               </form>
+                                           </div>
+                           </div>
+                       </div>
+                   </div>
+               </div>
+           </div>
+       </div>
+</div>
+{{template "ng/base/footer" .}} 
\ No newline at end of file
index 8b67dbd86ec8e2fbcd6bb2df6af986680acc590b..9db98cd0080820cecfcc426b82cda4f38f17239e 100644 (file)
                 <span class="form-label"></span>
                 <a href="/user/sign_up">{{.i18n.Tr "auth.sign_up_now" | Str2html}}</a>
             </p>
+            {{if .OauthEnabled}}
             <hr/>
             <div id="sign-social" class="text-center social-buttons">
                 {{template "ng/base/social" .}}
             </div>
+            {{end}}
         </div>
     </form>
 </div>