Iframe com

This commit is contained in:
2025-12-10 21:55:20 +01:00
parent acb8c34df6
commit e585aa9458
7 changed files with 102 additions and 10 deletions
+33
View File
@@ -43,6 +43,7 @@
"pg": "^8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-iframes-bridge": "^1.0.1",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"sonner": "^2.0.7",
@@ -4802,6 +4803,16 @@
"react": ">=16.13.1"
}
},
"node_modules/react-iframes-bridge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/react-iframes-bridge/-/react-iframes-bridge-1.0.1.tgz",
"integrity": "sha512-sjUbHOF7x23nZCek+i3okMasTBYKhvlJXYZe3IBvF/8GAspEG/uHxeoVvLmTj2IZKdUTcKBPNCqCB8lz6LFxTQ==",
"license": "MIT",
"dependencies": {
"uuid": "^9.0.0",
"zod": "^3.22.4"
}
},
"node_modules/react-markdown": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
@@ -5381,6 +5392,19 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/vfile": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
@@ -5483,6 +5507,15 @@
"url": "https://github.com/sponsors/dmonad"
}
},
"node_modules/zod": {
"version": "3.25.76",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zustand": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
+1
View File
@@ -46,6 +46,7 @@
"pg": "^8.16.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-iframes-bridge": "^1.0.1",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"sonner": "^2.0.7",
+1 -1
View File
@@ -1,6 +1,6 @@
"use client";
import MessageBox from "@/components/MessageBox";
import MessageBox from "@/components/channel/MessageBox";
import AppLayout from "@/components/app/AppLayout";
import { useParams, useRouter } from "next/navigation";
import useApp from "@/hooks/use-app";
+2 -2
View File
@@ -2,14 +2,14 @@
import { useEffect, useRef, useState } from "react";
import { useParams, useSearchParams } from "next/navigation";
import MessageBox from "@/components/MessageBox";
import MessageBox from "@/components/channel/MessageBox";
import AppLayout from "@/components/app/AppLayout";
import { Server as ServerType } from "@/types/types";
import auth from "@/lib/auth";
import { useServerMessages } from "@/hooks/use-messages";
import useApp from "@/hooks/use-app";
import { useEffectOnceWhenReady } from "@/hooks/use-once";
import ChannelView from "@/components/ChannelView";
import ChannelView from "@/components/channel/ChannelView";
export default function Server() {
const { ip } = useParams<{ ip: string }>();
@@ -1,7 +1,8 @@
import { Channel, Message, Server } from "@/types/types";
import MessageBox from "./MessageBox";
import App from "@/types/app";
import React, { Ref } from "react";
import React, { Ref, useEffect, useRef } from "react";
import PluginChannel from "./PluginChannel";
export default function ChannelView({
app,
@@ -47,6 +48,13 @@ export default function ChannelView({
return null;
default:
return <iframe src={app.currentChannel.kind} className="w-full" />;
return (
<PluginChannel
app={app}
messages={messages}
ip={ip}
serverRef={serverRef}
/>
);
}
}
@@ -1,24 +1,24 @@
"use client";
import { Message } from "@/types/types";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Button } from "../ui/button";
import { Input } from "../ui/input";
import * as emoji from "emoji-picker-react";
import EmojiPicker from "emoji-picker-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuTrigger,
} from "./ui/dropdown-menu";
} from "../ui/dropdown-menu";
import { ChevronLeftIcon, SendIcon, SmilePlusIcon } from "lucide-react";
import { useRef, useState } from "react";
import { format, isToday, isYesterday } from "date-fns";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import { UserProfile } from "@/hooks/get-user";
import ProfilePicture from "./ProfilePicture";
import ProfilePicture from "../ProfilePicture";
import App from "@/types/app";
import { Textarea } from "./ui/textarea";
import { Textarea } from "../ui/textarea";
function MessageContainer({ message, app }: { message: Message; app: App }) {
const [profile, setProfile] = useState<UserProfile | null>();
+50
View File
@@ -0,0 +1,50 @@
import { Message } from "@/types/types";
import App from "@/types/app";
import React, { useEffect, useRef } from "react";
import { useParentCommunication } from "react-iframes-bridge";
export default function PluginChannel({
app,
messages,
ip,
serverRef,
}: {
app: App;
messages: Record<string, Message[]>;
ip: string;
serverRef: React.RefObject<WebSocket | null>;
}) {
if (!app.currentChannel)
return (
<div className="h-svh w-full max-h-svh flex flex-col pb-5 pl-5 gap-5" />
);
const iframeRef = useRef<HTMLIFrameElement>(null);
const parentComm = useParentCommunication(iframeRef, {
allowedOrigins: [new URL(app.currentChannel.kind).origin],
communication: { debug: false },
});
useEffect(() => {
parentComm.onMessage("GET_MESSAGES", () => {
parentComm.sendToChild("MESSAGES", messages);
});
parentComm.onMessage("SEND_MESSAGE", (msg: string) => {
serverRef.current?.send(
JSON.stringify({
type: "send_message",
params: {
channel_id: app.currentChannel?.id,
contents: msg,
},
})
);
});
}, [parentComm]);
return (
<iframe src={app.currentChannel.kind} className="w-full" ref={iframeRef} />
);
}