fix: Various fixes for unread tracking
This commit is contained in:
parent
d487da8f15
commit
26b9566b96
|
@ -6,7 +6,8 @@ const Badge = styled.span`
|
|||
padding: 2px 6px 3px;
|
||||
background-color: ${({ yellow, primary, theme }) =>
|
||||
yellow ? theme.yellow : primary ? theme.primary : theme.textTertiary};
|
||||
color: ${({ primary, theme }) => (primary ? theme.white : theme.background)};
|
||||
color: ${({ primary, yellow, theme }) =>
|
||||
primary ? theme.white : yellow ? theme.text : theme.background};
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
|
|
|
@ -18,8 +18,7 @@ const Container = styled(Flex)`
|
|||
`;
|
||||
|
||||
const Modified = styled.span`
|
||||
color: ${(props) =>
|
||||
props.highlight ? props.theme.text : props.theme.textTertiary};
|
||||
color: ${(props) => props.theme.textTertiary};
|
||||
font-weight: ${(props) => (props.highlight ? "600" : "400")};
|
||||
`;
|
||||
|
||||
|
@ -28,6 +27,7 @@ type Props = {
|
|||
auth: AuthStore,
|
||||
showCollection?: boolean,
|
||||
showPublished?: boolean,
|
||||
showLastViewed?: boolean,
|
||||
document: Document,
|
||||
children: React.Node,
|
||||
to?: string,
|
||||
|
@ -38,6 +38,7 @@ function DocumentMeta({
|
|||
collections,
|
||||
showPublished,
|
||||
showCollection,
|
||||
showLastViewed,
|
||||
document,
|
||||
children,
|
||||
to,
|
||||
|
@ -66,37 +67,37 @@ function DocumentMeta({
|
|||
if (deletedAt) {
|
||||
content = (
|
||||
<span>
|
||||
deleted <Time dateTime={deletedAt} /> ago
|
||||
deleted <Time dateTime={deletedAt} addSuffix />
|
||||
</span>
|
||||
);
|
||||
} else if (archivedAt) {
|
||||
content = (
|
||||
<span>
|
||||
archived <Time dateTime={archivedAt} /> ago
|
||||
archived <Time dateTime={archivedAt} addSuffix />
|
||||
</span>
|
||||
);
|
||||
} else if (createdAt === updatedAt) {
|
||||
content = (
|
||||
<span>
|
||||
created <Time dateTime={updatedAt} /> ago
|
||||
created <Time dateTime={updatedAt} addSuffix />
|
||||
</span>
|
||||
);
|
||||
} else if (publishedAt && (publishedAt === updatedAt || showPublished)) {
|
||||
content = (
|
||||
<span>
|
||||
published <Time dateTime={publishedAt} /> ago
|
||||
published <Time dateTime={publishedAt} addSuffix />
|
||||
</span>
|
||||
);
|
||||
} else if (isDraft) {
|
||||
content = (
|
||||
<span>
|
||||
saved <Time dateTime={updatedAt} /> ago
|
||||
saved <Time dateTime={updatedAt} addSuffix />
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<Modified highlight={modifiedSinceViewed}>
|
||||
updated <Time dateTime={updatedAt} /> ago
|
||||
updated <Time dateTime={updatedAt} addSuffix />
|
||||
</Modified>
|
||||
);
|
||||
}
|
||||
|
@ -105,12 +106,20 @@ function DocumentMeta({
|
|||
const updatedByMe = auth.user && auth.user.id === updatedBy.id;
|
||||
|
||||
const timeSinceNow = () => {
|
||||
if (!lastViewedAt)
|
||||
return <Modified highlight={true}>Never viewed</Modified>;
|
||||
if (isDraft || !showLastViewed) {
|
||||
return null;
|
||||
}
|
||||
if (!lastViewedAt) {
|
||||
return (
|
||||
<>
|
||||
• <Modified highlight>Never viewed</Modified>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
Viewed <Time dateTime={updatedAt} /> ago
|
||||
• Viewed <Time dateTime={lastViewedAt} addSuffix shorten />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
@ -127,7 +136,7 @@ function DocumentMeta({
|
|||
</strong>
|
||||
</span>
|
||||
)}
|
||||
• {timeSinceNow()}
|
||||
{timeSinceNow()}
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -86,6 +86,7 @@ class DocumentPreview extends React.Component<Props> {
|
|||
>
|
||||
<Heading>
|
||||
<Title text={document.titleWithDefault} highlight={highlight} />
|
||||
{document.isNew && <Badge yellow>New</Badge>}
|
||||
{!document.isDraft &&
|
||||
!document.isArchived &&
|
||||
!document.isTemplate && (
|
||||
|
@ -105,7 +106,6 @@ class DocumentPreview extends React.Component<Props> {
|
|||
{document.isTemplate && showTemplate && (
|
||||
<Badge primary>Template</Badge>
|
||||
)}
|
||||
{document.isNew && <Badge yellow>New</Badge>}
|
||||
<SecondaryActions>
|
||||
{document.isTemplate &&
|
||||
!document.isArchived &&
|
||||
|
@ -134,6 +134,7 @@ class DocumentPreview extends React.Component<Props> {
|
|||
document={document}
|
||||
showCollection={showCollection}
|
||||
showPublished={showPublished}
|
||||
showLastViewed
|
||||
/>
|
||||
</DocumentLink>
|
||||
);
|
||||
|
|
|
@ -24,6 +24,8 @@ type Props = {
|
|||
dateTime: string,
|
||||
children?: React.Node,
|
||||
tooltipDelay?: number,
|
||||
addSuffix?: boolean,
|
||||
shorten?: boolean,
|
||||
};
|
||||
|
||||
class Time extends React.Component<Props> {
|
||||
|
@ -40,6 +42,18 @@ class Time extends React.Component<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { shorten, addSuffix } = this.props;
|
||||
let content = distanceInWordsToNow(this.props.dateTime, {
|
||||
addSuffix,
|
||||
});
|
||||
|
||||
if (shorten) {
|
||||
content = content
|
||||
.replace("about", "")
|
||||
.replace("minute", "min")
|
||||
.replace("less than a minute ago", "just now");
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
tooltip={format(this.props.dateTime, "MMMM Do, YYYY h:mm a")}
|
||||
|
@ -47,7 +61,7 @@ class Time extends React.Component<Props> {
|
|||
placement="bottom"
|
||||
>
|
||||
<time dateTime={this.props.dateTime}>
|
||||
{this.props.children || distanceInWordsToNow(this.props.dateTime)}
|
||||
{this.props.children || content}
|
||||
</time>
|
||||
</Tooltip>
|
||||
);
|
||||
|
|
|
@ -21,11 +21,11 @@ export default class Document extends BaseModel {
|
|||
@observable isSaving: boolean = false;
|
||||
@observable embedsDisabled: boolean = false;
|
||||
@observable injectTemplate: boolean = false;
|
||||
@observable lastViewedAt: ?string;
|
||||
store: DocumentsStore;
|
||||
|
||||
collaborators: User[];
|
||||
collectionId: string;
|
||||
@observable lastViewedAt: ?string;
|
||||
createdAt: string;
|
||||
createdBy: User;
|
||||
updatedAt: string;
|
||||
|
|
|
@ -23,7 +23,6 @@ type ImportOptions = {
|
|||
};
|
||||
|
||||
export default class DocumentsStore extends BaseStore<Document> {
|
||||
@observable recentlyViewedIds: string[] = [];
|
||||
@observable searchCache: Map<string, SearchResult[]> = new Map();
|
||||
@observable starredIds: Map<string, boolean> = new Map();
|
||||
@observable backlinks: Map<string, string[]> = new Map();
|
||||
|
@ -50,8 +49,8 @@ export default class DocumentsStore extends BaseStore<Document> {
|
|||
@computed
|
||||
get recentlyViewed(): Document[] {
|
||||
return orderBy(
|
||||
compact(this.recentlyViewedIds.map((id) => this.data.get(id))),
|
||||
"updatedAt",
|
||||
filter(this.all, (d) => d.lastViewedAt),
|
||||
"lastViewedAt",
|
||||
"desc"
|
||||
);
|
||||
}
|
||||
|
@ -299,15 +298,7 @@ export default class DocumentsStore extends BaseStore<Document> {
|
|||
|
||||
@action
|
||||
fetchRecentlyViewed = async (options: ?PaginationParams): Promise<*> => {
|
||||
const data = await this.fetchNamedPage("viewed", options);
|
||||
|
||||
runInAction("DocumentsStore#fetchRecentlyViewed", () => {
|
||||
// $FlowFixMe
|
||||
this.recentlyViewedIds.replace(
|
||||
uniq(this.recentlyViewedIds.concat(map(data, "id")))
|
||||
);
|
||||
});
|
||||
return data;
|
||||
return this.fetchNamedPage("viewed", options);
|
||||
};
|
||||
|
||||
@action
|
||||
|
@ -541,10 +532,6 @@ export default class DocumentsStore extends BaseStore<Document> {
|
|||
async delete(document: Document) {
|
||||
await super.delete(document);
|
||||
|
||||
runInAction(() => {
|
||||
this.recentlyViewedIds = without(this.recentlyViewedIds, document.id);
|
||||
});
|
||||
|
||||
// check to see if we have any shares related to this document already
|
||||
// loaded in local state. If so we can go ahead and remove those too.
|
||||
const share = this.rootStore.shares.getByDocumentId(document.id);
|
||||
|
|
|
@ -283,7 +283,11 @@ router.post("documents.viewed", auth(), pagination(), async (ctx) => {
|
|||
limit: ctx.state.pagination.limit,
|
||||
});
|
||||
|
||||
const documents = views.map((view) => view.document);
|
||||
const documents = views.map((view) => {
|
||||
const document = view.document;
|
||||
document.views = [view];
|
||||
return document;
|
||||
});
|
||||
const data = await Promise.all(
|
||||
documents.map((document) => presentDocument(document))
|
||||
);
|
||||
|
|
Reference in New Issue