Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions infrastructure/socket.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { type Socket, io } from "socket.io-client";

import type { JsonValue, RefContent } from "../../backend/pkg/index.ts";

/** Messages handled by the `SocketServer`. */
export type Handlers = {
create_doc: (data: RefContent, callback: (docId: string) => void) => void;
get_doc: (refId: string, callback: (docId: string | null) => void) => void;
};

/** Messages emitted by the `SocketServer`. */
export type Requests = {
autosave: (data: RefContent) => void;
};

/** Encapsulates socket.io for internal communication with the backend.

Intermediates between the backend server written in Rust and the Automerge
server running in this Node process.
*/
export class SocketServer {
private socket: Socket<Handlers, Requests>;

constructor(
port: number | string,
handlers: {
createDoc: (data: RefContent) => string;
getDoc: (refId: string) => string | null;
},
) {
const socket: Socket<Handlers, Requests> = io(`http://localhost:${port}`);

socket.on("create_doc", (data, callback) => callback(handlers.createDoc(data)));
socket.on("get_doc", (refId, callback) => callback(handlers.getDoc(refId)));

this.socket = socket;
}

autosave(refId: string, content: JsonValue) {
this.socket.emit("autosave", { refId, content });
}

close() {
this.socket.close();
}
}
10 changes: 10 additions & 0 deletions packages/frontend/src/model/model_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import "./model_editor.css";

import ChartSpline from "lucide-solid/icons/chart-spline";
import Network from "lucide-solid/icons/network";
import { sharingLink, sharingLinkPopup } from './share_model';
import { Copy, Link2 } from "lucide-solid";

export default function ModelPage() {
const params = useParams();
Expand Down Expand Up @@ -67,8 +69,12 @@ export function ModelDocumentEditor(props: {

return (
<div class="growable-container">

<BrandedToolbar>
<HelpButton />
<IconButton onClick={() => sharingLinkPopup({sharingLink: sharingLink})} tooltip="Share model">
<Link2 />
</IconButton>
<MaybePermissionsButton permissions={props.liveModel?.liveDoc.permissions} />
<Show when={props.liveModel?.theory()?.supportsInstances}>
<IconButton
Expand Down Expand Up @@ -116,6 +122,7 @@ export function ModelPane(props: {
placeholder="Untitled"
/>
</div>

<TheorySelectorDialog
theory={props.liveModel.theory()}
setTheory={(id) => {
Expand Down Expand Up @@ -210,3 +217,6 @@ function judgmentLabel(judgment: ModelJudgment): string | undefined {
return theory?.modelMorTypeMeta(judgment.morType)?.name;
}
}



44 changes: 44 additions & 0 deletions packages/frontend/src/model/share_model.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { RefDoc } from '../../../backend/pkg/src/RefDoc';
import { Doc, DocHandle } from "@automerge/automerge-repo";
import Dialog from "@corvu/dialog"
import {SocketServer } from '../../../../infrastructure/socket';
import { IconButton } from '../components';
import { Copy, Icon, Link2 } from 'lucide-solid';




export function sharingLink(props: { Ref: RefDoc, socketServer: SocketServer, linktoShare: string }) {
let copied = false;
const doctoShare = props.socketServer.autosave;
console.log(doctoShare)
async function copy(doctoShare: string) {
try {
await navigator.clipboard.writeText(doctoShare);
if (!copied) {
copied = true;
setTimeout(() => (copied = false), 2000);
}
} catch (error: any) {
alert(error.message);
}
}
}

export function sharingLinkPopup(props: {sharingLink: any}) {
return (
<Dialog>
<Dialog.Trigger />
<Dialog.Portal>
<Dialog.Overlay />
<Dialog.Content>
Share model
<Link2 onClick={() => sharingLink({ Ref: props.sharingLink.Ref, socketServer: props.sharingLink.socketServer, linktoShare: props.sharingLink.linktoShare })} />
<Dialog.Close />
<Dialog.Label />
<Dialog.Description />
</Dialog.Content>
</Dialog.Portal>
</Dialog>
)
}
Loading