Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/next/components/share/file-contents.tsx
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import Markdown from "@cocalc/frontend/editors/slate/static-markdown";6import {7isAudio,8isCodemirror,9isHTML,10isImage,11isMarkdown,12isVideo,13} from "@cocalc/frontend/file-extensions";14import Slides from "@cocalc/frontend/frame-editors/slides-editor/share";15import Whiteboard from "@cocalc/frontend/frame-editors/whiteboard-editor/share/index";16import JupyterNotebook from "@cocalc/frontend/jupyter/nbviewer/nbviewer";17import { FileContext } from "@cocalc/frontend/lib/file-context";18import A from "components/misc/A";19import { isIOS, isSafari } from "lib/share/feature";20import rawURL from "lib/share/raw-url";21import getUrlTransform from "lib/share/url-transform";22import { containingPath, getExtension } from "lib/share/util";23import useCustomize from "lib/use-customize";24import getAnchorTagComponent from "./anchor-tag-component";25import CodeMirror from "./codemirror";26import SageWorksheet from "./sage-worksheet";2728interface Props {29id: string;30content?: string;31relativePath: string;32path: string;33truncated?: boolean;34jupyter_api?: boolean;35}3637export default function FileContents({38id,39content,40path,41relativePath,42jupyter_api,43}: Props): JSX.Element {44const filename = relativePath ? relativePath : path;45const ext = getExtension(filename);46const raw = rawURL({ id, path, relativePath });47const { jupyterApiEnabled } = useCustomize();4849const withFileContext = (x) => {50const relPath = containingPath(relativePath);51const value = {52urlTransform: getUrlTransform({ id, path, relativePath: relPath }),53AnchorTagComponent: getAnchorTagComponent({ id, relativePath: relPath }),54jupyterApiEnabled: jupyterApiEnabled && jupyter_api,55noSanitize: false, // We **MUST** sanitize, since we users could launch XSS attacks, mess up style, etc.,56// This will, of course, break things, in which case users will have to open them in their own projects.57};58return <FileContext.Provider value={value}>{x}</FileContext.Provider>;59};6061if (isImage(ext)) {62return <img src={raw} style={{ maxWidth: "100%" }} />;63} else if (isVideo(ext)) {64return (65<video66controls={true}67autoPlay={true}68loop={true}69style={{ width: "100%", height: "auto" }}70src={raw}71/>72);73} else if (isAudio(ext)) {74return <audio src={raw} autoPlay={true} controls={true} loop={false} />;75} else if (ext === "pdf") {76// iOS and iPADOS does not have any way to embed PDF's in pages.77// I think pretty much every other web browser does, though78// strangely even desktop Safari seems often broken, so we also block that.79// Amazingly, nextjs handles this sort of thing fine!80return isIOS() || isSafari() ? (81<h1 style={{ textAlign: "center", margin: "30px" }}>82<A href={raw} external>83View this PDF...84</A>85</h1>86) : (87<embed88style={{ width: "100%", height: "100vh" }}89src={raw}90type="application/pdf"91/>92);93} else if (content == null) {94return (95<h1 style={{ textAlign: "center", margin: "30px" }}>96<A href={raw} external>97Open or Download...98</A>{" "}99</h1>100);101} else if (isCodemirror(ext)) {102return <CodeMirror content={content} filename={filename} />;103} else if (isMarkdown(ext)) {104return withFileContext(<Markdown value={content} />);105} else if (isHTML(ext)) {106// We use a sandboxed iframe since it is much more likely to be107// useful to users than our HTML component. Most use of our108// HTML component with math rendering, etc., is much better done109// via a Markdown file. This makes it easy to show, e.g.,110// static k3d plots, which CUP is doing. HTML files tend to111// be independent of cocalc anyways.112return (113<iframe114srcDoc={content}115style={{ width: "100%", height: "100vh" }}116sandbox="allow-scripts"117/>118);119// return withFileContext(120// <HTML value={content} style={{ width: "100%", height: "100vh" }} />121// );122} else if (ext == "sagews") {123return withFileContext(<SageWorksheet content={content} />);124} else if (ext == "ipynb") {125return withFileContext(<JupyterNotebook content={content} />);126} else if (ext == "board") {127return withFileContext(<Whiteboard content={content} />);128} else if (ext == "slides") {129return withFileContext(<Slides content={content} />);130}131return <pre>{content}</pre>;132}133134135