Merge remote-tracking branch 'upstream/v3.0.x-release' into pres-graphql
This commit is contained in:
commit
128e89fc83
@ -18,7 +18,8 @@ case class MeetingLockSettingsDbModel(
|
|||||||
hideUserList: Boolean,
|
hideUserList: Boolean,
|
||||||
lockOnJoin: Boolean,
|
lockOnJoin: Boolean,
|
||||||
lockOnJoinConfigurable: Boolean,
|
lockOnJoinConfigurable: Boolean,
|
||||||
hideViewersCursor: Boolean
|
hideViewersCursor: Boolean,
|
||||||
|
hideViewersAnnotation: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
class MeetingLockSettingsDbTableDef(tag: Tag) extends Table[MeetingLockSettingsDbModel](tag, "meeting_lockSettings") {
|
class MeetingLockSettingsDbTableDef(tag: Tag) extends Table[MeetingLockSettingsDbModel](tag, "meeting_lockSettings") {
|
||||||
@ -32,10 +33,11 @@ class MeetingLockSettingsDbTableDef(tag: Tag) extends Table[MeetingLockSettingsD
|
|||||||
val lockOnJoin = column[Boolean]("lockOnJoin")
|
val lockOnJoin = column[Boolean]("lockOnJoin")
|
||||||
val lockOnJoinConfigurable = column[Boolean]("lockOnJoinConfigurable")
|
val lockOnJoinConfigurable = column[Boolean]("lockOnJoinConfigurable")
|
||||||
val hideViewersCursor = column[Boolean]("hideViewersCursor")
|
val hideViewersCursor = column[Boolean]("hideViewersCursor")
|
||||||
|
val hideViewersAnnotation = column[Boolean]("hideViewersAnnotation")
|
||||||
|
|
||||||
// def fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId)
|
// def fk_meetingId: ForeignKeyQuery[MeetingDbTableDef, MeetingDbModel] = foreignKey("fk_meetingId", meetingId, TableQuery[MeetingDbTableDef])(_.meetingId)
|
||||||
|
|
||||||
override def * : ProvenShape[MeetingLockSettingsDbModel] = (meetingId, disableCam, disableMic, disablePrivateChat, disablePublicChat, disableNotes, hideUserList, lockOnJoin, lockOnJoinConfigurable, hideViewersCursor) <> (MeetingLockSettingsDbModel.tupled, MeetingLockSettingsDbModel.unapply)
|
override def * : ProvenShape[MeetingLockSettingsDbModel] = (meetingId, disableCam, disableMic, disablePrivateChat, disablePublicChat, disableNotes, hideUserList, lockOnJoin, lockOnJoinConfigurable, hideViewersCursor, hideViewersAnnotation) <> (MeetingLockSettingsDbModel.tupled, MeetingLockSettingsDbModel.unapply)
|
||||||
}
|
}
|
||||||
|
|
||||||
object MeetingLockSettingsDAO {
|
object MeetingLockSettingsDAO {
|
||||||
@ -52,7 +54,8 @@ object MeetingLockSettingsDAO {
|
|||||||
hideUserList = lockSettingsProps.hideUserList,
|
hideUserList = lockSettingsProps.hideUserList,
|
||||||
lockOnJoin = lockSettingsProps.lockOnJoin,
|
lockOnJoin = lockSettingsProps.lockOnJoin,
|
||||||
lockOnJoinConfigurable = lockSettingsProps.lockOnJoinConfigurable,
|
lockOnJoinConfigurable = lockSettingsProps.lockOnJoinConfigurable,
|
||||||
hideViewersCursor = lockSettingsProps.hideViewersCursor
|
hideViewersCursor = lockSettingsProps.hideViewersCursor,
|
||||||
|
hideViewersAnnotation = lockSettingsProps.hideViewersAnnotation,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).onComplete {
|
).onComplete {
|
||||||
@ -76,7 +79,8 @@ object MeetingLockSettingsDAO {
|
|||||||
hideUserList = permissions.hideUserList,
|
hideUserList = permissions.hideUserList,
|
||||||
lockOnJoin = permissions.lockOnJoin,
|
lockOnJoin = permissions.lockOnJoin,
|
||||||
lockOnJoinConfigurable = permissions.lockOnJoinConfigurable,
|
lockOnJoinConfigurable = permissions.lockOnJoinConfigurable,
|
||||||
hideViewersCursor = permissions.hideViewersCursor
|
hideViewersCursor = permissions.hideViewersCursor,
|
||||||
|
hideViewersAnnotation = permissions.hideViewersAnnotation,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
).onComplete {
|
).onComplete {
|
||||||
|
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/msgpatch"
|
"github.com/iMDT/bbb-graphql-middleware/internal/msgpatch"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/rediscli"
|
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/websrv"
|
"github.com/iMDT/bbb-graphql-middleware/internal/websrv"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -21,7 +20,7 @@ func main() {
|
|||||||
msgpatch.ClearAllCaches()
|
msgpatch.ClearAllCaches()
|
||||||
|
|
||||||
// Listen msgs from akka (for example to invalidate connection)
|
// Listen msgs from akka (for example to invalidate connection)
|
||||||
go rediscli.StartRedisListener()
|
go websrv.StartRedisListener()
|
||||||
|
|
||||||
// Websocket listener
|
// Websocket listener
|
||||||
// set default port
|
// set default port
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package rediscli
|
|
||||||
|
|
||||||
import "github.com/redis/go-redis/v9"
|
|
||||||
|
|
||||||
var redisClient = redis.NewClient(&redis.Options{
|
|
||||||
Addr: "127.0.0.1:6379",
|
|
||||||
Password: "",
|
|
||||||
DB: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
func GetRedisConn() *redis.Client {
|
|
||||||
return redisClient
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package rediscli
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func StartRedisListener() {
|
|
||||||
log := log.WithField("_routine", "StartRedisListener")
|
|
||||||
|
|
||||||
var ctx = context.Background()
|
|
||||||
|
|
||||||
subscriber := GetRedisConn().Subscribe(ctx, "from-akka-apps-redis-channel")
|
|
||||||
|
|
||||||
for {
|
|
||||||
msg, err := subscriber.ReceiveMessage(ctx)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("error: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip parsing unnecessary messages
|
|
||||||
if !strings.Contains(msg.Payload, "InvalidateUserGraphqlConnectionSysMsg") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var message interface{}
|
|
||||||
if err := json.Unmarshal([]byte(msg.Payload), &message); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
messageAsMap := message.(map[string]interface{})
|
|
||||||
|
|
||||||
messageEnvelopeAsMap := messageAsMap["envelope"].(map[string]interface{})
|
|
||||||
|
|
||||||
messageType := messageEnvelopeAsMap["name"]
|
|
||||||
|
|
||||||
if messageType == "InvalidateUserGraphqlConnectionSysMsg" {
|
|
||||||
messageCoreAsMap := messageAsMap["core"].(map[string]interface{})
|
|
||||||
messageBodyAsMap := messageCoreAsMap["body"].(map[string]interface{})
|
|
||||||
sessionTokenToInvalidate := messageBodyAsMap["sessionToken"]
|
|
||||||
log.Debugf("Received invalidate request for sessionToken %v", sessionTokenToInvalidate)
|
|
||||||
|
|
||||||
//Not being used yet
|
|
||||||
//websrv.InvalidateSessionTokenConnections(sessionTokenToInvalidate.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import (
|
|||||||
"github.com/iMDT/bbb-graphql-middleware/internal/common"
|
"github.com/iMDT/bbb-graphql-middleware/internal/common"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/hascli"
|
"github.com/iMDT/bbb-graphql-middleware/internal/hascli"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/msgpatch"
|
"github.com/iMDT/bbb-graphql-middleware/internal/msgpatch"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/rediscli"
|
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/websrv/reader"
|
"github.com/iMDT/bbb-graphql-middleware/internal/websrv/reader"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/websrv/writer"
|
"github.com/iMDT/bbb-graphql-middleware/internal/websrv/writer"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -65,7 +64,7 @@ func ConnectionHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
sessionTokenRemoved := BrowserConnections[browserConnectionId].SessionToken
|
sessionTokenRemoved := BrowserConnections[browserConnectionId].SessionToken
|
||||||
delete(BrowserConnections, browserConnectionId)
|
delete(BrowserConnections, browserConnectionId)
|
||||||
BrowserConnectionsMutex.Unlock()
|
BrowserConnectionsMutex.Unlock()
|
||||||
go rediscli.SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId)
|
go SendUserGraphqlConnectionClosedSysMsg(sessionTokenRemoved, browserConnectionId)
|
||||||
|
|
||||||
log.Infof("connection removed")
|
log.Infof("connection removed")
|
||||||
}()
|
}()
|
||||||
@ -136,7 +135,7 @@ func InvalidateSessionTokenConnections(sessionTokenToInvalidate string) {
|
|||||||
browserConnection.HasuraConnection.ContextCancelFunc()
|
browserConnection.HasuraConnection.ContextCancelFunc()
|
||||||
log.Debugf("Processed invalidate request for sessionToken %v (hasura connection %v)", sessionTokenToInvalidate, browserConnection.HasuraConnection.Id)
|
log.Debugf("Processed invalidate request for sessionToken %v (hasura connection %v)", sessionTokenToInvalidate, browserConnection.HasuraConnection.Id)
|
||||||
|
|
||||||
//go SendInvalidatedUserGraphqlConnectionEvtMsg(browserConnection.SessionToken)
|
go SendUserGraphqlConnectionInvalidatedEvtMsg(browserConnection.SessionToken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package websrv
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/iMDT/bbb-graphql-middleware/internal/rediscli"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -36,7 +35,7 @@ func ConnectionInitHandler(browserConnectionId string, browserConnectionContext
|
|||||||
browserConnection.SessionToken = sessionToken
|
browserConnection.SessionToken = sessionToken
|
||||||
BrowserConnectionsMutex.Unlock()
|
BrowserConnectionsMutex.Unlock()
|
||||||
|
|
||||||
go rediscli.SendUserGraphqlConnectionStablishedSysMsg(sessionToken, browserConnectionId)
|
go SendUserGraphqlConnectionStablishedSysMsg(sessionToken, browserConnectionId)
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,66 @@
|
|||||||
package rediscli
|
package websrv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var redisClient = redis.NewClient(&redis.Options{
|
||||||
|
Addr: "127.0.0.1:6379",
|
||||||
|
Password: "",
|
||||||
|
DB: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
func GetRedisConn() *redis.Client {
|
||||||
|
return redisClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartRedisListener() {
|
||||||
|
log := log.WithField("_routine", "StartRedisListener")
|
||||||
|
|
||||||
|
var ctx = context.Background()
|
||||||
|
|
||||||
|
subscriber := GetRedisConn().Subscribe(ctx, "from-akka-apps-redis-channel")
|
||||||
|
|
||||||
|
for {
|
||||||
|
msg, err := subscriber.ReceiveMessage(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("error: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip parsing unnecessary messages
|
||||||
|
if !strings.Contains(msg.Payload, "InvalidateUserGraphqlConnectionSysMsg") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var message interface{}
|
||||||
|
if err := json.Unmarshal([]byte(msg.Payload), &message); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageAsMap := message.(map[string]interface{})
|
||||||
|
|
||||||
|
messageEnvelopeAsMap := messageAsMap["envelope"].(map[string]interface{})
|
||||||
|
|
||||||
|
messageType := messageEnvelopeAsMap["name"]
|
||||||
|
|
||||||
|
if messageType == "InvalidateUserGraphqlConnectionSysMsg" {
|
||||||
|
messageCoreAsMap := messageAsMap["core"].(map[string]interface{})
|
||||||
|
messageBodyAsMap := messageCoreAsMap["body"].(map[string]interface{})
|
||||||
|
sessionTokenToInvalidate := messageBodyAsMap["sessionToken"]
|
||||||
|
log.Debugf("Received invalidate request for sessionToken %v", sessionTokenToInvalidate)
|
||||||
|
|
||||||
|
//Not being used yet
|
||||||
|
InvalidateSessionTokenConnections(sessionTokenToInvalidate.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getCurrTimeInMs() int64 {
|
func getCurrTimeInMs() int64 {
|
||||||
currentTime := time.Now()
|
currentTime := time.Now()
|
||||||
milliseconds := currentTime.UnixNano() / int64(time.Millisecond)
|
milliseconds := currentTime.UnixNano() / int64(time.Millisecond)
|
@ -158,7 +158,8 @@ create table "meeting_lockSettings" (
|
|||||||
"hideUserList" boolean,
|
"hideUserList" boolean,
|
||||||
"lockOnJoin" boolean,
|
"lockOnJoin" boolean,
|
||||||
"lockOnJoinConfigurable" boolean,
|
"lockOnJoinConfigurable" boolean,
|
||||||
"hideViewersCursor" boolean
|
"hideViewersCursor" boolean,
|
||||||
|
"hideViewersAnnotation" boolean
|
||||||
);
|
);
|
||||||
create index "idx_meeting_lockSettings_meetingId" on "meeting_lockSettings"("meetingId");
|
create index "idx_meeting_lockSettings_meetingId" on "meeting_lockSettings"("meetingId");
|
||||||
|
|
||||||
@ -172,6 +173,7 @@ SELECT
|
|||||||
mls."disableNotes",
|
mls."disableNotes",
|
||||||
mls."hideUserList",
|
mls."hideUserList",
|
||||||
mls."hideViewersCursor",
|
mls."hideViewersCursor",
|
||||||
|
mls."hideViewersAnnotation",
|
||||||
mup."webcamsOnlyForModerator",
|
mup."webcamsOnlyForModerator",
|
||||||
CASE WHEN
|
CASE WHEN
|
||||||
mls."disableCam" IS TRUE THEN TRUE
|
mls."disableCam" IS TRUE THEN TRUE
|
||||||
@ -181,6 +183,7 @@ SELECT
|
|||||||
WHEN mls."disableNotes" IS TRUE THEN TRUE
|
WHEN mls."disableNotes" IS TRUE THEN TRUE
|
||||||
WHEN mls."hideUserList" IS TRUE THEN TRUE
|
WHEN mls."hideUserList" IS TRUE THEN TRUE
|
||||||
WHEN mls."hideViewersCursor" IS TRUE THEN TRUE
|
WHEN mls."hideViewersCursor" IS TRUE THEN TRUE
|
||||||
|
WHEN mls."hideViewersAnnotation" IS TRUE THEN TRUE
|
||||||
WHEN mup."webcamsOnlyForModerator" IS TRUE THEN TRUE
|
WHEN mup."webcamsOnlyForModerator" IS TRUE THEN TRUE
|
||||||
ELSE FALSE
|
ELSE FALSE
|
||||||
END "hasActiveLockSetting"
|
END "hasActiveLockSetting"
|
||||||
|
@ -18,6 +18,7 @@ select_permissions:
|
|||||||
- hasActiveLockSetting
|
- hasActiveLockSetting
|
||||||
- hideUserList
|
- hideUserList
|
||||||
- hideViewersCursor
|
- hideViewersCursor
|
||||||
|
- hideViewersAnnotation
|
||||||
- webcamsOnlyForModerator
|
- webcamsOnlyForModerator
|
||||||
filter:
|
filter:
|
||||||
meetingId:
|
meetingId:
|
||||||
|
@ -6,6 +6,16 @@ configuration:
|
|||||||
custom_column_names: {}
|
custom_column_names: {}
|
||||||
custom_name: pres_annotation_curr
|
custom_name: pres_annotation_curr
|
||||||
custom_root_fields: {}
|
custom_root_fields: {}
|
||||||
|
object_relationships:
|
||||||
|
- name: user
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
column_mapping:
|
||||||
|
userId: userId
|
||||||
|
insertion_order: null
|
||||||
|
remote_table:
|
||||||
|
name: v_user_ref
|
||||||
|
schema: public
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: bbb_client
|
- role: bbb_client
|
||||||
permission:
|
permission:
|
||||||
@ -18,5 +28,26 @@ select_permissions:
|
|||||||
- annotationInfo
|
- annotationInfo
|
||||||
- lastUpdatedAt
|
- lastUpdatedAt
|
||||||
filter:
|
filter:
|
||||||
meetingId:
|
_and:
|
||||||
_eq: X-Hasura-MeetingId
|
- meetingId:
|
||||||
|
_eq: X-Hasura-UserId
|
||||||
|
- _or:
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-ModeratorInMeeting
|
||||||
|
- userId:
|
||||||
|
_eq: X-Hasura-LockedUserId
|
||||||
|
- meetingId:
|
||||||
|
_neq: X-Hasura-LockedInMeeting
|
||||||
|
- _exists:
|
||||||
|
_table:
|
||||||
|
name: v_meeting_lockSettings
|
||||||
|
schema: public
|
||||||
|
_where:
|
||||||
|
_and:
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-MeetingId
|
||||||
|
- hideViewersAnnotation:
|
||||||
|
_eq: false
|
||||||
|
- user:
|
||||||
|
isModerator:
|
||||||
|
_eq: true
|
||||||
|
@ -6,6 +6,16 @@ configuration:
|
|||||||
custom_column_names: {}
|
custom_column_names: {}
|
||||||
custom_name: pres_annotation_history_curr
|
custom_name: pres_annotation_history_curr
|
||||||
custom_root_fields: {}
|
custom_root_fields: {}
|
||||||
|
object_relationships:
|
||||||
|
- name: user
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
column_mapping:
|
||||||
|
userId: userId
|
||||||
|
insertion_order: null
|
||||||
|
remote_table:
|
||||||
|
name: v_user_ref
|
||||||
|
schema: public
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: bbb_client
|
- role: bbb_client
|
||||||
permission:
|
permission:
|
||||||
@ -17,5 +27,26 @@ select_permissions:
|
|||||||
- sequence
|
- sequence
|
||||||
- annotationInfo
|
- annotationInfo
|
||||||
filter:
|
filter:
|
||||||
meetingId:
|
_and:
|
||||||
_eq: X-Hasura-MeetingId
|
- meetingId:
|
||||||
|
_eq: X-Hasura-MeetingId
|
||||||
|
- _or:
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-ModeratorInMeeting
|
||||||
|
- userId:
|
||||||
|
_eq: X-Hasura-LockedUserId
|
||||||
|
- meetingId:
|
||||||
|
_neq: X-Hasura-LockedInMeeting
|
||||||
|
- _exists:
|
||||||
|
_table:
|
||||||
|
name: v_meeting_lockSettings
|
||||||
|
schema: public
|
||||||
|
_where:
|
||||||
|
_and:
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-MeetingId
|
||||||
|
- hideViewersAnnotation:
|
||||||
|
_eq: false
|
||||||
|
- user:
|
||||||
|
isModerator:
|
||||||
|
_eq: true
|
||||||
|
@ -28,5 +28,26 @@ select_permissions:
|
|||||||
- xPercent
|
- xPercent
|
||||||
- yPercent
|
- yPercent
|
||||||
filter:
|
filter:
|
||||||
meetingId:
|
_and:
|
||||||
_eq: X-Hasura-MeetingId
|
- meetingId:
|
||||||
|
_eq: X-Hasura-MeetingId
|
||||||
|
- _or:
|
||||||
|
- user:
|
||||||
|
isModerator:
|
||||||
|
_eq: true
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-ModeratorInMeeting
|
||||||
|
- meetingId:
|
||||||
|
_neq: X-Hasura-LockedInMeeting
|
||||||
|
- userId:
|
||||||
|
_eq: X-Hasura-LockedUserId
|
||||||
|
- _exists:
|
||||||
|
_table:
|
||||||
|
name: v_meeting_lockSettings
|
||||||
|
schema: public
|
||||||
|
_where:
|
||||||
|
_and:
|
||||||
|
- meetingId:
|
||||||
|
_eq: X-Hasura-MeetingId
|
||||||
|
- hideViewersCursor:
|
||||||
|
_eq: false
|
||||||
|
@ -85,6 +85,7 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({
|
|||||||
|
|
||||||
const sameSender = (previousMessage?.user?.userId
|
const sameSender = (previousMessage?.user?.userId
|
||||||
|| lastSenderPreviousPage) === message?.user?.userId;
|
|| lastSenderPreviousPage) === message?.user?.userId;
|
||||||
|
const isSystemSender = message.messageType === ChatMessageType.BREAKOUT_ROOM;
|
||||||
const dateTime = new Date(message?.createdAt);
|
const dateTime = new Date(message?.createdAt);
|
||||||
const messageContent: {
|
const messageContent: {
|
||||||
name: string,
|
name: string,
|
||||||
@ -123,12 +124,26 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
case ChatMessageType.BREAKOUT_ROOM:
|
||||||
|
return {
|
||||||
|
name: message.senderName,
|
||||||
|
color: '#0F70D7',
|
||||||
|
isModerator: true,
|
||||||
|
isSystemSender: true,
|
||||||
|
component: (
|
||||||
|
<ChatMessageTextContent
|
||||||
|
emphasizedMessage
|
||||||
|
text={message.message}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
};
|
||||||
case ChatMessageType.TEXT:
|
case ChatMessageType.TEXT:
|
||||||
default:
|
default:
|
||||||
return {
|
return {
|
||||||
name: message.user?.name,
|
name: message.user?.name,
|
||||||
color: message.user?.color,
|
color: message.user?.color,
|
||||||
isModerator: message.user?.isModerator,
|
isModerator: message.user?.isModerator,
|
||||||
|
isSystemSender: ChatMessageType.BREAKOUT_ROOM,
|
||||||
component: (
|
component: (
|
||||||
<ChatMessageTextContent
|
<ChatMessageTextContent
|
||||||
emphasizedMessage={message?.user?.isModerator}
|
emphasizedMessage={message?.user?.isModerator}
|
||||||
@ -139,14 +154,14 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<ChatWrapper sameSender={sameSender} ref={messageRef}>
|
<ChatWrapper isSystemSender={isSystemSender} sameSender={sameSender} ref={messageRef}>
|
||||||
{(!message?.user || !sameSender) && (
|
{(!message?.user || !sameSender) && (
|
||||||
<ChatAvatar
|
<ChatAvatar
|
||||||
avatar={message.user?.avatar}
|
avatar={message.user?.avatar}
|
||||||
color={messageContent.color}
|
color={messageContent.color}
|
||||||
moderator={messageContent.isModerator}
|
moderator={messageContent.isModerator}
|
||||||
>
|
>
|
||||||
{message.user?.avatar.length === 0 ? messageContent.name.toLowerCase().slice(0, 2) || '' : ''}
|
{!message.user || message.user?.avatar.length === 0 ? messageContent.name.toLowerCase().slice(0, 2) || 'q' : 'a'}
|
||||||
</ChatAvatar>
|
</ChatAvatar>
|
||||||
)}
|
)}
|
||||||
<ChatContent sameSender={message?.user ? sameSender : false}>
|
<ChatContent sameSender={message?.user ? sameSender : false}>
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
|
|
||||||
interface ChatWrapperProps {
|
interface ChatWrapperProps {
|
||||||
sameSender: boolean;
|
sameSender: boolean;
|
||||||
|
isSystemSender: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChatContentProps {
|
interface ChatContentProps {
|
||||||
@ -50,6 +51,12 @@ export const ChatWrapper = styled.div<ChatWrapperProps>`
|
|||||||
margin: ${borderSize} ${borderSize} 0 0;
|
margin: ${borderSize} ${borderSize} 0 0;
|
||||||
}
|
}
|
||||||
font-size: ${fontSizeBase};
|
font-size: ${fontSizeBase};
|
||||||
|
${({ isSystemSender }) => isSystemSender && `
|
||||||
|
background-color: #fef9f1;
|
||||||
|
border-left: 2px solid #f5c67f;
|
||||||
|
border-radius: 0px 3px 3px 0px;
|
||||||
|
padding: 8px 2px;
|
||||||
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ChatContent = styled.div<ChatContentProps>`
|
export const ChatContent = styled.div<ChatContentProps>`
|
||||||
@ -118,7 +125,7 @@ export const ChatAvatar = styled.div<ChatAvatarProps>`
|
|||||||
${({ moderator }) => moderator && `
|
${({ moderator }) => moderator && `
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
`}
|
`}
|
||||||
|
|
||||||
// ================ image ================
|
// ================ image ================
|
||||||
${({ avatar, emoji, color }) => avatar?.length !== 0 && !emoji && css`
|
${({ avatar, emoji, color }) => avatar?.length !== 0 && !emoji && css`
|
||||||
background-image: url(${avatar});
|
background-image: url(${avatar});
|
||||||
@ -136,7 +143,7 @@ export const ChatAvatar = styled.div<ChatAvatarProps>`
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items:center;
|
align-items:center;
|
||||||
// ================ content ================
|
// ================ content ================
|
||||||
|
|
||||||
& .react-loading-skeleton {
|
& .react-loading-skeleton {
|
||||||
height: 2.25rem;
|
height: 2.25rem;
|
||||||
width: 2.25rem;
|
width: 2.25rem;
|
||||||
|
@ -27,6 +27,8 @@ export const CHAT_MESSAGE_PUBLIC_SUBSCRIPTION = gql`
|
|||||||
messageId
|
messageId
|
||||||
createdAt
|
createdAt
|
||||||
messageMetadata
|
messageMetadata
|
||||||
|
senderName
|
||||||
|
senderRole
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -10,5 +10,6 @@ export const enum ChatMessageType {
|
|||||||
TEXT = 'default',
|
TEXT = 'default',
|
||||||
POLL = 'poll',
|
POLL = 'poll',
|
||||||
PRESENTATION = 'presentation',
|
PRESENTATION = 'presentation',
|
||||||
CHAT_CLEAR = 'publicChatHistoryCleared'
|
CHAT_CLEAR = 'publicChatHistoryCleared',
|
||||||
|
BREAKOUT_ROOM = 'breakoutRoomModeratorMsg',
|
||||||
}
|
}
|
||||||
|
@ -434,6 +434,7 @@ exports.dropAreaLeft = 'div[data-test="dropArea-contentLeft"]';
|
|||||||
exports.dropAreaRight = 'div[data-test="dropArea-contentRight"]';
|
exports.dropAreaRight = 'div[data-test="dropArea-contentRight"]';
|
||||||
exports.dropAreaTop = 'div[data-test="dropArea-contentTop"]';
|
exports.dropAreaTop = 'div[data-test="dropArea-contentTop"]';
|
||||||
exports.dropAreaSidebarBottom = 'div[data-test="dropArea-sidebarContentBottom"]';
|
exports.dropAreaSidebarBottom = 'div[data-test="dropArea-sidebarContentBottom"]';
|
||||||
|
exports.selfViewDisableBtn = 'li[data-test="selfViewDisableBtn"]';
|
||||||
|
|
||||||
exports.videoQualitySelector = 'select[id="setQuality"]';
|
exports.videoQualitySelector = 'select[id="setQuality"]';
|
||||||
exports.webcamItemTalkingUser = 'div[data-test="webcamItemTalkingUser"]';
|
exports.webcamItemTalkingUser = 'div[data-test="webcamItemTalkingUser"]';
|
||||||
|
@ -197,7 +197,7 @@ test.describe.parallel('User', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// https://docs.bigbluebutton.org/2.6/release-tests.html#see-other-viewers-in-the-users-list
|
// https://docs.bigbluebutton.org/2.6/release-tests.html#see-other-viewers-in-the-users-list
|
||||||
test('Lock See other viewers in the Users list', async ({ browser, context, page }) => {
|
test('Lock See other viewers in the Users list @flaky', async ({ browser, context, page }) => {
|
||||||
const lockViewers = new LockViewers(browser, context);
|
const lockViewers = new LockViewers(browser, context);
|
||||||
await lockViewers.initPages(page);
|
await lockViewers.initPages(page);
|
||||||
await lockViewers.lockSeeOtherViewersUserList();
|
await lockViewers.lockSeeOtherViewersUserList();
|
||||||
|
@ -86,6 +86,23 @@ class Webcam extends Page {
|
|||||||
await expect(height).toBe(windowHeight);
|
await expect(height).toBe(windowHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async disableSelfView() {
|
||||||
|
await this.waitAndClick(e.joinVideo);
|
||||||
|
await this.waitForSelector(e.noneBackgroundButton);
|
||||||
|
|
||||||
|
await uploadBackgroundVideoImage(this);
|
||||||
|
await this.waitAndClick(e.selectCustomBackground);
|
||||||
|
await sleep(1000);
|
||||||
|
await this.waitAndClick(e.startSharingWebcam);
|
||||||
|
await this.waitForSelector(e.webcamContainer);
|
||||||
|
|
||||||
|
await this.waitAndClick(e.dropdownWebcamButton);
|
||||||
|
await this.waitAndClick(e.selfViewDisableBtn);
|
||||||
|
|
||||||
|
const webcamVideoLocator = await this.getLocator(e.webcamConnecting);
|
||||||
|
await expect(webcamVideoLocator).toHaveScreenshot('disable-self-view.png');
|
||||||
|
}
|
||||||
|
|
||||||
async managingNewBackground() {
|
async managingNewBackground() {
|
||||||
await this.waitAndClick(e.joinVideo);
|
await this.waitAndClick(e.joinVideo);
|
||||||
await this.waitForSelector(e.noneBackgroundButton);
|
await this.waitForSelector(e.noneBackgroundButton);
|
||||||
|
@ -42,6 +42,12 @@ test.describe.parallel('Webcam', () => {
|
|||||||
await webcam.webcamFullscreen();
|
await webcam.webcamFullscreen();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Disable Self-view', async ({ browser, page }) => {
|
||||||
|
const webcam = new Webcam(browser, page);
|
||||||
|
await webcam.init(true, true);
|
||||||
|
await webcam.disableSelfView();
|
||||||
|
});
|
||||||
|
|
||||||
test.describe('Webcam background', () => {
|
test.describe('Webcam background', () => {
|
||||||
/* this test has the flaky tag because it is breaking due to a default video from chrome that
|
/* this test has the flaky tag because it is breaking due to a default video from chrome that
|
||||||
is overlapping the virtual background. */
|
is overlapping the virtual background. */
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
@ -84,6 +84,7 @@ class ConnectionController {
|
|||||||
"X-Hasura-Role" "bbb_client"
|
"X-Hasura-Role" "bbb_client"
|
||||||
"X-Hasura-Locked" u.locked ? "true" : "false"
|
"X-Hasura-Locked" u.locked ? "true" : "false"
|
||||||
"X-Hasura-LockedInMeeting" u.locked ? userSession.meetingID : ""
|
"X-Hasura-LockedInMeeting" u.locked ? userSession.meetingID : ""
|
||||||
|
"X-Hasura-LockedUserId" u.locked ? userSession.internalUserId : ""
|
||||||
"X-Hasura-ModeratorInMeeting" u.isModerator() ? userSession.meetingID : ""
|
"X-Hasura-ModeratorInMeeting" u.isModerator() ? userSession.meetingID : ""
|
||||||
"X-Hasura-PresenterInMeeting" u.isPresenter() ? userSession.meetingID : ""
|
"X-Hasura-PresenterInMeeting" u.isPresenter() ? userSession.meetingID : ""
|
||||||
"X-Hasura-UserId" userSession.internalUserId
|
"X-Hasura-UserId" userSession.internalUserId
|
||||||
|
Loading…
Reference in New Issue
Block a user