blowater/app/UI/dm.tsx

180 lines
6.6 KiB
TypeScript
Raw Normal View History

2023-06-30 14:05:57 +00:00
/** @jsx h */
import { Component, h, VNode } from "preact";
import { PublicKey } from "@blowater/nostr-sdk";
import { NostrAccountContext } from "@blowater/nostr-sdk";
2024-01-01 17:28:10 +00:00
import { RelayRecordGetter } from "../database.ts";
2023-10-04 21:34:43 +00:00
import { EventBus } from "../event-bus.ts";
2024-01-02 12:42:11 +00:00
import { ChatMessagesGetter, UI_Interaction_Event, UserBlocker } from "./app_update.tsx";
import { IconButtonClass } from "./components/tw.ts";
2024-01-01 17:28:10 +00:00
import { LeftArrowIcon } from "./icons/left-arrow-icon.tsx";
2024-03-20 02:20:55 +00:00
import { MessagePanel_V0 } from "./message-panel.tsx";
2024-05-14 09:52:02 +00:00
import { func_GetProfileByPublicKey, func_GetProfilesByText } from "./search.tsx";
2024-01-01 17:28:10 +00:00
import {
ConversationList,
ConversationListRetriever,
NewMessageChecker,
PinListGetter,
} from "./conversation-list.tsx";
2024-06-01 06:57:02 +00:00
import { func_GetEventByID, func_GetReactionsByEventID, func_IsAdmin } from "./message-list.tsx";
2023-10-09 18:52:30 +00:00
export type DM_Model = {
currentConversation: PublicKey | undefined;
2023-10-09 18:52:30 +00:00
};
2023-06-30 14:05:57 +00:00
type DirectMessageContainerProps = {
2023-10-04 21:34:43 +00:00
ctx: NostrAccountContext;
bus: EventBus<UI_Interaction_Event>;
getters: {
2024-04-29 09:32:11 +00:00
getProfileByPublicKey: func_GetProfileByPublicKey;
getProfilesByText: func_GetProfilesByText;
messageGetter: ChatMessagesGetter;
pinListGetter: PinListGetter;
convoListRetriever: ConversationListRetriever;
newMessageChecker: NewMessageChecker;
relayRecordGetter: RelayRecordGetter;
isUserBlocked: (pubkey: PublicKey) => boolean;
getEventByID: func_GetEventByID;
2024-05-14 09:52:02 +00:00
isAdmin: func_IsAdmin | undefined;
2024-06-01 06:57:02 +00:00
getReactionsByEventID: func_GetReactionsByEventID;
};
2024-01-02 12:42:11 +00:00
userBlocker: UserBlocker;
} & DM_Model;
2023-06-30 14:05:57 +00:00
2023-10-07 17:15:27 +00:00
export type StartInvite = {
type: "StartInvite";
publicKey: PublicKey;
};
export class DirectMessageContainer extends Component<DirectMessageContainerProps> {
render(props: DirectMessageContainerProps) {
const t = Date.now();
console.log(DirectMessageContainer.name, "?");
const vDom = (
<div
2024-04-02 06:02:29 +00:00
class={`h-full flex-1 flex bg-[#36393F] overflow-hidden`}
>
<div
class={`w-fit max-sm:w-full
${props.currentConversation ? "max-sm:hidden" : ""}`}
>
2024-01-01 17:28:10 +00:00
<ConversationList
eventSub={props.bus}
emit={props.bus.emit}
getters={props.getters}
2024-01-02 12:42:11 +00:00
userBlocker={props.userBlocker}
/>
</div>
{this.props.currentConversation
? (
<div class={`flex flex-col flex-1 overflow-hidden`}>
<TopBar
bus={this.props.bus}
buttons={[]}
currentConversation={this.props.currentConversation}
2024-04-29 09:32:11 +00:00
getters={this.props.getters}
/>
<div class={`flex-1 overflow-auto`}>
<MessagePanel_V0
key={this.props.currentConversation}
myPublicKey={props.ctx.publicKey}
emit={props.bus.emit}
eventSub={props.bus}
getters={props.getters}
messages={props.getters.messageGetter.getChatMessages(
this.props.currentConversation.hex,
)}
/>
</div>
</div>
)
: undefined}
</div>
);
console.debug("DirectMessageContainer:end", Date.now() - t);
return vDom;
2023-10-19 03:44:43 +00:00
}
}
2023-10-19 03:44:43 +00:00
function TopBar(props: {
bus: EventBus<UI_Interaction_Event>;
currentConversation: PublicKey;
buttons: VNode[];
2024-04-29 09:32:11 +00:00
getters: {
getProfilesByText: func_GetProfilesByText;
getProfileByPublicKey: func_GetProfileByPublicKey;
};
}) {
2024-04-29 09:32:11 +00:00
const conversation_profile = props.getters.getProfileByPublicKey(
2024-03-20 02:20:55 +00:00
props.currentConversation,
);
let conversation_name = conversation_profile?.profile.name ||
conversation_profile?.profile.display_name ||
props.currentConversation.bech32();
return (
2023-06-30 14:05:57 +00:00
<div
class={`h-14 border-l border-b border-[#36393F] flex
items-center justify-between bg-[#2F3136]`}
2023-06-30 14:05:57 +00:00
>
<div class={`flex items-center overflow-hidden`}>
<button
onClick={() => {
props.bus.emit({
type: "BackToContactList",
});
}}
class={`w-6 h-6 mx-2 ${IconButtonClass}`}
>
<LeftArrowIcon
class={`w-4 h-4`}
style={{
fill: "rgb(185, 187, 190)",
}}
/>
</button>
<span
// https://tailwindcss.com/docs/customizing-colors
// https://tailwindcss.com/docs/cursor
class={`text-[#F3F4EA] text-[1.2rem]
hover:text-[#60a5fa] hover:cursor-pointer
whitespace-nowrap truncate`}
onClick={() => {
if (!props.currentConversation) {
return;
}
props.bus.emit({
type: "ViewUserDetail",
pubkey: props.currentConversation,
});
}}
>
2024-03-20 02:20:55 +00:00
{conversation_name}
</span>
</div>
<div>
{props.buttons}
<button
class={`absolute z-10 w-6 h-6 transition-transform duration-100 ease-in-out
right-4 mobile:right-0 top-4 ${IconButtonClass}`}
onClick={() => {
props.bus.emit({
type: "ViewUserDetail",
pubkey: props.currentConversation,
});
}}
>
<LeftArrowIcon
class={`w-4 h-4`}
style={{
fill: "#F3F4EA",
}}
/>
</button>
</div>
2023-06-30 14:05:57 +00:00
</div>
);
}