mirror of
https://github.com/balzack/databag.git
synced 2025-04-25 02:55:21 +00:00
loading remote cards
This commit is contained in:
parent
563a0ca46d
commit
84a5eaa727
8
app/client/web/src/contacts/Contacts.tsx
Normal file
8
app/client/web/src/contacts/Contacts.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import { Text } from '@mantine/core'
|
||||
import { useContacts } from './useContacts.hook';
|
||||
|
||||
export function Contacts() {
|
||||
const { state, actions } = useContacts();
|
||||
|
||||
return <Text>CONTACTS</Text>
|
||||
}
|
31
app/client/web/src/contacts/useContacts.hook.ts
Normal file
31
app/client/web/src/contacts/useContacts.hook.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { useState, useContext, useEffect } from 'react'
|
||||
import { AppContext } from '../context/AppContext'
|
||||
import { ContextType } from '../context/ContextType'
|
||||
import { Card } from 'databag-client-sdk'
|
||||
|
||||
export function useContacts() {
|
||||
const app = useContext(AppContext) as ContextType
|
||||
const [state, setState] = useState({
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updateState = (value: any) => {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const contact = app.state.session?.getContact();
|
||||
const setCards = (cards: Card[]) => {
|
||||
console.log("CARDS", cards);
|
||||
};
|
||||
contact.addCardListener(setCards);
|
||||
return () => {
|
||||
contact.removeCardListener(setCards);
|
||||
}
|
||||
}, [])
|
||||
|
||||
const actions = {
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
}
|
@ -10,6 +10,7 @@ import {
|
||||
} from '@tabler/icons-react'
|
||||
import { Settings } from '../settings/Settings'
|
||||
import { Identity } from '../identity/Identity'
|
||||
import { Contacts } from '../contacts/Contacts'
|
||||
import { useDisclosure } from '@mantine/hooks'
|
||||
|
||||
export function Session() {
|
||||
@ -17,11 +18,8 @@ export function Session() {
|
||||
const display = useContext(DisplayContext) as ContextType
|
||||
const [settings, { open: openSettings, close: closeSettings }] =
|
||||
useDisclosure(false)
|
||||
|
||||
const click = () => {
|
||||
console.log('SESSION DRAWER', openSettings)
|
||||
openSettings()
|
||||
}
|
||||
const [contacts, { open: openContacts, close: closeContacts }] =
|
||||
useDisclosure(false)
|
||||
|
||||
return (
|
||||
<div className={classes.session}>
|
||||
@ -29,6 +27,7 @@ export function Session() {
|
||||
<>
|
||||
<div className={classes.screen}>
|
||||
{tab === 'settings' && <Settings showLogout={true} />}
|
||||
{tab === 'contacts' && <Contacts />}
|
||||
</div>
|
||||
<div className={classes.tabs}>
|
||||
{tab === 'channels' && (
|
||||
@ -78,9 +77,18 @@ export function Session() {
|
||||
{display.state.layout === 'large' && (
|
||||
<div className={classes.display}>
|
||||
<div className={classes.left}>
|
||||
<Identity settings={click} contacts={() => {}} />
|
||||
<Identity settings={openSettings} contacts={openContacts} />
|
||||
</div>
|
||||
<div className={classes.right}></div>
|
||||
<Drawer
|
||||
opened={contacts}
|
||||
onClose={closeContacts}
|
||||
withCloseButton={false}
|
||||
size="sm"
|
||||
position="right"
|
||||
>
|
||||
<Contacts />
|
||||
</Drawer>
|
||||
<Drawer
|
||||
opened={settings}
|
||||
onClose={closeSettings}
|
||||
|
@ -3,9 +3,11 @@ import type { Contact, Logging } from './api';
|
||||
import type { Card, Topic, Asset, Tag, Profile, Participant} from './types';
|
||||
import type { CardEntity } from './entities';
|
||||
import type { ArticleRevision, ArticleDetail, ChannelRevision, ChannelSummary, ChannelDetail, CardRevision, CardNotification, CardProfile, CardDetail } from './items';
|
||||
import { defaultConfigItem } from './items';
|
||||
import { defaultCardItem } from './items';
|
||||
import { Store } from './store';
|
||||
import { getCards } from './net/getCards';
|
||||
import { getCardProfile } from './net/getCardProfile';
|
||||
import { getCardDetail } from './net/getCardDetail';
|
||||
|
||||
const CLOSE_POLL_MS = 100;
|
||||
const RETRY_POLL_MS = 2000;
|
||||
@ -140,13 +142,13 @@ export class ContactModule implements Contact {
|
||||
await this.sync();
|
||||
}
|
||||
|
||||
private getCardEntry(id: string) { item: CardItem, card: Card } {
|
||||
private getCardEntry(id: string) {
|
||||
const entry = this.cardEntries.get(id);
|
||||
if (entry) {
|
||||
return entry;
|
||||
}
|
||||
const item = JSON.parse(JSON.strifying(defaultCardItem));
|
||||
const card = this.setCard(item);
|
||||
const item = JSON.parse(JSON.stringify(defaultCardItem));
|
||||
const card = this.setCard(id, item);
|
||||
const cardEntry = { item, card };
|
||||
this.cardEntries.set(id, cardEntry);
|
||||
return cardEntry;
|
||||
@ -166,54 +168,58 @@ export class ContactModule implements Contact {
|
||||
if (data) {
|
||||
const entry = this.getCardEntry(id);
|
||||
|
||||
if (data.detailRevision !== entry.detail.revison) {
|
||||
// update detail
|
||||
entry.detail.revision = data.detailRevision;
|
||||
// store detail
|
||||
if (data.detailRevision !== entry.item.detail.revison) {
|
||||
const detail = data.cardDetail ? data.cardDetail : await getCardDetail(node, secure, token, id);
|
||||
const { status, statusUpdated, token } = detail;
|
||||
entry.item.detail = { revision: data.detailRevision, status, statusUpdated, token }
|
||||
entry.card = this.setCard(id, entry.item);
|
||||
this.store.setContactCardDetail(guid, id, entry.item.detail);
|
||||
}
|
||||
|
||||
if (data.profileRevision !== entry.profile.revision) {
|
||||
// update profile
|
||||
entry.profile.revision = data.profileRevision;
|
||||
// store profile
|
||||
if (data.profileRevision !== entry.item.profile.revision) {
|
||||
const profile = data.cardProfile ? data.cardProfile : await getCardProfile(node, secure, token, id);
|
||||
const { guid, handle, name, description, location, imageSet, node, seal } = profile;
|
||||
entry.item.profile = { revision: data.profileRevision, handle, guid, name, description, location, imageSet, node, seal };
|
||||
entry.card = this.setCard(id, entry.item);
|
||||
this.store.setContactCardProfile(guid, id, entry.item.profile);
|
||||
}
|
||||
|
||||
if (data.notifiedProfile !== entry.remote.profile) {
|
||||
entry.remote.profile = data.notifiedProfile;
|
||||
if (data.notifiedProfile !== entry.item.remote.profile) {
|
||||
entry.item.remote.profile = data.notifiedProfile;
|
||||
try {
|
||||
// sync profile
|
||||
}
|
||||
catch (err) {
|
||||
this.log.warn(err);
|
||||
entry.offsync = true;
|
||||
entry.item.offsync = true;
|
||||
// store offsync
|
||||
}
|
||||
// store remote
|
||||
}
|
||||
|
||||
if (data.notifiedArticle !== entry.remote.article) {
|
||||
entry.remote.article = data.notifiedArticle;
|
||||
if (data.notifiedArticle !== entry.item.remote.article) {
|
||||
entry.item.remote.article = data.notifiedArticle;
|
||||
try {
|
||||
// sync articles
|
||||
}
|
||||
catch (err) {
|
||||
this.log.warn(err);
|
||||
entry.offsync = true;
|
||||
entry.item.offsync = true;
|
||||
// store offsync
|
||||
}
|
||||
this.emitCardArticles(id);
|
||||
this.emitArticles(id);
|
||||
// store remote
|
||||
}
|
||||
|
||||
if (data.notifiedChannel !== entry.remote.channel) {
|
||||
entry.remote.channel = data.notifiedChannel;
|
||||
if (data.notifiedChannel !== entry.item.remote.channel) {
|
||||
entry.item.remote.channel = data.notifiedChannel;
|
||||
try {
|
||||
//sync channels
|
||||
}
|
||||
catch (err) {
|
||||
this.log.warn(err);
|
||||
entry.offsync = true;
|
||||
this.emitCardChannels(id);
|
||||
entry.item.offsync = true;
|
||||
this.emitChannels(id);
|
||||
// store offsync
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,26 @@
|
||||
import type { Profile } from './types';
|
||||
|
||||
export type CardDetailEntity = {
|
||||
status: string,
|
||||
statusUpdated: number,
|
||||
token: string,
|
||||
notes: string,
|
||||
groups: [ string ]
|
||||
}
|
||||
|
||||
export type CardProfileEntity = {
|
||||
guid: string,
|
||||
handle: string,
|
||||
name: string,
|
||||
description: string,
|
||||
location: string,
|
||||
imageSet: boolean,
|
||||
version: string,
|
||||
node: string,
|
||||
seal: string,
|
||||
revision: number,
|
||||
}
|
||||
|
||||
export type CardEntity = {
|
||||
id: string,
|
||||
revision: number,
|
||||
@ -9,25 +30,8 @@ export type CardEntity = {
|
||||
notifiedProfile: number,
|
||||
notifiedArticle: number,
|
||||
notifiedChannel: number,
|
||||
cardDetail?: {
|
||||
status: string,
|
||||
statusUpdated: number,
|
||||
token: string,
|
||||
notes: string,
|
||||
groups: [ string ]
|
||||
},
|
||||
cardProfile?: {
|
||||
guid: string,
|
||||
handle: string,
|
||||
name: string,
|
||||
description: string,
|
||||
location: string,
|
||||
imageSet: boolean,
|
||||
version: string,
|
||||
node: string,
|
||||
seal: string,
|
||||
revision: number,
|
||||
}
|
||||
cardDetail?: CardDetailEntity,
|
||||
cardProfile?: CardProfileEntity,
|
||||
}
|
||||
}
|
||||
|
||||
|
10
app/sdk/src/net/getCardDetail.ts
Normal file
10
app/sdk/src/net/getCardDetail.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
import { CardDetailEntity } from '../entities';
|
||||
|
||||
export async function getCardDetail(node: string, secure: boolean, token: string, cardId: string): Promise<CardDetailEntity> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/contact/cards/${cardId}/detail?agent=${token}`;
|
||||
const detail = await fetchWithTimeout(endpoint, { method: 'GET' })
|
||||
checkResponse(detail.status);
|
||||
return await detail.json();
|
||||
}
|
||||
|
10
app/sdk/src/net/getCardProfile.ts
Normal file
10
app/sdk/src/net/getCardProfile.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
import { CardProfileEntity } from '../entities';
|
||||
|
||||
export async function getCardProfile(node: string, secure: boolean, token: string, cardId: string): Promise<CardProfileEntity> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/contact/cards/${cardId}/profile?agent=${token}`;
|
||||
const profile = await fetchWithTimeout(endpoint, { method: 'GET' })
|
||||
checkResponse(profile.status);
|
||||
return await profile.json();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Login, ProfileEntity, defaultProfileEntity, ConfigEntity, defaultConfigEntity } from './entities';
|
||||
import type { ArticleRevision, ArticleDetail, ArticleItem, ChannelItem, CardItem, CardRevision, CardNotification, CardProfile, CardDetail, ChannelRevision, ChannelSummary, ChannelDetail } from './items';
|
||||
import type { ArticleRevision, ArticleDetail, ArticleItem, ChannelItem, CardItem, CardNotification, CardProfile, CardDetail, ChannelRevision, ChannelSummary, ChannelDetail } from './items';
|
||||
import type { Logging } from './logging';
|
||||
|
||||
export interface Store {
|
||||
@ -25,7 +25,7 @@ export interface Store {
|
||||
setContactRevision(guid: string, revision: number): Promise<void>;
|
||||
|
||||
getContacts(guid: string): Promise<{ cardId: string, item: CardItem }[]>;
|
||||
setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise<void>;
|
||||
setContactCardRevision(guid: string, cardId: string, revision: number): Promise<void>;
|
||||
setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise<void>;
|
||||
setContactCardDetail(guid: string, cardId: string, detail: CardDetail): Promise<void>;
|
||||
setContactCardBlocked(guid: string, cardId: string, blocked: boolean): Promise<void>;
|
||||
@ -170,7 +170,7 @@ export class OfflineStore implements Store {
|
||||
return [];
|
||||
}
|
||||
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise<void> {
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: number): Promise<void> {
|
||||
}
|
||||
|
||||
public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise<void> {
|
||||
@ -319,7 +319,7 @@ export class OnlineStore implements Store {
|
||||
return [];
|
||||
}
|
||||
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise<void> {
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: number): Promise<void> {
|
||||
}
|
||||
|
||||
public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise<void> {
|
||||
@ -442,7 +442,7 @@ export class NoStore implements Store {
|
||||
return [];
|
||||
}
|
||||
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: CardRevision): Promise<void> {
|
||||
public async setContactCardRevision(guid: string, cardId: string, revision: number): Promise<void> {
|
||||
}
|
||||
|
||||
public async setContactCardProfile(guid: string, cardId: string, profile: CardProfile): Promise<void> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user