diff --git a/frontend/components/DocumentPreview/DocumentPreview.js b/frontend/components/DocumentPreview/DocumentPreview.js index 409c96d4..30cc0f84 100644 --- a/frontend/components/DocumentPreview/DocumentPreview.js +++ b/frontend/components/DocumentPreview/DocumentPreview.js @@ -1,10 +1,12 @@ // @flow import React, { Component } from 'react'; +import { observer } from 'mobx-react'; import { Link } from 'react-router-dom'; import Document from 'models/Document'; import styled from 'styled-components'; import { color } from 'styles/constants'; import PublishingInfo from 'components/PublishingInfo'; +import StarIcon from 'components/Icon/StarIcon'; type Props = { document: Document, @@ -13,10 +15,27 @@ type Props = { innerRef?: Function, }; +const StyledStar = styled(StarIcon)` + top: 2px; + position: relative; + margin-left: 4px; + opacity: ${props => (props.solid ? 1 : 0.25)}; + transition: opacity 100ms ease-in-out; + + &:hover { + opacity: 1; + } + + svg { + width: 1em; + height: 1em; + } +`; + const DocumentLink = styled(Link)` display: block; margin: 0 -16px; - padding: 16px; + padding: 10px 16px; border-radius: 8px; border: 2px solid transparent; max-height: 50vh; @@ -37,18 +56,36 @@ const DocumentLink = styled(Link)` h3 { margin-top: 0; + margin-bottom: .25em; } `; -class DocumentPreview extends Component { +@observer class DocumentPreview extends Component { props: Props; + star = (ev: SyntheticEvent) => { + ev.preventDefault(); + ev.stopPropagation(); + this.props.document.star(); + }; + + unstar = (ev: SyntheticEvent) => { + ev.preventDefault(); + ev.stopPropagation(); + this.props.document.unstar(); + }; + render() { const { document, showCollection, innerRef, ...rest } = this.props; return ( -

{document.title}

+

+ {document.title} + {document.starred + ? + : } +

, @@ -52,10 +48,7 @@ type KeyData = { constructor(props: Props) { super(props); - this.schema = createSchema({ - onStar: props.onStar, - onUnstar: props.onUnstar, - }); + this.schema = createSchema(); this.plugins = createPlugins({ onImageUploadStart: props.onImageUploadStart, onImageUploadStop: props.onImageUploadStop, @@ -84,10 +77,6 @@ type KeyData = { } } - getChildContext() { - return { starred: this.props.starred }; - } - onChange = (state: State) => { this.setState({ state }); }; @@ -207,7 +196,6 @@ type KeyData = { (this.editor = ref)} placeholder="Start with a title…" bodyPlaceholder="Insert witty platitude here" @@ -232,10 +220,6 @@ type KeyData = { }; } -MarkdownEditor.childContextTypes = { - starred: PropTypes.bool, -}; - const MaxWidth = styled(Flex)` max-width: 50em; height: 100%; diff --git a/frontend/components/Editor/components/Heading.js b/frontend/components/Editor/components/Heading.js index 05e2b857..f7a30a3f 100644 --- a/frontend/components/Editor/components/Heading.js +++ b/frontend/components/Editor/components/Heading.js @@ -1,11 +1,9 @@ // @flow import React from 'react'; -import PropTypes from 'prop-types'; -import styled from 'styled-components'; import { Document } from 'slate'; +import styled from 'styled-components'; import _ from 'lodash'; import slug from 'slug'; -import StarIcon from 'components/Icon/StarIcon'; import type { Node, Editor } from '../types'; import styles from '../Editor.scss'; @@ -14,46 +12,22 @@ type Props = { placeholder?: boolean, parent: Node, node: Node, - onStar?: Function, - onUnstar?: Function, editor: Editor, readOnly: boolean, component?: string, }; -type Context = { - starred?: boolean, -}; - const Wrapper = styled.div` + display: inline; margin-left: ${props => (props.hasEmoji ? '-1.2em' : 0)} `; -const StyledStar = styled(StarIcon)` - top: 3px; - position: relative; - margin-left: 4px; - opacity: ${props => (props.solid ? 1 : 0.25)}; - transition: opacity 100ms ease-in-out; - - &:hover { - opacity: 1; - } - - svg { - width: 28px; - height: 28px; - } -`; - -function Heading(props: Props, { starred }: Context) { +function Heading(props: Props) { const { parent, placeholder, node, editor, - onStar, - onUnstar, readOnly, children, component = 'h1', @@ -62,8 +36,7 @@ function Heading(props: Props, { starred }: Context) { const firstHeading = parentIsDocument && parent.nodes.first() === node; const showPlaceholder = placeholder && firstHeading && !node.text; const slugish = _.escape(`${component}-${slug(node.text)}`); - const showStar = readOnly && !!onStar; - const showHash = readOnly && !!slugish && !showStar; + const showHash = readOnly && !!slugish; const Component = component; const emoji = editor.props.emoji || ''; const title = node.text.trim(); @@ -79,14 +52,8 @@ function Heading(props: Props, { starred }: Context) { } {showHash && #} - {showStar && starred && } - {showStar && !starred && } ); } -Heading.contextTypes = { - starred: PropTypes.bool, -}; - export default Heading; diff --git a/frontend/components/Editor/schema.js b/frontend/components/Editor/schema.js index 0ae017e6..58a19c20 100644 --- a/frontend/components/Editor/schema.js +++ b/frontend/components/Editor/schema.js @@ -9,12 +9,7 @@ import Paragraph from './components/Paragraph'; import type { Props, Node, Transform } from './types'; import styles from './Editor.scss'; -type Options = { - onStar: Function, - onUnstar: Function, -}; - -const createSchema = ({ onStar, onUnstar }: Options) => { +const createSchema = () => { return { marks: { bold: (props: Props) => {props.children}, @@ -44,9 +39,7 @@ const createSchema = ({ onStar, onUnstar }: Options) => { image: Image, link: Link, 'list-item': ListItem, - heading1: (props: Props) => ( - - ), + heading1: (props: Props) => , heading2: (props: Props) => , heading3: (props: Props) => , heading4: (props: Props) => , diff --git a/frontend/components/Layout/components/SidebarCollectionList/SidebarCollectionList.js b/frontend/components/Layout/components/SidebarCollectionList/SidebarCollectionList.js index 7d605586..c672ae42 100644 --- a/frontend/components/Layout/components/SidebarCollectionList/SidebarCollectionList.js +++ b/frontend/components/Layout/components/SidebarCollectionList/SidebarCollectionList.js @@ -26,6 +26,7 @@ const SidebarCollectionList = observer(({ history, collections }: Props) => {
Collections
{collections.data.map(collection => ( diff --git a/server/api/documents.js b/server/api/documents.js index f5192660..178e590a 100644 --- a/server/api/documents.js +++ b/server/api/documents.js @@ -40,7 +40,19 @@ router.post('documents.viewed', auth(), pagination(), async ctx => { const views = await View.findAll({ where: { userId: user.id }, order: [[sort, direction]], - include: [{ model: Document, required: true }], + include: [ + { + model: Document, + include: [ + { + model: Star, + as: 'starred', + where: { userId: user.id }, + required: false, + }, + ], + }, + ], offset: ctx.state.pagination.offset, limit: ctx.state.pagination.limit, });