Skip to content

Commit 0953176

Browse files
feat: join code for users to join without invitation (#52)
1 parent bcc6636 commit 0953176

File tree

5 files changed

+122
-15
lines changed

5 files changed

+122
-15
lines changed

vitty-backend-api/api/serializers/circles.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ func CirclesListSerializer(ucj []models.UsersCirclesJoin) []map[string]interface
88
for _, userCircle := range ucj {
99

1010
out := map[string]interface{}{
11-
"circle_id": userCircle.CID,
12-
"circle_role": userCircle.CircleRole,
13-
"circle_name": userCircle.Circles.CircleName,
11+
"circle_id": userCircle.CID,
12+
"circle_role": userCircle.CircleRole,
13+
"circle_name": userCircle.Circles.CircleName,
14+
"circle_join_code": userCircle.Circles.CircleJoinCode,
1415
}
16+
1517
result = append(result, out)
1618
}
1719

@@ -39,11 +41,15 @@ func UsersListCircleSerializer(users []models.User) []map[string]interface{} {
3941
var result []map[string]interface{}
4042

4143
for _, user := range users {
44+
45+
currStatus := user.GetCurrentStatus()
46+
4247
out := map[string]interface{}{
43-
"username": user.Username,
44-
"name": user.Name,
45-
"picture": user.Picture,
46-
"email": user.Email,
48+
"current_status": currStatus,
49+
"username": user.Username,
50+
"name": user.Name,
51+
"picture": user.Picture,
52+
"email": user.Email,
4753
}
4854
result = append(result, out)
4955
}

vitty-backend-api/api/v2/circleHandler.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ func circleHandler(api fiber.Router) {
2222
group.Get("/requests/sent", getSentCircleRequests)
2323
group.Post("/create/:circleName", createCircle)
2424
group.Post("/sendRequest/:circleId/:username", sendCircleRequestToUser)
25+
group.Post("/:circleId/generateJoinCode", generateCircleJoinCode)
2526
group.Post("/acceptRequest/:circleId", acceptCircleRequest)
27+
group.Post("/join", joinCircleByCode)
2628
group.Post("/declineRequest/:circleId", declineCircleRequest)
2729
group.Patch("/", updateCircleName)
2830
group.Delete("/:circleId", deleteCircle)
@@ -279,6 +281,32 @@ func sendCircleRequestToUser(c *fiber.Ctx) error {
279281
})
280282
}
281283

284+
func generateCircleJoinCode(c *fiber.Ctx) error {
285+
var circle models.Circles
286+
287+
circleId := c.Params("circleId")
288+
289+
circle.CircleId = circleId
290+
291+
joinCode := utils.GenerateJoinCode(10)
292+
err := circle.CreateCircleJoinCode(joinCode)
293+
294+
if err != nil {
295+
if errors.Is(err, gorm.ErrRecordNotFound) {
296+
return c.Status(fiber.StatusBadRequest).JSON(fiber.ErrBadRequest)
297+
}
298+
299+
log.Println(err)
300+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
301+
"detail": "circle share code generation failed",
302+
})
303+
}
304+
305+
return c.Status(fiber.StatusOK).JSON(fiber.Map{
306+
"detail": "circle code generated",
307+
})
308+
}
309+
282310
func acceptCircleRequest(c *fiber.Ctx) error {
283311
var circleRequest models.CircleRequest
284312

@@ -308,6 +336,50 @@ func acceptCircleRequest(c *fiber.Ctx) error {
308336
})
309337
}
310338

