github.com/EngineerKamesh/gofullstack@v0.0.0-20180609171605-d41341d7d4ee/volume3/section5/gopherface/client/handlers/myprofile.go (about)

     1  package handlers
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"strings"
     7  
     8  	"honnef.co/go/js/dom"
     9  	"honnef.co/go/js/xhr"
    10  
    11  	"github.com/EngineerKamesh/gofullstack/volume3/section5/gopherface/client/common"
    12  	"github.com/EngineerKamesh/gofullstack/volume3/section5/gopherface/forms"
    13  	"github.com/EngineerKamesh/gofullstack/volume3/section5/gopherface/models"
    14  	"github.com/gopherjs/gopherjs/js"
    15  
    16  	"go.isomorphicgo.org/go/isokit"
    17  )
    18  
    19  var myProfileForm *forms.MyProfileForm
    20  
    21  func MyProfileHandler(env *common.Env) isokit.Handler {
    22  	return isokit.HandlerFunc(func(ctx context.Context) {
    23  		myProfileForm = forms.NewMyProfileForm(nil)
    24  		var profile chan models.UserProfile = make(chan models.UserProfile, 1)
    25  		GetUserProfileRequest(profile)
    26  		u := <-profile
    27  		u.Form = myProfileForm
    28  		u.PageTitle = "My Profile"
    29  		env.TemplateSet.Render("myprofile_content", &isokit.RenderParams{Data: u, Disposition: isokit.PlacementReplaceInnerContents, Element: env.PrimaryContent})
    30  		InitializeMyProfileEventHandlers(env)
    31  	})
    32  }
    33  
    34  func InitializeMyProfileEventHandlers(env *common.Env) {
    35  
    36  	if myProfileForm == nil {
    37  		myProfileForm = forms.NewMyProfileForm(nil)
    38  	}
    39  
    40  	saveProfileButton := env.Document.GetElementByID("saveProfileButton").(*dom.HTMLButtonElement)
    41  	saveProfileButton.AddEventListener("click", false, func(event dom.Event) {
    42  		VerifyProfileForm(env, event, myProfileForm)
    43  	})
    44  
    45  	uploadInput := env.Document.GetElementByID("imagefile").(*dom.HTMLInputElement)
    46  	uploadInput.AddEventListener("change", false, func(event dom.Event) {
    47  		go UploadProfileImageRequest(env, event)
    48  	})
    49  
    50  	go PopulateFriendsList(env)
    51  }
    52  
    53  func blobToBytes(blob *js.Object) []byte {
    54  	var b = make(chan []byte)
    55  	fileReader := js.Global.Get("FileReader").New()
    56  	fileReader.Set("onload", func() {
    57  		b <- js.Global.Get("Uint8Array").New(fileReader.Get("result")).Interface().([]byte)
    58  	})
    59  	fileReader.Call("readAsArrayBuffer", blob)
    60  	return <-b
    61  }
    62  
    63  func UploadProfileImageRequest(env *common.Env, event dom.Event) {
    64  	fileElement := event.Target()
    65  	file := fileElement.Underlying().Get("files").Index(0)
    66  	b := blobToBytes(file)
    67  
    68  	data, err := xhr.Send("POST", "/restapi/save-user-profile-image", b)
    69  	if err != nil {
    70  		println(err)
    71  	}
    72  
    73  	if !strings.Contains(string(data), "Error:") {
    74  		profileImage := env.Document.GetElementByID("profileImage").(*dom.HTMLImageElement)
    75  		profileImage.SetAttribute("src", string(data))
    76  		js.Global.Get("alertify").Call("success", "Profile image changed successfully!")
    77  
    78  	} else {
    79  		js.Global.Get("alertify").Call("error", string(data))
    80  	}
    81  }
    82  
    83  func VerifyProfileForm(env *common.Env, event dom.Event, profileForm *forms.MyProfileForm) {
    84  
    85  	event.PreventDefault()
    86  
    87  	formElement := env.Document.GetElementByID("userProfileForm").(*dom.HTMLFormElement)
    88  	profileForm.SetFormParams(&isokit.FormParams{FormElement: formElement})
    89  	validationResult := profileForm.Validate()
    90  	if validationResult == true {
    91  
    92  		about := env.Document.GetElementByID("aboutTextArea").(*dom.HTMLTextAreaElement).Value
    93  		location := env.Document.GetElementByID("locationInput").(*dom.HTMLInputElement).Value
    94  		interests := env.Document.GetElementByID("interestsInput").(*dom.HTMLInputElement).Value
    95  
    96  		u := models.UserProfile{}
    97  		u.About = about
    98  		u.Location = location
    99  		u.Interests = interests
   100  		go SaveProfileRequest(u)
   101  
   102  	} else {
   103  		profileForm.DisplayErrors()
   104  	}
   105  
   106  }
   107  
   108  func SaveProfileRequest(u models.UserProfile) {
   109  
   110  	profileBytes, err := json.Marshal(u)
   111  	if err != nil {
   112  		println(err)
   113  	}
   114  	data, err := xhr.Send("POST", "/restapi/save-user-profile", profileBytes)
   115  	if err != nil {
   116  		println(err)
   117  	}
   118  
   119  	if strings.Contains(string(data), "Error:") {
   120  
   121  		js.Global.Get("alertify").Call("error", string(data))
   122  
   123  	} else {
   124  
   125  		js.Global.Get("alertify").Call("success", "Profile saved successfully!")
   126  	}
   127  
   128  }
   129  
   130  func GetUserProfileRequest(profile chan models.UserProfile) {
   131  
   132  	data, err := xhr.Send("GET", "/restapi/get-user-profile", nil)
   133  	if err != nil {
   134  		println("Encountered error while making XHR call: ", err)
   135  	}
   136  
   137  	var u models.UserProfile
   138  	err = json.Unmarshal(data, &u)
   139  	if err != nil {
   140  		println("Encountered error while unmarshalling JSON: ", err)
   141  	}
   142  
   143  	profile <- u
   144  
   145  }
   146  
   147  func PopulateFriendsList(env *common.Env) {
   148  
   149  	data, err := xhr.Send("POST", "/restapi/get-friends-list", nil)
   150  	if err != nil {
   151  		println("Encountered error while attempting to submit POST request via XHR: ", err)
   152  		println(err)
   153  	}
   154  
   155  	var gophers []models.Gopher
   156  	json.Unmarshal(data, &gophers)
   157  
   158  	friendsListContainer := env.Document.GetElementByID("friendsListContainer").(*dom.HTMLDivElement)
   159  	env.TemplateSet.Render("partials/friends_list", &isokit.RenderParams{Data: gophers, Disposition: isokit.PlacementReplaceInnerContents, Element: friendsListContainer})
   160  
   161  	unfollowButtons := friendsListContainer.QuerySelectorAll(".unfollowButton")
   162  	for i := 0; i < len(unfollowButtons); i++ {
   163  		unfollowButtons[i].AddEventListener("click", false, func(event dom.Event) {
   164  			go UnfollowGopherRequest(env, event)
   165  		})
   166  	}
   167  
   168  }
   169  
   170  func UnfollowGopherRequest(env *common.Env, event dom.Event) {
   171  	button := event.Target()
   172  	button.SetAttribute("disabled", "")
   173  	uuid := button.GetAttribute("data-uuid")
   174  	username := button.GetAttribute("data-username")
   175  	friendItemDiv := env.Document.GetElementByID("followingitem_" + uuid).(*dom.HTMLDivElement)
   176  	textBytes, err := json.Marshal(uuid)
   177  
   178  	if err != nil {
   179  		println("Encountered error while attempting to marshal JSON: ", err)
   180  		println(err)
   181  	}
   182  
   183  	data, err := xhr.Send("POST", "/restapi/unfollow-gopher", textBytes)
   184  	if err != nil {
   185  		println("Encountered error while attempting to submit POST request via XHR: ", err)
   186  		println(err)
   187  	}
   188  
   189  	var resultErr error
   190  	json.Unmarshal(data, &resultErr)
   191  
   192  	if resultErr == nil {
   193  		js.Global.Get("alertify").Call("success", "Unfollowed "+username+" successfully!")
   194  		friendItemDiv.ParentNode().RemoveChild(friendItemDiv)
   195  
   196  	} else {
   197  		js.Global.Get("alertify").Call("error", "Unfollow operation failed.")
   198  		button.RemoveAttribute("disabled")
   199  	}
   200  
   201  }