mirror of
https://github.com/BlowaterNostr/blowater.git
synced 2024-10-18 07:33:22 +00:00
Distinguish between DM and GM (#209)
This commit is contained in:
parent
8d15e2b174
commit
2b91bb3b8c
@ -386,8 +386,8 @@ export function AppComponent(props: {
|
|||||||
editors: model.editors,
|
editors: model.editors,
|
||||||
...model.dm,
|
...model.dm,
|
||||||
rightPanelModel: model.rightPanelModel,
|
rightPanelModel: model.rightPanelModel,
|
||||||
emit: app.eventBus.emit,
|
bus: app.eventBus,
|
||||||
myAccountContext: myAccountCtx,
|
ctx: myAccountCtx,
|
||||||
db: app.database,
|
db: app.database,
|
||||||
pool: props.pool,
|
pool: props.pool,
|
||||||
conversationLists: app.conversationLists,
|
conversationLists: app.conversationLists,
|
||||||
|
@ -37,6 +37,7 @@ export function initialModel(): Model {
|
|||||||
focusedContent: new Map(),
|
focusedContent: new Map(),
|
||||||
hasNewMessages: new Set(),
|
hasNewMessages: new Set(),
|
||||||
currentSelectedContact: undefined,
|
currentSelectedContact: undefined,
|
||||||
|
isGroupMessage: false,
|
||||||
},
|
},
|
||||||
// allUsersInfo: new Map(),
|
// allUsersInfo: new Map(),
|
||||||
editors: editors,
|
editors: editors,
|
||||||
|
@ -196,6 +196,7 @@ export async function* UI_Interaction_Update(args: {
|
|||||||
model.dm.focusedContent.set(event.pubkey.hex, event.pubkey);
|
model.dm.focusedContent.set(event.pubkey.hex, event.pubkey);
|
||||||
}
|
}
|
||||||
app.popOverInputChan.put({ children: undefined });
|
app.popOverInputChan.put({ children: undefined });
|
||||||
|
app.model.dm.isGroupMessage = event.isGroupChat;
|
||||||
} else if (event.type == "BackToContactList") {
|
} else if (event.type == "BackToContactList") {
|
||||||
model.dm.currentSelectedContact = undefined;
|
model.dm.currentSelectedContact = undefined;
|
||||||
} else if (event.type == "PinConversation") {
|
} else if (event.type == "PinConversation") {
|
||||||
@ -650,6 +651,7 @@ export async function* Database_Update(
|
|||||||
emit({
|
emit({
|
||||||
type: "SelectConversation",
|
type: "SelectConversation",
|
||||||
pubkey: k,
|
pubkey: k,
|
||||||
|
isGroupChat: false, // todo
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -60,7 +60,10 @@ export class ConversationLists implements ConversationListRetriever, GroupChatLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getConversationType(pubkey: PublicKey) {
|
getConversationType(pubkey: PublicKey, isGroupChat: boolean) {
|
||||||
|
if (isGroupChat) {
|
||||||
|
return "Group";
|
||||||
|
}
|
||||||
const contact = this.convoSummaries.get(pubkey.hex);
|
const contact = this.convoSummaries.get(pubkey.hex);
|
||||||
if (contact == undefined) {
|
if (contact == undefined) {
|
||||||
return "Strangers";
|
return "Strangers";
|
||||||
|
@ -4,9 +4,9 @@ import { tw } from "https://esm.sh/twind@0.16.16";
|
|||||||
import { Avatar } from "./components/avatar.tsx";
|
import { Avatar } from "./components/avatar.tsx";
|
||||||
import { CenterClass, IconButtonClass, LinearGradientsClass } from "./components/tw.ts";
|
import { CenterClass, IconButtonClass, LinearGradientsClass } from "./components/tw.ts";
|
||||||
import { ConversationSummary, sortUserInfo } from "./conversation-list.ts";
|
import { ConversationSummary, sortUserInfo } from "./conversation-list.ts";
|
||||||
import { emitFunc } from "../event-bus.ts";
|
import { emitFunc, EventSubscriber } from "../event-bus.ts";
|
||||||
import { PinIcon, UnpinIcon } from "./icons/mod.tsx";
|
import { PinIcon, UnpinIcon } from "./icons/mod.tsx";
|
||||||
import { SearchUpdate } from "./search_model.ts";
|
import { SearchUpdate, SelectConversation } from "./search_model.ts";
|
||||||
import { PublicKey } from "../lib/nostr-ts/key.ts";
|
import { PublicKey } from "../lib/nostr-ts/key.ts";
|
||||||
import { PinConversation, UnpinConversation } from "../nostr.ts";
|
import { PinConversation, UnpinConversation } from "../nostr.ts";
|
||||||
import { PrimaryTextColor } from "./style/colors.ts";
|
import { PrimaryTextColor } from "./style/colors.ts";
|
||||||
@ -15,10 +15,12 @@ import { ChatIcon } from "./icons2/chat-icon.tsx";
|
|||||||
import { StartCreateGroupChat } from "./create-group.tsx";
|
import { StartCreateGroupChat } from "./create-group.tsx";
|
||||||
import { GroupIcon } from "./icons2/group-icon.tsx";
|
import { GroupIcon } from "./icons2/group-icon.tsx";
|
||||||
import { Component } from "https://esm.sh/preact@10.17.1";
|
import { Component } from "https://esm.sh/preact@10.17.1";
|
||||||
|
import { UI_Interaction_Event } from "./app_update.tsx";
|
||||||
|
|
||||||
export interface ConversationListRetriever extends GroupChatListGetter {
|
export interface ConversationListRetriever extends GroupChatListGetter {
|
||||||
getContacts: () => Iterable<ConversationSummary>;
|
getContacts: () => Iterable<ConversationSummary>;
|
||||||
getStrangers: () => Iterable<ConversationSummary>;
|
getStrangers: () => Iterable<ConversationSummary>;
|
||||||
|
getConversationType(pubkey: PublicKey, isGourpChat: boolean): "Contacts" | "Strangers" | "Group";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupChatListGetter {
|
export interface GroupChatListGetter {
|
||||||
@ -35,14 +37,15 @@ export type ContactUpdate =
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
emit: emitFunc<ContactUpdate | SearchUpdate>;
|
emit: emitFunc<ContactUpdate | SearchUpdate>;
|
||||||
|
eventBus: EventSubscriber<UI_Interaction_Event>;
|
||||||
convoListRetriever: ConversationListRetriever;
|
convoListRetriever: ConversationListRetriever;
|
||||||
currentSelected: PublicKey | undefined;
|
|
||||||
pinListGetter: PinListGetter;
|
pinListGetter: PinListGetter;
|
||||||
hasNewMessages: Set<string>;
|
hasNewMessages: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
selectedContactGroup: ConversationType;
|
selectedContactGroup: ConversationType;
|
||||||
|
currentSelected: SelectConversation | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ConversationList extends Component<Props, State> {
|
export class ConversationList extends Component<Props, State> {
|
||||||
@ -50,8 +53,23 @@ export class ConversationList extends Component<Props, State> {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
for await (const e of this.props.eventBus.onChange()) {
|
||||||
|
if (e.type == "SelectConversation") {
|
||||||
|
this.setState({
|
||||||
|
currentSelected: e,
|
||||||
|
selectedContactGroup: this.props.convoListRetriever.getConversationType(
|
||||||
|
e.pubkey,
|
||||||
|
e.isGroupChat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
state: Readonly<State> = {
|
state: Readonly<State> = {
|
||||||
selectedContactGroup: "Contacts",
|
selectedContactGroup: "Contacts",
|
||||||
|
currentSelected: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
render(props: Props) {
|
render(props: Props) {
|
||||||
@ -166,8 +184,9 @@ export class ConversationList extends Component<Props, State> {
|
|||||||
|
|
||||||
<ContactGroup
|
<ContactGroup
|
||||||
contacts={Array.from(convoListToRender.values())}
|
contacts={Array.from(convoListToRender.values())}
|
||||||
currentSelected={props.currentSelected}
|
currentSelected={this.state.currentSelected}
|
||||||
pinListGetter={props.pinListGetter}
|
pinListGetter={props.pinListGetter}
|
||||||
|
isGroupChat={listToRender === groups}
|
||||||
emit={props.emit}
|
emit={props.emit}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -181,13 +200,13 @@ export interface PinListGetter {
|
|||||||
|
|
||||||
type ConversationListProps = {
|
type ConversationListProps = {
|
||||||
contacts: { conversation: ConversationSummary; isMarked: boolean }[];
|
contacts: { conversation: ConversationSummary; isMarked: boolean }[];
|
||||||
currentSelected: PublicKey | undefined;
|
currentSelected: SelectConversation | undefined;
|
||||||
pinListGetter: PinListGetter;
|
pinListGetter: PinListGetter;
|
||||||
|
isGroupChat: boolean;
|
||||||
emit: emitFunc<ContactUpdate>;
|
emit: emitFunc<ContactUpdate>;
|
||||||
};
|
};
|
||||||
|
|
||||||
function ContactGroup(props: ConversationListProps) {
|
function ContactGroup(props: ConversationListProps) {
|
||||||
const t = Date.now();
|
|
||||||
props.contacts.sort((a, b) => {
|
props.contacts.sort((a, b) => {
|
||||||
return sortUserInfo(a.conversation, b.conversation);
|
return sortUserInfo(a.conversation, b.conversation);
|
||||||
});
|
});
|
||||||
@ -209,16 +228,16 @@ function ContactGroup(props: ConversationListProps) {
|
|||||||
<li
|
<li
|
||||||
class={tw`${
|
class={tw`${
|
||||||
props.currentSelected && contact.conversation.pubkey.hex ===
|
props.currentSelected && contact.conversation.pubkey.hex ===
|
||||||
props.currentSelected.hex
|
props.currentSelected.pubkey.hex &&
|
||||||
|
props.isGroupChat == props.currentSelected.isGroupChat
|
||||||
? "bg-[#42464D] text-[#FFFFFF]"
|
? "bg-[#42464D] text-[#FFFFFF]"
|
||||||
: "bg-[#42464D] text-[#96989D]"
|
: "bg-[#42464D] text-[#96989D]"
|
||||||
} cursor-pointer p-2 hover:bg-[#3C3F45] my-2 rounded-lg flex items-center w-full relative group`}
|
} cursor-pointer p-2 hover:bg-[#3C3F45] my-2 rounded-lg flex items-center w-full relative group`}
|
||||||
onClick={() => {
|
onClick={selectConversation(
|
||||||
props.emit({
|
props.emit,
|
||||||
type: "SelectConversation",
|
contact.conversation.pubkey,
|
||||||
pubkey: contact.conversation.pubkey,
|
props.isGroupChat,
|
||||||
});
|
)}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ConversationListItem
|
<ConversationListItem
|
||||||
conversation={contact.conversation}
|
conversation={contact.conversation}
|
||||||
@ -255,16 +274,16 @@ function ContactGroup(props: ConversationListProps) {
|
|||||||
<li
|
<li
|
||||||
class={tw`${
|
class={tw`${
|
||||||
props.currentSelected && contact.conversation?.pubkey.hex ===
|
props.currentSelected && contact.conversation?.pubkey.hex ===
|
||||||
props.currentSelected.hex
|
props.currentSelected.pubkey.hex &&
|
||||||
|
props.isGroupChat == props.currentSelected.isGroupChat
|
||||||
? "bg-[#42464D] text-[#FFFFFF]"
|
? "bg-[#42464D] text-[#FFFFFF]"
|
||||||
: "bg-transparent text-[#96989D]"
|
: "bg-transparent text-[#96989D]"
|
||||||
} cursor-pointer p-2 hover:bg-[#3C3F45] my-2 rounded-lg flex items-center w-full relative group`}
|
} cursor-pointer p-2 hover:bg-[#3C3F45] my-2 rounded-lg flex items-center w-full relative group`}
|
||||||
onClick={() => {
|
onClick={selectConversation(
|
||||||
props.emit({
|
props.emit,
|
||||||
type: "SelectConversation",
|
contact.conversation.pubkey,
|
||||||
pubkey: contact.conversation.pubkey,
|
props.isGroupChat,
|
||||||
});
|
)}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ConversationListItem
|
<ConversationListItem
|
||||||
conversation={contact.conversation}
|
conversation={contact.conversation}
|
||||||
@ -357,3 +376,12 @@ function ConversationListItem(props: ListItemProps) {
|
|||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectConversation =
|
||||||
|
(emit: emitFunc<SelectConversation>, pubkey: PublicKey, isGroupChat: boolean) => () => {
|
||||||
|
emit({
|
||||||
|
type: "SelectConversation",
|
||||||
|
pubkey,
|
||||||
|
isGroupChat,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -69,7 +69,7 @@ const view = () => {
|
|||||||
db={database}
|
db={database}
|
||||||
eventSyncer={new EventSyncer(pool, database)}
|
eventSyncer={new EventSyncer(pool, database)}
|
||||||
profilesSyncer={new ProfileSyncer(database, pool)}
|
profilesSyncer={new ProfileSyncer(database, pool)}
|
||||||
emit={testEventBus.emit}
|
bus={testEventBus.emit}
|
||||||
rightPanelModel={{
|
rightPanelModel={{
|
||||||
show: true,
|
show: true,
|
||||||
}}
|
}}
|
||||||
@ -77,7 +77,7 @@ const view = () => {
|
|||||||
currentSelectedContact={model.dm.currentSelectedContact}
|
currentSelectedContact={model.dm.currentSelectedContact}
|
||||||
focusedContent={model.dm.focusedContent}
|
focusedContent={model.dm.focusedContent}
|
||||||
hasNewMessages={model.dm.hasNewMessages}
|
hasNewMessages={model.dm.hasNewMessages}
|
||||||
myAccountContext={ctx}
|
ctx={ctx}
|
||||||
pool={pool}
|
pool={pool}
|
||||||
selectedContactGroup={model.dm.selectedContactGroup}
|
selectedContactGroup={model.dm.selectedContactGroup}
|
||||||
/>
|
/>
|
||||||
|
1
UI/dm.ts
1
UI/dm.ts
@ -13,6 +13,7 @@ export type DM_Model = {
|
|||||||
currentSelectedContact: PublicKey | undefined;
|
currentSelectedContact: PublicKey | undefined;
|
||||||
focusedContent: Map<string, NostrEvent /* thread root event */ | PublicKey /* selected user profile */>;
|
focusedContent: Map<string, NostrEvent /* thread root event */ | PublicKey /* selected user profile */>;
|
||||||
hasNewMessages: Set<string>;
|
hasNewMessages: Set<string>;
|
||||||
|
isGroupMessage: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function convertEventsToChatMessages(
|
export function convertEventsToChatMessages(
|
||||||
|
19
UI/dm.tsx
19
UI/dm.tsx
@ -4,7 +4,7 @@ import { tw } from "https://esm.sh/twind@0.16.16";
|
|||||||
import * as cl from "./conversation-list.tsx";
|
import * as cl from "./conversation-list.tsx";
|
||||||
import { Database_Contextual_View } from "../database.ts";
|
import { Database_Contextual_View } from "../database.ts";
|
||||||
import { MessagePanel, RightPanelModel } from "./message-panel.tsx";
|
import { MessagePanel, RightPanelModel } from "./message-panel.tsx";
|
||||||
import { emitFunc, EventBus } from "../event-bus.ts";
|
import { EventBus } from "../event-bus.ts";
|
||||||
import { LeftArrowIcon } from "./icons/left-arrow-icon.tsx";
|
import { LeftArrowIcon } from "./icons/left-arrow-icon.tsx";
|
||||||
import { CenterClass, IconButtonClass } from "./components/tw.ts";
|
import { CenterClass, IconButtonClass } from "./components/tw.ts";
|
||||||
import { DM_EditorModel } from "./editor.tsx";
|
import { DM_EditorModel } from "./editor.tsx";
|
||||||
@ -25,9 +25,9 @@ import { GroupChatController } from "../group-chat.ts";
|
|||||||
type DirectMessageContainerProps = {
|
type DirectMessageContainerProps = {
|
||||||
editors: Map<string, DM_EditorModel>;
|
editors: Map<string, DM_EditorModel>;
|
||||||
rightPanelModel: RightPanelModel;
|
rightPanelModel: RightPanelModel;
|
||||||
myAccountContext: NostrAccountContext;
|
ctx: NostrAccountContext;
|
||||||
pool: ConnectionPool;
|
pool: ConnectionPool;
|
||||||
emit: emitFunc<UI_Interaction_Event>;
|
bus: EventBus<UI_Interaction_Event>;
|
||||||
db: Database_Contextual_View;
|
db: Database_Contextual_View;
|
||||||
conversationLists: ConversationLists;
|
conversationLists: ConversationLists;
|
||||||
profilesSyncer: ProfileSyncer;
|
profilesSyncer: ProfileSyncer;
|
||||||
@ -102,10 +102,10 @@ export function DirectMessageContainer(props: DirectMessageContainerProps) {
|
|||||||
return _;
|
return _;
|
||||||
})();
|
})();
|
||||||
messagePanel = new MessagePanel({
|
messagePanel = new MessagePanel({
|
||||||
myPublicKey: props.myAccountContext.publicKey,
|
myPublicKey: props.ctx.publicKey,
|
||||||
messages: convoMsgs,
|
messages: convoMsgs,
|
||||||
rightPanelModel: props.rightPanelModel,
|
rightPanelModel: props.rightPanelModel,
|
||||||
emit: props.emit,
|
emit: props.bus.emit,
|
||||||
editorModel: currentEditorModel,
|
editorModel: currentEditorModel,
|
||||||
focusedContent: focusedContent,
|
focusedContent: focusedContent,
|
||||||
db: props.db,
|
db: props.db,
|
||||||
@ -114,7 +114,7 @@ export function DirectMessageContainer(props: DirectMessageContainerProps) {
|
|||||||
allUserInfo: props.conversationLists.convoSummaries,
|
allUserInfo: props.conversationLists.convoSummaries,
|
||||||
}).render();
|
}).render();
|
||||||
}
|
}
|
||||||
const canEditGroupProfile = currentConversation &&
|
const canEditGroupProfile = currentConversation && props.isGroupMessage &&
|
||||||
props.groupChatController.getGroupAdminCtx(currentConversation);
|
props.groupChatController.getGroupAdminCtx(currentConversation);
|
||||||
|
|
||||||
const vDom = (
|
const vDom = (
|
||||||
@ -123,7 +123,8 @@ export function DirectMessageContainer(props: DirectMessageContainerProps) {
|
|||||||
>
|
>
|
||||||
<div class={tw`${currentConversation ? "mobile:hidden" : "mobile:w-full"}`}>
|
<div class={tw`${currentConversation ? "mobile:hidden" : "mobile:w-full"}`}>
|
||||||
<cl.ConversationList
|
<cl.ConversationList
|
||||||
currentSelected={currentConversation}
|
eventBus={props.bus}
|
||||||
|
emit={props.bus.emit}
|
||||||
convoListRetriever={props.conversationLists}
|
convoListRetriever={props.conversationLists}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
@ -137,7 +138,7 @@ export function DirectMessageContainer(props: DirectMessageContainerProps) {
|
|||||||
<div class={tw`flex items-center`}>
|
<div class={tw`flex items-center`}>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.emit({
|
props.bus.emit({
|
||||||
type: "BackToContactList",
|
type: "BackToContactList",
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@ -161,7 +162,7 @@ export function DirectMessageContainer(props: DirectMessageContainerProps) {
|
|||||||
<button
|
<button
|
||||||
class={tw`w-8 h-8 ${CenterClass}`}
|
class={tw`w-8 h-8 ${CenterClass}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
props.emit({
|
props.bus.emit({
|
||||||
type: "StartEditGroupChatProfile",
|
type: "StartEditGroupChatProfile",
|
||||||
publicKey: currentConversation,
|
publicKey: currentConversation,
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,6 @@ import { InMemoryAccountContext, NostrKind } from "../lib/nostr-ts/nostr.ts";
|
|||||||
import { Database_Contextual_View } from "../database.ts";
|
import { Database_Contextual_View } from "../database.ts";
|
||||||
import { testEventBus, testEventsAdapter } from "./_setup.test.ts";
|
import { testEventBus, testEventsAdapter } from "./_setup.test.ts";
|
||||||
import { prepareNormalNostrEvent } from "../lib/nostr-ts/event.ts";
|
import { prepareNormalNostrEvent } from "../lib/nostr-ts/event.ts";
|
||||||
import { getSocialPosts } from "../features/social.ts";
|
|
||||||
import { ConversationLists } from "./conversation-list.ts";
|
import { ConversationLists } from "./conversation-list.ts";
|
||||||
import { EventSyncer } from "./event_syncer.ts";
|
import { EventSyncer } from "./event_syncer.ts";
|
||||||
import { ConnectionPool } from "../lib/nostr-ts/relay.ts";
|
import { ConnectionPool } from "../lib/nostr-ts/relay.ts";
|
||||||
@ -25,25 +24,32 @@ const lamport = new LamportTime(0);
|
|||||||
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi`));
|
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi`));
|
||||||
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi 2`));
|
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi 2`));
|
||||||
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi 3`));
|
await database.addEvent(await prepareNormalNostrEvent(ctx, NostrKind.TEXT_NOTE, [], `hi 3`));
|
||||||
const allUserInfo = new ConversationLists(ctx);
|
const allUserInfo = new ConversationLists(ctx, new ProfileSyncer(database, new ConnectionPool()));
|
||||||
const pool = new ConnectionPool();
|
const pool = new ConnectionPool();
|
||||||
const model = initialModel();
|
const model = initialModel();
|
||||||
pool.addRelayURL(relays[0]);
|
pool.addRelayURL(relays[0]);
|
||||||
|
|
||||||
|
const editor = model.editors.get(ctx.publicKey.hex);
|
||||||
|
|
||||||
const view = () => {
|
const view = () => {
|
||||||
const threads = getSocialPosts(database, allUserInfo.convoSummaries);
|
if (editor == undefined) {
|
||||||
console.log(database.events, threads);
|
return undefined;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<MessagePanel
|
<MessagePanel
|
||||||
allUserInfo={allUserInfo.convoSummaries}
|
allUserInfo={allUserInfo.convoSummaries}
|
||||||
db={database}
|
db={database}
|
||||||
editorModel={model.social.editor}
|
/**
|
||||||
|
* If we use a map to store all editor models,
|
||||||
|
* need to distinguish editor models for DMs and GMs
|
||||||
|
*/
|
||||||
|
editorModel={editor}
|
||||||
eventSyncer={new EventSyncer(pool, database)}
|
eventSyncer={new EventSyncer(pool, database)}
|
||||||
focusedContent={undefined}
|
focusedContent={undefined}
|
||||||
myPublicKey={ctx.publicKey}
|
myPublicKey={ctx.publicKey}
|
||||||
profilesSyncer={new ProfileSyncer(database, pool)}
|
profilesSyncer={new ProfileSyncer(database, pool)}
|
||||||
emit={testEventBus.emit}
|
emit={testEventBus.emit}
|
||||||
messages={threads}
|
messages={[]}
|
||||||
rightPanelModel={{
|
rightPanelModel={{
|
||||||
show: true,
|
show: true,
|
||||||
}}
|
}}
|
||||||
@ -62,8 +68,6 @@ for await (const e of testEventBus.onChange()) {
|
|||||||
lamport,
|
lamport,
|
||||||
pool,
|
pool,
|
||||||
model.editors,
|
model.editors,
|
||||||
model.social.editor,
|
|
||||||
model.social.replyEditors,
|
|
||||||
database,
|
database,
|
||||||
);
|
);
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
@ -71,7 +75,6 @@ for await (const e of testEventBus.onChange()) {
|
|||||||
continue; // todo: global error toast
|
continue; // todo: global error toast
|
||||||
}
|
}
|
||||||
} else if (e.type == "UpdateMessageText") {
|
} else if (e.type == "UpdateMessageText") {
|
||||||
model.social.editor.text = e.text;
|
|
||||||
}
|
}
|
||||||
render(view(), document.body);
|
render(view(), document.body);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,6 @@ interface DirectMessagePanelProps {
|
|||||||
allUserInfo: Map<string, ConversationSummary>;
|
allUserInfo: Map<string, ConversationSummary>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export function MessagePanel(props: DirectMessagePanelProps) {
|
|
||||||
export class MessagePanel extends Component<DirectMessagePanelProps> {
|
export class MessagePanel extends Component<DirectMessagePanelProps> {
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/** @jsx h */
|
/** @jsx h */
|
||||||
import { Fragment, h } from "https://esm.sh/preact@10.17.1";
|
import { Fragment, h } from "https://esm.sh/preact@10.17.1";
|
||||||
import { tw } from "https://esm.sh/twind@0.16.16";
|
import { tw } from "https://esm.sh/twind@0.16.16";
|
||||||
import { emitFunc, EventEmitter } from "../event-bus.ts";
|
import { emitFunc } from "../event-bus.ts";
|
||||||
import {
|
import {
|
||||||
DirectMessagePanelUpdate,
|
DirectMessagePanelUpdate,
|
||||||
NameAndTime,
|
NameAndTime,
|
||||||
|
@ -82,6 +82,7 @@ export class Search extends Component<Props, State> {
|
|||||||
this.props.emit({
|
this.props.emit({
|
||||||
type: "SelectConversation",
|
type: "SelectConversation",
|
||||||
pubkey: profile instanceof PublicKey ? profile : profile.publicKey,
|
pubkey: profile instanceof PublicKey ? profile : profile.publicKey,
|
||||||
|
isGroupChat: false, // todo
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ export type SearchPublicKey = {
|
|||||||
export type SelectConversation = {
|
export type SelectConversation = {
|
||||||
type: "SelectConversation";
|
type: "SelectConversation";
|
||||||
pubkey: PublicKey;
|
pubkey: PublicKey;
|
||||||
|
isGroupChat: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SearchModel = {
|
export type SearchModel = {
|
||||||
|
@ -65,9 +65,6 @@ export class Database_Contextual_View implements DirectMessageGetter {
|
|||||||
const initialEvents:
|
const initialEvents:
|
||||||
(Text_Note_Event | NostrEvent<NostrKind.DIRECT_MESSAGE> | Profile_Nostr_Event)[] =
|
(Text_Note_Event | NostrEvent<NostrKind.DIRECT_MESSAGE> | Profile_Nostr_Event)[] =
|
||||||
await loadInitialData(allEvents, eventsAdapter);
|
await loadInitialData(allEvents, eventsAdapter);
|
||||||
if (initialEvents instanceof Error) {
|
|
||||||
return initialEvents;
|
|
||||||
}
|
|
||||||
console.log("Database_Contextual_View:parsed", Date.now() - t);
|
console.log("Database_Contextual_View:parsed", Date.now() - t);
|
||||||
|
|
||||||
// Load DMs
|
// Load DMs
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { chan, multi } from "https://raw.githubusercontent.com/BlowaterNostr/csp/master/csp.ts";
|
import { chan, Channel, multi } from "https://raw.githubusercontent.com/BlowaterNostr/csp/master/csp.ts";
|
||||||
|
|
||||||
export class EventBus<T> implements EventEmitter<T> {
|
export class EventBus<T> implements EventEmitter<T>, EventSubscriber<T> {
|
||||||
private readonly c = chan<T>();
|
private readonly c = chan<T>();
|
||||||
private readonly caster = multi<T>(this.c);
|
private readonly caster = multi<T>(this.c);
|
||||||
|
|
||||||
@ -17,3 +17,7 @@ export type EventEmitter<T> = {
|
|||||||
emit: (event: T) => void;
|
emit: (event: T) => void;
|
||||||
};
|
};
|
||||||
export type emitFunc<T extends { type: string }> = (event: T) => void;
|
export type emitFunc<T extends { type: string }> = (event: T) => void;
|
||||||
|
|
||||||
|
export type EventSubscriber<T> = {
|
||||||
|
onChange(): Channel<T>;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user