frontend > app

This commit is contained in:
Tom Moor
2017-10-25 22:49:04 -07:00
parent aa34db8318
commit 4863680d86
239 changed files with 11 additions and 11 deletions

View File

@@ -0,0 +1,41 @@
// @flow
import { observable, action } from 'mobx';
import invariant from 'invariant';
import { client } from 'utils/ApiClient';
import type { User } from 'types';
type View = {
user: User,
count: number,
};
class DocumentViewersStore {
documentId: string;
@observable viewers: Array<View>;
@observable isFetching: boolean;
@action fetchViewers = async () => {
this.isFetching = true;
try {
const res = await client.post(
'/views.list',
{
id: this.documentId,
},
{ cache: true }
);
invariant(res && res.data, 'Data should be available');
this.viewers = res.data.users;
} catch (e) {
console.error('Something went wrong');
}
this.isFetching = false;
};
constructor(documentId: string) {
this.documentId = documentId;
}
}
export default DocumentViewersStore;

View File

@@ -0,0 +1,76 @@
// @flow
import React, { Component } from 'react';
import { observer } from 'mobx-react';
import Popover from 'components/Popover';
import styled from 'styled-components';
import DocumentViewers from './components/DocumentViewers';
import DocumentViewersStore from './DocumentViewersStore';
import Flex from 'components/Flex';
const Container = styled(Flex)`
font-size: 13px;
user-select: none;
a {
color: #ccc;
&:hover {
color: #aaa;
}
}
`;
type Props = {
documentId: string,
count: number,
};
@observer class DocumentViews extends Component {
anchor: HTMLElement;
store: DocumentViewersStore;
props: Props;
state: {
opened: boolean,
};
state = {};
constructor(props: Props) {
super(props);
this.store = new DocumentViewersStore(props.documentId);
}
openPopover = () => {
this.setState({ opened: true });
};
closePopover = () => {
this.setState({ opened: false });
};
setRef = (ref: HTMLElement) => {
this.anchor = ref;
};
render() {
return (
<Container align="center">
<a ref={this.setRef} onClick={this.openPopover}>
Viewed
{' '}
{this.props.count}
{' '}
{this.props.count === 1 ? 'time' : 'times'}
</a>
{this.state.opened &&
<Popover anchor={this.anchor} onClose={this.closePopover}>
<DocumentViewers
onMount={this.store.fetchViewers}
viewers={this.store.viewers}
/>
</Popover>}
</Container>
);
}
}
export default DocumentViews;

View File

@@ -0,0 +1,55 @@
// @flow
import React, { Component } from 'react';
import Flex from 'components/Flex';
import styled from 'styled-components';
import map from 'lodash/map';
import Avatar from 'components/Avatar';
import Scrollable from 'components/Scrollable';
type Props = {
viewers: Array<Object>,
onMount: Function,
};
const List = styled.ul`
list-style: none;
font-size: 13px;
margin: -4px 0;
padding: 0;
li {
padding: 4px 0;
}
`;
const UserName = styled.span`
padding-left: 8px;
`;
class DocumentViewers extends Component {
props: Props;
componentDidMount() {
this.props.onMount();
}
render() {
return (
<Scrollable>
<List>
{map(this.props.viewers, view => (
<li key={view.user.id}>
<Flex align="center">
<Avatar src={view.user.avatarUrl} />
{' '}
<UserName>{view.user.name}</UserName>
</Flex>
</li>
))}
</List>
</Scrollable>
);
}
}
export default DocumentViewers;

View File

@@ -0,0 +1,3 @@
// @flow
import DocumentViewers from './DocumentViewers';
export default DocumentViewers;

View File

@@ -0,0 +1,3 @@
// @flow
import DocumentViews from './DocumentViews';
export default DocumentViews;