add notifications and chat tracking
This commit is contained in:
parent
a4ee2b4048
commit
5dcb013c12
@ -17,6 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var NodeToken string
|
var NodeToken string
|
||||||
|
var NodeID string
|
||||||
|
|
||||||
type LocalServerConfig struct {
|
type LocalServerConfig struct {
|
||||||
configFilePath string
|
configFilePath string
|
||||||
@ -82,7 +83,7 @@ func (l *LocalServerConfig) startup() (err error) {
|
|||||||
"from": id,
|
"from": id,
|
||||||
"to": "serv",
|
"to": "serv",
|
||||||
"token": "",
|
"token": "",
|
||||||
"peerType":"node",
|
"peerType": "node",
|
||||||
"payload": map[string]string{
|
"payload": map[string]string{
|
||||||
"nodeId": id,
|
"nodeId": id,
|
||||||
"nodeKey": string(key),
|
"nodeKey": string(key),
|
||||||
@ -114,6 +115,7 @@ func (l *LocalServerConfig) startup() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Println(config)
|
logger.Println(config)
|
||||||
|
NodeID = l.NodeId
|
||||||
l.NodeId = config["nodeId"]
|
l.NodeId = config["nodeId"]
|
||||||
l.PrivateKeyPath = config["privKeyPath"]
|
l.PrivateKeyPath = config["privKeyPath"]
|
||||||
l.Token = config["token"]
|
l.Token = config["token"]
|
||||||
@ -138,7 +140,7 @@ func (l *LocalServerConfig) authenticate() (err error) {
|
|||||||
body, err := json.Marshal(map[string]interface{}{
|
body, err := json.Marshal(map[string]interface{}{
|
||||||
"type": "login_key_node",
|
"type": "login_key_node",
|
||||||
"from": l.NodeId,
|
"from": l.NodeId,
|
||||||
"peerType":"node",
|
"peerType": "node",
|
||||||
"payload": map[string]string{
|
"payload": map[string]string{
|
||||||
"id": l.NodeId,
|
"id": l.NodeId,
|
||||||
"signature": sig,
|
"signature": sig,
|
||||||
@ -160,6 +162,7 @@ func (l *LocalServerConfig) authenticate() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = l.handleLoginResponse(payload)
|
err = l.handleLoginResponse(payload)
|
||||||
|
NodeID = l.NodeId
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -138,7 +138,7 @@ func loadHostedSquads(token string, hostId string) (squads []*Squad, err error)
|
|||||||
"type": LIST_HOSTED_SQUADS_BY_HOST,
|
"type": LIST_HOSTED_SQUADS_BY_HOST,
|
||||||
"mac": sig,
|
"mac": sig,
|
||||||
"from": hostId,
|
"from": hostId,
|
||||||
"peerType":"node",
|
"peerType": "node",
|
||||||
"payload": map[string]string{
|
"payload": map[string]string{
|
||||||
"host": hostId,
|
"host": hostId,
|
||||||
"lastIndex": "0",
|
"lastIndex": "0",
|
||||||
|
|||||||
@ -284,7 +284,7 @@ func (zach *ZoneAudioChannelsHandler) AddNewAudioChannel(channelName string, own
|
|||||||
ID: channelName,
|
ID: channelName,
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
ChannelType: channelType,
|
ChannelType: channelType,
|
||||||
Members: append(m,owner),
|
Members: append(m, owner),
|
||||||
}
|
}
|
||||||
bs, jsonErr := json.Marshal(baseConfig)
|
bs, jsonErr := json.Marshal(baseConfig)
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
|
|||||||
@ -10,16 +10,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ZoneChatTrackingDB struct {
|
type ZoneChatTrackingDB struct {
|
||||||
|
ZoneID string
|
||||||
db func(cb func(*badger.DB) (err error)) (err error)
|
db func(cb func(*badger.DB) (err error)) (err error)
|
||||||
lock *sync.RWMutex
|
lock *sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZoneChatTracking(zoneId,chatId string,members ...string) (*ZoneChatTrackingDB,error) {
|
func NewZoneChatTracking(zoneId, chatId string, members ...string) (*ZoneChatTrackingDB, error) {
|
||||||
if _,dirErr := os.ReadDir(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__")); os.IsNotExist(dirErr) {
|
if _, dirErr := os.ReadDir(filepath.Join("data", "zones", zoneId, "chats", chatId, "__tracking__")); os.IsNotExist(dirErr) {
|
||||||
_ = os.MkdirAll(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__"),0700)
|
_ = os.MkdirAll(filepath.Join("data", "zones", zoneId, "chats", chatId, "__tracking__"), 0700)
|
||||||
}
|
}
|
||||||
db := func(f func(*badger.DB) (err error)) (err error) {
|
db := func(f func(*badger.DB) (err error)) (err error) {
|
||||||
db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zoneId, "chats", chatId,"__tracking__")).WithLogger(dbLogger))
|
db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zoneId, "chats", chatId, "__tracking__")).WithLogger(dbLogger))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -30,11 +31,11 @@ func NewZoneChatTracking(zoneId,chatId string,members ...string) (*ZoneChatTrack
|
|||||||
lock := new(sync.RWMutex)
|
lock := new(sync.RWMutex)
|
||||||
if err := db(func(d *badger.DB) (err error) {
|
if err := db(func(d *badger.DB) (err error) {
|
||||||
err = d.Update(func(txn *badger.Txn) error {
|
err = d.Update(func(txn *badger.Txn) error {
|
||||||
b := make([]byte,bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b,0)
|
binary.BigEndian.PutUint64(b, 0)
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
if _,rerr := txn.Get([]byte(member)); rerr == badger.ErrKeyNotFound {
|
if _, rerr := txn.Get([]byte(member)); rerr == badger.ErrKeyNotFound {
|
||||||
txn.Set([]byte(member),b)
|
_ = txn.Set([]byte(member), b)
|
||||||
} else if rerr != nil {
|
} else if rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
@ -45,21 +46,34 @@ func NewZoneChatTracking(zoneId,chatId string,members ...string) (*ZoneChatTrack
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
});err != nil {
|
}); err != nil {
|
||||||
return nil,err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &ZoneChatTrackingDB{db,lock},nil
|
return &ZoneChatTrackingDB{zoneId, db, lock}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zctdb *ZoneChatTrackingDB) Initialize(lastIndex uint64,users ...string) (err error) {
|
func (zctdb *ZoneChatTrackingDB) Initialize(lastIndex uint64, users ...string) (err error) {
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
if err = zctdb.SetUserLastIndex(user,lastIndex);err != nil {
|
if err = zctdb.SetUserLastIndex(user, lastIndex); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (zctdb *ZoneChatTrackingDB) updateDBCallbackFolder(newChatId string) {
|
||||||
|
db := func(f func(*badger.DB) (err error)) (err error) {
|
||||||
|
db, err := badger.Open(badger.DefaultOptions(filepath.Join("data", "zones", zctdb.ZoneID, "chats", newChatId, "__tracking__")).WithLogger(dbLogger))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
err = f(db)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
zctdb.db = db
|
||||||
|
}
|
||||||
|
|
||||||
func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err error) {
|
func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err error) {
|
||||||
zctdb.lock.Lock()
|
zctdb.lock.Lock()
|
||||||
defer zctdb.lock.Unlock()
|
defer zctdb.lock.Unlock()
|
||||||
@ -69,7 +83,7 @@ func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err
|
|||||||
opt := badger.DefaultIteratorOptions
|
opt := badger.DefaultIteratorOptions
|
||||||
it := txn.NewIterator(opt)
|
it := txn.NewIterator(opt)
|
||||||
defer it.Close()
|
defer it.Close()
|
||||||
for it.Rewind();it.Valid();it.Next() {
|
for it.Rewind(); it.Valid(); it.Next() {
|
||||||
item := it.Item()
|
item := it.Item()
|
||||||
if err = item.Value(func(val []byte) error {
|
if err = item.Value(func(val []byte) error {
|
||||||
li := binary.BigEndian.Uint64(val)
|
li := binary.BigEndian.Uint64(val)
|
||||||
@ -88,9 +102,9 @@ func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err
|
|||||||
}
|
}
|
||||||
err = d.Update(func(txn *badger.Txn) error {
|
err = d.Update(func(txn *badger.Txn) error {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
b := make([]byte,bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b,lastIndex)
|
binary.BigEndian.PutUint64(b, lastIndex)
|
||||||
if updateErr := txn.Set(key,b); updateErr != nil {
|
if updateErr := txn.Set(key, b); updateErr != nil {
|
||||||
return updateErr
|
return updateErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,14 +115,14 @@ func (zctdb *ZoneChatTrackingDB) RevertTrackingLastIndex(lastIndex uint64) (err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zctdb *ZoneChatTrackingDB) SetUserLastIndex(userId string,lastIndex uint64) (err error) {
|
func (zctdb *ZoneChatTrackingDB) SetUserLastIndex(userId string, lastIndex uint64) (err error) {
|
||||||
zctdb.lock.Lock()
|
zctdb.lock.Lock()
|
||||||
defer zctdb.lock.Unlock()
|
defer zctdb.lock.Unlock()
|
||||||
err = zctdb.db(func(d *badger.DB) (err error) {
|
err = zctdb.db(func(d *badger.DB) (err error) {
|
||||||
err = d.Update(func(txn *badger.Txn) error {
|
err = d.Update(func(txn *badger.Txn) error {
|
||||||
b := make([]byte,bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b,lastIndex)
|
binary.BigEndian.PutUint64(b, lastIndex)
|
||||||
updateErr := txn.Set([]byte(userId),b)
|
updateErr := txn.Set([]byte(userId), b)
|
||||||
return updateErr
|
return updateErr
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -116,16 +130,16 @@ func (zctdb *ZoneChatTrackingDB) SetUserLastIndex(userId string,lastIndex uint64
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zctdb *ZoneChatTrackingDB) GetUserLastIndex(userId string) (index uint,err error) {
|
func (zctdb *ZoneChatTrackingDB) GetUserLastIndex(userId string) (index uint, err error) {
|
||||||
zctdb.lock.Lock()
|
zctdb.lock.Lock()
|
||||||
defer zctdb.lock.Unlock()
|
defer zctdb.lock.Unlock()
|
||||||
err = zctdb.db(func(d *badger.DB) (err error) {
|
err = zctdb.db(func(d *badger.DB) (err error) {
|
||||||
err = d.Update(func(txn *badger.Txn) error {
|
err = d.Update(func(txn *badger.Txn) error {
|
||||||
item,rerr := txn.Get([]byte(userId))
|
item, rerr := txn.Get([]byte(userId))
|
||||||
if rerr != nil {
|
if rerr != nil {
|
||||||
return rerr
|
return rerr
|
||||||
}
|
}
|
||||||
item.Value(func(val []byte) error {
|
_ = item.Value(func(val []byte) error {
|
||||||
index = uint(binary.BigEndian.Uint64(val))
|
index = uint(binary.BigEndian.Uint64(val))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|||||||
@ -85,26 +85,23 @@ func NewZoneChatDBHandler(zoneId string, chatID string) (zoneChatDBHandler *Zone
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) calculateNewChatCount(previousId uint64) ( count uint,err error) {
|
func (zcdbh *ZoneChatDBHandler) calculateNewChatCount(previousId uint64) (count uint, err error) {
|
||||||
err = zcdbh.db(func(d *badger.DB) (err error) {
|
err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
err = d.View(func(txn *badger.Txn) error {
|
err = d.View(func(txn *badger.Txn) error {
|
||||||
opt := badger.DefaultIteratorOptions
|
opt := badger.DefaultIteratorOptions
|
||||||
it := txn.NewIterator(opt)
|
it := txn.NewIterator(opt)
|
||||||
defer it.Close()
|
defer it.Close()
|
||||||
count = 0
|
count = 0
|
||||||
b := make([]byte,bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b,previousId)
|
binary.BigEndian.PutUint64(b, previousId)
|
||||||
for it.Seek(b); it.Valid(); it.Next() {
|
if previousId == 0 || previousId == 1 {
|
||||||
item := it.Item()
|
count++
|
||||||
if err = item.Value(func(val []byte) (err error) {
|
for it.Rewind(); it.Valid(); it.Next() {
|
||||||
var chatMessage *ChatMessage
|
count++
|
||||||
if err = json.Unmarshal(val, &chatMessage); err != nil {
|
}
|
||||||
return err
|
} else {
|
||||||
}
|
for it.Seek(b); it.Valid(); it.Next() {
|
||||||
count++
|
count++
|
||||||
return
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
@ -118,8 +115,6 @@ func (zcdbh *ZoneChatDBHandler) calculateNewChatCount(previousId uint64) ( count
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) revertPreviousId() (err error) {
|
func (zcdbh *ZoneChatDBHandler) revertPreviousId() (err error) {
|
||||||
zcdbh.lock.Lock()
|
|
||||||
defer zcdbh.lock.Unlock()
|
|
||||||
err = zcdbh.db(func(d *badger.DB) (err error) {
|
err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
err = d.View(func(txn *badger.Txn) error {
|
err = d.View(func(txn *badger.Txn) error {
|
||||||
opt := badger.DefaultIteratorOptions
|
opt := badger.DefaultIteratorOptions
|
||||||
@ -162,8 +157,6 @@ func (zcdbh *ZoneChatDBHandler) updateDbCallbackFolder(newChatId string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err error) {
|
func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err error) {
|
||||||
zcdbh.lock.Lock()
|
|
||||||
defer zcdbh.lock.Unlock()
|
|
||||||
b := make([]byte, bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
zcdbh.PreviousId++
|
zcdbh.PreviousId++
|
||||||
binary.BigEndian.PutUint64(b, zcdbh.PreviousId)
|
binary.BigEndian.PutUint64(b, zcdbh.PreviousId)
|
||||||
@ -188,8 +181,6 @@ func (zcdbh *ZoneChatDBHandler) AddNewChatMessage(chatMessage *ChatMessage) (err
|
|||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) DeleteChatMessage(key uint64) (err error) {
|
func (zcdbh *ZoneChatDBHandler) DeleteChatMessage(key uint64) (err error) {
|
||||||
if err = zcdbh.db(func(d *badger.DB) (err error) {
|
if err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
zcdbh.lock.Lock()
|
|
||||||
defer zcdbh.lock.Unlock()
|
|
||||||
err = d.Update(func(txn *badger.Txn) (err error) {
|
err = d.Update(func(txn *badger.Txn) (err error) {
|
||||||
b := make([]byte, bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b, key)
|
binary.BigEndian.PutUint64(b, key)
|
||||||
@ -207,8 +198,6 @@ func (zcdbh *ZoneChatDBHandler) DeleteChatMessage(key uint64) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) DeleteChatFile(filename string, key uint64) (err error) {
|
func (zcdbh *ZoneChatDBHandler) DeleteChatFile(filename string, key uint64) (err error) {
|
||||||
zcdbh.lock.Lock()
|
|
||||||
defer zcdbh.lock.Unlock()
|
|
||||||
if err = zcdbh.DeleteChatMessage(key); err != nil {
|
if err = zcdbh.DeleteChatMessage(key); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -217,8 +206,6 @@ func (zcdbh *ZoneChatDBHandler) DeleteChatFile(filename string, key uint64) (err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chatMessages []*ChatMessage, l int, done bool, err error) {
|
func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chatMessages []*ChatMessage, l int, done bool, err error) {
|
||||||
zcdbh.lock.RLock()
|
|
||||||
defer zcdbh.lock.RUnlock()
|
|
||||||
err = zcdbh.db(func(d *badger.DB) (err error) {
|
err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
err = d.View(func(txn *badger.Txn) (err error) {
|
err = d.View(func(txn *badger.Txn) (err error) {
|
||||||
opt := badger.DefaultIteratorOptions
|
opt := badger.DefaultIteratorOptions
|
||||||
@ -264,8 +251,6 @@ func (zcdbh *ZoneChatDBHandler) ListChatMessages(lastIndex int, limit int) (chat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) ListChatFiles(lastIndex int, limit int) (chatMessages []*ChatFile, l int, err error) {
|
func (zcdbh *ZoneChatDBHandler) ListChatFiles(lastIndex int, limit int) (chatMessages []*ChatFile, l int, err error) {
|
||||||
zcdbh.lock.RLock()
|
|
||||||
defer zcdbh.lock.RUnlock()
|
|
||||||
err = zcdbh.db(func(d *badger.DB) (err error) {
|
err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
err = d.View(func(txn *badger.Txn) (err error) {
|
err = d.View(func(txn *badger.Txn) (err error) {
|
||||||
opt := badger.DefaultIteratorOptions
|
opt := badger.DefaultIteratorOptions
|
||||||
@ -326,8 +311,6 @@ func (zcdbh *ZoneChatDBHandler) ListChatFiles(lastIndex int, limit int) (chatMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatMessage, err error) {
|
func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatMessage, err error) {
|
||||||
zcdbh.lock.RLock()
|
|
||||||
defer zcdbh.lock.RUnlock()
|
|
||||||
err = zcdbh.db(func(d *badger.DB) (err error) {
|
err = zcdbh.db(func(d *badger.DB) (err error) {
|
||||||
err = d.View(func(txn *badger.Txn) (err error) {
|
err = d.View(func(txn *badger.Txn) (err error) {
|
||||||
b := make([]byte, bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
@ -347,8 +330,6 @@ func (zcdbh *ZoneChatDBHandler) GetChatMessage(index uint64) (chatMessage *ChatM
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zcdbh *ZoneChatDBHandler) ModifyChatMessage(key uint64, newContent string) (err error) {
|
func (zcdbh *ZoneChatDBHandler) ModifyChatMessage(key uint64, newContent string) (err error) {
|
||||||
zcdbh.lock.Lock()
|
|
||||||
defer zcdbh.lock.Unlock()
|
|
||||||
b := make([]byte, bufferSize)
|
b := make([]byte, bufferSize)
|
||||||
binary.BigEndian.PutUint64(b, key)
|
binary.BigEndian.PutUint64(b, key)
|
||||||
chatMessage, err := zcdbh.GetChatMessage(key)
|
chatMessage, err := zcdbh.GetChatMessage(key)
|
||||||
|
|||||||
@ -79,6 +79,7 @@ type Chat struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ZoneChatsHandler struct {
|
type ZoneChatsHandler struct {
|
||||||
|
ZoneName string
|
||||||
ZoneId string
|
ZoneId string
|
||||||
HostId string
|
HostId string
|
||||||
ChatFSInstance *ChatFSInstance
|
ChatFSInstance *ChatFSInstance
|
||||||
@ -92,17 +93,17 @@ type ZoneChatsHandler struct {
|
|||||||
init bool
|
init bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneChatsHandler *ZoneChatsHandler, err error) {
|
func NewZoneChatsHandler(hostId, zoneId, zoneName, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneChatsHandler *ZoneChatsHandler, err error) {
|
||||||
var dirs []fs.DirEntry
|
var dirs []fs.DirEntry
|
||||||
dirs, err = os.ReadDir(filepath.Join("data", "zones", zoneId, "chats"))
|
dirs, err = os.ReadDir(filepath.Join("data", "zones", zoneId, "chats"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
logger.Printf("creating chat directory for zone %s...\n", zoneId)
|
logger.Printf("creating chat directory for zone %s...\n", zoneId)
|
||||||
mkdirErr := os.MkdirAll(filepath.Join("data", "zones", zoneId, "chats", "general"), 0700)
|
mkdirErr := os.MkdirAll(filepath.Join("data", "zones", zoneId, "chats", GENERAL), 0700)
|
||||||
if mkdirErr != nil {
|
if mkdirErr != nil {
|
||||||
return nil, mkdirErr
|
return nil, mkdirErr
|
||||||
}
|
}
|
||||||
file, ferr := os.Create(filepath.Join("data", "zones", zoneId, "chats", "general", "chatConfig.json"))
|
file, ferr := os.Create(filepath.Join("data", "zones", zoneId, "chats", GENERAL, "chatConfig.json"))
|
||||||
if ferr != nil {
|
if ferr != nil {
|
||||||
return nil, ferr
|
return nil, ferr
|
||||||
}
|
}
|
||||||
@ -110,7 +111,7 @@ func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []strin
|
|||||||
ChatId: GENERAL,
|
ChatId: GENERAL,
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
ChatType: "public",
|
ChatType: "public",
|
||||||
Members: authorizedMembers,
|
Members: []string{},
|
||||||
}
|
}
|
||||||
bs, jsonErr := json.Marshal(baseConfig)
|
bs, jsonErr := json.Marshal(baseConfig)
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
@ -134,10 +135,6 @@ func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []strin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
zoneChatTracking,err := NewZoneChatTracking(zoneId, chat.Name())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var bs []byte
|
var bs []byte
|
||||||
bs, err = os.ReadFile(filepath.Join("data", "zones", zoneId, "chats", chat.Name(), "chatConfig.json"))
|
bs, err = os.ReadFile(filepath.Join("data", "zones", zoneId, "chats", chat.Name(), "chatConfig.json"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -148,8 +145,9 @@ func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []strin
|
|||||||
if err = json.Unmarshal(bs, &c); err != nil {
|
if err = json.Unmarshal(bs, &c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err = zoneChatTracking.Initialize(0,c.Members...); err != nil {
|
zoneChatTracking, err := NewZoneChatTracking(zoneId, c.ChatId, c.Members...)
|
||||||
return nil,err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
logger.Println("chats data :", c.ChatId, c.ChatType, c.Owner, c.Members)
|
logger.Println("chats data :", c.ChatId, c.ChatType, c.Owner, c.Members)
|
||||||
c.DB = zoneChatDBHandler
|
c.DB = zoneChatDBHandler
|
||||||
@ -160,6 +158,7 @@ func NewZoneChatsHandler(hostId, zoneId, owner string, authorizedMembers []strin
|
|||||||
chatFSFlag := uint32(0)
|
chatFSFlag := uint32(0)
|
||||||
zoneChatsHandler = &ZoneChatsHandler{
|
zoneChatsHandler = &ZoneChatsHandler{
|
||||||
HostId: hostId,
|
HostId: hostId,
|
||||||
|
ZoneName: zoneName,
|
||||||
ChatFSInstance: NewChatFSInstance(zoneId, owner, authorizedMembers),
|
ChatFSInstance: NewChatFSInstance(zoneId, owner, authorizedMembers),
|
||||||
ChatFSInstanceFlag: &chatFSFlag,
|
ChatFSInstanceFlag: &chatFSFlag,
|
||||||
ZoneId: zoneId,
|
ZoneId: zoneId,
|
||||||
@ -200,6 +199,8 @@ func (zch *ZoneChatsHandler) sendDataChannelMessage(reqType string, from string,
|
|||||||
return jsonErr
|
return jsonErr
|
||||||
}
|
}
|
||||||
err = zch.DataChannels[to].DataChannel.SendText(string(bs))
|
err = zch.DataChannels[to].DataChannel.SendText(string(bs))
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("no corresponding dataChannel")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -250,7 +251,7 @@ func (zch *ZoneChatsHandler) signalCandidate(from string, to string, candidate *
|
|||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-d:
|
case <-d:
|
||||||
case err = <-e:
|
case <-e:
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -262,7 +263,6 @@ func (zch *ZoneChatsHandler) GetChats(userId string, chatsId ...interface{}) (er
|
|||||||
err = fmt.Errorf("id of wrong type")
|
err = fmt.Errorf("id of wrong type")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println("chat from get chats", id.(string))
|
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
if _, ok := zch.Chats[id.(string)]; ok {
|
if _, ok := zch.Chats[id.(string)]; ok {
|
||||||
logger.Println(zch.Chats[id.(string)])
|
logger.Println(zch.Chats[id.(string)])
|
||||||
@ -271,35 +271,24 @@ func (zch *ZoneChatsHandler) GetChats(userId string, chatsId ...interface{}) (er
|
|||||||
return
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fmt.Println("first loop done")
|
|
||||||
for _, chat := range chats {
|
for _, chat := range chats {
|
||||||
fmt.Println(chat.ChatId)
|
index, err := chat.Tracking.GetUserLastIndex(userId)
|
||||||
index,err := chat.Tracking.GetUserLastIndex(userId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("there")
|
|
||||||
fmt.Println(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
chat.DB.lock.RLock()
|
unread, err := chat.DB.calculateNewChatCount(uint64(index))
|
||||||
defer chat.DB.lock.RUnlock()
|
|
||||||
unread,err := chat.DB.calculateNewChatCount(uint64(index))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("over there")
|
|
||||||
fmt.Println(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
chat.LastReadIndex = index
|
chat.LastReadIndex = index
|
||||||
chat.Unread = unread
|
chat.Unread = unread
|
||||||
}
|
}
|
||||||
fmt.Println(chats)
|
done, e := zch.sendDataChannelMessage(GET_CHATS_RESPONSE, "node", userId, map[string]interface{}{
|
||||||
done,e := zch.sendDataChannelMessage(GET_CHATS_RESPONSE,"node",userId,map[string]interface{}{
|
|
||||||
"chats": chats,
|
"chats": chats,
|
||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
fmt.Println("done")
|
case err = <-e:
|
||||||
case terr :=<-e:
|
|
||||||
fmt.Println(terr)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -324,7 +313,7 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType
|
|||||||
if mkdirErr != nil {
|
if mkdirErr != nil {
|
||||||
return mkdirErr
|
return mkdirErr
|
||||||
}
|
}
|
||||||
mkdirErr = os.Mkdir(filepath.Join("data", "zones", zch.ZoneId, "chats", chatName,"__tracking__"), 0700)
|
mkdirErr = os.Mkdir(filepath.Join("data", "zones", zch.ZoneId, "chats", chatName, "__tracking__"), 0700)
|
||||||
if mkdirErr != nil {
|
if mkdirErr != nil {
|
||||||
return mkdirErr
|
return mkdirErr
|
||||||
}
|
}
|
||||||
@ -333,16 +322,21 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType
|
|||||||
return ferr
|
return ferr
|
||||||
}
|
}
|
||||||
m := make([]string, 0, len(members))
|
m := make([]string, 0, len(members))
|
||||||
|
if chatType == PRIVATE {
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
if mbr, ok := member.(string); ok && mbr != owner {
|
if mbr, ok := member.(string); ok && mbr != owner {
|
||||||
m = append(m, mbr)
|
m = append(m, mbr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m = append(m, owner)
|
||||||
|
} else {
|
||||||
|
m = zch.ZoneMembersId
|
||||||
|
}
|
||||||
baseConfig := &ChatConfig{
|
baseConfig := &ChatConfig{
|
||||||
ChatId: chatName,
|
ChatId: chatName,
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
ChatType: chatType,
|
ChatType: chatType,
|
||||||
Members: append(m,owner),
|
Members: m,
|
||||||
}
|
}
|
||||||
bs, jsonErr := json.Marshal(baseConfig)
|
bs, jsonErr := json.Marshal(baseConfig)
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
@ -359,11 +353,11 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
zoneChatTrackingDB,err := NewZoneChatTracking(zch.ZoneId,chatName)
|
zoneChatTrackingDB, err := NewZoneChatTracking(zch.ZoneId, chatName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err = zoneChatTrackingDB.Initialize(1,baseConfig.Members...); err != nil {
|
if err = zoneChatTrackingDB.Initialize(1, baseConfig.Members...); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var c Chat
|
var c Chat
|
||||||
@ -387,10 +381,24 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType
|
|||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
case err = <-e:
|
case <-e:
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bs, err := json.Marshal(map[string]any{
|
||||||
|
"zoneId": zch.ZoneId,
|
||||||
|
"chatId": chatName,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
zch.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
||||||
|
"type": "added_in_chat",
|
||||||
|
"title": "Added in zone text channel 💬",
|
||||||
|
"body": fmt.Sprintf("Added in channel %s in zone %s", c.ChatId, zch.ZoneName),
|
||||||
|
"isPushed": true,
|
||||||
|
"payload": string(bs),
|
||||||
|
"recipients": members,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch c.ChatType {
|
switch c.ChatType {
|
||||||
@ -402,7 +410,10 @@ func (zch *ZoneChatsHandler) AddNewChat(chatName string, owner string, chatType
|
|||||||
return
|
return
|
||||||
})
|
})
|
||||||
case PRIVATE:
|
case PRIVATE:
|
||||||
|
err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
err = newChatForMembers(c.Members)
|
err = newChatForMembers(c.Members)
|
||||||
|
return
|
||||||
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -426,11 +437,24 @@ func (zch *ZoneChatsHandler) DeleteChat(chatId string) (err error) {
|
|||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
continue
|
case <-e:
|
||||||
case err = <-e:
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bs, err := json.Marshal(map[string]any{
|
||||||
|
"zoneId": zch.ZoneId,
|
||||||
|
"chatId": chatId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
zch.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]any{
|
||||||
|
"type": "removed_from_chat",
|
||||||
|
"title": "Removed from zone text channel ⛔️",
|
||||||
|
"body": fmt.Sprintf("You have no longer access to the channel %s in zone %s", chatId, zch.ZoneName),
|
||||||
|
"isPushed": true,
|
||||||
|
"payload": string(bs),
|
||||||
|
"recipients": members,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch zch.Chats[chatId].ChatType {
|
switch zch.Chats[chatId].ChatType {
|
||||||
@ -485,9 +509,10 @@ func (zch *ZoneChatsHandler) EditChatName(chatId string, newChatId string) (err
|
|||||||
ChatType: chatConfig.ChatType,
|
ChatType: chatConfig.ChatType,
|
||||||
Members: chatConfig.Members,
|
Members: chatConfig.Members,
|
||||||
DB: zch.Chats[chatId].DB,
|
DB: zch.Chats[chatId].DB,
|
||||||
Tracking:zch.Chats[chatId].Tracking,
|
Tracking: zch.Chats[chatId].Tracking,
|
||||||
}
|
}
|
||||||
chat.DB.updateDbCallbackFolder(newChatId)
|
chat.DB.updateDbCallbackFolder(newChatId)
|
||||||
|
chat.Tracking.updateDBCallbackFolder(newChatId)
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
defer delete(zch.Chats, chatId)
|
defer delete(zch.Chats, chatId)
|
||||||
zch.Chats[newChatId] = chat
|
zch.Chats[newChatId] = chat
|
||||||
@ -540,6 +565,9 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
chatConfig.ChatType = chatType
|
chatConfig.ChatType = chatType
|
||||||
|
if chatType == PUBLIC {
|
||||||
|
chatConfig.Members = zch.ZoneMembersId
|
||||||
|
}
|
||||||
bs, err = json.Marshal(&chatConfig)
|
bs, err = json.Marshal(&chatConfig)
|
||||||
f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -557,19 +585,14 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e
|
|||||||
ChatType: chatType,
|
ChatType: chatType,
|
||||||
Members: chatConfig.Members,
|
Members: chatConfig.Members,
|
||||||
DB: zch.Chats[chatId].DB,
|
DB: zch.Chats[chatId].DB,
|
||||||
Tracking:zch.Chats[chatId].Tracking,
|
Tracking: zch.Chats[chatId].Tracking,
|
||||||
}
|
}
|
||||||
switch chatType {
|
switch chatType {
|
||||||
case BROADCAST:
|
case BROADCAST:
|
||||||
fallthrough
|
fallthrough
|
||||||
case PUBLIC:
|
case PUBLIC:
|
||||||
var members = []string{}
|
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
|
||||||
members = append(members, zch.ZoneMembersId...)
|
|
||||||
return
|
|
||||||
})
|
|
||||||
for _, member := range zch.ZoneMembersId {
|
for _, member := range zch.ZoneMembersId {
|
||||||
if pubErr := zch.SetChatPublicForUser(chatId, member); pubErr != nil {
|
if pubErr := zch.AddChatMembers(chatId, []any{member}); pubErr != nil {
|
||||||
logger.Println(pubErr)
|
logger.Println(pubErr)
|
||||||
}
|
}
|
||||||
zch.sendDataChannelMessage(CHAT_TYPE_EDITED, "node", member, map[string]interface{}{
|
zch.sendDataChannelMessage(CHAT_TYPE_EDITED, "node", member, map[string]interface{}{
|
||||||
@ -578,11 +601,6 @@ func (zch *ZoneChatsHandler) EditChatType(chatId string, chatType string) (err e
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
case PRIVATE:
|
case PRIVATE:
|
||||||
var members = []string{}
|
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
|
||||||
members = append(members, zch.ZoneMembersId...)
|
|
||||||
return
|
|
||||||
})
|
|
||||||
for _, member := range zch.ZoneMembersId {
|
for _, member := range zch.ZoneMembersId {
|
||||||
if pubErr := zch.SetChatPrivateForUser(chatId, member); pubErr != nil {
|
if pubErr := zch.SetChatPrivateForUser(chatId, member); pubErr != nil {
|
||||||
logger.Println(pubErr)
|
logger.Println(pubErr)
|
||||||
@ -636,6 +654,21 @@ memberLoop:
|
|||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
bs, err = json.Marshal(map[string]any{
|
||||||
|
"zoneId": zch.ZoneId,
|
||||||
|
"chatId": chatId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
zch.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
||||||
|
"type": "added_in_chat",
|
||||||
|
"title": "Added in zone text channel 💬",
|
||||||
|
"body": fmt.Sprintf("Added in channel %s in zone %s", chatId, zch.ZoneName),
|
||||||
|
"isPushed": true,
|
||||||
|
"payload": string(bs),
|
||||||
|
"recipients": chatMembers,
|
||||||
|
})
|
||||||
bs, err = json.Marshal(&chatConfig)
|
bs, err = json.Marshal(&chatConfig)
|
||||||
f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
f, err := os.OpenFile(filepath.Join("data", "zones", zch.ZoneId, "chats", chatId, "chatConfig.json"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
|
||||||
defer func() {
|
defer func() {
|
||||||
@ -655,23 +688,20 @@ memberLoop:
|
|||||||
DB: zch.Chats[chatId].DB,
|
DB: zch.Chats[chatId].DB,
|
||||||
Tracking: zch.Chats[chatId].Tracking,
|
Tracking: zch.Chats[chatId].Tracking,
|
||||||
}
|
}
|
||||||
chat.DB.lock.Lock()
|
|
||||||
lastIndex := chat.DB.PreviousId
|
|
||||||
chat.DB.lock.Unlock()
|
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
|
lastIndex := chat.DB.PreviousId
|
||||||
zch.Chats[chatId] = chat
|
zch.Chats[chatId] = chat
|
||||||
return
|
|
||||||
})
|
|
||||||
var chmb []string
|
var chmb []string
|
||||||
if chat.ChatType == PRIVATE {
|
if chat.ChatType == PRIVATE {
|
||||||
chmb = chat.Members
|
chmb = chat.Members
|
||||||
} else {
|
} else {
|
||||||
chmb = zch.ZoneMembersId
|
chmb = zch.ZoneMembersId
|
||||||
}
|
}
|
||||||
broadcastLoop:
|
broadcastLoop:
|
||||||
for _, member := range chmb {
|
for _, member := range chmb {
|
||||||
for _, m := range addedMembers {
|
for _, m := range addedMembers {
|
||||||
if err = chat.Tracking.SetUserLastIndex(member,lastIndex); err != nil {
|
if err = chat.Tracking.SetUserLastIndex(member, lastIndex); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if member == m {
|
if member == m {
|
||||||
@ -699,6 +729,8 @@ broadcastLoop:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zch *ZoneChatsHandler) RemoveChatMember(chatId string, chatMember string) (err error) {
|
func (zch *ZoneChatsHandler) RemoveChatMember(chatId string, chatMember string) (err error) {
|
||||||
@ -770,6 +802,21 @@ func (zch *ZoneChatsHandler) RemoveChatMember(chatId string, chatMember string)
|
|||||||
"userId": chatMember,
|
"userId": chatMember,
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
})
|
})
|
||||||
|
bs, err = json.Marshal(map[string]any{
|
||||||
|
"zoneId": zch.ZoneId,
|
||||||
|
"chatId": chatId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
zch.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
||||||
|
"type": "removed_from_chat",
|
||||||
|
"title": "Removed from zone text channel ⛔️",
|
||||||
|
"body": fmt.Sprintf("You have no longer access to the channel %s in zone %s", chatId, zch.ZoneName),
|
||||||
|
"isPushed": true,
|
||||||
|
"payload": string(bs),
|
||||||
|
"recipients": []string{chatMember},
|
||||||
|
})
|
||||||
done, e := zch.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", chatMember, map[string]interface{}{
|
done, e := zch.sendDataChannelMessage(REMOVED_FROM_CHAT, "node", chatMember, map[string]interface{}{
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
"userId": chatMember,
|
"userId": chatMember,
|
||||||
@ -803,10 +850,10 @@ broadcastLoop:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func(zch *ZoneChatsHandler) ReadLastMessage(userId,chatId string) (err error) {
|
func (zch *ZoneChatsHandler) ReadLastMessage(userId, chatId string) (err error) {
|
||||||
err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
if chat, ok := zch.Chats[chatId]; ok {
|
if chat, ok := zch.Chats[chatId]; ok {
|
||||||
err = chat.Tracking.SetUserLastIndex(userId,chat.DB.PreviousId)
|
err = chat.Tracking.SetUserLastIndex(userId, chat.DB.PreviousId)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
@ -823,7 +870,7 @@ func (zch *ZoneChatsHandler) ListLatestChatMessages(userId, chatId string, lastI
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = chat.Tracking.SetUserLastIndex(userId,chat.DB.PreviousId)
|
err = chat.Tracking.SetUserLastIndex(userId, chat.DB.PreviousId)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@ -876,9 +923,12 @@ func (zch *ZoneChatsHandler) AddChatMessage(userId, chatId, content string, isRe
|
|||||||
Tags: make([]string, 0),
|
Tags: make([]string, 0),
|
||||||
Date: time.Now().Format("Mon, 02 Jan 2006 15:04:05 MST"),
|
Date: time.Now().Format("Mon, 02 Jan 2006 15:04:05 MST"),
|
||||||
}
|
}
|
||||||
|
var chatType string
|
||||||
|
var chatMembers []string
|
||||||
if err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
if err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
if chat, ok := zch.Chats[chatId]; ok {
|
if chat, ok := zch.Chats[chatId]; ok {
|
||||||
|
chatType = chat.ChatType
|
||||||
|
chatMembers = chat.Members
|
||||||
if isResponse {
|
if isResponse {
|
||||||
parentMessage, getErr := chat.DB.GetChatMessage(chatResponseId)
|
parentMessage, getErr := chat.DB.GetChatMessage(chatResponseId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -900,10 +950,44 @@ func (zch *ZoneChatsHandler) AddChatMessage(userId, chatId, content string, isRe
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notifyActivity := func(done <-chan struct{}, e <-chan error, member string) {
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
case <-e:
|
||||||
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
_ = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
chat := zch.Chats[chatId]
|
if chat, ok := zch.Chats[chatId]; ok {
|
||||||
logger.Println(chat.ChatType)
|
li, err := chat.Tracking.GetUserLastIndex(member)
|
||||||
switch chat.ChatType {
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
count, err := chat.DB.calculateNewChatCount(uint64(li))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count == 1 {
|
||||||
|
bs, err := json.Marshal(map[string]any{
|
||||||
|
"zoneId": zch.ZoneId,
|
||||||
|
"chatId": chatId,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
zch.sendZoneRequest(CREATE_NOTIFICATION, "node", map[string]interface{}{
|
||||||
|
"type": "new_chat_activity",
|
||||||
|
"title": "Unread messages 👀",
|
||||||
|
"body": fmt.Sprintf("New messages in channel %s of %s", chatId, zch.ZoneName),
|
||||||
|
"isPushed": true,
|
||||||
|
"payload": string(bs),
|
||||||
|
"recipients": []string{member},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch chatType {
|
||||||
case BROADCAST:
|
case BROADCAST:
|
||||||
fallthrough
|
fallthrough
|
||||||
case PUBLIC:
|
case PUBLIC:
|
||||||
@ -912,25 +996,17 @@ func (zch *ZoneChatsHandler) AddChatMessage(userId, chatId, content string, isRe
|
|||||||
"chatMessage": chatMessage,
|
"chatMessage": chatMessage,
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
})
|
})
|
||||||
select {
|
go notifyActivity(done, e, v)
|
||||||
case <-done:
|
|
||||||
case err = <-e:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case PRIVATE:
|
case PRIVATE:
|
||||||
for _, v := range chat.Members {
|
for _, v := range chatMembers {
|
||||||
done, e := zch.sendDataChannelMessage(NEW_CHAT_MESSAGE, "node", v, map[string]interface{}{
|
done, e := zch.sendDataChannelMessage(NEW_CHAT_MESSAGE, "node", v, map[string]interface{}{
|
||||||
"chatMessage": chatMessage,
|
"chatMessage": chatMessage,
|
||||||
"chatId": chatId,
|
"chatId": chatId,
|
||||||
})
|
})
|
||||||
select {
|
go notifyActivity(done, e, v)
|
||||||
case <-done:
|
|
||||||
case err = <-e:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
|
||||||
})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,7 +1031,7 @@ func (zch *ZoneChatsHandler) SetChatPrivateForUser(chatId string, member string)
|
|||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
case err = <-e:
|
case <-e:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -984,7 +1060,7 @@ func (zch *ZoneChatsHandler) SetChatPublicForUser(chatId string, member string)
|
|||||||
})
|
})
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
case err = <-e:
|
case <-e:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -997,15 +1073,22 @@ func (zch *ZoneChatsHandler) SetAllPublicChatForUser(userId string) (err error)
|
|||||||
for _, chat := range zch.Chats {
|
for _, chat := range zch.Chats {
|
||||||
logger.Println("--------------- public chat for all : ", chat)
|
logger.Println("--------------- public chat for all : ", chat)
|
||||||
if chat.ChatType == PUBLIC || chat.ChatType == BROADCAST {
|
if chat.ChatType == PUBLIC || chat.ChatType == BROADCAST {
|
||||||
if chat.ChatId == GENERAL {
|
var contains bool
|
||||||
if err = zch.AddChatMembers(chat.ChatId, []interface{}{userId}); err != nil {
|
for _, m := range chat.Members {
|
||||||
logger.Println(err)
|
if m == userId {
|
||||||
|
contains = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !contains {
|
||||||
|
if addErr := zch.AddChatMembers(chat.ChatId, []any{userId}); addErr != nil {
|
||||||
|
logger.Println(addErr)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err = zch.SetChatPublicForUser(chat.ChatId, userId); err != nil {
|
// if addErr := zch.SetChatPublicForUser(chat.ChatId, userId); addErr != nil {
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -1048,7 +1131,7 @@ func (zch *ZoneChatsHandler) ConnectToChatFSInstance(channelId string, userId st
|
|||||||
d, e := zch.ChatFSInstance.HandleOffer(context.Background(), channelId, userId, sdp, zch.HostId, zch.sendDataChannelMessage, zch.signalCandidate)
|
d, e := zch.ChatFSInstance.HandleOffer(context.Background(), channelId, userId, sdp, zch.HostId, zch.sendDataChannelMessage, zch.signalCandidate)
|
||||||
select {
|
select {
|
||||||
case <-d:
|
case <-d:
|
||||||
case err = <-e:
|
case <-e:
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
})
|
})
|
||||||
@ -1116,7 +1199,7 @@ func (zch *ZoneChatsHandler) DeleteChatMessage(key uint64, chatId string) (err e
|
|||||||
func (zch *ZoneChatsHandler) UpdateChatMessage(key uint64, chatId, newContent string) (err error) {
|
func (zch *ZoneChatsHandler) UpdateChatMessage(key uint64, chatId, newContent string) (err error) {
|
||||||
err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
err = atomicallyExecute(zch.ChatFlag, func() (err error) {
|
||||||
if _, ok := zch.Chats[chatId]; !ok {
|
if _, ok := zch.Chats[chatId]; !ok {
|
||||||
err = fmt.Errorf("no file corresponding to id %s", chatId)
|
err = fmt.Errorf("no chat corresponding to id %s", chatId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = zch.Chats[chatId].DB.ModifyChatMessage(key, newContent); err != nil {
|
if err = zch.Chats[chatId].DB.ModifyChatMessage(key, newContent); err != nil {
|
||||||
@ -1279,13 +1362,10 @@ func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneReq
|
|||||||
}
|
}
|
||||||
err = zch.AddNewChat(req.Payload["chatId"].(string), req.Payload["owner"].(string), req.Payload["chatType"].(string), req.Payload["members"].([]interface{}))
|
err = zch.AddNewChat(req.Payload["chatId"].(string), req.Payload["owner"].(string), req.Payload["chatType"].(string), req.Payload["members"].([]interface{}))
|
||||||
case GET_CHATS:
|
case GET_CHATS:
|
||||||
fmt.Println("got a get chat req")
|
|
||||||
if err = verifyFieldsSliceInterface(req.Payload, "chatsId"); err != nil {
|
if err = verifyFieldsSliceInterface(req.Payload, "chatsId"); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println("calling get chat")
|
|
||||||
err = zch.GetChats(req.From, req.Payload["chatsId"].([]interface{})...)
|
err = zch.GetChats(req.From, req.Payload["chatsId"].([]interface{})...)
|
||||||
fmt.Println("get chat done")
|
|
||||||
case LIST_LATEST_CHATS:
|
case LIST_LATEST_CHATS:
|
||||||
if err = verifyFieldsString(req.Payload, "chatId"); err != nil {
|
if err = verifyFieldsString(req.Payload, "chatId"); err != nil {
|
||||||
return
|
return
|
||||||
@ -1308,7 +1388,7 @@ func (zch *ZoneChatsHandler) handleZoneRequest(ctx context.Context, req *ZoneReq
|
|||||||
if err = verifyFieldsString(req.Payload, "chatId"); err != nil {
|
if err = verifyFieldsString(req.Payload, "chatId"); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = zch.ReadLastMessage(req.From,req.Payload["chatId"].(string))
|
err = zch.ReadLastMessage(req.From, req.Payload["chatId"].(string))
|
||||||
case ADD_CHAT_MESSAGE:
|
case ADD_CHAT_MESSAGE:
|
||||||
logger.Println("got request in zone chat handler", req)
|
logger.Println("got request in zone chat handler", req)
|
||||||
if err = verifyFieldsString(req.Payload, "chatId", "content"); err != nil {
|
if err = verifyFieldsString(req.Payload, "chatId", "content"); err != nil {
|
||||||
|
|||||||
@ -264,7 +264,7 @@ func (fs *FSInstance) SetupFileDownload(path, filename, userId string) (err erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.Println("done")
|
logger.Println("done")
|
||||||
<-time.After(4*time.Second)
|
<-time.After(4 * time.Second)
|
||||||
_ = dc.SendText("done")
|
_ = dc.SendText("done")
|
||||||
<-time.After(time.Second)
|
<-time.After(time.Second)
|
||||||
_ = dc.Close()
|
_ = dc.Close()
|
||||||
|
|||||||
@ -52,7 +52,7 @@ type Zone struct {
|
|||||||
|
|
||||||
func NewZone(hostId string, zoneId string, zoneName string, imageUrl string, owner string, creationDate string, initialized bool, authorizedMembers []string) (zone *Zone, err error) {
|
func NewZone(hostId string, zoneId string, zoneName string, imageUrl string, owner string, creationDate string, initialized bool, authorizedMembers []string) (zone *Zone, err error) {
|
||||||
dataChannels, dataChannelFlag := make(map[string]*DataChannel), uint32(0)
|
dataChannels, dataChannelFlag := make(map[string]*DataChannel), uint32(0)
|
||||||
zoneChatHandler, err := NewZoneChatsHandler(hostId, zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag)
|
zoneChatHandler, err := NewZoneChatsHandler(hostId, zoneId, zoneName, owner, authorizedMembers, dataChannels, &dataChannelFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -68,11 +68,15 @@ func NewZone(hostId string, zoneId string, zoneName string, imageUrl string, own
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
zoneNotificationsHandler, err := NewZoneNotificationsHandler(hostId, zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
zoneFileHandler, err := NewZoneFileHandler(hostId, zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag)
|
zoneFileHandler, err := NewZoneFileHandler(hostId, zoneId, owner, authorizedMembers, dataChannels, &dataChannelFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
zoneScheduler, e := NewZoneRequestScheduler(authorizedMembers, zoneUsersHandler, zoneAudioChannelsHandler, zoneVideoChannelsHandler, zoneFileHandler, zoneChatHandler)
|
zoneScheduler, e := NewZoneRequestScheduler(authorizedMembers, zoneUsersHandler, zoneAudioChannelsHandler, zoneVideoChannelsHandler, zoneFileHandler, zoneChatHandler, zoneNotificationsHandler)
|
||||||
go func() {
|
go func() {
|
||||||
for schedErr := range e {
|
for schedErr := range e {
|
||||||
logger.Println("from scheduler :", schedErr)
|
logger.Println("from scheduler :", schedErr)
|
||||||
@ -111,7 +115,7 @@ func NewZoneManager(id string, token string) (zoneManager *ZoneManager, err erro
|
|||||||
}
|
}
|
||||||
zoneMap[zone.ID] = z
|
zoneMap[zone.ID] = z
|
||||||
}
|
}
|
||||||
zonesFolder,err := os.ReadDir(filepath.Join("data", "zones"))
|
zonesFolder, err := os.ReadDir(filepath.Join("data", "zones"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -130,7 +134,7 @@ func NewZoneManager(id string, token string) (zoneManager *ZoneManager, err erro
|
|||||||
candidateFlag: &candidateFlag,
|
candidateFlag: &candidateFlag,
|
||||||
}
|
}
|
||||||
for _, z := range zonesFolder {
|
for _, z := range zonesFolder {
|
||||||
if _,ok := zoneMap[z.Name()]; !ok {
|
if _, ok := zoneMap[z.Name()]; !ok {
|
||||||
logger.Println(zoneManager.DeleteZone(z.Name()))
|
logger.Println(zoneManager.DeleteZone(z.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +167,7 @@ func (zm *ZoneManager) sendSignalingMessage(messageType, from, to string, payloa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zm *ZoneManager) DeleteZone(zoneId string) error {
|
func (zm *ZoneManager) DeleteZone(zoneId string) error {
|
||||||
return os.RemoveAll(filepath.Join("data", "zones",zoneId))
|
return os.RemoveAll(filepath.Join("data", "zones", zoneId))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zm *ZoneManager) fetchZones(nodeId string, token string) (zones []*Zone, err error) {
|
func (zm *ZoneManager) fetchZones(nodeId string, token string) (zones []*Zone, err error) {
|
||||||
@ -173,7 +177,7 @@ func (zm *ZoneManager) fetchZones(nodeId string, token string) (zones []*Zone, e
|
|||||||
"type": LIST_ZONES_BY_HOST,
|
"type": LIST_ZONES_BY_HOST,
|
||||||
"mac": sig,
|
"mac": sig,
|
||||||
"from": nodeId,
|
"from": nodeId,
|
||||||
"peerType":"node",
|
"peerType": "node",
|
||||||
"payload": map[string]string{
|
"payload": map[string]string{
|
||||||
"host": nodeId,
|
"host": nodeId,
|
||||||
"lastIndex": "0",
|
"lastIndex": "0",
|
||||||
@ -246,8 +250,8 @@ func (zm *ZoneManager) HandleOffer(ctx context.Context, from string, to string,
|
|||||||
}
|
}
|
||||||
logger.Println("handling zone offer")
|
logger.Println("handling zone offer")
|
||||||
|
|
||||||
if _,ok := zm.RTCPeerConnections[from]; ok {
|
if _, ok := zm.RTCPeerConnections[from]; ok {
|
||||||
if e := zm.HandleLeavingMember(from,req["zoneId"]); e != nil {
|
if e := zm.HandleLeavingMember(from, req["zoneId"]); e != nil {
|
||||||
logger.Println(e)
|
logger.Println(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -708,8 +712,8 @@ func (zm *ZoneManager) AddCandidate(candidate *webrtc.ICECandidateInit, from str
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) {
|
func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error) {
|
||||||
defer func () {
|
defer func() {
|
||||||
logger.Println(zm.notifyLeavingMember(id,zoneId,zm.ID))
|
logger.Println(zm.notifyLeavingMember(id, zoneId, zm.ID))
|
||||||
}()
|
}()
|
||||||
logger.Println("---------------- handling leaving member", id)
|
logger.Println("---------------- handling leaving member", id)
|
||||||
if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) {
|
if err = atomicallyExecute(zm.peerConnectionFlag, func() (err error) {
|
||||||
@ -771,14 +775,14 @@ func (zm *ZoneManager) HandleLeavingMember(id string, zoneId string) (err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (zm *ZoneManager) notifyLeavingMember(userId,zoneId,hostId string) (err error) {
|
func (zm *ZoneManager) notifyLeavingMember(userId, zoneId, hostId string) (err error) {
|
||||||
em := NewEncryptionManager()
|
em := NewEncryptionManager()
|
||||||
sig := em.SignRequestHMAC(hostId)
|
sig := em.SignRequestHMAC(hostId)
|
||||||
body, err := json.Marshal(map[string]interface{}{
|
body, err := json.Marshal(map[string]interface{}{
|
||||||
"type": DISCONNECT_ZONE_MEMBER,
|
"type": DISCONNECT_ZONE_MEMBER,
|
||||||
"mac": sig,
|
"mac": sig,
|
||||||
"from": hostId,
|
"from": hostId,
|
||||||
"peerType":"node",
|
"peerType": "node",
|
||||||
"payload": map[string]string{
|
"payload": map[string]string{
|
||||||
"zoneId": zoneId,
|
"zoneId": zoneId,
|
||||||
"userId": userId,
|
"userId": userId,
|
||||||
|
|||||||
41
zoneNotificationsDBHandler.go
Normal file
41
zoneNotificationsDBHandler.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package localserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
sync "sync"
|
||||||
|
|
||||||
|
"github.com/dgraph-io/badger/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ZoneNotification struct {
|
||||||
|
ID string
|
||||||
|
Type string
|
||||||
|
Description string
|
||||||
|
Recipients []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ZoneNotificationDBHandler struct {
|
||||||
|
ZoneID string
|
||||||
|
db func(func(*badger.DB) (err error)) (err error)
|
||||||
|
lock *sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewZoneNotificationDBHandler(zoneId string) (zoneFilesDBHandler *ZoneNotificationDBHandler, err error) {
|
||||||
|
zoneFilesDBHandler = &ZoneNotificationDBHandler{
|
||||||
|
db: func(f func(*badger.DB) (err error)) (err error) {
|
||||||
|
path := filepath.Join("data", "zones", zoneId, "notifications")
|
||||||
|
db, err := badger.Open(badger.DefaultOptions(path).WithLogger(dbLogger))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
err = f(db)
|
||||||
|
return
|
||||||
|
},
|
||||||
|
ZoneID: zoneId,
|
||||||
|
lock: new(sync.RWMutex),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Todo: implement pull notification module for beta only push notification are enabled for simplicity
|
||||||
@ -1,10 +1,179 @@
|
|||||||
package localserver
|
package localserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CREATE_NOTIFICATION = "create_notification"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NOTIFY = "notify"
|
||||||
|
)
|
||||||
|
|
||||||
type ZoneNotificationsHandler struct {
|
type ZoneNotificationsHandler struct {
|
||||||
ZoneId string
|
ZoneId string
|
||||||
ZoneMembersId []string
|
ZoneMembersId []string
|
||||||
DataChannels map[string]*DataChannel
|
DataChannels map[string]*DataChannel
|
||||||
Flag *uint32
|
Flag *uint32
|
||||||
|
DB *ZoneNotificationDBHandler
|
||||||
Publishers []<-chan *ZoneRequest
|
Publishers []<-chan *ZoneRequest
|
||||||
reqChans []chan<- *ZoneRequest
|
reqChans []chan<- *ZoneRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewZoneNotificationsHandler(_ string, zoneId string, owner string, authorizedMembers []string, dataChannels map[string]*DataChannel, flag *uint32) (zoneNotificationsHandler *ZoneNotificationsHandler, err error) {
|
||||||
|
db, err := NewZoneNotificationDBHandler(zoneId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, dirErr := os.ReadDir(filepath.Join("data", "zones", zoneId, "notifications")); os.IsNotExist(dirErr) {
|
||||||
|
dirErr := os.MkdirAll(filepath.Join("data", "zones", zoneId, "notifications"), 0700)
|
||||||
|
if dirErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zoneNotificationsHandler = &ZoneNotificationsHandler{
|
||||||
|
ZoneId: zoneId,
|
||||||
|
ZoneMembersId: authorizedMembers,
|
||||||
|
DataChannels: dataChannels,
|
||||||
|
DB: db,
|
||||||
|
Flag: flag,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (znh *ZoneNotificationsHandler) sendZoneRequest(reqType string, from string, payload map[string]interface{}) {
|
||||||
|
go func() {
|
||||||
|
for _, rc := range znh.reqChans {
|
||||||
|
rc <- &ZoneRequest{
|
||||||
|
ReqType: reqType,
|
||||||
|
From: from,
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (znh *ZoneNotificationsHandler) sendDataChannelMessage(reqType string, from string, to string, payload map[string]interface{}) (<-chan struct{}, <-chan error) {
|
||||||
|
done, errCh := make(chan struct{}), make(chan error)
|
||||||
|
go func() {
|
||||||
|
if err := atomicallyExecute(znh.Flag, func() (err error) {
|
||||||
|
if _, ok := znh.DataChannels[to]; ok {
|
||||||
|
bs, jsonErr := json.Marshal(&ZoneResponse{
|
||||||
|
Type: reqType,
|
||||||
|
From: from,
|
||||||
|
To: to,
|
||||||
|
Payload: payload,
|
||||||
|
})
|
||||||
|
if jsonErr != nil {
|
||||||
|
return jsonErr
|
||||||
|
}
|
||||||
|
err = znh.DataChannels[to].DataChannel.SendText(string(bs))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}); err != nil {
|
||||||
|
errCh <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
return done, errCh
|
||||||
|
}
|
||||||
|
|
||||||
|
func (znh *ZoneNotificationsHandler) Init(ctx context.Context, authorizedMembers []string) (err error) {
|
||||||
|
//? initialization code here
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (znh *ZoneNotificationsHandler) Subscribe(ctx context.Context, publisher <-chan *ZoneRequest) (reqChan chan *ZoneRequest, done chan struct{}, errCh chan error) {
|
||||||
|
reqChan, done, errCh = make(chan *ZoneRequest), make(chan struct{}), make(chan error)
|
||||||
|
znh.reqChans = append(znh.reqChans, reqChan)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
done <- struct{}{}
|
||||||
|
return
|
||||||
|
case req := <-publisher:
|
||||||
|
if err := znh.handleZoneRequest(ctx, req); err != nil {
|
||||||
|
errCh <- err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (zng *ZoneNotificationsHandler) ListNotifications(userId string) {}
|
||||||
|
|
||||||
|
func (zng *ZoneNotificationsHandler) CreateNotification(notificationType, title, body, payload string, isPushed bool, recipients ...string) (err error) {
|
||||||
|
if isPushed {
|
||||||
|
err = zng.PushNotification(notificationType, title, body, payload, recipients...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (zng *ZoneNotificationsHandler) DeleteNotification() {}
|
||||||
|
|
||||||
|
func (zng *ZoneNotificationsHandler) PushNotification(notificationType, title, body ,payload string, recipients ...string) (err error) {
|
||||||
|
em := NewEncryptionManager()
|
||||||
|
sig := em.SignRequestHMAC(NodeID)
|
||||||
|
b, err := json.Marshal(map[string]interface{}{
|
||||||
|
"type": NOTIFY,
|
||||||
|
"mac": sig,
|
||||||
|
"from": NodeID,
|
||||||
|
"peerType": "node",
|
||||||
|
"payload": map[string]interface{}{
|
||||||
|
"type": notificationType,
|
||||||
|
"title": title,
|
||||||
|
"body": body,
|
||||||
|
"recipients": recipients,
|
||||||
|
"payload": payload,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = http.Post("https://app.zippytal.com/req", "application/json", bytes.NewBuffer(b))
|
||||||
|
if err != nil {
|
||||||
|
logger.Println("error come from there in zone manager")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (zng *ZoneNotificationsHandler) handleZoneRequest(ctx context.Context, req *ZoneRequest) (err error) {
|
||||||
|
switch req.ReqType {
|
||||||
|
case CREATE_NOTIFICATION:
|
||||||
|
if err = verifyFieldsString(req.Payload, "type", "title", "body","payload"); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = verifyFieldsBool(req.Payload, "isPushed"); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := req.Payload["recipients"]; !ok {
|
||||||
|
err = fmt.Errorf("no field recipient in payload")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := req.Payload["recipients"].([]string); !ok {
|
||||||
|
err = fmt.Errorf(" field recipient in payload is wrong type")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// recipients := []string{}
|
||||||
|
// for _, recipient := range req.Payload["recipients"].([]any) {
|
||||||
|
// if r, ok := recipient.(string); ok {
|
||||||
|
// recipients = append(recipients, r)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
err = zng.CreateNotification(req.Payload["type"].(string), req.Payload["title"].(string), req.Payload["body"].(string), req.Payload["payload"].(string),req.Payload["isPushed"].(bool),req.Payload["recipients"].([]string)...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -72,7 +72,7 @@ func verifyFieldsSliceInterface(payload map[string]interface{}, fields ...string
|
|||||||
if _, ok := payload[field]; !ok {
|
if _, ok := payload[field]; !ok {
|
||||||
err = fmt.Errorf("no field %s in payload", field)
|
err = fmt.Errorf("no field %s in payload", field)
|
||||||
return
|
return
|
||||||
} else if _, ok := payload[field].([]interface{}); !ok {
|
} else if _, ok := payload[field].([]any); !ok {
|
||||||
err = fmt.Errorf("field %s in payload is not a []interface{}", field)
|
err = fmt.Errorf("field %s in payload is not a []interface{}", field)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,7 +282,7 @@ func (zvch *ZoneVideoChannelsHandler) AddNewVideoChannel(channelName string, own
|
|||||||
ID: channelName,
|
ID: channelName,
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
ChannelType: channelType,
|
ChannelType: channelType,
|
||||||
Members: append(m,owner),
|
Members: append(m, owner),
|
||||||
}
|
}
|
||||||
bs, jsonErr := json.Marshal(baseConfig)
|
bs, jsonErr := json.Marshal(baseConfig)
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user