diff --git a/internal/db/db.go b/internal/db/db.go index 4182b2d..3ccd47d 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -121,6 +121,14 @@ func OrderByUsersCreatedAtDesc(db *gorm.DB) *gorm.DB { return db.Order("users.created_at desc") } +func OrderByRoomCreatedAtAsc(db *gorm.DB) *gorm.DB { + return db.Order("rooms.created_at asc") +} + +func OrderByRoomCreatedAtDesc(db *gorm.DB) *gorm.DB { + return db.Order("rooms.created_at desc") +} + func OrderByIDAsc(db *gorm.DB) *gorm.DB { return db.Order("id asc") } diff --git a/internal/db/room.go b/internal/db/room.go index fb5ae6c..83ecb86 100644 --- a/internal/db/room.go +++ b/internal/db/room.go @@ -21,7 +21,7 @@ func WithSetting(setting *model.RoomSettings) CreateRoomConfig { func WithCreator(creator *model.User) CreateRoomConfig { return func(r *model.Room) { r.CreatorID = creator.ID - r.GroupUserRelations = []*model.RoomMember{ + r.RoomMembers = []*model.RoomMember{ { UserID: creator.ID, Status: model.RoomMemberStatusActive, @@ -35,7 +35,7 @@ func WithCreator(creator *model.User) CreateRoomConfig { func WithRelations(relations []*model.RoomMember) CreateRoomConfig { return func(r *model.Room) { - r.GroupUserRelations = append(r.GroupUserRelations, relations...) + r.RoomMembers = append(r.RoomMembers, relations...) } } diff --git a/internal/model/room.go b/internal/model/room.go index 48794f6..c0588eb 100644 --- a/internal/model/room.go +++ b/internal/model/room.go @@ -31,16 +31,16 @@ func (r RoomStatus) String() string { } type Room struct { - ID string `gorm:"primaryKey;type:char(32)" json:"id"` - CreatedAt time.Time - UpdatedAt time.Time - Status RoomStatus `gorm:"not null;default:2"` - Name string `gorm:"not null;uniqueIndex;type:varchar(32)"` - Settings *RoomSettings `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"settings"` - CreatorID string `gorm:"index;type:char(32)"` - HashedPassword []byte - GroupUserRelations []*RoomMember `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` - Movies []*Movie `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` + ID string `gorm:"primaryKey;type:char(32)" json:"id"` + CreatedAt time.Time + UpdatedAt time.Time + Status RoomStatus `gorm:"not null;default:2"` + Name string `gorm:"not null;uniqueIndex;type:varchar(32)"` + Settings *RoomSettings `gorm:"foreignKey:ID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"settings"` + CreatorID string `gorm:"index;type:char(32)"` + HashedPassword []byte + RoomMembers []*RoomMember `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` + Movies []*Movie `gorm:"foreignKey:RoomID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` } func (r *Room) BeforeCreate(tx *gorm.DB) error { diff --git a/server/handlers/admin.go b/server/handlers/admin.go index 61e051f..52b1d62 100644 --- a/server/handlers/admin.go +++ b/server/handlers/admin.go @@ -632,8 +632,12 @@ func AdminGetUserJoinedRooms(ctx *gin.Context) { scopes := []func(db *gorm.DB) *gorm.DB{ func(db *gorm.DB) *gorm.DB { return db. - InnerJoins("JOIN room_members ON rooms.id = room_members.room_id"). - Where("room_members.user_id = ? AND rooms.creator_id != ?", id, id) + InnerJoins("JOIN room_members ON rooms.id = room_members.room_id AND room_members.user_id = ? AND rooms.creator_id != ?", id, id) + }, + func(db *gorm.DB) *gorm.DB { + return db.Preload("RoomMembers", func(db *gorm.DB) *gorm.DB { + return db.Where("user_id = ?", id) + }) }, } @@ -668,15 +672,15 @@ func AdminGetUserJoinedRooms(ctx *gin.Context) { switch ctx.DefaultQuery("sort", "name") { case "createdAt": if desc { - scopes = append(scopes, db.OrderByCreatedAtDesc) + scopes = append(scopes, db.OrderByRoomCreatedAtDesc) } else { - scopes = append(scopes, db.OrderByCreatedAtAsc) + scopes = append(scopes, db.OrderByRoomCreatedAtAsc) } case "name": if desc { - scopes = append(scopes, db.OrderByDesc("name")) + scopes = append(scopes, db.OrderByDesc("rooms.name")) } else { - scopes = append(scopes, db.OrderByAsc("name")) + scopes = append(scopes, db.OrderByAsc("rooms.name")) } default: log.Errorf("not support sort") @@ -684,7 +688,7 @@ func AdminGetUserJoinedRooms(ctx *gin.Context) { return } - list, err := genRoomListResp(append(scopes, db.Paginate(page, pageSize))...) + list, err := genJoinedRoomListResp(append(scopes, db.Paginate(page, pageSize))...) if err != nil { log.Errorf("failed to get all rooms: %v", err) ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) diff --git a/server/handlers/init.go b/server/handlers/init.go index 03fb12e..d69a298 100644 --- a/server/handlers/init.go +++ b/server/handlers/init.go @@ -267,6 +267,8 @@ func initUser(user *gin.RouterGroup, needAuthUser *gin.RouterGroup) { needAuthUser.GET("/rooms", UserRooms) + needAuthUser.GET("/rooms/joined", UserJoinedRooms) + needAuthUser.POST("/username", SetUsername) needAuthUser.POST("/password", SetUserPassword) diff --git a/server/handlers/room.go b/server/handlers/room.go index 16a90de..9b27993 100644 --- a/server/handlers/room.go +++ b/server/handlers/room.go @@ -251,6 +251,34 @@ func genRoomListResp(scopes ...func(db *gorm.DB) *gorm.DB) ([]*model.RoomListRes return resp, nil } +func genJoinedRoomListResp(scopes ...func(db *gorm.DB) *gorm.DB) ([]*model.JoinedRoomResp, error) { + rs, err := db.GetAllRooms(scopes...) + if err != nil { + return nil, err + } + resp := make([]*model.JoinedRoomResp, len(rs)) + for i, r := range rs { + if len(r.RoomMembers) == 0 { + return nil, fmt.Errorf("room %s load member failed", r.ID) + } + resp[i] = &model.JoinedRoomResp{ + RoomListResp: model.RoomListResp{ + RoomId: r.ID, + RoomName: r.Name, + PeopleNum: op.PeopleNum(r.ID), + NeedPassword: len(r.HashedPassword) != 0, + CreatorID: r.CreatorID, + Creator: op.GetUserName(r.CreatorID), + CreatedAt: r.CreatedAt.UnixMilli(), + Status: r.Status, + }, + MemberStatus: r.RoomMembers[0].Status, + MemberRole: r.RoomMembers[0].Role, + } + } + return resp, nil +} + func CheckRoom(ctx *gin.Context) { log := ctx.MustGet("log").(*logrus.Entry) roomId, err := middlewares.GetRoomIdFromContext(ctx) diff --git a/server/handlers/user.go b/server/handlers/user.go index 8654cd0..fbd0b00 100644 --- a/server/handlers/user.go +++ b/server/handlers/user.go @@ -185,10 +185,13 @@ func UserJoinedRooms(ctx *gin.Context) { scopes := []func(db *gorm.DB) *gorm.DB{ func(db *gorm.DB) *gorm.DB { return db. - InnerJoins("JOIN room_members ON rooms.id = room_members.room_id"). - Where("room_members.user_id = ? AND rooms.creator_id != ?", user.ID, user.ID) + InnerJoins("JOIN room_members ON rooms.id = room_members.room_id AND room_members.user_id = ? AND rooms.creator_id != ?", user.ID, user.ID) + }, + func(db *gorm.DB) *gorm.DB { + return db.Preload("RoomMembers", func(db *gorm.DB) *gorm.DB { + return db.Where("user_id = ?", user.ID) + }) }, - db.WhereStatus(dbModel.RoomStatusActive), } if keyword := ctx.Query("keyword"); keyword != "" { @@ -213,15 +216,15 @@ func UserJoinedRooms(ctx *gin.Context) { switch ctx.DefaultQuery("sort", "name") { case "createdAt": if desc { - scopes = append(scopes, db.OrderByCreatedAtDesc) + scopes = append(scopes, db.OrderByRoomCreatedAtDesc) } else { - scopes = append(scopes, db.OrderByCreatedAtAsc) + scopes = append(scopes, db.OrderByRoomCreatedAtAsc) } case "name": if desc { - scopes = append(scopes, db.OrderByDesc("name")) + scopes = append(scopes, db.OrderByDesc("rooms.name")) } else { - scopes = append(scopes, db.OrderByAsc("name")) + scopes = append(scopes, db.OrderByAsc("rooms.name")) } default: log.Errorf("not support sort") @@ -229,9 +232,9 @@ func UserJoinedRooms(ctx *gin.Context) { return } - list, err := genRoomListResp(append(scopes, db.Paginate(page, pageSize))...) + list, err := genJoinedRoomListResp(append(scopes, db.Paginate(page, pageSize))...) if err != nil { - log.Errorf("failed to get all rooms: %v", err) + log.Errorf("failed to get joined rooms: %v", err) ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) return } diff --git a/server/model/room.go b/server/model/room.go index 137707e..fb43d24 100644 --- a/server/model/room.go +++ b/server/model/room.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/synctv-org/synctv/internal/model" + dbModel "github.com/synctv-org/synctv/internal/model" ) var ( @@ -68,6 +69,12 @@ type RoomListResp struct { Status model.RoomStatus `json:"status"` } +type JoinedRoomResp struct { + RoomListResp + MemberStatus dbModel.RoomMemberStatus `json:"memberStatus"` + MemberRole dbModel.RoomMemberRole `json:"memberRole"` +} + type LoginRoomReq struct { RoomId string `json:"roomId"` Password string `json:"password"`