syncronizing cards

This commit is contained in:
Roland Osborne 2022-04-02 23:30:49 -07:00
parent 18ce5f311b
commit f8824c6afe
7 changed files with 202 additions and 46 deletions

View File

@ -1019,8 +1019,6 @@ paths:
- contact
description: Get list of cards. Access granted to app tokens of account holder.
operationId: get-cards
security:
- bearerAuth: []
parameters:
- name: revision
in: query
@ -1028,6 +1026,12 @@ paths:
required: false
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: successful operation
@ -1054,8 +1058,13 @@ paths:
- contact
description: Add a contact card. Access granted to app tokens of account holder.
operationId: add-card
security:
- bearerAuth: []
parameters:
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1078,8 +1087,6 @@ paths:
- contact
description: Remove card entry. Access granted to app tokens of account holder.
operationId: remove-card
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1087,6 +1094,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1105,8 +1118,6 @@ paths:
- contact
description: Updated connected status of contact. Access granted to app tokens of account holder.
operationId: set-card-status
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1114,6 +1125,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
- name: token
in: query
description: token for accessing card
@ -1172,8 +1189,6 @@ paths:
- contact
description: Get message for connecting to other contacts. Access granted to app tokens for account holder.
operationId: get-open-message
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1181,6 +1196,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1228,8 +1249,6 @@ paths:
- contact
description: Get message for closing connection with contact. Access granted to app tokens for account holder.
operationId: get-close-message
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1237,6 +1256,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: successful operation
@ -1280,8 +1305,6 @@ paths:
- contact
description: Get profile of card entry. Access granted to app tokens of account holder.
operationId: get-card-profile
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1289,6 +1312,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: successful operation
@ -1309,8 +1338,6 @@ paths:
- contact
description: Set profile of card entry. Access granted to app tokens of account holder.
operationId: set-card-profile
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1318,6 +1345,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1345,8 +1378,6 @@ paths:
- contact
description: Get image of card profile. Access granted to app tokens of account holder.
operationId: get-card-profile-image
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1354,6 +1385,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1379,8 +1416,6 @@ paths:
- contact
description: Get specified card detail. Access granted to app tokens for account holder.
operationId: get-card-detail
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1388,6 +1423,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1410,8 +1451,6 @@ paths:
- contact
description: Update card notes for specified card. Access granted to app tokens for account holder.
operationId: set-card-notes
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1419,6 +1458,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1444,8 +1489,6 @@ paths:
- contact
description: Clear notes for specified card. Access granted to app tokens of account holder.
operationId: clear-card-notes
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1453,6 +1496,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1475,8 +1524,6 @@ paths:
- contact
description: Set sharing group for contact. Access granted to app tokens for account holder.
operationId: set-card-group
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1490,6 +1537,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1510,8 +1563,6 @@ paths:
- contact
description: Clear sharing group for card. Access granted to app tokens for account holder.
operationId: clear-card-group
security:
- bearerAuth: []
parameters:
- name: cardId
in: path
@ -1525,6 +1576,12 @@ paths:
required: true
schema:
type: string
- name: agent
in: query
description: agent token
required: false
schema:
type: string
responses:
'200':
description: success
@ -1547,8 +1604,13 @@ paths:
- contact
description: Set profile revision for contact. This is intend to be invoked automatically anytime a contact updates their profile. Access granted to contact tokens.
operationId: set-profile-revision
security:
- bearerAuth: []
parameters:
- name: contact
in: query
description: contact token
required: false
schema:
type: string
responses:
'200':
description: revision set
@ -1571,8 +1633,13 @@ paths:
- contact
description: Set artcile 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-article-revision
security:
- bearerAuth: []
parameters:
- name: contact
in: query
description: contact token
required: false
schema:
type: string
responses:
'200':
description: revision set
@ -1595,8 +1662,13 @@ paths:
- contact
description: Set channel 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-channel-revision
security:
- bearerAuth: []
parameters:
- name: contact
in: query
description: contact token
required: false
schema:
type: string
responses:
'200':
description: revision set
@ -1619,8 +1691,13 @@ paths:
- 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: []
parameters:
- name: contact
in: query
description: contact token
required: false
schema:
type: string
responses:
'200':
description: revision set
@ -3749,3 +3826,4 @@ components:

View File

