CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/components/app/iframe.tsx
Views: 687
1
import { Button, Popover } from "antd";
2
import { Icon } from "@cocalc/frontend/components/icon";
3
import { CSSProperties, useRef, useState } from "react";
4
import SiteName from "components/share/site-name";
5
import A from "components/misc/A";
6
import { trunc_middle } from "@cocalc/util/misc";
7
8
interface Props {
9
src: string;
10
appURL?: string;
11
path?: string;
12
style?: CSSProperties;
13
fullscreen?: boolean;
14
description?: string;
15
start?: boolean; // if true, immediately load iframe rather than waiting for user to click a button.
16
}
17
18
export default function IFrame({
19
src: src0,
20
appURL,
21
path,
22
style,
23
fullscreen: fullscreen0,
24
start: start0,
25
description,
26
}: Props) {
27
const [fullscreen, setFullscreen] = useState<boolean>(!!fullscreen0);
28
const [reload, setReload] = useState<number>(0);
29
const iframeRef = useRef<any>(null);
30
const [start, setStart] = useState<boolean>(!!start0);
31
32
const url = new URL("http://example.com" + src0);
33
url.search += (url.search ? "&" : "") + `reload=${reload}`;
34
const src = url.pathname + url.search + url.hash;
35
36
return (
37
<div
38
style={
39
fullscreen
40
? {
41
position: "fixed",
42
top: 0,
43
left: 0,
44
width: "100vw",
45
height: "100vh",
46
zIndex: 1000,
47
background: "white",
48
}
49
: {
50
padding: "5px 15px",
51
height: start ? "95vh" : undefined,
52
border: "1px solid #ddd",
53
borderRadius: "5px",
54
boxShadow: "5px 5px 5px #eee",
55
display: "flex",
56
flexDirection: "column",
57
background: "white",
58
...style,
59
}
60
}
61
>
62
<div>
63
{start && (
64
<div style={{ display: "flex" }}>
65
<Button
66
title="Reload this"
67
size="small"
68
type="text"
69
onClick={() => {
70
setReload(reload + 1);
71
//iframeRef.current?.contentWindow.location.reload();
72
}}
73
>
74
<Icon name={"reload"} />
75
</Button>
76
<div
77
style={{
78
flex: 1,
79
textAlign: "center",
80
paddingTop: "2.5px",
81
paddingLeft: fullscreen ? "15px" : undefined,
82
}}
83
>
84
{appURL && (
85
<Popover
86
title="Open in the App"
87
content={
88
<div style={{ maxWidth: "350px" }}>
89
Open {path} in the <SiteName /> app for more options and
90
to see your other files...
91
</div>
92
}
93
>
94
<A href={appURL} external>
95
<Icon name="external-link" style={{ marginRight: "5px" }} />
96
{path ? trunc_middle(path, 50) : ""}
97
</A>
98
</Popover>
99
)}
100
</div>
101
<Button
102
size="small"
103
type="text"
104
title="Full screen"
105
onClick={() => {
106
if (!fullscreen) {
107
document.documentElement.requestFullscreen();
108
} else {
109
if (document.fullscreenElement) {
110
document.exitFullscreen();
111
}
112
}
113
setFullscreen(!fullscreen);
114
}}
115
>
116
<Icon name={fullscreen ? "compress" : "expand"} />
117
</Button>
118
</div>
119
)}
120
</div>
121
{start && <hr style={{ width: "100%" }} />}
122
{!start ? (
123
<Button
124
style={{ margin: "15px auto" }}
125
size="large"
126
type="primary"
127
shape="round"
128
onClick={() => setStart(true)}
129
>
130
<span style={{ marginRight: "10px" }}>
131
<Icon name={"run"} />{" "}
132
</span>{" "}
133
Load {description ?? "Editor"}...
134
</Button>
135
) : (
136
<iframe
137
ref={iframeRef}
138
src={src}
139
width={"100%"}
140
height={"100%"}
141
frameBorder="0"
142
/>
143
)}
144
</div>
145
);
146
}
147
148