2023-06-30 14:05:57 +00:00
|
|
|
/** @jsx h */
|
2023-10-06 00:05:35 +00:00
|
|
|
import { h, render } from "https://esm.sh/preact@10.17.1";
|
2023-06-30 14:05:57 +00:00
|
|
|
import * as dm from "../features/dm.ts";
|
2023-10-07 20:40:18 +00:00
|
|
|
import { DirectMessageContainer } from "./dm.tsx";
|
2023-06-30 14:05:57 +00:00
|
|
|
import { tw } from "https://esm.sh/twind@0.16.16";
|
|
|
|
import { EditProfile } from "./edit-profile.tsx";
|
|
|
|
import * as nav from "./nav.tsx";
|
|
|
|
import { EventBus } from "../event-bus.ts";
|
|
|
|
import { Setting } from "./setting.tsx";
|
2023-11-16 13:22:18 +00:00
|
|
|
import { Datebase_View } from "../database.ts";
|
2023-10-15 22:39:21 +00:00
|
|
|
import { DM_List } from "./conversation-list.ts";
|
2023-10-07 20:40:18 +00:00
|
|
|
import { new_DM_EditorModel } from "./editor.tsx";
|
2023-06-30 14:05:57 +00:00
|
|
|
import { initialModel, Model } from "./app_model.ts";
|
2023-09-23 20:53:40 +00:00
|
|
|
import { AppEventBus, Database_Update, UI_Interaction_Event, UI_Interaction_Update } from "./app_update.tsx";
|
2023-06-30 14:05:57 +00:00
|
|
|
import * as time from "../time.ts";
|
2023-09-28 19:37:24 +00:00
|
|
|
import { PublicKey } from "../lib/nostr-ts/key.ts";
|
2023-08-28 17:58:05 +00:00
|
|
|
import { NostrAccountContext, NostrEvent, NostrKind } from "../lib/nostr-ts/nostr.ts";
|
2023-07-09 08:06:49 +00:00
|
|
|
import { getCurrentSignInCtx, setSignInState, SignIn } from "./signIn.tsx";
|
2023-07-19 08:25:36 +00:00
|
|
|
import { SecondaryBackgroundColor } from "./style/colors.ts";
|
2023-07-05 09:32:02 +00:00
|
|
|
import { EventSyncer } from "./event_syncer.ts";
|
2023-11-24 10:35:27 +00:00
|
|
|
import { RelayConfig } from "./relay-config.ts";
|
2023-07-11 09:49:58 +00:00
|
|
|
import { DexieDatabase } from "./dexie-db.ts";
|
2023-07-12 16:20:38 +00:00
|
|
|
import { About } from "./about.tsx";
|
2023-10-01 20:59:07 +00:00
|
|
|
import { ProfileSyncer } from "../features/profile.ts";
|
2023-09-10 17:56:37 +00:00
|
|
|
import { Popover, PopOverInputChannel } from "./components/popover.tsx";
|
2023-11-14 06:22:50 +00:00
|
|
|
import { Channel } from "https://raw.githubusercontent.com/BlowaterNostr/csp/master/csp.ts";
|
2023-10-23 06:52:25 +00:00
|
|
|
import { group_GM_events, GroupChatSyncer, GroupMessageController } from "../features/gm.ts";
|
2023-10-01 22:21:55 +00:00
|
|
|
import { OtherConfig } from "./config-other.ts";
|
2023-10-07 20:40:18 +00:00
|
|
|
import { ProfileGetter } from "./search.tsx";
|
2023-10-09 18:39:52 +00:00
|
|
|
import { DirectedMessageController } from "../features/dm.ts";
|
2023-11-03 13:09:13 +00:00
|
|
|
import { ConnectionPool } from "../lib/nostr-ts/relay-pool.ts";
|
2023-11-18 17:11:07 +00:00
|
|
|
import { LamportTime } from "../time.ts";
|
2023-07-09 07:06:13 +00:00
|
|
|
|
2023-07-11 09:49:58 +00:00
|
|
|
export async function Start(database: DexieDatabase) {
|
2023-08-28 20:34:41 +00:00
|
|
|
console.log("Start the application");
|
|
|
|
|
2023-11-27 13:35:01 +00:00
|
|
|
const installPrompt: nav.InstallPrompt = {
|
|
|
|
event: undefined,
|
|
|
|
};
|
|
|
|
window.addEventListener("beforeinstallprompt", async (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
installPrompt.event = event;
|
|
|
|
});
|
|
|
|
|
2023-11-25 14:29:50 +00:00
|
|
|
const lamport = new LamportTime();
|
2023-07-11 10:45:57 +00:00
|
|
|
const model = initialModel();
|
|
|
|
const eventBus = new EventBus<UI_Interaction_Event>();
|
|
|
|
const pool = new ConnectionPool();
|
2023-09-10 17:56:37 +00:00
|
|
|
const popOverInputChan: PopOverInputChannel = new Channel();
|
2023-11-17 07:06:11 +00:00
|
|
|
const dbView = await Datebase_View.New(database, database, database);
|
2023-11-25 13:26:03 +00:00
|
|
|
const newNostrEventChannel = new Channel<NostrEvent>();
|
|
|
|
(async () => {
|
|
|
|
for await (const event of newNostrEventChannel) {
|
|
|
|
const err = await pool.sendEvent(event);
|
|
|
|
if (err instanceof Error) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})();
|
2023-07-11 10:45:57 +00:00
|
|
|
|
2023-07-09 08:06:49 +00:00
|
|
|
const ctx = await getCurrentSignInCtx();
|
2023-07-09 12:43:03 +00:00
|
|
|
if (ctx instanceof Error) {
|
|
|
|
console.error(ctx);
|
|
|
|
} else if (ctx) {
|
2023-11-25 14:29:50 +00:00
|
|
|
const otherConfig = await OtherConfig.FromLocalStorage(ctx, newNostrEventChannel, lamport);
|
2023-10-08 18:51:53 +00:00
|
|
|
const app = await App.Start({
|
|
|
|
database: dbView,
|
|
|
|
model,
|
|
|
|
ctx,
|
|
|
|
eventBus,
|
|
|
|
pool,
|
|
|
|
popOverInputChan,
|
|
|
|
otherConfig,
|
2023-11-25 14:29:50 +00:00
|
|
|
lamport,
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt,
|
2023-10-08 18:51:53 +00:00
|
|
|
});
|
2023-07-11 10:45:57 +00:00
|
|
|
model.app = app;
|
2023-07-09 08:17:09 +00:00
|
|
|
}
|
2023-07-09 07:06:13 +00:00
|
|
|
|
2023-09-06 16:29:27 +00:00
|
|
|
/* first render */ render(
|
|
|
|
AppComponent({
|
|
|
|
eventBus,
|
|
|
|
model,
|
|
|
|
pool,
|
2023-09-10 17:56:37 +00:00
|
|
|
popOverInputChan,
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt,
|
2023-09-06 16:29:27 +00:00
|
|
|
}),
|
|
|
|
document.body,
|
|
|
|
);
|
2023-07-21 12:40:49 +00:00
|
|
|
|
2023-09-10 17:56:37 +00:00
|
|
|
for await (
|
|
|
|
let _ of UI_Interaction_Update({
|
|
|
|
model,
|
|
|
|
eventBus,
|
2023-11-16 13:22:18 +00:00
|
|
|
dbView: dbView,
|
2023-09-10 17:56:37 +00:00
|
|
|
pool,
|
|
|
|
popOver: popOverInputChan,
|
2023-11-25 13:26:03 +00:00
|
|
|
newNostrEventChannel: newNostrEventChannel,
|
2023-11-25 14:29:50 +00:00
|
|
|
lamport,
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt,
|
2023-09-10 17:56:37 +00:00
|
|
|
})
|
|
|
|
) {
|
2023-07-09 07:06:13 +00:00
|
|
|
const t = Date.now();
|
|
|
|
{
|
2023-09-06 16:29:27 +00:00
|
|
|
render(
|
|
|
|
AppComponent({
|
|
|
|
eventBus,
|
|
|
|
model,
|
|
|
|
pool,
|
2023-09-10 17:56:37 +00:00
|
|
|
popOverInputChan,
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt,
|
2023-09-06 16:29:27 +00:00
|
|
|
}),
|
|
|
|
document.body,
|
|
|
|
);
|
2023-07-09 07:06:13 +00:00
|
|
|
}
|
2023-09-15 08:58:40 +00:00
|
|
|
console.log("UI_Interaction_Update render:", Date.now() - t);
|
2023-07-09 07:06:13 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-30 14:05:57 +00:00
|
|
|
|
|
|
|
export class App {
|
2023-10-08 18:51:53 +00:00
|
|
|
private constructor(
|
2023-11-16 13:22:18 +00:00
|
|
|
public readonly database: Datebase_View,
|
2023-07-11 10:45:57 +00:00
|
|
|
public readonly model: Model,
|
2023-09-15 08:58:40 +00:00
|
|
|
public readonly ctx: NostrAccountContext,
|
2023-07-11 10:45:57 +00:00
|
|
|
public readonly eventBus: EventBus<UI_Interaction_Event>,
|
2023-09-15 08:58:40 +00:00
|
|
|
public readonly pool: ConnectionPool,
|
2023-09-10 17:56:37 +00:00
|
|
|
public readonly popOverInputChan: PopOverInputChannel,
|
2023-10-01 23:16:08 +00:00
|
|
|
public readonly otherConfig: OtherConfig,
|
2023-10-08 18:51:53 +00:00
|
|
|
public readonly profileSyncer: ProfileSyncer,
|
|
|
|
public readonly eventSyncer: EventSyncer,
|
2023-10-15 22:39:21 +00:00
|
|
|
public readonly conversationLists: DM_List,
|
2023-10-08 18:51:53 +00:00
|
|
|
public readonly relayConfig: RelayConfig,
|
2023-10-09 18:39:52 +00:00
|
|
|
public readonly groupChatController: GroupMessageController,
|
2023-10-08 18:51:53 +00:00
|
|
|
public readonly lamport: time.LamportTime,
|
2023-10-09 18:39:52 +00:00
|
|
|
public readonly dmController: DirectedMessageController,
|
2023-10-08 18:51:53 +00:00
|
|
|
) {}
|
|
|
|
|
|
|
|
static async Start(args: {
|
2023-11-16 13:22:18 +00:00
|
|
|
database: Datebase_View;
|
2023-10-08 18:51:53 +00:00
|
|
|
model: Model;
|
|
|
|
ctx: NostrAccountContext;
|
|
|
|
eventBus: EventBus<UI_Interaction_Event>;
|
|
|
|
pool: ConnectionPool;
|
|
|
|
popOverInputChan: PopOverInputChannel;
|
|
|
|
otherConfig: OtherConfig;
|
2023-11-25 14:29:50 +00:00
|
|
|
lamport: LamportTime;
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt: nav.InstallPrompt;
|
2023-10-08 18:51:53 +00:00
|
|
|
}) {
|
2023-11-25 14:29:50 +00:00
|
|
|
args.lamport.fromEvents(args.database.getAllEvents());
|
2023-10-08 18:51:53 +00:00
|
|
|
const eventSyncer = new EventSyncer(args.pool, args.database);
|
2023-11-18 17:11:07 +00:00
|
|
|
|
|
|
|
// init relay config
|
|
|
|
const relayConfig = await RelayConfig.FromLocalStorage({
|
|
|
|
ctx: args.ctx,
|
|
|
|
relayPool: args.pool,
|
|
|
|
});
|
|
|
|
console.log(relayConfig.getRelayURLs());
|
|
|
|
|
|
|
|
// init profile syncer
|
2023-10-08 18:51:53 +00:00
|
|
|
const profileSyncer = new ProfileSyncer(args.database, args.pool);
|
|
|
|
profileSyncer.add(args.ctx.publicKey.hex);
|
|
|
|
|
2023-11-18 17:11:07 +00:00
|
|
|
// init conversation list
|
2023-11-28 18:06:49 +00:00
|
|
|
const conversationLists = new DM_List(args.ctx);
|
2023-11-17 07:50:53 +00:00
|
|
|
conversationLists.addEvents(Array.from(args.database.getAllEvents()));
|
2023-10-03 15:15:45 +00:00
|
|
|
|
2023-10-09 21:02:13 +00:00
|
|
|
const dmController = new DirectedMessageController(args.ctx);
|
2023-10-08 22:08:18 +00:00
|
|
|
const groupSyncer = new GroupChatSyncer(args.database, args.pool);
|
2023-10-09 18:39:52 +00:00
|
|
|
const groupChatController = new GroupMessageController(
|
2023-10-08 22:08:18 +00:00
|
|
|
args.ctx,
|
|
|
|
groupSyncer,
|
|
|
|
profileSyncer,
|
|
|
|
);
|
2023-10-09 18:39:52 +00:00
|
|
|
|
|
|
|
(async () => {
|
2023-10-23 06:52:25 +00:00
|
|
|
// load DMs
|
2023-11-17 07:50:53 +00:00
|
|
|
for (const e of args.database.getAllEvents()) {
|
2023-10-23 06:52:25 +00:00
|
|
|
if (e.kind == NostrKind.DIRECT_MESSAGE) {
|
2023-10-09 21:02:13 +00:00
|
|
|
const error = await dmController.addEvent({
|
2023-10-09 18:39:52 +00:00
|
|
|
...e,
|
|
|
|
kind: e.kind,
|
|
|
|
});
|
|
|
|
if (error instanceof Error) {
|
2023-10-23 05:49:45 +00:00
|
|
|
console.error(error.message);
|
|
|
|
await args.database.remove(e.id);
|
2023-10-09 18:39:52 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
continue;
|
2023-10-08 18:51:53 +00:00
|
|
|
}
|
|
|
|
}
|
2023-10-23 06:52:25 +00:00
|
|
|
// load GMs
|
2023-11-17 07:50:53 +00:00
|
|
|
const group_events = await group_GM_events(args.ctx, Array.from(args.database.getAllEvents()));
|
2023-10-23 06:52:25 +00:00
|
|
|
for (const e of group_events.creataions) {
|
|
|
|
const error = await groupChatController.addEvent(e);
|
|
|
|
if (error instanceof Error) {
|
|
|
|
console.error(error, e);
|
|
|
|
await args.database.remove(e.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const e of group_events.invites) {
|
|
|
|
const error = await groupChatController.addEvent(e);
|
|
|
|
if (error instanceof Error) {
|
|
|
|
console.error(error, e);
|
|
|
|
await args.database.remove(e.id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const e of group_events.messages) {
|
|
|
|
const error = await groupChatController.addEvent(e);
|
|
|
|
if (error instanceof Error) {
|
|
|
|
console.error(error, e);
|
|
|
|
await args.database.remove(e.id);
|
|
|
|
}
|
|
|
|
}
|
2023-10-09 18:39:52 +00:00
|
|
|
})();
|
2023-10-08 00:53:54 +00:00
|
|
|
|
2023-10-23 03:59:41 +00:00
|
|
|
const app = new App(
|
2023-10-08 18:51:53 +00:00
|
|
|
args.database,
|
|
|
|
args.model,
|
|
|
|
args.ctx,
|
|
|
|
args.eventBus,
|
|
|
|
args.pool,
|
|
|
|
args.popOverInputChan,
|
|
|
|
args.otherConfig,
|
|
|
|
profileSyncer,
|
|
|
|
eventSyncer,
|
|
|
|
conversationLists,
|
|
|
|
relayConfig,
|
|
|
|
groupChatController,
|
2023-11-25 14:29:50 +00:00
|
|
|
args.lamport,
|
2023-10-09 21:02:13 +00:00
|
|
|
dmController,
|
2023-10-08 18:51:53 +00:00
|
|
|
);
|
2023-11-27 13:35:01 +00:00
|
|
|
await app.initApp(args.installPrompt);
|
2023-10-23 03:59:41 +00:00
|
|
|
return app;
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|
|
|
|
|
2023-11-27 13:35:01 +00:00
|
|
|
private initApp = async (installPrompt: nav.InstallPrompt) => {
|
2023-07-09 07:06:13 +00:00
|
|
|
console.log("App.initApp");
|
2023-09-15 08:58:40 +00:00
|
|
|
|
2023-11-25 13:26:03 +00:00
|
|
|
// configurations: pin list
|
|
|
|
(async () => {
|
|
|
|
const stream = await this.pool.newSub(OtherConfig.name, {
|
|
|
|
authors: [this.ctx.publicKey.hex],
|
2023-11-25 14:29:50 +00:00
|
|
|
kinds: [NostrKind.Encrypted_Custom_App_Data],
|
2023-11-25 13:26:03 +00:00
|
|
|
});
|
|
|
|
if (stream instanceof Error) {
|
|
|
|
throw stream; // crash the app
|
|
|
|
}
|
|
|
|
for await (const msg of stream.chan) {
|
|
|
|
if (msg.res.type == "EOSE") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const ok = await this.database.addEvent(msg.res.event, msg.url);
|
|
|
|
if (ok instanceof Error) {
|
|
|
|
console.error(msg.res.event);
|
|
|
|
console.error(ok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2023-10-08 00:53:54 +00:00
|
|
|
// group chat synchronization
|
2023-09-24 21:56:29 +00:00
|
|
|
(async () => {
|
2023-10-08 21:03:15 +00:00
|
|
|
const stream = await this.pool.newSub("gm_send", {
|
2023-09-24 21:56:29 +00:00
|
|
|
authors: [this.ctx.publicKey.hex],
|
2023-10-07 10:59:06 +00:00
|
|
|
kinds: [NostrKind.Group_Message],
|
2023-09-24 21:56:29 +00:00
|
|
|
});
|
|
|
|
if (stream instanceof Error) {
|
2023-10-08 00:53:54 +00:00
|
|
|
throw stream; // crash the app
|
2023-09-24 21:56:29 +00:00
|
|
|
}
|
|
|
|
for await (const msg of stream.chan) {
|
|
|
|
if (msg.res.type == "EOSE") {
|
|
|
|
continue;
|
|
|
|
}
|
2023-11-16 09:18:30 +00:00
|
|
|
const ok = await this.database.addEvent(msg.res.event, msg.url);
|
2023-10-08 00:53:54 +00:00
|
|
|
if (ok instanceof Error) {
|
2023-10-07 23:23:53 +00:00
|
|
|
console.error(msg.res.event);
|
2023-10-08 00:53:54 +00:00
|
|
|
console.error(ok);
|
2023-10-04 15:07:40 +00:00
|
|
|
}
|
2023-09-24 21:56:29 +00:00
|
|
|
}
|
|
|
|
})();
|
2023-10-08 21:03:15 +00:00
|
|
|
(async () => {
|
|
|
|
const stream = await this.pool.newSub("gm_receive", {
|
|
|
|
"#p": [this.ctx.publicKey.hex],
|
|
|
|
kinds: [NostrKind.Group_Message],
|
|
|
|
});
|
|
|
|
if (stream instanceof Error) {
|
|
|
|
throw stream; // crash the app
|
|
|
|
}
|
|
|
|
for await (const msg of stream.chan) {
|
|
|
|
if (msg.res.type == "EOSE") {
|
|
|
|
continue;
|
|
|
|
}
|
2023-11-16 09:18:30 +00:00
|
|
|
const ok = await this.database.addEvent(msg.res.event, msg.url);
|
2023-10-08 21:03:15 +00:00
|
|
|
if (ok instanceof Error) {
|
|
|
|
console.error(msg.res.event);
|
|
|
|
console.error(ok);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
2023-09-14 21:45:26 +00:00
|
|
|
// Sync DM events
|
2023-09-15 08:58:40 +00:00
|
|
|
(async function sync_dm_events(
|
2023-11-16 13:22:18 +00:00
|
|
|
database: Datebase_View,
|
2023-09-15 08:58:40 +00:00
|
|
|
ctx: NostrAccountContext,
|
|
|
|
pool: ConnectionPool,
|
|
|
|
) {
|
2023-09-14 21:45:26 +00:00
|
|
|
const messageStream = dm.getAllEncryptedMessagesOf(
|
|
|
|
ctx.publicKey,
|
|
|
|
pool,
|
|
|
|
);
|
|
|
|
for await (const msg of messageStream) {
|
|
|
|
if (msg.res.type == "EVENT") {
|
2023-11-16 09:18:30 +00:00
|
|
|
const err = await database.addEvent(msg.res.event, msg.url);
|
2023-09-14 21:45:26 +00:00
|
|
|
if (err instanceof Error) {
|
|
|
|
console.log(err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-15 08:58:40 +00:00
|
|
|
})(this.database, this.ctx, this.pool);
|
2023-09-14 21:45:26 +00:00
|
|
|
|
2023-06-30 14:05:57 +00:00
|
|
|
/* my profile */
|
2023-10-08 00:53:54 +00:00
|
|
|
const myProfileEvent = this.database.getProfilesByPublicKey(this.ctx.publicKey);
|
|
|
|
if (myProfileEvent != undefined) {
|
|
|
|
this.model.myProfile = myProfileEvent.profile;
|
|
|
|
}
|
2023-06-30 14:05:57 +00:00
|
|
|
|
|
|
|
/* contacts */
|
2023-09-24 21:56:29 +00:00
|
|
|
for (const contact of this.conversationLists.convoSummaries.values()) {
|
2023-10-21 11:29:47 +00:00
|
|
|
const editor = this.model.dmEditors.get(contact.pubkey.hex);
|
2023-06-30 14:05:57 +00:00
|
|
|
if (editor == null) {
|
|
|
|
const pubkey = PublicKey.FromHex(contact.pubkey.hex);
|
|
|
|
if (pubkey instanceof Error) {
|
|
|
|
throw pubkey; // impossible
|
|
|
|
}
|
2023-10-21 11:29:47 +00:00
|
|
|
this.model.dmEditors.set(
|
2023-06-30 14:05:57 +00:00
|
|
|
contact.pubkey.hex,
|
2023-10-07 10:59:06 +00:00
|
|
|
new_DM_EditorModel(
|
2023-06-30 14:05:57 +00:00
|
|
|
pubkey,
|
2023-10-07 10:59:06 +00:00
|
|
|
),
|
2023-06-30 14:05:57 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-14 21:45:26 +00:00
|
|
|
this.profileSyncer.add(
|
2023-09-24 21:56:29 +00:00
|
|
|
...Array.from(this.conversationLists.convoSummaries.keys()),
|
2023-06-30 14:05:57 +00:00
|
|
|
);
|
2023-09-14 21:45:26 +00:00
|
|
|
console.log("user set", this.profileSyncer.userSet);
|
2023-06-30 14:05:57 +00:00
|
|
|
|
2023-07-09 07:06:13 +00:00
|
|
|
// Database
|
2023-06-30 14:05:57 +00:00
|
|
|
(async () => {
|
2023-07-09 07:06:13 +00:00
|
|
|
let i = 0;
|
2023-06-30 14:05:57 +00:00
|
|
|
for await (
|
|
|
|
let _ of Database_Update(
|
2023-09-15 08:58:40 +00:00
|
|
|
this.ctx,
|
2023-06-30 14:05:57 +00:00
|
|
|
this.database,
|
|
|
|
this.model,
|
2023-07-09 07:06:13 +00:00
|
|
|
this.profileSyncer,
|
|
|
|
this.lamport,
|
2023-09-24 21:56:29 +00:00
|
|
|
this.conversationLists,
|
2023-10-08 00:53:54 +00:00
|
|
|
this.groupChatController,
|
2023-10-09 18:39:52 +00:00
|
|
|
this.dmController,
|
2023-10-15 22:39:21 +00:00
|
|
|
this.eventBus.emit,
|
2023-11-25 13:26:03 +00:00
|
|
|
{
|
|
|
|
otherConfig: this.otherConfig,
|
|
|
|
},
|
2023-06-30 14:05:57 +00:00
|
|
|
)
|
|
|
|
) {
|
2023-09-15 08:58:40 +00:00
|
|
|
const t = Date.now();
|
2023-09-06 16:29:27 +00:00
|
|
|
render(
|
|
|
|
AppComponent({
|
|
|
|
eventBus: this.eventBus,
|
|
|
|
model: this.model,
|
2023-09-15 08:58:40 +00:00
|
|
|
pool: this.pool,
|
2023-09-10 17:56:37 +00:00
|
|
|
popOverInputChan: this.popOverInputChan,
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt: installPrompt,
|
2023-09-06 16:29:27 +00:00
|
|
|
}),
|
|
|
|
document.body,
|
|
|
|
);
|
2023-09-15 08:58:40 +00:00
|
|
|
console.log(`Database_Update: render ${++i} times, ${Date.now() - t}`);
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|
|
|
|
})();
|
|
|
|
};
|
|
|
|
|
|
|
|
logout = () => {
|
|
|
|
setSignInState("none");
|
|
|
|
window.location.reload();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function AppComponent(props: {
|
2023-07-11 10:45:57 +00:00
|
|
|
model: Model;
|
|
|
|
eventBus: AppEventBus;
|
2023-09-06 16:29:27 +00:00
|
|
|
pool: ConnectionPool;
|
2023-09-10 17:56:37 +00:00
|
|
|
popOverInputChan: PopOverInputChannel;
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt: nav.InstallPrompt;
|
2023-06-30 14:05:57 +00:00
|
|
|
}) {
|
|
|
|
const t = Date.now();
|
2023-07-11 10:45:57 +00:00
|
|
|
const model = props.model;
|
|
|
|
|
|
|
|
if (model.app == undefined) {
|
2023-06-30 14:05:57 +00:00
|
|
|
console.log("render sign in page");
|
2023-11-09 14:43:10 +00:00
|
|
|
return <SignIn emit={props.eventBus.emit} />;
|
2023-06-30 14:05:57 +00:00
|
|
|
}
|
|
|
|
|
2023-07-11 10:45:57 +00:00
|
|
|
const app = model.app;
|
2023-09-15 08:58:40 +00:00
|
|
|
const myAccountCtx = model.app.ctx;
|
2023-07-11 10:45:57 +00:00
|
|
|
|
2023-06-30 14:05:57 +00:00
|
|
|
let dmVNode;
|
|
|
|
let aboutNode;
|
|
|
|
if (
|
2023-07-11 10:45:57 +00:00
|
|
|
model.navigationModel.activeNav == "DM" ||
|
|
|
|
model.navigationModel.activeNav == "About"
|
2023-06-30 14:05:57 +00:00
|
|
|
) {
|
2023-07-11 10:45:57 +00:00
|
|
|
if (model.navigationModel.activeNav == "DM") {
|
2023-06-30 14:05:57 +00:00
|
|
|
dmVNode = (
|
|
|
|
<div
|
|
|
|
class={tw`flex-1 overflow-hidden`}
|
|
|
|
>
|
|
|
|
{DirectMessageContainer({
|
2023-07-11 10:45:57 +00:00
|
|
|
...model.dm,
|
|
|
|
rightPanelModel: model.rightPanelModel,
|
2023-10-04 21:34:43 +00:00
|
|
|
bus: app.eventBus,
|
|
|
|
ctx: myAccountCtx,
|
2023-10-06 00:05:35 +00:00
|
|
|
profileGetter: app.database,
|
2023-09-06 16:29:27 +00:00
|
|
|
pool: props.pool,
|
2023-10-04 15:07:40 +00:00
|
|
|
conversationLists: app.conversationLists,
|
2023-07-05 05:50:34 +00:00
|
|
|
profilesSyncer: app.profileSyncer,
|
2023-07-05 09:32:02 +00:00
|
|
|
eventSyncer: app.eventSyncer,
|
2023-10-01 22:21:55 +00:00
|
|
|
pinListGetter: app.otherConfig,
|
2023-10-04 15:07:40 +00:00
|
|
|
groupChatController: app.groupChatController,
|
2023-10-07 20:40:18 +00:00
|
|
|
newMessageChecker: app.conversationLists,
|
2023-11-20 09:14:17 +00:00
|
|
|
messageGetter: model.dm.isGroupMessage ? app.groupChatController : app.dmController,
|
|
|
|
newMessageListener: model.dm.isGroupMessage
|
|
|
|
? app.groupChatController
|
|
|
|
: app.dmController,
|
2023-11-23 04:28:45 +00:00
|
|
|
relayRecordGetter: app.database,
|
2023-06-30 14:05:57 +00:00
|
|
|
})}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-07-11 10:45:57 +00:00
|
|
|
if (model.navigationModel.activeNav == "About") {
|
2023-06-30 14:05:57 +00:00
|
|
|
aboutNode = About();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-30 06:39:53 +00:00
|
|
|
console.debug("AppComponent:2", Date.now() - t);
|
|
|
|
|
2023-06-30 14:05:57 +00:00
|
|
|
const final = (
|
|
|
|
<div
|
|
|
|
class={tw`font-roboto flex flex-col h-screen w-screen overflow-hidden`}
|
|
|
|
>
|
|
|
|
<div class={tw`w-full h-full flex flex-col`}>
|
|
|
|
<div class={tw`w-full flex-1 flex overflow-hidden`}>
|
|
|
|
<div class={tw`mobile:hidden`}>
|
2023-11-02 13:10:16 +00:00
|
|
|
<nav.NavBar
|
|
|
|
publicKey={app.ctx.publicKey}
|
|
|
|
profileGetter={app.database}
|
|
|
|
emit={app.eventBus.emit}
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt={props.installPrompt}
|
2023-11-02 13:10:16 +00:00
|
|
|
/>
|
2023-06-30 14:05:57 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
2023-11-13 06:20:13 +00:00
|
|
|
class={tw`h-full px-[3rem] mobile:px-4 bg-[${SecondaryBackgroundColor}] flex-1 overflow-auto${
|
2023-07-11 10:45:57 +00:00
|
|
|
model.navigationModel.activeNav == "Profile" ? " block" : " hidden"
|
2023-06-30 14:05:57 +00:00
|
|
|
}`}
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
class={tw`max-w-[35rem] h-full m-auto`}
|
|
|
|
>
|
2023-10-23 13:57:58 +00:00
|
|
|
<EditProfile
|
|
|
|
ctx={model.app.ctx}
|
|
|
|
profileGetter={app.database}
|
|
|
|
emit={props.eventBus.emit}
|
|
|
|
/>
|
2023-06-30 14:05:57 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{dmVNode}
|
|
|
|
{aboutNode}
|
2023-10-26 04:42:24 +00:00
|
|
|
{Setting({
|
|
|
|
show: model.navigationModel.activeNav == "Setting",
|
|
|
|
logout: app.logout,
|
|
|
|
relayConfig: app.relayConfig,
|
|
|
|
myAccountContext: myAccountCtx,
|
|
|
|
relayPool: props.pool,
|
|
|
|
emit: props.eventBus.emit,
|
|
|
|
})}
|
2023-09-10 17:56:37 +00:00
|
|
|
<Popover
|
|
|
|
inputChan={props.popOverInputChan}
|
|
|
|
/>
|
2023-06-30 14:05:57 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class={tw`desktop:hidden`}>
|
2023-11-15 11:35:02 +00:00
|
|
|
{!model.dm.currentEditor
|
|
|
|
? (
|
|
|
|
<nav.NavBar
|
|
|
|
publicKey={app.ctx.publicKey}
|
|
|
|
profileGetter={app.database}
|
|
|
|
emit={app.eventBus.emit}
|
|
|
|
isMobile={true}
|
2023-11-27 13:35:01 +00:00
|
|
|
installPrompt={props.installPrompt}
|
2023-11-15 11:35:02 +00:00
|
|
|
/>
|
|
|
|
)
|
|
|
|
: <div class={tw`h-4 bg-[#36393F]`}></div>}
|
2023-06-30 14:05:57 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
2023-07-13 13:52:52 +00:00
|
|
|
console.debug("AppComponent:end", Date.now() - t);
|
2023-06-30 14:05:57 +00:00
|
|
|
return final;
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: move to somewhere else
|
|
|
|
export function getFocusedContent(
|
|
|
|
focusedContent: PublicKey | NostrEvent | undefined,
|
2023-10-07 20:40:18 +00:00
|
|
|
profileGetter: ProfileGetter,
|
2023-06-30 14:05:57 +00:00
|
|
|
) {
|
|
|
|
if (focusedContent == undefined) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (focusedContent instanceof PublicKey) {
|
2023-10-07 20:40:18 +00:00
|
|
|
const profileData = profileGetter.getProfilesByPublicKey(focusedContent)?.profile;
|
2023-06-30 14:05:57 +00:00
|
|
|
return {
|
|
|
|
type: "ProfileData" as "ProfileData",
|
|
|
|
data: profileData,
|
|
|
|
pubkey: focusedContent,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|