Iframe com
This commit is contained in:
Generated
+33
@@ -43,6 +43,7 @@
|
|||||||
"pg": "^8.16.3",
|
"pg": "^8.16.3",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "19.1.0",
|
||||||
|
"react-iframes-bridge": "^1.0.1",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
@@ -4802,6 +4803,16 @@
|
|||||||
"react": ">=16.13.1"
|
"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": {
|
"node_modules/react-markdown": {
|
||||||
"version": "10.1.0",
|
"version": "10.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
|
"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"
|
"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": {
|
"node_modules/vfile": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz",
|
||||||
@@ -5483,6 +5507,15 @@
|
|||||||
"url": "https://github.com/sponsors/dmonad"
|
"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": {
|
"node_modules/zustand": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
"pg": "^8.16.3",
|
"pg": "^8.16.3",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "19.1.0",
|
||||||
|
"react-iframes-bridge": "^1.0.1",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import MessageBox from "@/components/MessageBox";
|
import MessageBox from "@/components/channel/MessageBox";
|
||||||
import AppLayout from "@/components/app/AppLayout";
|
import AppLayout from "@/components/app/AppLayout";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import useApp from "@/hooks/use-app";
|
import useApp from "@/hooks/use-app";
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useParams, useSearchParams } from "next/navigation";
|
import { useParams, useSearchParams } from "next/navigation";
|
||||||
import MessageBox from "@/components/MessageBox";
|
import MessageBox from "@/components/channel/MessageBox";
|
||||||
import AppLayout from "@/components/app/AppLayout";
|
import AppLayout from "@/components/app/AppLayout";
|
||||||
import { Server as ServerType } from "@/types/types";
|
import { Server as ServerType } from "@/types/types";
|
||||||
import auth from "@/lib/auth";
|
import auth from "@/lib/auth";
|
||||||
import { useServerMessages } from "@/hooks/use-messages";
|
import { useServerMessages } from "@/hooks/use-messages";
|
||||||
import useApp from "@/hooks/use-app";
|
import useApp from "@/hooks/use-app";
|
||||||
import { useEffectOnceWhenReady } from "@/hooks/use-once";
|
import { useEffectOnceWhenReady } from "@/hooks/use-once";
|
||||||
import ChannelView from "@/components/ChannelView";
|
import ChannelView from "@/components/channel/ChannelView";
|
||||||
|
|
||||||
export default function Server() {
|
export default function Server() {
|
||||||
const { ip } = useParams<{ ip: string }>();
|
const { ip } = useParams<{ ip: string }>();
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Channel, Message, Server } from "@/types/types";
|
import { Channel, Message, Server } from "@/types/types";
|
||||||
import MessageBox from "./MessageBox";
|
import MessageBox from "./MessageBox";
|
||||||
import App from "@/types/app";
|
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({
|
export default function ChannelView({
|
||||||
app,
|
app,
|
||||||
@@ -47,6 +48,13 @@ export default function ChannelView({
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
default:
|
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";
|
"use client";
|
||||||
|
|
||||||
import { Message } from "@/types/types";
|
import { Message } from "@/types/types";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "../ui/button";
|
||||||
import { Input } from "./ui/input";
|
import { Input } from "../ui/input";
|
||||||
import * as emoji from "emoji-picker-react";
|
import * as emoji from "emoji-picker-react";
|
||||||
import EmojiPicker from "emoji-picker-react";
|
import EmojiPicker from "emoji-picker-react";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from "./ui/dropdown-menu";
|
} from "../ui/dropdown-menu";
|
||||||
import { ChevronLeftIcon, SendIcon, SmilePlusIcon } from "lucide-react";
|
import { ChevronLeftIcon, SendIcon, SmilePlusIcon } from "lucide-react";
|
||||||
import { useRef, useState } from "react";
|
import { useRef, useState } from "react";
|
||||||
import { format, isToday, isYesterday } from "date-fns";
|
import { format, isToday, isYesterday } from "date-fns";
|
||||||
import ReactMarkdown from "react-markdown";
|
import ReactMarkdown from "react-markdown";
|
||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import { UserProfile } from "@/hooks/get-user";
|
import { UserProfile } from "@/hooks/get-user";
|
||||||
import ProfilePicture from "./ProfilePicture";
|
import ProfilePicture from "../ProfilePicture";
|
||||||
import App from "@/types/app";
|
import App from "@/types/app";
|
||||||
import { Textarea } from "./ui/textarea";
|
import { Textarea } from "../ui/textarea";
|
||||||
|
|
||||||
function MessageContainer({ message, app }: { message: Message; app: App }) {
|
function MessageContainer({ message, app }: { message: Message; app: App }) {
|
||||||
const [profile, setProfile] = useState<UserProfile | null>();
|
const [profile, setProfile] = useState<UserProfile | null>();
|
||||||
@@ -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} />
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user