landed community join and unjoin functionality

This commit is contained in:
2025-10-22 16:27:01 -06:00
parent 6d3403cd53
commit 11537d5d7f
7 changed files with 249 additions and 4 deletions
+166
View File
@@ -10,6 +10,8 @@
package main
import (
"errors"
"fmt"
"net/http"
"strings"
@@ -62,6 +64,7 @@ func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
}
ctxt.VarMap().Set("commName", comm.Name)
ctxt.VarMap().Set("commAlias", comm.Alias)
if ci.PhotoURL != nil && *ci.PhotoURL != "" {
ctxt.VarMap().Set("logoURL", *ci.PhotoURL)
} else {
@@ -132,3 +135,166 @@ func ShowCommunity(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("amsterdam_pageTitle", "Community Profile: "+comm.Name)
return "framed_template", "comprofile.jet", nil
}
/* JoinCommunity joins a public community, or starts the process of joining a private one.
* Parameters:
* ctxt - The AmContext for the request.
* Returns:
* Command string dictating what to be rendered.
* Data as a parameter for the command string.
* Standard Go error status.
*/
func JoinCommunity(ctxt ui.AmContext) (string, any, error) {
me := ctxt.CurrentUser()
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
ctxt.SetLeftMenu("community")
if err != nil {
ctxt.SetRC(http.StatusNotFound)
return ui.ErrorPage(ctxt, err)
}
comm := ctxt.CurrentCommunity()
mbr, _, _, err := comm.Membership(me)
if err != nil {
return ui.ErrorPage(ctxt, err)
}
if mbr {
// already member, this is a no-op
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if comm.TestPermission("Community.Join", me.BaseLevel) {
if comm.JoinKey != nil && *comm.JoinKey != "" {
dlg, err := ui.AmLoadDialog("join")
if err != nil {
return ui.ErrorPage(ctxt, err)
}
dlg.SetCommunity(comm)
dlg.Field("cc").Value = comm.Alias
return dlg.Render(ctxt)
}
// if get here, this is a public community, and we can join
err = comm.SetMembership(me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
if err != nil {
return ui.ErrorPage(ctxt, err)
}
} else {
return ui.ErrorPage(ctxt, errors.New("you are not permitted to join this community"))
}
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
/* JoinCommunityWithKey joins a private community with a properly specified join key.
* Parameters:
* ctxt - The AmContext for the request.
* Returns:
* Command string dictating what to be rendered.
* Data as a parameter for the command string.
* Standard Go error status.
*/
func JoinCommunityWithKey(ctxt ui.AmContext) (string, any, error) {
me := ctxt.CurrentUser()
err := ctxt.SetCommunityContext(ctxt.FormField("cc"))
if err != nil {
ctxt.SetRC(http.StatusNotFound)
return ui.ErrorPage(ctxt, err)
}
comm := ctxt.CurrentCommunity()
ctxt.SetLeftMenu("community")
mbr, _, _, err := comm.Membership(me)
if err != nil {
return ui.ErrorPage(ctxt, err)
}
if mbr {
// already member, this is a no-op
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if comm.TestPermission("Community.Join", me.BaseLevel) {
dlg, err := ui.AmLoadDialog("join")
if err != nil {
return ui.ErrorPage(ctxt, err)
}
dlg.SetCommunity(comm)
dlg.LoadFromForm(ctxt)
action := dlg.WhichButton(ctxt)
if action == "cancel" {
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if action == "join_now" {
key := dlg.Field("key").Value
dlg.Field("key").Value = "" // clear it in case we redisplay the form
if key == "" {
return dlg.RenderError(ctxt, "No join key specified. Please try again.")
}
if comm.JoinKey != nil && key != *comm.JoinKey {
return dlg.RenderError(ctxt, "The join key does not match the community. Please try again.")
}
err = comm.SetMembership(me, database.AmDefaultRole("Community.NewUser").Level(), false, me.Uid, ctxt.RemoteIP())
if err != nil {
return dlg.RenderError(ctxt, fmt.Sprintf("Error joining: %v", err))
}
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
return dlg.RenderError(ctxt, "Unknown button pressed on join form.")
}
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
func UnjoinCommunity(ctxt ui.AmContext) (string, any, error) {
me := ctxt.CurrentUser()
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
if err != nil {
ctxt.SetRC(http.StatusNotFound)
return ui.ErrorPage(ctxt, err)
}
comm := ctxt.CurrentCommunity()
ctxt.SetLeftMenu("community")
mbr, lock, _, err := comm.Membership(me)
if err != nil {
return ui.ErrorPage(ctxt, err)
}
if !mbr {
// not a member, just redirect to profile
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if lock {
ctxt.SetRC(http.StatusForbidden)
return ui.ErrorPage(ctxt, errors.New("you are not permitted to unjoin this community"))
}
ctxt.VarMap().Set("comm", comm)
ctxt.VarMap().Set("amsterdam_pageTitle", "Unjoin Community")
return "framed_template", "unjoin.jet", nil
}
func UnjoinCommunityConfirm(ctxt ui.AmContext) (string, any, error) {
me := ctxt.CurrentUser()
err := ctxt.SetCommunityContext(ctxt.URLParam("cid"))
if err != nil {
ctxt.SetRC(http.StatusNotFound)
return ui.ErrorPage(ctxt, err)
}
comm := ctxt.CurrentCommunity()
ctxt.SetLeftMenu("community")
mbr, lock, _, err := comm.Membership(me)
if err != nil {
return ui.ErrorPage(ctxt, err)
}
if !mbr {
// not a member, just redirect to profile
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if lock {
ctxt.SetRC(http.StatusForbidden)
return ui.ErrorPage(ctxt, errors.New("you are not permitted to unjoin this community"))
}
if ctxt.FormFieldIsSet("cancel") {
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
if ctxt.FormFieldIsSet("unjoin") {
err = comm.SetMembership(me, 0, false, me.Uid, ctxt.RemoteIP())
if err != nil {
return ui.ErrorPage(ctxt, err)
}
ctxt.ClearCommunityContext()
return "redirect", fmt.Sprintf("/comm/%s/profile", comm.Alias), nil
}
return ui.ErrorPage(ctxt, errors.New("unknown button pressed to confirm unjoin"))
}