Skip to content

Commit

Permalink
Update markdown viewer (same as editor preview) and add image upload …
Browse files Browse the repository at this point in the history
…to editor (#931)

* update markdown viewer

* add viewer to blog editor

* fix tests

* more fixes

* fix proposal test

* add image uploader

* fix tests

* remove `scrollIntoViewIfNeeded`
  • Loading branch information
Megha-Dev-19 authored Sep 23, 2024
1 parent 4a10f82 commit b781c7f
Show file tree
Hide file tree
Showing 32 changed files with 460 additions and 199 deletions.
1 change: 1 addition & 0 deletions instances/devhub.near/widget/config/css.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const CssContainer = styled.div`
a {
color: inherit;
text-decoration: inherit;
}
.attractable {
Expand Down
214 changes: 149 additions & 65 deletions instances/devhub.near/widget/devhub/components/molecule/Compose.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const Compose = ({
onChangeKeyup,
handler,
sortedRelevantUsers,
isTailwind,
}) => {
State.init({
data: data,
Expand All @@ -50,73 +51,156 @@ const Compose = ({
}
}, [data, handler]);

return (
<Wrapper>
<div className="card">
<div className="card-header" style={{ position: "relative" }}>
<div>
<ul class="nav nav-tabs">
<li class="nav-item">
<button
class={`nav-link ${
state.selectedTab === "editor" ? "active" : ""
}`}
onClick={() =>
State.update({ selectedTab: "editor", autoFocus: true })
}
>
Write
</button>
</li>
<li class="nav-item">
<button
class={`nav-link ${
state.selectedTab === "preview" ? "active" : ""
}`}
onClick={() => State.update({ selectedTab: "preview" })}
>
Preview
</button>
</li>
</ul>
</div>
</div>
// classes are different for tailwind and bootstrap
if (isTailwind) {
return (
<div>
<div className="bg-white shadow-sm rounded-lg">
<ul
className="p-2 flex flex-wrap text-sm font-medium text-center text-gray-500 border-b border-gray-200 dark:border-gray-700 dark:text-gray-400"
style={{ position: "relative" }}
>
<li className="me-2">
<button
className={
"inline-block p-3 rounded-t-lg " +
(state.selectedTab === "editor" &&
" active text-blue-600 bg-gray-100")
}
onClick={() =>
State.update({ selectedTab: "editor", autoFocus: true })
}
>
Write
</button>
</li>
<li className="me-2">
<button
className={
"inline-block p-3 rounded-t-lg " +
(state.selectedTab === "preview" &&
" active text-blue-600 bg-gray-100")
}
onClick={() => State.update({ selectedTab: "preview" })}
>
Preview
</button>
</li>
</ul>

{state.selectedTab === "editor" ? (
<>
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE"}
props={{
data: { handler: state.handler, content: state.data },
onChange: (content) => {
State.update({ data: content, handler: "update" });
},
placeholder: placeholder,
height,
embeddCSS: embeddCSS || EmbeddCSS,
showAutoComplete: autocompleteEnabled,
showProposalIdAutoComplete: showProposalIdAutoComplete,
autoFocus: state.autoFocus,
onChangeKeyup: onChangeKeyup,
sortedRelevantUsers,
}}
/>
</>
) : (
<div className="card-body">
<Widget
src={
"${REPL_DEVHUB}/widget/devhub.components.molecule.MarkdownViewer"
}
props={{
text: state.data,
}}
/>
</div>
)}
{state.selectedTab === "editor" ? (
<>
<Widget
src={
"${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE"
}
props={{
data: { handler: state.handler, content: state.data },
onChange: (content) => {
State.update({ data: content, handler: "update" });
},
placeholder: placeholder,
height,
embeddCSS: embeddCSS || EmbeddCSS,
showAutoComplete: autocompleteEnabled,
showProposalIdAutoComplete: showProposalIdAutoComplete,
autoFocus: state.autoFocus,
onChangeKeyup: onChangeKeyup,
sortedRelevantUsers,
}}
/>
</>
) : (
<div className="p-3">
<Widget
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDEViewer`}
props={{
content: state.data,
embeddCSS: `
body{
font-size:14px;
}
`,
}}
/>
</div>
)}
</div>
</div>
</Wrapper>
);
);
} else
return (
<Wrapper>
<div className="card">
<div className="card-header" style={{ position: "relative" }}>
<div>
<ul class="nav nav-tabs">
<li class="nav-item">
<button
class={`nav-link ${
state.selectedTab === "editor" ? "active" : ""
}`}
onClick={() =>
State.update({ selectedTab: "editor", autoFocus: true })
}
>
Write
</button>
</li>
<li class="nav-item">
<button
class={`nav-link ${
state.selectedTab === "preview" ? "active" : ""
}`}
onClick={() => State.update({ selectedTab: "preview" })}
>
Preview
</button>
</li>
</ul>
</div>
</div>

{state.selectedTab === "editor" ? (
<>
<Widget
src={
"${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDE"
}
props={{
data: { handler: state.handler, content: state.data },
onChange: (content) => {
State.update({ data: content, handler: "update" });
},
placeholder: placeholder,
height,
embeddCSS: embeddCSS || EmbeddCSS,
showAutoComplete: autocompleteEnabled,
showProposalIdAutoComplete: showProposalIdAutoComplete,
autoFocus: state.autoFocus,
onChangeKeyup: onChangeKeyup,
sortedRelevantUsers,
}}
/>
</>
) : (
<div className="card-body">
<Widget
src={`${REPL_DEVHUB}/widget/devhub.components.molecule.SimpleMDEViewer`}
props={{
content: state.data,
embeddCSS: `
body {
font-size: 14px;
}
`,
}}
/>
</div>
)}
</div>
</Wrapper>
);
};

return Compose(props);
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,62 @@ const simplemde = new SimpleMDE({
"quote",
"code",
"link",
{
name: "image",
action: function customFunction(editor) {
const loadingIndicator = document.createElement('div');
loadingIndicator.textContent = 'Uploading...';
loadingIndicator.style.position = 'absolute';
loadingIndicator.style.top = '10px'; // Adjust position as needed
loadingIndicator.style.right = '10px';
loadingIndicator.style.display = 'none'; // Initially hidden
loadingIndicator.style.backgroundColor = 'rgba(255, 255, 255, 0.8)';
loadingIndicator.style.border = '1px solid #ccc';
loadingIndicator.style.padding = '5px';
loadingIndicator.style.borderRadius = '5px';
document.body.appendChild(loadingIndicator); // Append to the body or desired container
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = 'image/*';
fileInput.addEventListener('change', async function(event) {
const file = event.target.files[0];
if (file) {
loadingIndicator.style.display = 'block';
try {
const response = await fetch("https://ipfs.near.social/add", {
method: "POST",
headers: {
Accept: "application/json"
},
body: file
});
const data = await response.json();
if (data && data.cid) {
const imgSrc = 'https://ipfs.near.social/ipfs/' + data.cid
const imgMarkdown = "![" + imgSrc + "](" + imgSrc + ")";
editor.codemirror.replaceRange(imgMarkdown, editor.codemirror.getCursor());
editor.codemirror.focus();
} else {
console.error('Image upload failed:', data);
}
} catch (error) {
console.error('Error uploading image:', error);
}
finally {
// Hide the loading indicator when done
loadingIndicator.style.display = 'none';
}
}
});
fileInput.click();
},
className: "fa fa-picture-o",
title: "Upload Image",
},
],
placeholder: \`${placeholder}\`,
initialValue: "",
Expand Down
Loading

0 comments on commit b781c7f

Please sign in to comment.