@ -10,7 +10,7 @@ import (
func GetCardDetail(w http.ResponseWriter, r *http.Request) {
account, code, err := BearerAppToken(r, false);
account, code, err := ParamAgentToken(r, false);
if err != nil {
ErrResponse(w, code, err)
return

View File

@ -10,7 +10,7 @@ import (
func GetCardProfile(w http.ResponseWriter, r *http.Request) {
account, code, err := BearerAppToken(r, false);
account, code, err := ParamAgentToken(r, false);
if err != nil {
ErrResponse(w, code, err)
return

View File

@ -10,7 +10,7 @@ func GetCards(w http.ResponseWriter, r *http.Request) {
var cardRevisionSet bool
var cardRevision int64
account, code, err := BearerAppToken(r, false);
account, code, err := ParamAgentToken(r, false);
if err != nil {
ErrResponse(w, code, err)
return

View File

@ -426,11 +426,10 @@ func GetCardToken(account string, cardId string) (token string, err error) {
vars := make(map[string]string)
vars["cardId"] = cardId
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/detail", nil); err != nil {
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/detail?agent=" + account, nil); err != nil {
return
}
r = mux.SetURLVars(r, vars)
SetBearerAuth(r, account)
GetCardDetail(w, r)
if err = ReadResponse(w, &cardDetail); err != nil {
return
@ -440,11 +439,10 @@ func GetCardToken(account string, cardId string) (token string, err error) {
return
}
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/profile", nil); err != nil {
if r, w, err = NewRequest("GET", "/contact/cards/{cardId}/profile?agent=" + account, nil); err != nil {
return
}
r = mux.SetURLVars(r, vars)
SetBearerAuth(r, account)
GetCardProfile(w, r)
if err = ReadResponse(w, &cardProfile); err != nil {
return
@ -459,10 +457,9 @@ func GetCardId(account string, guid string) (cardId string, err error) {
var w *httptest.ResponseRecorder
var cards []Card
if r, w, err = NewRequest("GET", "/contact/cards", nil); err != nil {
if r, w, err = NewRequest("GET", "/contact/cards?agent=" + account, nil); err != nil {
return
}
SetBearerAuth(r, account)
GetCards(w, r)
if err = ReadResponse(w, &cards); err != nil {
return

View File

@ -98,3 +98,27 @@ export async function getListing(server) {
return await listing.json();
}
export async function getCards(token, revision) {
let param = "?agent=" + token
if (revision != null) {
param += '&revision=' + revision
}
let cards = await fetchWithTimeout('/contact/cards' + param, { method: 'GET', timeout: FETCH_TIMEOUT });
checkResponse(cards)
return await cards.json()
}
export async function getCardProfile(token, cardId) {
let param = "?agent=" + token
let profile = await fetchWithTimeout(`/contact/cards/${cardId}/profile${param}`, { method: 'GET', timeout: FETCH_TIMEOUT });
checkResponse(profile);
return await profile.json()
}
export async function getCardDetail(token, cardId) {
let param = "?agent=" + token
let detail = await fetchWithTimeout(`/contact/cards/${cardId}/detail${param}`, { method: 'GET', timeout: FETCH_TIMEOUT });
checkResponse(detail);
return await detail.json()
}

View File

@ -1,5 +1,5 @@
import { useEffect, useState, useRef } from 'react';
import { getListingImageUrl, getListing, setProfileImage, setProfileData, getProfileImageUrl, getAccountStatus, setAccountSearchable, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
import { getCards, getCardProfile, getCardDetail, getListingImageUrl, getListing, setProfileImage, setProfileData, getProfileImageUrl, getAccountStatus, setAccountSearchable, getProfile, getGroups, getAvailable, getUsername, setLogin, createAccount } from './fetchUtil';
async function updateAccount(token, updateData) {
let status = await getAccountStatus(token);
@ -19,6 +19,53 @@ async function updateGroups(token, revision, groupMap, updateData) {
updateData({ groups: Array.from(groupMap.values()) });
}
async function updateCards(token, revision, cardMap, updateData) {
let cards = await getCards(token, revision);
for (let card of cards) {
let cur = cardMap.get(card.id);
if (cur == null) {
cur = { id: card.id, data: {} }
}
if (cur.data.DetailRevision != card.data.DetailRevision) {
if (card.data.CardDetail != null) {
cur.data.CardDetail = card.data.CardDetail;
}
else {
cur.data.CardDetail = await getCardDetail(token, card.id);
}
cur.data.DetailRevision = card.data.DetailRevision;
}
if (cur.data.ProfileRevision != card.data.ProfileRevision) {
if (cur.data.CardProfile != null) {
cur.data.CardProfile = card.data.CardProfile;
}
else {
cur.data.CardProfile = await getCardProfile(token, card.id);
}
cur.data.ProfileRevision = card.data.ProfileRevision;
}
if (cur.data.NotifiedProfile != card.data.NotifiedProfile) {
// update remote profile
cur.data.NotifiedProfile = card.data.NotifiedProfile;
}
if (cur.data.NotifiedView != card.data.NotifiedView) {
// update remote articles and channels
cur.data.NotifiedArticle = card.data.NotifiedArticle;
cur.data.NotifiedChannel = card.data.NotifiedChannel;
cur.data.NotifiedView = card.data.NotifiedView;
}
if (cur.data.NotifiedArticle != card.data.NotifiedArticle) {
// update remote articles
cur.data.NotifiedArticle = card.data.NotifiedArticle;
}
if (cur.data.NotifiedChannel != card.data.NotifiedChannel) {
// update remote channels
cur.data.NotifiedChannel = card.data.NotifiedChannel;
}
cur.revision = card.revision;
}
}
async function appCreate(username, password, updateState, setWebsocket) {
await createAccount(username, password);
let access = await setLogin(username, password)
@ -48,7 +95,9 @@ export function useAppContext() {
const groupRevision = useRef(null);
const accountRevision = useRef(null);
const profileRevision = useRef(null);
const cardRevision = useRef(null);
const cards = useRef(new Map());
const groups = useRef(new Map());
const delay = useRef(2);
@ -68,6 +117,8 @@ export function useAppContext() {
revision.current = null;
profileRevision.current = null;
groupRevision.current = null;
cardRevision.current = null;
cards.current = new Map();
groups.current = new Map();
setState({});
}
@ -125,6 +176,12 @@ export function useAppContext() {
groupRevision.current = rev.group
}
// update card status if revision changed
if (rev.card != cardRevision.current) {
await updateCards(token, cardRevision.current, cards.current, updateData);
cardRevision.current = rev.card
}
// update account status if revision changed
if (rev.account != accountRevision.current) {
await updateAccount(token, updateData)