client: improve rendered post styling; length is 100% if uneditable

This commit is contained in:
Max Leiter 2022-03-08 16:39:24 -08:00
parent 5b71fc6b27
commit 844ccded3c
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
7 changed files with 113 additions and 82 deletions

View file

@ -24,3 +24,7 @@
/* Override geist-ui styling */
margin: 0 !important;
}
.textarea {
height: 100%;
}

View file

@ -17,6 +17,7 @@ type Props = {
const Document = ({ remove, editable, title, content, setTitle, setContent, initialTab = 'edit' }: Props) => {
const codeEditorRef = useRef<HTMLTextAreaElement>(null)
const [tab, setTab] = useState(initialTab)
const height = editable ? "500px" : '100%'
const handleTabChange = (newTab: string) => {
if (newTab === 'edit') {
@ -59,20 +60,23 @@ const Document = ({ remove, editable, title, content, setTitle, setContent, init
<Tabs onChange={handleTabChange} initialValue={initialTab} hideDivider leftSpace={0}>
<Tabs.Item label={editable ? "Edit" : "Raw"} value="edit">
{/* <textarea className={styles.lineCounter} wrap='off' readOnly ref={lineNumberRef}>1.</textarea> */}
<Textarea
ref={codeEditorRef}
placeholder="Type some contents..."
value={content}
onChange={(event) => setContent ? setContent(event.target.value) : null}
width="100%"
height="500px"
disabled={!editable}
resize="vertical"
className={styles.textarea}
/>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<Textarea
ref={codeEditorRef}
placeholder="Type some contents..."
value={content}
onChange={(event) => setContent ? setContent(event.target.value) : null}
width="100%"
disabled={!editable}
// TODO: Textarea should grow to fill parent if height == 100%
style={{ flex: 1, minHeight: 350 }}
resize="vertical"
className={styles.textarea}
/>
</div>
</Tabs.Item>
<Tabs.Item label="Preview" value="preview">
<MarkdownPreview height={500} content={content} />
<MarkdownPreview height={height} content={content} />
</Tabs.Item>
</Tabs>

View file

@ -13,28 +13,27 @@
.mobile {
position: relative;
z-index: 1;
z-index: 2;
}
.controls {
display: none !important;
}
@media only screen and (max-width: 650px) {
.tabs {
display: none;
}
.controls {
display: block !important;
}
}
.controls {
flex: 1 1;
display: flex;
align-items: center;
justify-content: flex-end;
}
.controls :global(.menu-toggle) {
display: flex;
align-items: center;
min-width: 40px;
height: 40px;
padding: 0;
}
.wrapper {

View file

@ -72,12 +72,12 @@ const Header = ({ changeTheme, theme }: DriftProps) => {
condition: !isSignedIn
},
{
name: "",
name: isMobile ? "GitHub" : "",
href: "https://github.com/maxleiter/drift",
icon: <GitHubIcon />,
condition: true
}
], [isSignedIn, router])
], [isMobile, isSignedIn, router])
useEffect(() => {
setSelectedTab(pages.find((page) => {
@ -89,7 +89,7 @@ const Header = ({ changeTheme, theme }: DriftProps) => {
return (
<Page.Header height={'var(--page-nav-height)'} margin={0} paddingBottom={0} paddingTop={"var(--gap)"}>
{!isMobile && <div className={styles.tabs}>
<div className={styles.tabs}>
<Tabs
value={selectedTab}
leftSpace={0}
@ -116,17 +116,14 @@ const Header = ({ changeTheme, theme }: DriftProps) => {
else return null
})}
</Tabs>
</div>}
<div className="controls">
{isMobile && (
<Button
className="menu-toggle"
auto
type="abort"
onClick={() => setExpanded(!expanded)}>
<MenuIcon size="1.125rem" />
</Button>
)}
</div>
<div className={styles.controls}>
<Button
auto
type="abort"
onClick={() => setExpanded(!expanded)}>
<MenuIcon size="1.125rem" />
</Button>
</div>
{isMobile && expanded && (<div className={styles.mobile}>
<ButtonGroup vertical>

View file

@ -1,15 +1,8 @@
import { memo } from "react"
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
// @ts-ignore because of no types in remark-a11y-emoji
import a11yEmoji from '@fec/remark-a11y-emoji';
import styles from './preview.module.css'
import ReactMarkdownPreview from "./react-markdown-preview"
const MarkdownPreview = ({ content, height }: { content?: string, height?: number | string }) => {
{/* remarkGfm is github flavored markdown support, a11yEmoji wraps emojis in accessible spans for screen readers */ }
return (<div style={{ height }}><ReactMarkdown className={styles.markdownPreview} remarkPlugins={[remarkGfm, a11yEmoji]} >
{content || ""}
</ReactMarkdown></div>)
const MarkdownPreview = ({ content = '', height = 500 }: { content?: string, height?: number | string }) => {
return (<ReactMarkdownPreview height={height} content={content} />)
}
export default memo(MarkdownPreview)

View file

@ -0,0 +1,19 @@
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
// @ts-ignore because of no types in remark-a11y-emoji
import a11yEmoji from '@fec/remark-a11y-emoji';
import styles from './preview.module.css'
type Props = {
content: string | undefined
height: number | string
}
const ReactMarkdownPreview = ({ content, height }: Props) => {
return (<div style={{ height }}><ReactMarkdown className={styles.markdownPreview} remarkPlugins={[remarkGfm, a11yEmoji]} >
{content || ""}
</ReactMarkdown></div>)
}
export default ReactMarkdownPreview

View file

@ -5,7 +5,54 @@ import { Page, Spacer } from '@geist-ui/core'
import Header from '../components/header'
import { ThemeProps } from './_app'
import Document from '../components/document'
const Home = ({ theme, changeTheme }: ThemeProps) => {
export function getStaticProps() {
const introDoc = `# Welcome to Drift
### Drift is a self-hostable clone of GitHub Gist.
#### It is a simple way to share code and text snippets with your friends, with support for the following:
- Render GitHub Extended Markdown (including images)
- User authentication
- Private, public, and secret posts
If you want to signup, you can join at [/signup](/signup) as long as you have a passcode provided by the administrator (which you don't need for this demo).
**This demo is on a memory-only database, so accounts and pastes can be deleted at any time.**
You can find the source code on [GitHub](https://github.com/MaxLeiter/drift).
Drift was inspired by [this tweet](https://twitter.com/emilyst/status/1499858264346935297):
> What is the absolute closest thing to GitHub Gist that can be self-hosted?
In terms of design and functionality. Hosts images and markdown, rendered. Creates links that can be private or public. Uses/requires registration.
I have looked at dozens of pastebin-like things.
`
const todoDoc =
`#### In no particular order:
- Less JavaScript usage (it's currently required)
- A non-Node backend
- Hosting images
- Password-protected posts
- Administrator panel
- Meta tags
- User settings
- Search
- "Forking"
- LaTeX
- Syntax highlighting based on filename ending"`
return {
props: {
introContent: introDoc,
todoContent: todoDoc,
}
}
}
type Props = ThemeProps & {
introContent: string
todoContent: string
}
const Home = ({ theme, changeTheme, introContent, todoContent }: Props) => {
return (
<Page className={styles.container} width="100%">
<Head>
@ -16,49 +63,17 @@ const Home = ({ theme, changeTheme }: ThemeProps) => {
<Page.Header>
<Header theme={theme} changeTheme={changeTheme} />
</Page.Header>
<Page.Content width={"var(--main-content-width)"} margin="auto">
<Page.Content width={"var(--main-content-width)"} margin="auto" paddingTop={"var(--gap)"}>
<Document
editable={false}
content={
`# Welcome to Drift
### Drift is a self-hostable clone of GitHub Gist.
#### It is a simple way to share code and text snippets with your friends, with support for the following:
- Render GitHub Extended Markdown (including images)
- User authentication
- Private, public, and secret posts
If you want to signup, you can join at [/signup](/signup) as long as you have a passcode provided by the administrator (which you don't need for this demo).
**This demo is on a memory-only database, so accounts and pastes can be deleted at any time.**
You can find the source code on [GitHub](https://github.com/MaxLeiter/drift).
Drift was inspired by [this tweet](https://twitter.com/emilyst/status/1499858264346935297):
> What is the absolute closest thing to GitHub Gist that can be self-hosted?
In terms of design and functionality. Hosts images and markdown, rendered. Creates links that can be private or public. Uses/requires registration.
I have looked at dozens of pastebin-like things.
`}
content={introContent}
title={`Welcome to Drift.md`}
initialTab={`preview`}
/>
<Spacer height={1} />
<Document
editable={false}
content={
`#### In no particular order:
- [ ] Less JavaScript usage (it's currently required)
- [ ] A non-Node backend
- [ ] Hosting images
- [ ] Password-protected posts
- [ ] Administrator panel
- [ ] Meta tags
- [ ] User settings
- [ ] Search
- [ ] "Forking
- [ ] LaTeX
- [ ] Syntax highlighting based on filename ending"`}
content={todoContent}
title={`TODO.md`}
initialTab={`preview`}
/>