339+
func joinCircleByCode(c *fiber.Ctx) error {
340+
var circle models.Circles
341+
var userCircle models.UsersCirclesJoin
342+
343+
joinCode := c.Query("code")
344+
reqUser := c.Locals("user").(models.User).Username
345+
346+
err := circle.GetCircleByJoinCode(joinCode)
347+
348+
if err != nil {
349+
350+
if errors.Is(err, gorm.ErrRecordNotFound) {
351+
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
352+
"detail": "invalid join code",
353+
})
354+
}
355+
log.Println(err)
356+
}
357+
358+
userCircle.CID = circle.CircleId
359+
userCircle.CircleRole = "member"
360+
userCircle.Uname = reqUser
361+
362+
err = userCircle.AddUserToCircle()
363+
364+
if err != nil {
365+
log.Println(err)
366+
367+
if errors.Is(err, gorm.ErrDuplicatedKey) {
368+
return c.Status(fiber.StatusConflict).JSON(fiber.Map{
369+
"error": "you are already part of the circle",
370+
})
371+
}
372+
373+
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
374+
"error": "failed to join circle",
375+
})
376+
}
377+
378+
return c.Status(fiber.StatusOK).JSON(fiber.Map{
379+
"detail": "joined circle successfully",
380+
})
381+
}
382+
311383
func updateCircleName(c *fiber.Ctx) error {
312384
var circle models.Circles
313385

vitty-backend-api/internal/database/initialize.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func Connect(debug string, dbUrls string) {
2020
})
2121
} else {
2222
DB, err = gorm.Open(postgres.Open(dbUrls), &gorm.Config{
23-
Logger: logger.Default.LogMode(logger.Silent),
23+
Logger: logger.Default.LogMode(logger.Silent),
2424
TranslateError: true,
2525
})
2626
}

vitty-backend-api/internal/models/circles.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,26 @@ import (
1111
)
1212

1313
type Circles struct {
14-
CircleId string `json:"circle_id" gorm:"unique"`
15-
CircleName string `json:"circle_name" gorm:"primaryKey"`
16-
Uname string `json:"omitempty" gorm:"primaryKey"`
17-
CircleSlots string
18-
User User `gorm:"foreignKey:Uname;references:Username;"`
14+
CircleId string `json:"circle_id" gorm:"unique"`
15+
CircleName string `json:"circle_name" gorm:"primaryKey"`
16+
Uname string `json:"omitempty" gorm:"primaryKey"`
17+
CircleSlots string
18+
CircleJoinCode string `json:"circle_join_code" gorm:"default:null"`
19+
User User `gorm:"foreignKey:Uname;references:Username;"`
1920
}
2021

2122
func (c *Circles) CreateCircle() error {
2223
err := database.DB.Create(c).Error
2324
return err
2425
}
2526

26-
func (c *Circles) GetCircleByCircleId() error {
27-
err := database.DB.Where(c).First(&c).Error
27+
func (c *Circles) GetCircleByCircleId(circleId string) error {
28+
results := database.DB.Where("circle_join_code = ?", circleId).First(&c).Error
29+
return results
30+
}
31+
32+
func (c *Circles) GetCircleByJoinCode(joinCode string) error {
33+
err := database.DB.Where("circle_join_code = ?", joinCode).First(&c).Error
2834
return err
2935
}
3036

@@ -54,6 +60,11 @@ func (c *Circles) updateCircleSlots(circleSlotMap map[string]string) error {
5460
return err
5561
}
5662

63+
func (c *Circles) CreateCircleJoinCode(joinCode string) error {
64+
err := database.DB.Model(&Circles{}).Where("circle_id like ?", c.CircleId).Update("circle_join_code", joinCode).Error
65+
return err
66+
}
67+
5768
func (c *Circles) DeleteCircle() error {
5869
result := database.DB.Where(&c).Delete(&Circles{})
5970

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package utils
2+
3+
import (
4+
"math/rand"
5+
"time"
6+
)
7+
8+
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
9+
10+
func GenerateJoinCode(length int) string {
11+
var rng = rand.New(rand.NewSource(time.Now().UnixNano()))
12+
13+
b := make([]byte, length)
14+
for i := range b {
15+
b[i] = charset[rng.Intn(len(charset))]
16+
}
17+
return string(b)
18+
}

0 commit comments

Comments
 (0)