-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathTextBox.js
More file actions
154 lines (138 loc) · 5.28 KB
/
Copy pathTextBox.js
File metadata and controls
154 lines (138 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { Button, Tabs, Dropdown, Menu, Space, Tooltip, message } from "antd";
const { TabPane } = Tabs;
import {
DownOutlined,
PlayCircleOutlined,
FullscreenOutlined,
FullscreenExitOutlined,
ShareAltOutlined
} from "@ant-design/icons"; // Combined all icons here
import { useIsMobile } from "./useIsMobile";
import React, { useState, useEffect } from 'react';
import preinstalled_programs from "../utils/preinstalled_programs";
import { encodeSnippet } from "../utils/snippet";
import dynamic from 'next/dynamic'
const Editor = dynamic(import('./Editor'), {
ssr: false
})
function TextBox({ disabled, sourceCode, setSourceCode, exampleName, setExampleName, activeTab, handleUserTabChange, myHeight,sourceUrl,setSourceUrl }) {
const isMobile = useIsMobile();
const [isFullScreen, setIsFullScreen] = useState(false);
// Listen for fullscreen changes (Esc key, browser buttons, etc.)
useEffect(() => {
const handler = () => setIsFullScreen(!!document.fullscreenElement);
document.addEventListener("fullscreenchange", handler);
return () => document.removeEventListener("fullscreenchange", handler);
}, []);
const handleFullScreen = () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
document.exitFullscreen();
}
};
const handleShare = () => {
// Step 1: Guard against sharing local/manual code without an external source
if (!sourceUrl) {
message.warning("Only code loaded from an external source (Gist/Snippet) can be shared.");
return;
}
// Step 2: Debug log before encoding to ensure the source URL is correct
console.log("[Share] Encoding:", sourceUrl);
// Step 3: Encode the full raw URL and build a clean base link
const hash = encodeSnippet(sourceUrl);
const shareLink = `${window.location.origin}?snippet=${hash}`;
// Step 4: Write to clipboard with success/error feedback
navigator.clipboard.writeText(shareLink)
.then(() => {
message.success("Shareable link copied to clipboard!");
})
.catch((err) => {
console.error("[Share] Clipboard Error:", err);
message.error("Failed to copy link.");
});
};
var menu_items = [];
for (let category in preinstalled_programs) {
var category_examples = []
for (let example in preinstalled_programs[category]) {
category_examples.push({
key: example,
label: example,
onClick: () => {
setSourceCode(preinstalled_programs[category][example]);
setExampleName(example);
if (setSourceUrl) setSourceUrl(""); // Clear the external URL
}
});
}
menu_items.push({
key: category,
label: category,
children: category_examples
});
}
const examples_menu = (<Menu items={menu_items}></Menu>);
const extraOperations = {
right: (
<Space>
{/* Tooltip provides UX context for why the button might be disabled */}
<Tooltip title={sourceUrl ? "Share this snippet" : "Load an external source to enable sharing"}>
<Button
icon={<ShareAltOutlined />}
onClick={handleShare}
disabled={!sourceUrl} // Ensures sharing only works for external sources
>
{!isMobile && "Share"}
</Button>
</Tooltip>
<Button
onClick={handleFullScreen}
icon={isFullScreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
>
{!isMobile && (isFullScreen ? " Exit Fullscreen" : " Fullscreen")}
</Button>
<Button
disabled={disabled}
onClick={() => handleUserTabChange(activeTab)}
icon={<PlayCircleOutlined />}
>
Run
</Button>
</Space>
),
left: (
<Dropdown menu={{ items: menu_items }} trigger={["hover"]}>
<a onClick={(e) => e.preventDefault()}>
<Space style={{ marginRight: "10px" }}>
{!isMobile && "Examples"} <DownOutlined />
</Space>
</a>
</Dropdown>
)
};
const tabItems = [
{
key: '1',
label: `${exampleName}.f90`,
children: (
<div style={{ height: myHeight }}>
<Editor
sourceCode={sourceCode}
setSourceCode={setSourceCode}
/>
</div>
),
},
];
return (
<div className="card-container" style={{height: "100%" }}>
<Tabs
tabBarExtraContent={extraOperations}
style={{ height: "100%" }}
items={tabItems}
/>
</div>
);
}
export default TextBox;