mirror of
https://github.com/BlowaterNostr/blowater.git
synced 2024-10-18 15:43:20 +00:00
151 lines
5.0 KiB
TypeScript
151 lines
5.0 KiB
TypeScript
import { Component, h } from "https://esm.sh/preact@10.17.1";
|
|
import { SingleRelayConnection } from "../../libs/nostr.ts/relay-single.ts";
|
|
import { emitFunc, EventBus } from "../event-bus.ts";
|
|
import { UI_Interaction_Event } from "./app_update.tsx";
|
|
import { setState } from "./_helper.ts";
|
|
import { ProfileGetter } from "./search.tsx";
|
|
|
|
import { RelayRecordGetter } from "../database.ts";
|
|
import { NewMessageChecker } from "./conversation-list.tsx";
|
|
import { ConversationListRetriever } from "./conversation-list.tsx";
|
|
import { NostrAccountContext } from "../../libs/nostr.ts/nostr.ts";
|
|
|
|
import { MessagePanel } from "./message-panel.tsx";
|
|
import { PublicKey } from "../../libs/nostr.ts/key.ts";
|
|
import { ChatMessage } from "./message.ts";
|
|
import { func_GetEventByID } from "./message-list.tsx";
|
|
import { Filter, FilterContent } from "./filter.tsx";
|
|
import { NoteID } from "../../libs/nostr.ts/nip19.ts";
|
|
|
|
export type Public_Model = {
|
|
relaySelectedChannel: Map<string, /* relay url */ string /* channel name */>;
|
|
};
|
|
|
|
export type func_IsUserBlocked = (pubkey: PublicKey) => boolean;
|
|
|
|
type Props = {
|
|
ctx: NostrAccountContext;
|
|
relay: SingleRelayConnection;
|
|
bus: EventBus<UI_Interaction_Event>;
|
|
messages: ChatMessage[];
|
|
getters: {
|
|
profileGetter: ProfileGetter;
|
|
convoListRetriever: ConversationListRetriever;
|
|
newMessageChecker: NewMessageChecker;
|
|
relayRecordGetter: RelayRecordGetter;
|
|
isUserBlocked: func_IsUserBlocked;
|
|
getEventByID: func_GetEventByID;
|
|
};
|
|
} & Public_Model;
|
|
|
|
type State = {
|
|
currentSelectedChannel: string /*channel name*/ | undefined;
|
|
currentEditor: {
|
|
text: string;
|
|
};
|
|
filter: FilterContent | undefined;
|
|
};
|
|
|
|
export class PublicMessageContainer extends Component<Props, State> {
|
|
state: State = {
|
|
currentSelectedChannel: "general",
|
|
currentEditor: {
|
|
text: "",
|
|
},
|
|
filter: undefined,
|
|
};
|
|
|
|
async componentDidMount() {
|
|
for await (const e of this.props.bus.onChange()) {
|
|
if (e.type == "FilterContent") {
|
|
await setState(this, {
|
|
filter: e,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
render(props: Props, state: State) {
|
|
let msgs = props.messages;
|
|
const filter = this.state.filter;
|
|
if (filter) {
|
|
msgs = filter_messages(this.props.messages, filter);
|
|
}
|
|
return (
|
|
<div class="flex flex-row h-full w-full flex bg-[#36393F] overflow-hidden">
|
|
{this.state.currentSelectedChannel
|
|
? (
|
|
<div class={`flex flex-col flex-1 overflow-hidden`}>
|
|
<TopBar
|
|
currentSelected={state.currentSelectedChannel}
|
|
emit={props.bus.emit}
|
|
/>
|
|
<div class={`flex-1 overflow-auto`}>
|
|
{
|
|
<MessagePanel
|
|
key={props.relay.url}
|
|
myPublicKey={props.ctx.publicKey}
|
|
emit={props.bus.emit}
|
|
eventSub={props.bus}
|
|
getters={props.getters}
|
|
messages={msgs}
|
|
/>
|
|
}
|
|
</div>
|
|
</div>
|
|
)
|
|
: undefined}
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
function TopBar(props: {
|
|
currentSelected: string | undefined;
|
|
emit: emitFunc<FilterContent>;
|
|
}) {
|
|
return (
|
|
<div
|
|
class={`h-14 border-l border-b border-[#36393F] flex
|
|
items-center justify-between bg-[#2F3136]`}
|
|
>
|
|
<div class={`flex items-center overflow-hidden`}>
|
|
<span
|
|
class={`text-[#F3F4EA] text-[1.2rem] mx-4
|
|
whitespace-nowrap truncate`}
|
|
>
|
|
{props.currentSelected}
|
|
</span>
|
|
<div>
|
|
<Filter {...props}></Filter>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function filter_messages(msgs: ChatMessage[], filter: FilterContent) {
|
|
const filter_string = filter.content.trim().toLocaleLowerCase();
|
|
const pubkey = PublicKey.FromBech32(filter_string);
|
|
const is_pubkey = pubkey instanceof PublicKey;
|
|
const noteID = NoteID.FromBech32(filter_string);
|
|
const is_note = noteID instanceof NoteID;
|
|
msgs = msgs.filter((msg) => {
|
|
if (is_pubkey) {
|
|
if (msg.author.hex == pubkey.hex) {
|
|
return true;
|
|
}
|
|
}
|
|
if (is_note) {
|
|
if (msg.event.id == noteID.hex) {
|
|
return true;
|
|
}
|
|
}
|
|
if (msg.content.toLocaleLowerCase().indexOf(filter_string) != -1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
return msgs;
|
|
}
|