mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 18:15:19 +00:00
adding media files interface
This commit is contained in:
parent
f5c8cb7c68
commit
29e868bd22
12
app/client/web/src/MediaFiles.ts
Normal file
12
app/client/web/src/MediaFiles.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Files } from 'databag-client-sdk'
|
||||
|
||||
export class MediaFiles implements Files {
|
||||
public async read(source: any): Promise<{ size: number, getData: (position: number, length: number)=>Promise<string> }> {
|
||||
return { size: 0, getData: async (position: number, length: number)=>('') };
|
||||
}
|
||||
|
||||
public async write(): Promise<{ setData: (data: string)=>Promise<void>, getPath: ()=>Promise<string> }> {
|
||||
return { setData: async (data: string)=>{}, getPath: async ()=>('') };
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,9 @@ import { useState, useEffect, useRef } from 'react'
|
||||
import { DatabagSDK, Session, Focus } from 'databag-client-sdk'
|
||||
import { SessionStore } from '../SessionStore'
|
||||
import { WebCrypto } from '../WebCrypto'
|
||||
import { MediaFiles } from '../MediaFiles'
|
||||
|
||||
const databag = new DatabagSDK({ tagBatch: 32, topicBatch: 32, articleTypes: [], channelTypes: ['sealed', 'superbasic'] }, new WebCrypto())
|
||||
const databag = new DatabagSDK({ tagBatch: 32, topicBatch: 32, articleTypes: [], channelTypes: ['sealed', 'superbasic'] }, new WebCrypto(), new MediaFiles())
|
||||
|
||||
export function useAppContext() {
|
||||
const sdk = useRef(databag)
|
||||
|
@ -8,6 +8,7 @@ import type { ArticleDetail, ChannelSummary, ChannelDetail, CardProfile, CardDet
|
||||
import { defaultCardItem, defaultChannelItem } from './items';
|
||||
import { Store } from './store';
|
||||
import { Crypto } from './crypto';
|
||||
import { Files } from './files';
|
||||
import { getCards } from './net/getCards';
|
||||
import { getCardProfile } from './net/getCardProfile';
|
||||
import { getCardDetail } from './net/getCardDetail';
|
||||
@ -51,6 +52,7 @@ export class ContactModule implements Contact {
|
||||
private focus: FocusModule | null;
|
||||
|
||||
private crypto: Crypto | null;
|
||||
private files: Files | null;
|
||||
private store: Store;
|
||||
private revision: number;
|
||||
private nextRevision: number | null;
|
||||
@ -72,7 +74,7 @@ export class ContactModule implements Contact {
|
||||
// view of channels
|
||||
private channelEntries: Map<string, Map<string, { item: ChannelItem; channel: Channel }>>;
|
||||
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, guid: string, token: string, node: string, secure: boolean, articleTypes: string[], channelTypes: string[]) {
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, files: Files | null, guid: string, token: string, node: string, secure: boolean, articleTypes: string[], channelTypes: string[]) {
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
this.node = node;
|
||||
@ -80,6 +82,7 @@ export class ContactModule implements Contact {
|
||||
this.log = log;
|
||||
this.store = store;
|
||||
this.crypto = crypto;
|
||||
this.files = files;
|
||||
this.emitter = new EventEmitter();
|
||||
this.articleTypes = articleTypes;
|
||||
this.channelTypes = channelTypes;
|
||||
@ -618,9 +621,9 @@ export class ContactModule implements Contact {
|
||||
const channelKey = channelEntry.item.channelKey;
|
||||
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, cardId, channelId, this.guid, { node, secure: !insecure, token: `${guid}.${token}` }, channelKey, sealEnabled, revision);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.files, cardId, channelId, this.guid, { node, secure: !insecure, token: `${guid}.${token}` }, channelKey, sealEnabled, revision);
|
||||
} else {
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, cardId, channelId, this.guid, null, null, false, 0);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.files, cardId, channelId, this.guid, null, null, false, 0);
|
||||
}
|
||||
return this.focus;
|
||||
}
|
||||
|
4
app/sdk/src/files.ts
Normal file
4
app/sdk/src/files.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface Files {
|
||||
read(source: any): Promise<{ size: number, getData: (position: number, length: number)=>Promise<string> }>;
|
||||
write(): Promise<{ setData: (data: string)=>Promise<void>, getPath: ()=>Promise<string> }>;
|
||||
}
|
@ -5,6 +5,8 @@ import type { Topic, Asset, AssetSource, Participant } from './types';
|
||||
import type { Logging } from './logging';
|
||||
import { Store } from './store';
|
||||
import { Crypto } from './crypto';
|
||||
import { Files } from './files';
|
||||
import { Files } from './files';
|
||||
import { HostingMode } from './types';
|
||||
import { defaultTopicItem } from './items';
|
||||
import { getChannelTopics } from './net/getChannelTopics';
|
||||
@ -27,6 +29,7 @@ export class FocusModule implements Focus {
|
||||
private log: Logging;
|
||||
private emitter: EventEmitter;
|
||||
private crypto: Crypto | null;
|
||||
private files: Files | null;
|
||||
private store: Store;
|
||||
private guid: string;
|
||||
private connection: { node: string; secure: boolean; token: string } | null;
|
||||
@ -46,13 +49,14 @@ export class FocusModule implements Focus {
|
||||
// view of topics
|
||||
private topicEntries: Map<string, { item: TopicItem; topic: Topic }>;
|
||||
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, cardId: string | null, channelId: string, guid: string, connection: { node: string; secure: boolean; token: string } | null, channelKey: string, sealEnabled: boolean, revision: number) {
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, files: Files | null, cardId: string | null, channelId: string, guid: string, connection: { node: string; secure: boolean; token: string } | null, channelKey: string, sealEnabled: boolean, revision: number) {
|
||||
this.cardId = cardId;
|
||||
this.channelId = channelId;
|
||||
this.log = log;
|
||||
this.emitter = new EventEmitter();
|
||||
this.store = store;
|
||||
this.crypto = crypto;
|
||||
this.files = files;
|
||||
this.guid = guid;
|
||||
this.connection = connection;
|
||||
this.channelKey = channelKey;
|
||||
@ -293,6 +297,8 @@ export class FocusModule implements Focus {
|
||||
// encrypt
|
||||
// add confirmed topic
|
||||
|
||||
|
||||
|
||||
if (files.length == 0) {
|
||||
if (sealed) {
|
||||
const decrypted = subject([]);
|
||||
@ -311,6 +317,34 @@ export class FocusModule implements Focus {
|
||||
}
|
||||
} else {
|
||||
const topicId = await this.addRemoteChannelTopic(type, {}, false);
|
||||
if (sealed) {
|
||||
const { sealEnabled, channelKey, crypto } = this;
|
||||
if (!sealEnabled || !channelKey || !crypto) {
|
||||
throw new Error('encryption not set');
|
||||
}
|
||||
const assetContext = [] as { assetId: string, context: string }[];
|
||||
const assetItems = [] as AssetItem[];
|
||||
for (const asset of assets) {
|
||||
for (const transform of asset.transforms) {
|
||||
if (transform.type === TransformType.Thumb && transform.thumb) {
|
||||
const assetItem = {
|
||||
assetId: `${assetList.size}`,
|
||||
mimeType: 'image',
|
||||
encrytped: true,
|
||||
hosting: HostingMode.inline,
|
||||
inline: await transform.thumb(),
|
||||
}
|
||||
const { assetId, context } = assetItem;
|
||||
assetContext.push({ assetId, context });
|
||||
assetItems.push(assetItem);
|
||||
} else if (transform.type === TransformType.Copy) {
|
||||
} else {
|
||||
throw new Error('transform not supported')
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
for (const asset of files) {
|
||||
const upload = await this.uploadFile(asset.source, ['ithumb;photo', 'ilg;photo'], topicId, (progress: number) => {
|
||||
|
@ -15,23 +15,27 @@ import type { Session, Node, Contributor } from './api';
|
||||
import type { Params, SessionParams } from './types';
|
||||
import type { Login } from './entities';
|
||||
import type { Crypto } from './crypto';
|
||||
import type { Files } from './files';
|
||||
import type { WebStore, SqlStore } from './store';
|
||||
|
||||
export * from './api';
|
||||
export * from './types';
|
||||
export { WebStore, SqlStore } from './store';
|
||||
export { Crypto } from './crypto';
|
||||
export { Files } from './files';
|
||||
|
||||
export class DatabagSDK {
|
||||
private log: Logging;
|
||||
private crypto: Crypto | null;
|
||||
private files: Files | null;
|
||||
private store: Store;
|
||||
private params: Params;
|
||||
|
||||
constructor(params: Params, crypto?: Crypto, log?: Logging) {
|
||||
constructor(params: Params, crypto?: Crypto, files?: Files, log?: Logging) {
|
||||
this.store = new NoStore();
|
||||
this.params = params;
|
||||
this.crypto = crypto ? crypto : null;
|
||||
this.files = files ? files : null;
|
||||
this.log = log ? log : new ConsoleLogging();
|
||||
this.log.info('databag sdk');
|
||||
}
|
||||
@ -40,14 +44,14 @@ export class DatabagSDK {
|
||||
const { articleTypes, channelTypes } = this.params;
|
||||
this.store = new OfflineStore(this.log, sql);
|
||||
const login = await this.store.init();
|
||||
return login ? new SessionModule(this.store, this.crypto, this.log, login.guid, login.token, login.node, login.secure, login.timestamp, articleTypes, channelTypes) : null;
|
||||
return login ? new SessionModule(this.store, this.crypto, this.log, this.files, login.guid, login.token, login.node, login.secure, login.timestamp, articleTypes, channelTypes) : null;
|
||||
}
|
||||
|
||||
public async initOnlineStore(web: WebStore): Promise<Session | null> {
|
||||
const { articleTypes, channelTypes } = this.params;
|
||||
this.store = new OnlineStore(this.log, web);
|
||||
const login = await this.store.init();
|
||||
return login ? new SessionModule(this.store, this.crypto, this.log, login.guid, login.token, login.node, login.secure, login.timestamp, articleTypes, channelTypes) : null;
|
||||
return login ? new SessionModule(this.store, this.crypto, this.log, this.files, login.guid, login.token, login.node, login.secure, login.timestamp, articleTypes, channelTypes) : null;
|
||||
}
|
||||
|
||||
public async available(node: string, secure: boolean): Promise<number> {
|
||||
@ -71,7 +75,7 @@ export class DatabagSDK {
|
||||
pushSupported,
|
||||
};
|
||||
await this.store.setLogin(login);
|
||||
return new SessionModule(this.store, this.crypto, this.log, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
return new SessionModule(this.store, this.crypto, this.log, this.files, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
}
|
||||
|
||||
public async access(node: string, secure: boolean, token: string, params: SessionParams): Promise<Session> {
|
||||
@ -87,7 +91,7 @@ export class DatabagSDK {
|
||||
pushSupported,
|
||||
};
|
||||
await this.store.setLogin(login);
|
||||
return new SessionModule(this.store, this.crypto, this.log, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
return new SessionModule(this.store, this.crypto, this.log, this.files, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
}
|
||||
|
||||
public async create(handle: string, password: string, node: string, secure: boolean, token: string | null, params: SessionParams): Promise<Session> {
|
||||
@ -104,7 +108,7 @@ export class DatabagSDK {
|
||||
pushSupported,
|
||||
};
|
||||
await this.store.setLogin(login);
|
||||
return new SessionModule(this.store, this.crypto, this.log, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
return new SessionModule(this.store, this.crypto, this.log, this.files, guid, appToken, node, secure, created, articleTypes, channelTypes);
|
||||
}
|
||||
|
||||
public async remove(session: Session): Promise<void> {
|
||||
|
@ -171,11 +171,11 @@ export type TopicItem = {
|
||||
};
|
||||
|
||||
export type AssetItem = {
|
||||
assetIndex: number;
|
||||
assetId: string;
|
||||
mimeType: string;
|
||||
encrypted: boolean;
|
||||
hosting: string;
|
||||
extension: string;
|
||||
encrypted: boolean;
|
||||
hosting: HostingMode;
|
||||
split?: { blockId: string, blockIv: string }[];
|
||||
basic?: string;
|
||||
inline?: string;
|
||||
|
@ -18,11 +18,13 @@ import { Call } from './types';
|
||||
import { Store } from './store';
|
||||
import type { Logging } from './logging';
|
||||
import type { Crypto } from './crypto';
|
||||
import type { Files } from './files';
|
||||
|
||||
export class SessionModule implements Session {
|
||||
private emitter: EventEmitter;
|
||||
private store: Store;
|
||||
private crypto: Crypto | null;
|
||||
private files: Files | null;
|
||||
private log: Logging;
|
||||
private guid: string;
|
||||
private token: string;
|
||||
@ -42,11 +44,12 @@ export class SessionModule implements Session {
|
||||
private channelTypes: string[];
|
||||
private articleTypes: string[];
|
||||
|
||||
constructor(store: Store, crypto: Crypto | null, log: Logging, guid: string, token: string, node: string, secure: boolean, loginTimestamp: number, articleTypes: string[], channelTypes: string[]) {
|
||||
constructor(store: Store, crypto: Crypto | null, log: Logging, files: Files | null, guid: string, token: string, node: string, secure: boolean, loginTimestamp: number, articleTypes: string[], channelTypes: string[]) {
|
||||
log.info('new databag session');
|
||||
|
||||
this.store = store;
|
||||
this.crypto = crypto;
|
||||
this.files = files;
|
||||
this.log = log;
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
@ -60,10 +63,10 @@ export class SessionModule implements Session {
|
||||
|
||||
this.identity = new IdentityModule(log, this.store, guid, token, node, secure);
|
||||
this.settings = new SettingsModule(log, this.store, this.crypto, guid, token, node, secure);
|
||||
this.contact = new ContactModule(log, this.store, this.crypto, guid, token, node, secure, articleTypes, channelTypes);
|
||||
this.contact = new ContactModule(log, this.store, this.crypto, this.files, guid, token, node, secure, articleTypes, channelTypes);
|
||||
this.alias = new AliasModule(log, this.settings, this.store, guid, token, node, secure);
|
||||
this.attribute = new AttributeModule(log, this.settings, this.store, guid, token, node, secure);
|
||||
this.stream = new StreamModule(log, this.store, this.crypto, guid, token, node, secure, channelTypes);
|
||||
this.stream = new StreamModule(log, this.store, this.crypto, this.files, guid, token, node, secure, channelTypes);
|
||||
this.content = new ContentModule(log, this.crypto, this.contact, this.stream);
|
||||
this.ring = new RingModule(log);
|
||||
this.connection = new Connection(log, token, node, secure);
|
||||
|
@ -6,6 +6,7 @@ import type { ChannelItem } from './items';
|
||||
import type { Channel, Topic, Asset, Tag, Participant } from './types';
|
||||
import { Store } from './store';
|
||||
import { Crypto } from './crypto';
|
||||
import { Files } from './files';
|
||||
import { addChannel } from './net/addChannel';
|
||||
import { removeChannel } from './net/removeChannel';
|
||||
import { getChannels } from './net/getChannels';
|
||||
@ -26,6 +27,7 @@ export class StreamModule {
|
||||
private log: Logging;
|
||||
private store: Store;
|
||||
private crypto: Crypto | null;
|
||||
private files: Files | null;
|
||||
private guid: string;
|
||||
private token: string;
|
||||
private node: string;
|
||||
@ -44,7 +46,7 @@ export class StreamModule {
|
||||
// view of channels
|
||||
private channelEntries: Map<string, { item: ChannelItem; channel: Channel }>;
|
||||
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, guid: string, token: string, node: string, secure: boolean, channelTypes: string[]) {
|
||||
constructor(log: Logging, store: Store, crypto: Crypto | null, files: Files | null, guid: string, token: string, node: string, secure: boolean, channelTypes: string[]) {
|
||||
this.guid = guid;
|
||||
this.token = token;
|
||||
this.node = node;
|
||||
@ -52,6 +54,7 @@ export class StreamModule {
|
||||
this.log = log;
|
||||
this.store = store;
|
||||
this.crypto = crypto;
|
||||
this.files = files;
|
||||
this.focus = null;
|
||||
this.seal = null;
|
||||
this.unsealAll = false;
|
||||
@ -376,10 +379,10 @@ export class StreamModule {
|
||||
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, null, channelId, this.guid, { node, secure, token }, channelKey, sealEnabled, revision);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.files, null, channelId, this.guid, { node, secure, token }, channelKey, sealEnabled, revision);
|
||||
}
|
||||
else {
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, cardId, channelId, this.guid, null, null, false, 0);
|
||||
this.focus = new FocusModule(this.log, this.store, this.crypto, this.files, cardId, channelId, this.guid, null, null, false, 0);
|
||||
}
|
||||
|
||||
return this.focus;
|
||||
|
@ -128,7 +128,7 @@ export type AssetSource = {
|
||||
mimeType: string;
|
||||
extension: string;
|
||||
source: any;
|
||||
transform: {type: TransformType, context: any, position?: number, thumb?: ()=>Promise<string>}[],
|
||||
transforms: {type: TransformType, context: any, position?: number, thumb?: ()=>Promise<string>}[],
|
||||
}
|
||||
|
||||
export type Asset = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user