diff --git a/conf/config-temp.toml b/conf/config-temp.toml index cff8ebe..5604587 100644 --- a/conf/config-temp.toml +++ b/conf/config-temp.toml @@ -7,9 +7,6 @@ address = ":5000" driver = "sqlite3" connect = "./data/ignite.db" -[ss] -image = "goignite/ss-go:latest" - [host] address = "localhost" from = 5001 diff --git a/controllers/index.go b/controllers/index.go index 256c345..d241a28 100644 --- a/controllers/index.go +++ b/controllers/index.go @@ -64,7 +64,7 @@ func (router *MainRouter) SignupHandler(c *gin.Context) { pwd := c.PostForm("password") confirmPwd := c.PostForm("confirm-password") - matched, _ := regexp.MatchString("^[a-zA-Z0-9]+$", username) + matched, _ := regexp.MatchString("^[a-zA-Z0-9][a-zA-Z0-9_.-]+$", username) if !matched { fmt.Println("Username is invalid!") diff --git a/controllers/panel.go b/controllers/panel.go index 4b7caef..414f68d 100644 --- a/controllers/panel.go +++ b/controllers/panel.go @@ -11,6 +11,27 @@ import ( "github.com/go-ignite/ignite/ss" ) +var ( + servers = []string{"SS", "SSR"} + ssMethods = []string{"aes-256-cfb", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305"} + ssrMethods = []string{"aes-256-cfb", "aes-256-ctr", "chacha20", "chacha20-ietf"} + serverMethodsMap = map[string]map[string]bool{} +) + +func init() { + ssMethodMap := map[string]bool{} + for _, method := range ssMethods { + ssMethodMap[method] = true + } + ssrMethodMap := map[string]bool{} + for _, method := range ssrMethods { + ssrMethodMap[method] = true + } + + serverMethodsMap["SS"] = ssMethodMap + serverMethodsMap["SSR"] = ssrMethodMap +} + func (router *MainRouter) PanelIndexHandler(c *gin.Context) { userID, exists := c.Get("userId") @@ -32,16 +53,24 @@ func (router *MainRouter) PanelIndexHandler(c *gin.Context) { } uInfo := &models.UserInfo{ - Id: user.Id, - Host: ss.Host, - Username: user.Username, - Status: user.Status, - PackageUsed: fmt.Sprintf("%.2f", user.PackageUsed), - PackageLimit: user.PackageLimit, - PackageLeft: fmt.Sprintf("%.2f", float32(user.PackageLimit)-user.PackageUsed), - ServicePort: user.ServicePort, - ServicePwd: user.ServicePwd, - Expired: user.Expired.Format("2006-01-02"), + Id: user.Id, + Host: ss.Host, + Username: user.Username, + Status: user.Status, + PackageUsed: fmt.Sprintf("%.2f", user.PackageUsed), + PackageLimit: user.PackageLimit, + PackageLeft: fmt.Sprintf("%.2f", float32(user.PackageLimit)-user.PackageUsed), + ServicePort: user.ServicePort, + ServicePwd: user.ServicePwd, + ServiceMethod: user.ServiceMethod, + ServiceType: user.ServiceType, + Expired: user.Expired.Format("2006-01-02"), + } + if uInfo.ServiceMethod == "" { + uInfo.ServiceMethod = "aes-256-cfb" + } + if uInfo.ServiceType == "" { + uInfo.ServiceType = "SS" } if user.PackageLimit == 0 { @@ -51,7 +80,10 @@ func (router *MainRouter) PanelIndexHandler(c *gin.Context) { } c.HTML(http.StatusOK, "panel.html", gin.H{ - "uInfo": uInfo, + "uInfo": uInfo, + "ss_methods": ssMethods, + "ssr_methods": ssrMethods, + "servers": servers, }) } @@ -65,26 +97,43 @@ func (router *MainRouter) LogoutHandler(c *gin.Context) { func (router *MainRouter) CreateServiceHandler(c *gin.Context) { userID, _ := c.Get("userId") + method := c.PostForm("method") + serverType := c.PostForm("server-type") - user := new(models.User) - router.db.Id(userID).Get(user) + fmt.Println("UserID", userID) + fmt.Println("ServerType:", serverType) + fmt.Println("Method:", method) - //Get all used ports. - var usedPorts []int - router.db.Table("user").Cols("service_port").Find(&usedPorts) + methodMap, ok := serverMethodsMap[serverType] + if !ok { + resp := models.Response{Success: false, Message: "服务类型配置错误!"} + c.JSON(http.StatusOK, resp) + return + } + if !methodMap[method] { + resp := models.Response{Success: false, Message: "加密方法配置错误!"} + c.JSON(http.StatusOK, resp) + return + } + + user := new(models.User) + router.db.Id(userID).Get(user) if user.ServiceId != "" { - resp := models.Response{Success: false, Message: "Service already created!"} + resp := models.Response{Success: false, Message: "服务已创建!"} c.JSON(http.StatusOK, resp) return } - // 1. Create ss service - result, err := ss.CreateAndStartContainer(user.Username, &usedPorts) + //Get all used ports. + var usedPorts []int + router.db.Table("user").Cols("service_port").Find(&usedPorts) + // 1. Create ss service + result, err := ss.CreateAndStartContainer(serverType, user.Username, method, &usedPorts) if err != nil { log.Println("Create ss service error:", err.Error()) - resp := models.Response{Success: false, Message: "Create service error!"} + resp := models.Response{Success: false, Message: "创建服务失败!"} c.JSON(http.StatusOK, resp) return } @@ -94,8 +143,9 @@ func (router *MainRouter) CreateServiceHandler(c *gin.Context) { user.ServiceId = result.ID user.ServicePort = result.Port user.ServicePwd = result.Password - affected, err := router.db.Id(userID).Cols("status", "service_port", "service_pwd", "service_id").Update(user) - + user.ServiceMethod = method + user.ServiceType = serverType + affected, err := router.db.Id(userID).Cols("status", "service_port", "service_pwd", "service_id", "service_method", "service_type").Update(user) if affected == 0 || err != nil { if err != nil { log.Println("Update user info error:", err.Error()) @@ -104,14 +154,14 @@ func (router *MainRouter) CreateServiceHandler(c *gin.Context) { //Force remove created container ss.RemoveContainer(result.ID) - resp := models.Response{Success: false, Message: "Create service error!"} + resp := models.Response{Success: false, Message: "更新用户信息失败!"} c.JSON(http.StatusOK, resp) return } result.PackageLimit = user.PackageLimit result.Host = ss.Host - resp := models.Response{Success: true, Message: "OK!", Data: result} + resp := models.Response{Success: true, Message: "服务创建成功!", Data: result} c.JSON(http.StatusOK, resp) } diff --git a/controllers/router.go b/controllers/router.go index 1861c11..37eb020 100644 --- a/controllers/router.go +++ b/controllers/router.go @@ -17,7 +17,6 @@ type MainRouter struct { func (self *MainRouter) Initialize(r *gin.Engine) { ss.Host = utils.HOST_Address - ss.ImageUrl = utils.SS_Image ss.PortRange = []int{utils.HOST_From, utils.HOST_To} //Init session store @@ -39,8 +38,11 @@ func (self *MainRouter) Initialize(r *gin.Engine) { } go func() { - if err := ss.PullImage(); err != nil { - log.Printf("Pull image [%s] error: %s\n", ss.ImageUrl, err.Error()) + if err := ss.PullImage(ss.SS_IMAGE); err != nil { + log.Printf("Pull image [%s] error: %s\n", ss.SS_IMAGE, err.Error()) + } + if err := ss.PullImage(ss.SSR_IMAGE); err != nil { + log.Printf("Pull image [%s] error: %s\n", ss.SSR_IMAGE, err.Error()) } }() self.router.Run(utils.APP_Address) diff --git a/models/user.go b/models/user.go index 1cb8c42..5b48b67 100644 --- a/models/user.go +++ b/models/user.go @@ -11,8 +11,10 @@ type User struct { PackageUsed float32 //Package bandwidth used, unit: GB Status int `xorm:"default 0"` // 0=>not created 1=>running 2=>stopped ServiceId string //SS container id + ServiceType string //SS container type ServicePort int `xorm:"not null default 0"` //Docker service port for SS ServicePwd string //Password for SS + ServiceMethod string //Encryption method for SS LastStatsResult uint64 //Last time stats result,unit: byte LastStatsTime *time.Time //Last time stats time Created time.Time `xorm:"created"` @@ -31,5 +33,7 @@ type UserInfo struct { PackageLeftPercent string ServicePort int ServicePwd string + ServiceMethod string + ServiceType string Expired string } diff --git a/ss/ss.go b/ss/ss.go index f489df3..22f3ab9 100644 --- a/ss/ss.go +++ b/ss/ss.go @@ -13,8 +13,12 @@ import ( "github.com/go-ignite/ignite/utils" ) +const ( + SS_IMAGE = "goignite/ss-libev:latest" + SSR_IMAGE = "goignite/ssr:latest" +) + var ( - ImageUrl string client *docker.Client PortRange []int Host string @@ -28,8 +32,17 @@ func init() { } } -func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, error) { - PullImage() +func CreateContainer(serverType, name, method string, usedPorts *[]int) (*models.ServiceResult, error) { + image := "" + switch serverType { + case "SS": + image = SS_IMAGE + case "SSR": + image = SSR_IMAGE + default: + return nil, errors.New("invalid server type") + } + PullImage(image) password := utils.NewPasswd(16) port, err := getAvailablePort(usedPorts) if err != nil { @@ -39,13 +52,14 @@ func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, erro container, err := client.CreateContainer(docker.CreateContainerOptions{ Name: name, Config: &docker.Config{ - Image: ImageUrl, - Cmd: []string{"-k", password, "-p", portStr}, - ExposedPorts: map[docker.Port]struct{}{docker.Port(portStr + "/tcp"): {}}, + Image: image, + Cmd: []string{"-k", password, "-m", method}, }, HostConfig: &docker.HostConfig{ PortBindings: map[docker.Port][]docker.PortBinding{ - docker.Port(portStr + "/tcp"): {{HostPort: portStr}}}, + docker.Port("3389/tcp"): {{HostPort: portStr}}, + docker.Port("3389/udp"): {{HostPort: portStr}}, + }, RestartPolicy: docker.AlwaysRestart(), }, }) @@ -61,11 +75,11 @@ func CreateContainer(name string, usedPorts *[]int) (*models.ServiceResult, erro } func StartContainer(id string) error { - return client.StartContainer(id, nil) + return client.StartContainer(id, &docker.HostConfig{}) } -func PullImage() error { - return client.PullImage(docker.PullImageOptions{Repository: ImageUrl, OutputStream: os.Stdout}, +func PullImage(image string) error { + return client.PullImage(docker.PullImageOptions{Repository: image, OutputStream: os.Stdout}, docker.AuthConfiguration{}) } @@ -130,8 +144,8 @@ func GetContainerStatsOutNet(id string) (uint64, error) { return stats.Networks["eth0"].TxBytes, nil } -func CreateAndStartContainer(name string, usedPorts *[]int) (*models.ServiceResult, error) { - r, err := CreateContainer(name, usedPorts) +func CreateAndStartContainer(serverType, name, method string, usedPorts *[]int) (*models.ServiceResult, error) { + r, err := CreateContainer(serverType, name, method, usedPorts) if err != nil { return nil, err } diff --git a/static/css/dropdown.css b/static/css/dropdown.css new file mode 100644 index 0000000..ed7e8f3 --- /dev/null +++ b/static/css/dropdown.css @@ -0,0 +1,79 @@ + + .big { + font-size: 1.2em; + } + + .small { + font-size: .7em; + } + + .square { + width: .7em; + height: .7em; + margin: .5em; + display: inline-block; + } + + /* Custom dropdown */ + .custom-dropdown { + position: relative; + display: inline-block; + vertical-align: middle; + margin: 10px; /* demo only */ + } + + .custom-dropdown select { + background-color: rgba(61, 201, 179, 1); + color: #fff; + font-size: inherit; + padding: .5em; + padding-right: 2.5em; + width: 245px; + border: 0; + margin: 0; + border-radius: 3px; + text-indent: 0.01px; + text-overflow: ''; + -webkit-appearance: button; /* hide default arrow in chrome OSX */ + } + + .custom-dropdown::before, + .custom-dropdown::after { + content: ""; + position: absolute; + pointer-events: none; + } + + .custom-dropdown::after { /* Custom dropdown arrow */ + content: "\25BC"; + height: 1em; + font-size: .625em; + line-height: 1; + right: 1.2em; + top: 50%; + margin-top: -.5em; + } + + .custom-dropdown::before { /* Custom dropdown arrow cover */ + width: 2em; + right: 0; + top: 0; + bottom: 0; + border-radius: 0 3px 3px 0; + } + + .custom-dropdown select[disabled] { + color: rgba(0,0,0,.3); + } + + .custom-dropdown select[disabled]::after { + color: rgba(0,0,0,.1); + } + + .custom-dropdown::before { + background-color: rgba(0,0,0,.15); + } + + .custom-dropdown::after { + color: rgba(0,0,0,.4); + } \ No newline at end of file diff --git a/static/css/styles.css b/static/css/styles.css index 3e00754..a214f64 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -204,11 +204,6 @@ h2::after { content: " "; border: solid 2px #3dc9b3; display: block; width: 35px transition: background-color .5s ease 0s; } -ul.dropdown-menu { - background-color: black; -} - - @media (max-width: 992px) { .opaque-navbar { background-color: black; @@ -217,6 +212,26 @@ ul.dropdown-menu { } } +@media (max-width: 768px) { + .navbar-fixed-bottom { + display: none; + } + .hero, + .infobox { + width: 100% !important; + } + .basic-slide { + display: block !important; + justify-content: space-around; + max-height: 200px; + overflow: auto; + } + .progressbar { + display: none !important; + } +} + + /* ========================================================================== Hero ========================================================================== */ @@ -235,25 +250,13 @@ Hero .signup-btn, .login-btn{ background: rgba(61, 201, 179, 1); padding: 20px 40px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -o-border-radius: 5px; color: #fff; text-transform: uppercase; letter-spacing: 1px; display: inline-block; -webkit-box-shadow: 0px 3px 0px 0px #309383; -moz-box-shadow: 0px 3px 0px 0px #309383; box-shadow: 0px 3px 0px 0px #309383; margin: 20px 0 0; font-weight: bold; } .signup-btn:hover, .login-btn:hover, .signup-btn:focus, .login-btn:focus { background: rgba(61, 201, 179, 0.6); color: #fff; } -/* ========================================================================== */ - -video { - position: fixed; - top: 50%; - left: 50%; - min-width: 100%; - min-height: 100%; - width: auto; - height: auto; - z-index: -100; - transform: translateX(-50%) translateY(-50%); - background: url('/static/images/helloworld.jpg') no-repeat; - background-size: cover; - transition: 1s opacity; +.signup-loginhref { + color: #a1a9b0 } - +/* ========================================================================== */ #signup { padding: 40px 0 0px 0; height: auto; display: none;} + #login { padding: 40px 0 0px 0; height: auto; display: none;} form { @@ -264,9 +267,6 @@ form { .form h1 { margin: 0px 0px 20px 0;} form input { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; outline: 0; border: 1px solid rgba(255, 255, 255, 0.4); background-color: rgba(255, 255, 255, 0.2); @@ -284,19 +284,19 @@ form input { } form input:hover { - background-color: rgba(255, 255, 255, 0.4); + background-color: rgba(255, 255, 255, 0.5); +} +form input::placeholder { + color: rgba(255, 255, 255, .7); } form input:focus { background-color: white; width: 300px; - color: #53e3a6; + color: #555; } .common-btn { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; outline: 0; background: rgba(61, 201, 179, 1); border: 0; @@ -344,6 +344,10 @@ InfoBox box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1); } +.infobox.multiline { + width: 650px; +} + .header-bar { width: 100%; height: 50px; @@ -352,7 +356,7 @@ InfoBox font-size: 20px; /*background: rgba(236, 155, 59, 0.67);*/ padding: 13px 10px; - margin: 0px 0px 5px 0px; + margin: 0px 0px 0px 0px; border-top-left-radius: 15px; border-top-right-radius: 15px; } @@ -365,7 +369,7 @@ InfoBox font-size: 20px; /*background: rgba(236, 155, 59, 0.67);*/ padding: 13px 10px; - margin: 5px 0px 5px 0px; + margin: 0px 0px 5px 0px; } .infobox span { @@ -374,9 +378,19 @@ InfoBox margin: 5px 10px; } +.basic-slide_line { + margin: 10px auto; + width: 280px; + position: relative; +} + .basic-slide { + padding: 10px 0; +} + +.basic-slide_input { + width: 100%; display: inline-block; - width: 280px; padding: 10px 0 10px 0px; font-family: "Open Sans", sans; font-weight: 400; @@ -389,7 +403,18 @@ InfoBox text-align: center; } -.basic-slide + label { +.multiline .basic-slide { + display: flex; + justify-content: space-around; +} + +.basic-slide_wrap { + display: block; + width: 280px; + margin: auto; +} + +.basic-slide_label { display: inline-block; position: absolute; top: 0; @@ -444,6 +469,24 @@ InfoBox margin-left: 2px; } + +/* video */ +.bg-videosnap, +.bg-video { + display: none; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: -100; + min-width: 100%; + min-height: 100%; + background: url('/static/images/helloworld.jpg') no-repeat; + background-size: cover; + transition: 1s opacity; +} + /*Bubbles*/ .bg-bubbles { position: absolute; @@ -556,8 +599,13 @@ InfoBox } } + /*Footer ========================================================================== */ +.footer { + display: flex; + justify-content: space-between; +} footer a { color: #a1a9b0; } footer { background-color: rgba(0,0,0,0.5); padding: 5px 0 5px; } footer p { color: #fff; } @@ -580,3 +628,5 @@ Waypoints .delay-05s { animation-delay: 0.5s; -webkit-animation-delay: 0.5s; } .delay-1s { animation-delay: 1s; -webkit-animation-delay: 1s; } .wp3 { background: url('/static/images/iphone-bg.png') no-repeat center center; background-position: 200px 10px; height: 100%; } + + diff --git a/static/js/panel.js b/static/js/panel.js index ada3e8d..34e8e3b 100644 --- a/static/js/panel.js +++ b/static/js/panel.js @@ -1,17 +1,45 @@ var Panel = function () { var createHandler = function () { + // $('#extend').on('click', function(e) { + // if($('#extend').hasClass('fa-angle-double-up')) { + // $('#extend').removeClass('fa-angle-double-up'); + // $('#extend').addClass('fa-angle-double-down'); + // $('#account-detail').slideToggle('slow'); + // } else { + // $('#extend').removeClass('fa-angle-double-down'); + // $('#extend').addClass('fa-angle-double-up'); + // $('#account-detail').slideToggle('slow'); + // } + // }); + + $('#server-type').on('change', function (e) { + var methods = []; + if (this.value == 'SS') { + // for ss + methods = ssMethods; + } else if (this.value == "SSR") { + // for ssr + methods = ssrMethods; + } + $("#method").empty(); + if (methods.length == 0) { + $("#method").append(""); + } else { + for (i in methods) { + $("#method").append(""); + } + } + }); + $('#create-btn').on('click', function (e) { e.preventDefault(); - //1. Hide create-btn. - $('#form-title').css('display', 'none'); - $('#create-btn').css('display', 'none'); - - //2. Show loading icon. + // Show loading + $('#create-form').css('display', 'none'); $('.boxLoading').fadeIn(500); - //3. Send create SS service request & show account info panel. + // Send create SS service request & show account info panel. var form = $('#create-form'); var url = form.attr("action"); $.post(url, form.serialize(), function (resp) { @@ -19,18 +47,22 @@ var Panel = function () { $('#host').val(resp.data.host); $('#port').val(resp.data.servicePort); $('#pwd').val(resp.data.servicePwd); + $('#encrypt').val($('#method').val()); + $('#types').val($('#server-type').val()); - $('#package-limit').html(resp.data.packageLimit+'GB'); + $('#package-limit').html(resp.data.packageLimit + 'GB'); $('#package-used').html('0GB'); - $('#package-left').html(resp.data.packageLimit+'GB'); + $('#package-left').html(resp.data.packageLimit + 'GB'); $('.progressbar').attr('data-perc', '0'); $('#service-status').html('
运行中'); $('.boxLoading').css('display', 'none'); $('.infobox').fadeIn(1500); } else { - //Create SS service failed - toastr.warning(data.message); + $('.boxLoading').css('display', 'block'); + $('.boxLoading').fadeOut(500); + $('#create-form').fadeIn(500); + toastr.warning(resp.message); return false; } }, "json"); @@ -43,4 +75,4 @@ var Panel = function () { createHandler(); } }; -}(); \ No newline at end of file +}(); diff --git a/static/js/scripts.js b/static/js/scripts.js index daf2f2c..9a933f5 100644 --- a/static/js/scripts.js +++ b/static/js/scripts.js @@ -1,55 +1,21 @@ -$(document).ready(function() { - //scaleVideoContainer(); - - initBannerVideoSize('.video-container .poster img'); - initBannerVideoSize('.video-container .filter'); - initBannerVideoSize('.video-container video'); - - $(window).on('resize', function() { - // scaleVideoContainer(); - scaleBannerVideoSize('.video-container .poster img'); - scaleBannerVideoSize('.video-container .filter'); - scaleBannerVideoSize('.video-container video'); - }); - - $('.main-title').css('visibility', 'visible').addClass('animated fadeInDown'); - -}); - -function initBannerVideoSize(element){ - - $(element).each(function(){ - $(this).data('height', $(this).height()); - $(this).data('width', $(this).width()); - }); - - scaleBannerVideoSize(element); -} - -function scaleBannerVideoSize(element){ - - var windowWidth = $(window).width(), - windowHeight = $(window).height() + 5, - videoWidth, - videoHeight; - - $(element).each(function(){ - var videoAspectRatio = $(this).data('height')/$(this).data('width'); - - $(this).width(windowWidth); - - if(windowWidth < 1000){ - videoHeight = windowHeight; - videoWidth = videoHeight / videoAspectRatio; - $(this).css({'margin-top' : 0, 'margin-left' : -(videoWidth - windowWidth) / 2 + 'px'}); - - $(this).width(videoWidth).height(videoHeight); - } - - $('.homepage-hero-module .video-container video').addClass('fadeIn animated'); - - }); -} +// client symbol +window.os = function() { + var ua = navigator.userAgent, + isWindowsPhone = /(?:Windows Phone)/.test(ua), + isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone, + isAndroid = /(?:Android)/.test(ua), + isFireFox = /(?:Firefox)/.test(ua), + isChrome = /(?:Chrome|CriOS)/.test(ua), + isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)), + isPhone = /(?:iPhone)/.test(ua) && !isTablet, + isPc = !isPhone && !isAndroid && !isSymbian; + return { + isTablet: isTablet, + isPhone: isPhone, + isAndroid : isAndroid, + isPc : isPc + }; +}(); /* ********************************************************** @@ -59,11 +25,11 @@ function scaleBannerVideoSize(element){ // Toggle tranparent navbar when the user scrolls the page - $(window).scroll(function() { - if($(this).scrollTop() > 50) /*height in pixels when the navbar becomes non opaque*/ - { - $('.opaque-navbar').addClass('opaque'); - } else { - $('.opaque-navbar').removeClass('opaque'); - } -}); +// $(window).scroll(function() { +// if($(this).scrollTop() > 50) /*height in pixels when the navbar becomes non opaque*/ +// { +// $('.opaque-navbar').addClass('opaque'); +// } else { +// $('.opaque-navbar').removeClass('opaque'); +// } +// }); diff --git a/static/js/user.js b/static/js/user.js index 9691d1c..8cf4126 100644 --- a/static/js/user.js +++ b/static/js/user.js @@ -1,15 +1,14 @@ var User = function () { + var currentId = 'hero'; + function animateToggle(targetId) { + $('#' + currentId).fadeOut(500); + $('#' + currentId).css("display", "none"); + $('.header-' + targetId).addClass("active").siblings().removeClass("active"); + $('#' + targetId).fadeIn(1000); + currentId = targetId; + } var signupHandler = function () { - $(".signup").click(function(event){ - event.preventDefault(); - $('#hero').fadeOut(1000); - $('#hero').css("display", "none"); - - $('#login').css("display", "none"); - $('.header-signup').addClass("active").siblings().removeClass("active"); - $('#signup').fadeIn(500); - }); $('#signup-btn').on('click', function (e) { e.preventDefault(); @@ -29,15 +28,6 @@ var User = function () { }; var loginHandler = function () { - $('.login').on('click', function (e) { - e.preventDefault(); - $('#hero').fadeOut(1000); - $('#hero').css("display", "none"); - - $('#signup').css("display", "none") - $('.header-login').addClass("active").siblings().removeClass("active"); - $('#login').fadeIn(500); - }); $('#login-btn').on('click', function (e) { e.preventDefault(); @@ -63,6 +53,15 @@ var User = function () { $('.header-li').on('click', function (e) { $(this).addClass("active").siblings().removeClass("active"); }); + $(".hero-move").click(function(){ + animateToggle('hero'); + }); + $(".signup-move").click(function(){ + animateToggle('signup'); + }); + $('.login-move').on('click', function() { + animateToggle('login'); + }); }; return { @@ -73,4 +72,4 @@ var User = function () { commonHandler(); } }; -}(); \ No newline at end of file +}(); diff --git a/templates/footer.html b/templates/footer.html index c79d1e7..5dae1b5 100644 --- a/templates/footer.html +++ b/templates/footer.html @@ -1,22 +1,20 @@ {{ define "footer.html" }} -{{end}} \ No newline at end of file +{{end}} diff --git a/templates/header.html b/templates/header.html index de67367..b8093a3 100644 --- a/templates/header.html +++ b/templates/header.html @@ -4,22 +4,22 @@
-{{end}} \ No newline at end of file +{{end}} diff --git a/templates/index.html b/templates/index.html index 0910393..bb37448 100644 --- a/templates/index.html +++ b/templates/index.html @@ -11,6 +11,8 @@ + + @@ -26,7 +28,8 @@ {{template "header.html" .}} -