mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 18:15:19 +00:00
implementing focus module
This commit is contained in:
parent
5ae031f268
commit
2ddf3e0d94
@ -1,7 +1,7 @@
|
||||
import { useState, useContext, useEffect, useRef } from 'react'
|
||||
import { AppContext } from '../context/AppContext'
|
||||
import { DisplayContext } from '../context/DisplayContext'
|
||||
import { Focus, Topic, AssetSource, HostingMode, TransformType } from 'databag-client-sdk'
|
||||
import { Focus, FocusDetail, Topic, AssetSource, HostingMode, TransformType } from 'databag-client-sdk'
|
||||
import { ContextType } from '../context/ContextType'
|
||||
|
||||
const img =
|
||||
@ -31,14 +31,14 @@ export function useConversation() {
|
||||
const setTopics = (topics: Topic[]) => {
|
||||
console.log(topics);
|
||||
}
|
||||
const setStatus = (status: string) => {
|
||||
console.log(status);
|
||||
const setDetail = (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => {
|
||||
console.log(focused);
|
||||
}
|
||||
focus.addTopicListener(setTopics);
|
||||
focus.addStatusListener(setStatus);
|
||||
focus.addDetailListener(setDetail);
|
||||
return () => {
|
||||
focus.removeTopicListener(setTopics);
|
||||
focus.removeStatusListener(setStatus);
|
||||
focus.removeDetailListener(setDetail);
|
||||
}
|
||||
}
|
||||
}, [app.state.focus]);
|
||||
|
13033
app/client/web/yarn.lock
13033
app/client/web/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
import type { Channel, Topic, AssetSource, Asset, Tag, Article, Group, Card, Profile, Call, Config, NodeConfig, NodeAccount, Participant } from './types';
|
||||
import type { Channel, Topic, AssetSource, Asset, Tag, Article, Group, Card, Profile, Call, FocusDetail, Config, NodeConfig, NodeAccount, Participant } from './types';
|
||||
|
||||
export interface Session {
|
||||
getSettings(): Settings;
|
||||
@ -138,8 +138,8 @@ export interface Focus {
|
||||
addTopicListener(ev: (topics: Topic[]) => void): void;
|
||||
removeTopicListener(ev: (topics: Topic[]) => void): void;
|
||||
|
||||
addStatusListener(ev: (status: string) => void): void;
|
||||
removeStatusListener(ev: (status: string) => void): void;
|
||||
addDetailListener(ev: (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => void): void;
|
||||
removeDetailListener(ev: (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => void): void;
|
||||
}
|
||||
|
||||
export interface Node {
|
||||
|
@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3';
|
||||
import type { Contact, Focus } from './api';
|
||||
import { Logging } from './logging';
|
||||
import { FocusModule } from './focus';
|
||||
import type { Card, Channel, Article, Topic, Asset, Tag, Profile, Participant } from './types';
|
||||
import type { Card, Channel, Article, Topic, Asset, Tag, FocusDetail, Profile, Participant } from './types';
|
||||
import { type CardEntity, avatar } from './entities';
|
||||
import type { ArticleDetail, ChannelSummary, ChannelDetail, CardProfile, CardDetail, CardItem, ChannelItem, ArticleItem } from './items';
|
||||
import { defaultCardItem, defaultChannelItem } from './items';
|
||||
@ -504,6 +504,20 @@ export class ContactModule implements Contact {
|
||||
};
|
||||
entry.item.unsealedDetail = null;
|
||||
await this.unsealChannelDetail(cardId, id, entry.item);
|
||||
if (this.focus) {
|
||||
const { dataType, data, enableImage, enableAudio, enableVideo, enableBinary } = detail;
|
||||
const sealed = dataType === 'sealed';
|
||||
const focusDetail = {
|
||||
sealed,
|
||||
dataType,
|
||||
data: sealed ? entry.item.unsealedDetail : data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(cardId, id, focusDetail);
|
||||
}
|
||||
entry.channel = this.setChannel(cardId, id, entry.item);
|
||||
await this.store.setContactCardChannelDetail(guid, cardId, id, entry.item.detail, entry.item.unsealedDetail);
|
||||
}
|
||||
@ -526,9 +540,9 @@ export class ContactModule implements Contact {
|
||||
this.setChannelUnread(cardId, id);
|
||||
entry.channel = this.setChannel(cardId, id, entry.item);
|
||||
await this.store.setContactCardChannelSummary(guid, cardId, id, entry.item.summary, entry.item.unsealedSummary);
|
||||
}
|
||||
if (this.focus) {
|
||||
await this.focus.setRevision(cardId, id, topicRevision);
|
||||
if (this.focus) {
|
||||
await this.focus.setRevision(cardId, id, topicRevision);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const channels = this.getChannelEntries(cardId);
|
||||
@ -632,6 +646,7 @@ export class ContactModule implements Contact {
|
||||
const channelsEntry = this.channelEntries.get(cardId);
|
||||
const channelEntry = channelsEntry?.get(channelId);
|
||||
if (cardEntry && channelEntry) {
|
||||
// allocate focus
|
||||
const node = cardEntry.item.profile.node;
|
||||
const guid = cardEntry.item.profile.guid;
|
||||
const token = cardEntry.item.detail.token;
|
||||
@ -640,6 +655,20 @@ export class ContactModule implements Contact {
|
||||
const sealEnabled = Boolean(this.seal);
|
||||
const insecure = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|:\d+$|$)){4}$/.test(node);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.media, cardId, channelId, this.guid, { node, secure: !insecure, token: `${guid}.${token}` }, channelKey, sealEnabled, revision, markRead, flagTopic);
|
||||
|
||||
// set current detail
|
||||
const { dataType, data, enableImage, enableAudio, enableVideo, enableBinary } = channelEntry.item.detail;
|
||||
const sealed = dataType === 'sealed';
|
||||
const focusDetail = {
|
||||
sealed,
|
||||
dataType,
|
||||
data: sealed ? channelEntry.item.unsealedDetail : data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(cardId, channelId, focusDetail);
|
||||
} else {
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.media, cardId, channelId, this.guid, null, null, false, 0, markRead, flagTopic);
|
||||
}
|
||||
@ -1022,6 +1051,19 @@ export class ContactModule implements Contact {
|
||||
if (item.channelKey) {
|
||||
const { data } = await this.crypto.aesDecrypt(subjectEncrypted, subjectIv, item.channelKey);
|
||||
item.unsealedDetail = data;
|
||||
if (this.focus) {
|
||||
const { dataType, enableImage, enableAudio, enableVideo, enableBinary } = item.detail;
|
||||
const focusDetail = {
|
||||
sealed: true,
|
||||
dataType,
|
||||
data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(cardId, channelId, focusDetail);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -2,7 +2,7 @@ import { EventEmitter } from 'eventemitter3';
|
||||
import type { Focus } from './api';
|
||||
import type { TopicItem, AssetItem, TopicDetail } from './items';
|
||||
import type { Topic, Asset, AssetSource, Participant } from './types';
|
||||
import { TransformType, HostingMode, AssetType } from './types';
|
||||
import { TransformType, HostingMode, AssetType, FocusDetail } from './types';
|
||||
import type { Logging } from './logging';
|
||||
import { Store } from './store';
|
||||
import { Crypto } from './crypto';
|
||||
@ -50,6 +50,7 @@ export class FocusModule implements Focus {
|
||||
private unsealAll: boolean;
|
||||
private markRead: ()=>Promise<void>;
|
||||
private flagChannelTopic: (id: string)=>Promise<void>;
|
||||
private focusDetail: FocusDetail | null;
|
||||
|
||||
private markers: Set<string>;
|
||||
|
||||
@ -79,6 +80,7 @@ export class FocusModule implements Focus {
|
||||
this.closing = false;
|
||||
this.closeMedia = [];
|
||||
this.nextRevision = null;
|
||||
this.focusDetail = null;
|
||||
this.loadMore = false;
|
||||
this.unsealAll = false;
|
||||
this.localComplete = false;
|
||||
@ -829,20 +831,36 @@ export class FocusModule implements Focus {
|
||||
this.emitter.emit('topic', topics);
|
||||
}
|
||||
|
||||
public addStatusListener(ev: (status: string) => void) {
|
||||
this.emitter.on('status', ev);
|
||||
const status = this.connection ? 'connected' : 'disconnected'
|
||||
ev(status);
|
||||
public addDetailListener(ev: (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => void) {
|
||||
const { cardId, channelId } = this;
|
||||
const access = Boolean(this.connection && (!this.focusDetail?.sealed || (this.sealEnabled && this.channelKey)))
|
||||
const detail = access ? this.focusDetail : null;
|
||||
this.emitter.on('detail', ev);
|
||||
ev({ cardId, channelId, detail });
|
||||
}
|
||||
|
||||
public removeStatusListener(ev: (status: string) => void) {
|
||||
this.emitter.off('status', ev);
|
||||
public removeDetailListener(ev: (focused: { cardId: string | null, channelId: string, detail: FocusDetail | null }) => void) {
|
||||
this.emitter.off('detail', ev);
|
||||
}
|
||||
|
||||
private emitDetail() {
|
||||
const { cardId, channelId } = this;
|
||||
const access = Boolean(this.connection && (!this.focusDetail?.sealed || (this.sealEnabled && this.channelKey)))
|
||||
const detail = access ? this.focusDetail : null;
|
||||
this.emitter.emit('detail', { cardId, channelId, detail });
|
||||
}
|
||||
|
||||
public disconnect(cardId: string | null, channelId: string) {
|
||||
if (cardId === this.cardId && channelId === this.channelId) {
|
||||
this.connection = null;
|
||||
this.emitStatus();
|
||||
this.emitDetail();
|
||||
}
|
||||
}
|
||||
|
||||
public setDetail(cardId: string | null, channelId: string, detail: FocusDetail) {
|
||||
if (cardId === this.cardId && channelId === this.channelId) {
|
||||
this.focusDetail = detail;
|
||||
this.emitDetail();
|
||||
}
|
||||
}
|
||||
|
||||
@ -856,6 +874,7 @@ export class FocusModule implements Focus {
|
||||
public async setSealEnabled(enable: boolean) {
|
||||
this.sealEnabled = enable;
|
||||
this.unsealAll = true;
|
||||
this.emitDetail();
|
||||
await this.sync();
|
||||
}
|
||||
|
||||
@ -863,6 +882,7 @@ export class FocusModule implements Focus {
|
||||
if (cardId === this.cardId && channelId === this.channelId) {
|
||||
this.channelKey = channelKey;
|
||||
this.unsealAll = true;
|
||||
this.emitDetail();
|
||||
await this.sync();
|
||||
}
|
||||
}
|
||||
@ -877,11 +897,6 @@ export class FocusModule implements Focus {
|
||||
});
|
||||
}
|
||||
|
||||
private emitStatus() {
|
||||
const status = this.connection ? 'connected' : 'disconnected'
|
||||
this.emitter.emit('status', status);
|
||||
}
|
||||
|
||||
private getTopicData(item: TopicItem): { data: any, assets: AssetItem[] } {
|
||||
const topicDetail = item.detail.sealed ? item.unsealedDetail : item.detail.data;
|
||||
const { revision } = item.detail;
|
||||
|
@ -141,6 +141,20 @@ export class StreamModule {
|
||||
entry.item.unsealedDetail = null;
|
||||
await this.unsealChannelDetail(id, entry.item);
|
||||
entry.channel = this.setChannel(id, entry.item);
|
||||
if (this.focus) {
|
||||
const { dataType, data, enableImage, enableAudio, enableVideo, enableBinary } = detail;
|
||||
const sealed = dataType === 'sealed';
|
||||
const focusDetail = {
|
||||
sealed,
|
||||
dataType,
|
||||
data: sealed ? entry.item.unsealedDetail : data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(null, id, focusDetail);
|
||||
}
|
||||
await this.store.setContentChannelDetail(guid, id, entry.item.detail, entry.item.unsealedDetail);
|
||||
}
|
||||
|
||||
@ -375,8 +389,6 @@ export class StreamModule {
|
||||
focus.close();
|
||||
}
|
||||
|
||||
const entry = this.channelEntries.get(channelId);
|
||||
|
||||
const markRead = async () => {
|
||||
try {
|
||||
await this.setUnreadChannel(channelId, false);
|
||||
@ -390,15 +402,26 @@ export class StreamModule {
|
||||
await addFlag(node, secure, guid, { channelId, topicId });
|
||||
}
|
||||
|
||||
const entry = this.channelEntries.get(channelId);
|
||||
const channelKey = entry ? entry.item.channelKey : null;
|
||||
const revision = entry ? entry.item.summary.revision : 0;
|
||||
const sealEnabled = Boolean(this.seal);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.media, null, channelId, this.guid, { node, secure, token }, channelKey, sealEnabled, revision, markRead, flagTopic);
|
||||
|
||||
if (entry) {
|
||||
const channelKey = entry.item.channelKey;
|
||||
const sealEnabled = Boolean(this.seal);
|
||||
const revision = entry.item.summary.revision;
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.media, null, channelId, this.guid, { node, secure, token }, channelKey, sealEnabled, revision, markRead, flagTopic);
|
||||
const { dataType, data, enableImage, enableAudio, enableVideo, enableBinary } = entry.item.detail;
|
||||
const sealed = dataType === 'sealed';
|
||||
const focusDetail = {
|
||||
sealed,
|
||||
dataType,
|
||||
data: sealed ? entry.item.unsealedDetail : data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(null, channelId, focusDetail);
|
||||
}
|
||||
else {
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.media, null, channelId, this.guid, null, null, false, 0, markRead, flagTopic);
|
||||
}
|
||||
|
||||
return this.focus;
|
||||
}
|
||||
@ -542,6 +565,19 @@ export class StreamModule {
|
||||
if (item.channelKey) {
|
||||
const { data } = await this.crypto.aesDecrypt(subjectEncrypted, subjectIv, item.channelKey);
|
||||
item.unsealedDetail = data;
|
||||
if (this.focus) {
|
||||
const { dataType, enableImage, enableAudio, enableVideo, enableBinary } = item.detail;
|
||||
const focusDetail = {
|
||||
sealed: true,
|
||||
dataType,
|
||||
data,
|
||||
enableImage,
|
||||
enableAudio,
|
||||
enableVideo,
|
||||
enableBinary,
|
||||
}
|
||||
this.focus.setDetail(null, channelId, focusDetail);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -65,6 +65,16 @@ export type Channel = {
|
||||
members: Member[];
|
||||
};
|
||||
|
||||
export type FocusDetail = {
|
||||
sealed: boolean;
|
||||
dataType: string;
|
||||
data: any;
|
||||
enableImage: boolean;
|
||||
enableAudio: boolean;
|
||||
enableVideo: boolean;
|
||||
enableBinary: boolean;
|
||||
}
|
||||
|
||||
export type Member = {
|
||||
guid: string;
|
||||
//pushEnabled: boolean;
|
||||
|
Loading…
x
Reference in New Issue
Block a user