mirror of
https://github.com/balzack/databag.git
synced 2025-02-12 03:29:16 +00:00
separating view and content notification
This commit is contained in:
parent
e51197a3e5
commit
b4b2c2c651
52
doc/api.oa3
52
doc/api.oa3
@ -1519,6 +1519,30 @@ paths:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
|
/contact/view/revision:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- contact
|
||||||
|
description: Set view revision for contact. This is intend to be invoked automatically anytime a contact updates their content or sharing. Access granted to contact tokens.
|
||||||
|
operationId: set-view-revision
|
||||||
|
security:
|
||||||
|
- bearerAuth: []
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: revision set
|
||||||
|
'401':
|
||||||
|
description: not authorized
|
||||||
|
'410':
|
||||||
|
description: account disabled
|
||||||
|
'500':
|
||||||
|
description: internal server error
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
|
||||||
/content/articleBlocks/view:
|
/content/articleBlocks/view:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@ -4121,8 +4145,9 @@ components:
|
|||||||
- cardId
|
- cardId
|
||||||
- profileRevision
|
- profileRevision
|
||||||
- dataRevision
|
- dataRevision
|
||||||
- remoteProfile
|
- notifiedProfile
|
||||||
- remoteContent
|
- notifiedContent
|
||||||
|
- notifiedView
|
||||||
properties:
|
properties:
|
||||||
cardId:
|
cardId:
|
||||||
type: string
|
type: string
|
||||||
@ -4132,10 +4157,13 @@ components:
|
|||||||
dataRevision:
|
dataRevision:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
remoteProfile:
|
notifiedProfile:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
remoteContent:
|
notifiedContent:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
notifiedView:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
@ -4186,8 +4214,9 @@ components:
|
|||||||
- cardId
|
- cardId
|
||||||
- cardProfile
|
- cardProfile
|
||||||
- cardData
|
- cardData
|
||||||
- profileRevision
|
- notifiedProfile
|
||||||
- contentRevision
|
- notifiedContent
|
||||||
|
- notifiedView
|
||||||
properties:
|
properties:
|
||||||
cardId:
|
cardId:
|
||||||
type: string
|
type: string
|
||||||
@ -4195,10 +4224,13 @@ components:
|
|||||||
$ref: '#/components/schemas/CardProfile'
|
$ref: '#/components/schemas/CardProfile'
|
||||||
cardData:
|
cardData:
|
||||||
$ref: '#/components/schemas/CardData'
|
$ref: '#/components/schemas/CardData'
|
||||||
profileRevision:
|
notifiedProfile:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
contentRevision:
|
notifiedContent:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
notifiedView:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
@ -4484,12 +4516,14 @@ components:
|
|||||||
required:
|
required:
|
||||||
- contact
|
- contact
|
||||||
- token
|
- token
|
||||||
- contentRevision
|
|
||||||
properties:
|
properties:
|
||||||
contact:
|
contact:
|
||||||
type: string
|
type: string
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
|
viewRevision:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
contentRevision:
|
contentRevision:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package databag
|
package databag
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -33,6 +34,25 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var articleBlock store.ArticleBlock
|
||||||
|
if err := store.DB.Preload("Articles").Where("account_id = ?", account.ID).Last(&articleBlock).Error; err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
if err := addArticleBlock(account, &articleBlock); err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(articleBlock.Articles) >= APP_ARTICLEBLOCKSIZE {
|
||||||
|
if err := addArticleBlock(account, &articleBlock); err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
article := &store.Article{
|
article := &store.Article{
|
||||||
ArticleId: uuid.New().String(),
|
ArticleId: uuid.New().String(),
|
||||||
AccountID: account.ID,
|
AccountID: account.ID,
|
||||||
@ -45,10 +65,13 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
Labels: labels,
|
Labels: labels,
|
||||||
}
|
}
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := store.DB.Save(article).Error; res != nil {
|
if res := tx.Save(article).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := store.DB.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
if res := tx.Model(&articleBlock).Update("revision", account.ContentRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if res := tx.Model(&account).Update("content_revision", account.ContentRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -58,7 +81,24 @@ func AddArticle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
articleEntry := &ArticleEntry{
|
||||||
|
BlockId: articleBlock.ArticleBlockId,
|
||||||
|
BlockRevision: articleBlock.Revision,
|
||||||
|
Article: getArticleModel(article, 0),
|
||||||
|
}
|
||||||
|
|
||||||
SetStatus(account)
|
SetStatus(account)
|
||||||
SetContentNotification(account)
|
SetContentNotification(account)
|
||||||
WriteResponse(w, getArticleModel(article, 0))
|
WriteResponse(w, articleEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addArticleBlock(account *store.Account, articleBlock *store.ArticleBlock) error {
|
||||||
|
articleBlock.ArticleBlockId = uuid.New().String()
|
||||||
|
articleBlock.AccountID = account.ID
|
||||||
|
articleBlock.Revision = account.ContentRevision
|
||||||
|
if err := store.DB.Save(articleBlock).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ func AddGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
Data: subject.Data,
|
Data: subject.Data,
|
||||||
}
|
}
|
||||||
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
err = store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := store.DB.Save(group).Error; res != nil {
|
if res := tx.Save(group).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := store.DB.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
if res := tx.Model(&account).Update("group_revision", account.GroupRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -9,8 +9,9 @@ type cardView struct {
|
|||||||
CardId string
|
CardId string
|
||||||
ProfileRevision int64
|
ProfileRevision int64
|
||||||
DataRevision int64
|
DataRevision int64
|
||||||
RemoteProfile int64
|
NotifiedProfile int64
|
||||||
RemoteContent int64
|
NotifiedContent int64
|
||||||
|
NotifiedView int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCardView(w http.ResponseWriter, r *http.Request) {
|
func GetCardView(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -31,8 +31,8 @@ func RemoveGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteResponse(w, nil)
|
|
||||||
SetStatus(account)
|
SetStatus(account)
|
||||||
SetContentNotification(account)
|
SetViewNotification(account)
|
||||||
|
WriteResponse(w, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +70,9 @@ func SetCardGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, group := range card.Groups {
|
for _, group := range card.Groups {
|
||||||
cardData.Groups = append(cardData.Groups, group.GroupId)
|
cardData.Groups = append(cardData.Groups, group.GroupId)
|
||||||
}
|
}
|
||||||
WriteResponse(w, cardData)
|
SetContactViewNotification(account, &card)
|
||||||
SetContactContentNotification(account, &card)
|
|
||||||
SetStatus(account)
|
SetStatus(account)
|
||||||
|
WriteResponse(w, cardData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,10 +32,10 @@ func NotifyContentRevision(card *store.Card, revision int64) error {
|
|||||||
|
|
||||||
act := &card.Account
|
act := &card.Account
|
||||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("remote_content", revision).Error; res != nil {
|
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_content", revision).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil {
|
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -61,8 +61,9 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
card.Version = connect.Version
|
card.Version = connect.Version
|
||||||
card.Node = connect.Node
|
card.Node = connect.Node
|
||||||
card.ProfileRevision = connect.ProfileRevision
|
card.ProfileRevision = connect.ProfileRevision
|
||||||
card.RemoteContent = connect.ContentRevision
|
card.NotifiedProfile = connect.ProfileRevision
|
||||||
card.RemoteProfile = connect.ProfileRevision
|
card.NotifiedContent = connect.ContentRevision
|
||||||
|
card.NotifiedView = connect.ViewRevision
|
||||||
card.Status = APP_CARDPENDING
|
card.Status = APP_CARDPENDING
|
||||||
card.DataRevision = 1
|
card.DataRevision = 1
|
||||||
card.OutToken = connect.Token
|
card.OutToken = connect.Token
|
||||||
@ -86,11 +87,14 @@ func SetOpenMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
card.Node = connect.Node
|
card.Node = connect.Node
|
||||||
card.ProfileRevision = connect.ProfileRevision
|
card.ProfileRevision = connect.ProfileRevision
|
||||||
}
|
}
|
||||||
if connect.ContentRevision > card.RemoteContent {
|
if connect.ContentRevision > card.NotifiedContent {
|
||||||
card.RemoteContent = connect.ContentRevision
|
card.NotifiedContent = connect.ContentRevision
|
||||||
}
|
}
|
||||||
if connect.ProfileRevision > card.RemoteProfile {
|
if connect.ViewRevision > card.NotifiedView {
|
||||||
card.RemoteProfile = connect.ProfileRevision
|
card.NotifiedView = connect.ViewRevision
|
||||||
|
}
|
||||||
|
if connect.ProfileRevision > card.NotifiedProfile {
|
||||||
|
card.NotifiedProfile = connect.ProfileRevision
|
||||||
}
|
}
|
||||||
if card.Status == APP_CARDCONFIRMED {
|
if card.Status == APP_CARDCONFIRMED {
|
||||||
card.Status = APP_CARDREQUESTED
|
card.Status = APP_CARDREQUESTED
|
||||||
|
@ -30,10 +30,9 @@ func SetProfileRevision(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func NotifyProfileRevision(card *store.Card, revision int64) error {
|
func NotifyProfileRevision(card *store.Card, revision int64) error {
|
||||||
|
|
||||||
card.RemoteProfile = revision
|
|
||||||
act := &card.Account
|
act := &card.Account
|
||||||
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
if res := tx.Model(card).Where("id = ?", card.ID).Update("remote_profile", revision).Error; res != nil {
|
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_profile", revision).Error; res != nil {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil {
|
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision+1).Error; res != nil {
|
||||||
|
49
net/server/internal/api_setViewRevision.go
Normal file
49
net/server/internal/api_setViewRevision.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package databag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"databag/internal/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SetViewRevision(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
card, code, err := BearerContactToken(r)
|
||||||
|
if err != nil {
|
||||||
|
ErrResponse(w, code, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var revision int64
|
||||||
|
if err := ParseRequest(r, w, &revision); err != nil {
|
||||||
|
ErrResponse(w, http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := NotifyProfileRevision(card, revision); err != nil {
|
||||||
|
ErrResponse(w, http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteResponse(w, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotifyViewRevision(card *store.Card, revision int64) error {
|
||||||
|
|
||||||
|
act := &card.Account
|
||||||
|
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
if res := tx.Model(card).Where("id = ?", card.ID).Update("notified_view", revision).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if res := tx.Model(act).Where("id = ?", act.ID).Update("card_revision", act.CardRevision + 1).Error; res != nil {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
SetStatus(act)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -20,8 +20,9 @@ const APP_CARDCONFIRMED = "confirmed"
|
|||||||
const APP_CARDREQUESTED = "requested"
|
const APP_CARDREQUESTED = "requested"
|
||||||
const APP_CARDCONNECTING = "connecting"
|
const APP_CARDCONNECTING = "connecting"
|
||||||
const APP_CARDCONNECTED = "connected"
|
const APP_CARDCONNECTED = "connected"
|
||||||
const APP_MODULEPROFILE = "profile"
|
const APP_NOTIFYPROFILE = "profile"
|
||||||
const APP_MODULECONTENT = "content"
|
const APP_NOTIFYCONTENT = "content"
|
||||||
|
const APP_NOTIFYVIEW = "view"
|
||||||
const APP_TOKENAPP = "app"
|
const APP_TOKENAPP = "app"
|
||||||
const APP_TOKENCONTACT = "contact"
|
const APP_TOKENCONTACT = "contact"
|
||||||
const APP_NOTIFYBUFFER = 4096
|
const APP_NOTIFYBUFFER = 4096
|
||||||
@ -29,6 +30,7 @@ const APP_ARTICLEUNCONFIRMED = "unconfirmed"
|
|||||||
const APP_ARTICLECONFIRMED = "confirmed"
|
const APP_ARTICLECONFIRMED = "confirmed"
|
||||||
const APP_ARTICLEINCOMPLETE = "incomplete"
|
const APP_ARTICLEINCOMPLETE = "incomplete"
|
||||||
const APP_ARTICLEERROR = "error"
|
const APP_ARTICLEERROR = "error"
|
||||||
|
const APP_ARTICLEBLOCKSIZE = 128
|
||||||
|
|
||||||
func AppCardStatus(status string) bool {
|
func AppCardStatus(status string) bool {
|
||||||
if status == APP_CARDPENDING {
|
if status == APP_CARDPENDING {
|
||||||
|
@ -14,8 +14,9 @@ func getCardModel(card *store.Card) *Card {
|
|||||||
|
|
||||||
return &Card{
|
return &Card{
|
||||||
CardId: card.CardId,
|
CardId: card.CardId,
|
||||||
ProfileRevision: card.RemoteProfile,
|
NotifiedProfile: card.NotifiedProfile,
|
||||||
ContentRevision: card.RemoteContent,
|
NotifiedContent: card.NotifiedContent,
|
||||||
|
NotifiedView: card.NotifiedView,
|
||||||
CardProfile: &CardProfile{
|
CardProfile: &CardProfile{
|
||||||
Guid: card.Guid,
|
Guid: card.Guid,
|
||||||
Handle: card.Username,
|
Handle: card.Username,
|
||||||
|
@ -88,8 +88,9 @@ type Card struct {
|
|||||||
CardId string `json:"cardId"`
|
CardId string `json:"cardId"`
|
||||||
CardProfile *CardProfile `json:"cardProfile"`
|
CardProfile *CardProfile `json:"cardProfile"`
|
||||||
CardData *CardData `json:"cardData"`
|
CardData *CardData `json:"cardData"`
|
||||||
ProfileRevision int64 `json:"profileRevision"`
|
NotifiedProfile int64 `json:"notifiedProfile"`
|
||||||
ContentRevision int64 `json:"contentRevision"`
|
NotifiedContent int64 `json:"notifiedContent"`
|
||||||
|
NotifiedView int64 `json:"notifiedView"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CardData struct {
|
type CardData struct {
|
||||||
@ -116,8 +117,9 @@ type CardView struct {
|
|||||||
CardId string `json:"cardId"`
|
CardId string `json:"cardId"`
|
||||||
ProfileRevision int64 `json:"profileRevision"`
|
ProfileRevision int64 `json:"profileRevision"`
|
||||||
DataRevision int64 `json:"dataRevision"`
|
DataRevision int64 `json:"dataRevision"`
|
||||||
RemoteProfile int64 `json:"remoteProfile"`
|
NotifiedProfile int64 `json:"notifiedProfile"`
|
||||||
RemoteContent int64 `json:"remoteContent"`
|
NotifiedContent int64 `json:"notifiedContent"`
|
||||||
|
NotifiedView int64 `json:"notifiedView"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContentArticlesBody struct {
|
type ContentArticlesBody struct {
|
||||||
@ -329,6 +331,7 @@ type Identity struct {
|
|||||||
type Connect struct {
|
type Connect struct {
|
||||||
Contact string `json:"contact"`
|
Contact string `json:"contact"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
ViewRevision int64 `json:"viewRevision"`
|
||||||
ContentRevision int64 `json:"contentRevision"`
|
ContentRevision int64 `json:"contentRevision"`
|
||||||
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
ProfileRevision int64 `json:"profileRevision,omitempty"`
|
||||||
Handle string `json:"handle,omitempty"`
|
Handle string `json:"handle,omitempty"`
|
||||||
|
@ -56,14 +56,18 @@ func SendLocalNotification(notification *store.Notification) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if notification.Module == APP_MODULEPROFILE {
|
if notification.Module == APP_NOTIFYPROFILE {
|
||||||
if err := NotifyProfileRevision(&card, notification.Revision); err != nil {
|
if err := NotifyProfileRevision(&card, notification.Revision); err != nil {
|
||||||
ErrMsg(err)
|
ErrMsg(err)
|
||||||
}
|
}
|
||||||
} else if notification.Module == APP_MODULECONTENT {
|
} else if notification.Module == APP_NOTIFYCONTENT {
|
||||||
if err := NotifyContentRevision(&card, notification.Revision); err != nil {
|
if err := NotifyContentRevision(&card, notification.Revision); err != nil {
|
||||||
ErrMsg(err)
|
ErrMsg(err)
|
||||||
}
|
}
|
||||||
|
} else if notification.Module == APP_NOTIFYVIEW {
|
||||||
|
if err := NotifyViewRevision(&card, notification.Revision); err != nil {
|
||||||
|
ErrMsg(err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LogMsg("unknown notification type")
|
LogMsg("unknown notification type")
|
||||||
}
|
}
|
||||||
@ -88,7 +92,7 @@ func SetProfileNotification(account *store.Account) {
|
|||||||
for _, card := range cards {
|
for _, card := range cards {
|
||||||
notification := &store.Notification{
|
notification := &store.Notification{
|
||||||
Node: card.Node,
|
Node: card.Node,
|
||||||
Module: APP_MODULEPROFILE,
|
Module: APP_NOTIFYPROFILE,
|
||||||
Token: card.OutToken,
|
Token: card.OutToken,
|
||||||
Revision: account.ProfileRevision,
|
Revision: account.ProfileRevision,
|
||||||
}
|
}
|
||||||
@ -106,7 +110,6 @@ func SetProfileNotification(account *store.Account) {
|
|||||||
|
|
||||||
// notify all cards of content change
|
// notify all cards of content change
|
||||||
// account.Content incremented by adding, updating, removing article
|
// account.Content incremented by adding, updating, removing article
|
||||||
// account.View incremented by removing a group or label or adding or removing a group with label
|
|
||||||
func SetContentNotification(account *store.Account) {
|
func SetContentNotification(account *store.Account) {
|
||||||
|
|
||||||
// select all connected cards
|
// select all connected cards
|
||||||
@ -121,9 +124,9 @@ func SetContentNotification(account *store.Account) {
|
|||||||
for _, card := range cards {
|
for _, card := range cards {
|
||||||
notification := &store.Notification{
|
notification := &store.Notification{
|
||||||
Node: card.Node,
|
Node: card.Node,
|
||||||
Module: APP_MODULECONTENT,
|
Module: APP_NOTIFYCONTENT,
|
||||||
Token: card.OutToken,
|
Token: card.OutToken,
|
||||||
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
Revision: account.ContentRevision,
|
||||||
}
|
}
|
||||||
if err := tx.Save(notification).Error; err != nil {
|
if err := tx.Save(notification).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
@ -148,9 +151,65 @@ func SetContactContentNotification(account *store.Account, card *store.Card) {
|
|||||||
// add new notification for card
|
// add new notification for card
|
||||||
notification := &store.Notification{
|
notification := &store.Notification{
|
||||||
Node: card.Node,
|
Node: card.Node,
|
||||||
Module: APP_MODULECONTENT,
|
Module: APP_NOTIFYCONTENT,
|
||||||
Token: card.OutToken,
|
Token: card.OutToken,
|
||||||
Revision: account.ViewRevision + account.ContentRevision + card.ViewRevision,
|
Revision: account.ContentRevision,
|
||||||
|
}
|
||||||
|
|
||||||
|
if res := store.DB.Save(notification).Error; res != nil {
|
||||||
|
ErrMsg(res)
|
||||||
|
} else {
|
||||||
|
notify <- notification
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// notify all cards of view change
|
||||||
|
// account.View incremented by removing a group or label or adding or removing a group with label
|
||||||
|
func SetViewNotification(account *store.Account) {
|
||||||
|
|
||||||
|
// select all connected cards
|
||||||
|
var cards []store.Card
|
||||||
|
if err := store.DB.Where("account_id = ? AND status = ?", account.Guid, APP_CARDCONNECTED).Find(&cards).Error; err != nil {
|
||||||
|
ErrMsg(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new notification for each card
|
||||||
|
err := store.DB.Transaction(func(tx *gorm.DB) error {
|
||||||
|
for _, card := range cards {
|
||||||
|
notification := &store.Notification{
|
||||||
|
Node: card.Node,
|
||||||
|
Module: APP_NOTIFYVIEW,
|
||||||
|
Token: card.OutToken,
|
||||||
|
Revision: account.ViewRevision + card.ViewRevision,
|
||||||
|
}
|
||||||
|
if err := tx.Save(notification).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
notify <- notification
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ErrMsg(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notify single card of content change
|
||||||
|
// card.View incremented by adding or removing card from group or label
|
||||||
|
func SetContactViewNotification(account *store.Account, card *store.Card) {
|
||||||
|
|
||||||
|
if card.Status != APP_CARDCONNECTED {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// add new notification for card
|
||||||
|
notification := &store.Notification{
|
||||||
|
Node: card.Node,
|
||||||
|
Module: APP_NOTIFYVIEW,
|
||||||
|
Token: card.OutToken,
|
||||||
|
Revision: account.ViewRevision + card.ViewRevision,
|
||||||
}
|
}
|
||||||
|
|
||||||
if res := store.DB.Save(notification).Error; res != nil {
|
if res := store.DB.Save(notification).Error; res != nil {
|
||||||
|
@ -397,6 +397,13 @@ var routes = Routes{
|
|||||||
SetOpenMessage,
|
SetOpenMessage,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Route{
|
||||||
|
"SetViewRevision",
|
||||||
|
strings.ToUpper("Put"),
|
||||||
|
"/contact/view/revision",
|
||||||
|
SetViewRevision,
|
||||||
|
},
|
||||||
|
|
||||||
Route{
|
Route{
|
||||||
"SetProfileRevision",
|
"SetProfileRevision",
|
||||||
strings.ToUpper("Put"),
|
strings.ToUpper("Put"),
|
||||||
|
@ -13,6 +13,7 @@ func AutoMigrate(db *gorm.DB) {
|
|||||||
db.AutoMigrate(&Card{});
|
db.AutoMigrate(&Card{});
|
||||||
db.AutoMigrate(&Asset{});
|
db.AutoMigrate(&Asset{});
|
||||||
db.AutoMigrate(&Article{});
|
db.AutoMigrate(&Article{});
|
||||||
|
db.AutoMigrate(&ArticleBlock{});
|
||||||
db.AutoMigrate(&ArticleAsset{});
|
db.AutoMigrate(&ArticleAsset{});
|
||||||
db.AutoMigrate(&ArticleTag{});
|
db.AutoMigrate(&ArticleTag{});
|
||||||
db.AutoMigrate(&Dialogue{});
|
db.AutoMigrate(&Dialogue{});
|
||||||
@ -141,8 +142,9 @@ type Card struct {
|
|||||||
Created int64 `gorm:"autoCreateTime"`
|
Created int64 `gorm:"autoCreateTime"`
|
||||||
Updated int64 `gorm:"autoUpdateTime"`
|
Updated int64 `gorm:"autoUpdateTime"`
|
||||||
ViewRevision int64 `gorm:"not null"`
|
ViewRevision int64 `gorm:"not null"`
|
||||||
RemoteProfile int64
|
NotifiedView int64
|
||||||
RemoteContent int64
|
NotifiedContent int64
|
||||||
|
NotifiedProfile int64
|
||||||
Groups []Group `gorm:"many2many:card_groups;"`
|
Groups []Group `gorm:"many2many:card_groups;"`
|
||||||
Account Account `gorm:"references:Guid"`
|
Account Account `gorm:"references:Guid"`
|
||||||
}
|
}
|
||||||
@ -162,10 +164,19 @@ type Asset struct {
|
|||||||
Account Account
|
Account Account
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ArticleBlock struct {
|
||||||
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
|
ArticleBlockId string `gorm:"not null;index:articleblock,unique"`
|
||||||
|
AccountID uint `gorm:"not null;index:articleblock,unique"`
|
||||||
|
Revision int64 `gorm:"not null"`
|
||||||
|
Articles []Article
|
||||||
|
}
|
||||||
|
|
||||||
type Article struct {
|
type Article struct {
|
||||||
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
ID uint `gorm:"primaryKey;not null;unique;autoIncrement"`
|
||||||
ArticleId string `gorm:"not null;index:article,unique"`
|
ArticleId string `gorm:"not null;index:article,unique"`
|
||||||
AccountID uint `gorm:"not null;index:article,unique"`
|
AccountID uint `gorm:"not null;index:article,unique"`
|
||||||
|
ArticleBlockID uint `gorm:"not null;index:articleblock"`
|
||||||
Revision int64 `gorm:"not null"`
|
Revision int64 `gorm:"not null"`
|
||||||
DataType string `gorm:"index"`
|
DataType string `gorm:"index"`
|
||||||
Data string
|
Data string
|
||||||
|
@ -9,7 +9,7 @@ func TestAddArticle(t *testing.T) {
|
|||||||
var set *TestGroup
|
var set *TestGroup
|
||||||
var err error
|
var err error
|
||||||
var rev *Revision
|
var rev *Revision
|
||||||
var article Article
|
var articleEntry ArticleEntry
|
||||||
var contentRevision int64
|
var contentRevision int64
|
||||||
|
|
||||||
// setup testing group
|
// setup testing group
|
||||||
@ -22,7 +22,7 @@ func TestAddArticle(t *testing.T) {
|
|||||||
|
|
||||||
// create article
|
// create article
|
||||||
articleAccess := &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
articleAccess := &ArticleAccess{ Groups: []string{set.A.B.GroupId} }
|
||||||
assert.NoError(t, SendEndpointTest(AddArticle, nil, articleAccess, set.A.Token, &article))
|
assert.NoError(t, SendEndpointTest(AddArticle, nil, articleAccess, set.A.Token, &articleEntry))
|
||||||
|
|
||||||
// check revisions
|
// check revisions
|
||||||
rev = GetTestRevision(set.A.Revisions)
|
rev = GetTestRevision(set.A.Revisions)
|
||||||
|
@ -18,7 +18,7 @@ func TestGroupContact(t *testing.T) {
|
|||||||
var cardData CardData
|
var cardData CardData
|
||||||
var contactRevision int64
|
var contactRevision int64
|
||||||
var card Card
|
var card Card
|
||||||
var contactCardRevision int64
|
var contactViewRevision int64
|
||||||
var wsA *websocket.Conn
|
var wsA *websocket.Conn
|
||||||
var wsB *websocket.Conn
|
var wsB *websocket.Conn
|
||||||
var err error
|
var err error
|
||||||
@ -62,7 +62,7 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
contactCardRevision = card.ContentRevision
|
contactViewRevision = card.NotifiedView
|
||||||
|
|
||||||
// set contact group
|
// set contact group
|
||||||
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil)
|
r, w, _ = NewRequest("PUT", "/contact/cards/{cardId}/groups/{groupId}", nil)
|
||||||
@ -102,8 +102,8 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
assert.NotEqual(t, contactCardRevision, card.ContentRevision)
|
assert.NotEqual(t, contactViewRevision, card.NotifiedView)
|
||||||
contactCardRevision = card.ContentRevision
|
contactViewRevision = card.NotifiedView
|
||||||
|
|
||||||
// show group view
|
// show group view
|
||||||
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
||||||
@ -166,7 +166,7 @@ func TestGroupContact(t *testing.T) {
|
|||||||
SetBearerAuth(r, b)
|
SetBearerAuth(r, b)
|
||||||
GetCard(w, r)
|
GetCard(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &card))
|
assert.NoError(t, ReadResponse(w, &card))
|
||||||
assert.NotEqual(t, contactCardRevision, card.ContentRevision)
|
assert.NotEqual(t, contactViewRevision, card.NotifiedView)
|
||||||
|
|
||||||
// show group view
|
// show group view
|
||||||
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
r, w, _ = NewRequest("GET", "/share/groups", nil)
|
||||||
|
@ -26,7 +26,7 @@ func TestProfileNotification(t *testing.T) {
|
|||||||
GetCardView(w, r)
|
GetCardView(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &views))
|
assert.NoError(t, ReadResponse(w, &views))
|
||||||
assert.Equal(t, len(views), 1)
|
assert.Equal(t, len(views), 1)
|
||||||
profileRevision := views[0].RemoteProfile
|
profileRevision := views[0].NotifiedProfile
|
||||||
|
|
||||||
// app connects websocket
|
// app connects websocket
|
||||||
ws, err = StatusConnection(a, &revision);
|
ws, err = StatusConnection(a, &revision);
|
||||||
@ -55,5 +55,5 @@ func TestProfileNotification(t *testing.T) {
|
|||||||
GetCardView(w, r)
|
GetCardView(w, r)
|
||||||
assert.NoError(t, ReadResponse(w, &views))
|
assert.NoError(t, ReadResponse(w, &views))
|
||||||
assert.Equal(t, len(views), 1)
|
assert.Equal(t, len(views), 1)
|
||||||
assert.NotEqual(t, profileRevision, views[0].RemoteProfile)
|
assert.NotEqual(t, profileRevision, views[0].NotifiedProfile)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user