Skip to content

Commit

Permalink
Merge pull request #249 from thematters/develop
Browse files Browse the repository at this point in the history
Release: v1.6.1
  • Loading branch information
robertu7 authored Apr 30, 2019
2 parents e671ff5 + 8504bcf commit 6ba4598
Show file tree
Hide file tree
Showing 28 changed files with 1,009 additions and 619 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.6.1] - 2019-04-30

### Added

- Add Collection notice #247

### Changed

- Fix memory leak caused by inMemoryCache #243
- Create collection in article sidebar #244
- Add editing support for collection popover #244
- Fix comment count #245

## [1.6.0] - 2019-04-27

### Added

- Sentry bug tracker #240

### Changed

- Add error handler for changing password #238
- Add "email_reset_confirm" code type #239

Expand Down
1 change: 1 addition & 0 deletions common/gql/fragmentTypes.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
{ "name": "UserNewFollowerNotice" },
{ "name": "ArticlePublishedNotice" },
{ "name": "ArticleNewDownstreamNotice" },
{ "name": "ArticleNewCollectedNotice" },
{ "name": "ArticleNewAppreciationNotice" },
{ "name": "ArticleNewSubscriberNotice" },
{ "name": "ArticleNewCommentNotice" },
Expand Down
30 changes: 9 additions & 21 deletions common/utils/cache.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,15 @@
import {
InMemoryCache,
IntrospectionFragmentMatcher
} from 'apollo-cache-inmemory'
import { CachePersistor } from 'apollo-cache-persist'
import getConfig from 'next/config'

import introspectionQueryResultData from '~/common/gql/fragmentTypes.json'

const {
publicRuntimeConfig: { ENV }
} = getConfig()
const isProd = ENV === 'production'

const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData
})

const APP_VERSION = process.env.app_version || '__UNVERSIONING__'
const APP_VERSION_KEY = 'app-version'

export const inMemoryCache = new InMemoryCache({ fragmentMatcher })

export const persistor = process.browser
? new CachePersistor({
cache: inMemoryCache,
storage: window.localStorage as any,
debug: !isProd
})
: null
let persistor: any = null

export const clearPersistCache = async () => {
if (!persistor || !process.browser) {
Expand All @@ -47,11 +29,17 @@ export const clearPersistCache = async () => {
}
}

export const setupPersistCache = async () => {
if (!persistor || !process.browser) {
export const setupPersistCache = async (inMemoryCache: any) => {
if (!process.browser) {
return
}

persistor = new CachePersistor({
cache: inMemoryCache,
storage: window.localStorage as any,
debug: !isProd
})

try {
/**
* Restore or purge cache from localStorage based on version from `package.json`
Expand Down
4 changes: 3 additions & 1 deletion common/utils/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ export const mergeConnections = ({
const { edges: newEdges, pageInfo: newPageInfo } = _get(newData, path)

const result = oldData

if (newPageInfo.endCursor !== oldPageInfo.endCursor) {
_set(result, path, {
const copy = JSON.parse(JSON.stringify(result))
return _set(copy, path, {
...rest,
pageInfo: newPageInfo,
edges: [...oldEdges, ...newEdges]
Expand Down
16 changes: 11 additions & 5 deletions common/utils/withApollo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import * as Sentry from '@sentry/browser'
import {
InMemoryCache,
IntrospectionFragmentMatcher
} from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink, split } from 'apollo-link'
import { setContext } from 'apollo-link-context'
Expand All @@ -11,13 +15,14 @@ import https from 'https'
import withApollo from 'next-with-apollo'
import getConfig from 'next/config'

import introspectionQueryResultData from '~/common/gql/fragmentTypes.json'
import { genSentryActionId } from '~/common/utils'

import {
inMemoryCache
// setupPersistCache
} from './cache'
// import { setupPersistCache } from './cache'

const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData
})
const isProd = process.env.NODE_ENV === 'production'

const {
Expand Down Expand Up @@ -106,9 +111,10 @@ const sentryLink = setContext((_, { headers }) => {
})

export default withApollo(({ ctx, headers, initialState }) => {
const inMemoryCache = new InMemoryCache({ fragmentMatcher })
inMemoryCache.restore(initialState || {})

// setupPersistCache()
// setupPersistCache(inMemoryCache)

return new ApolloClient({
link: ApolloLink.from([
Expand Down
19 changes: 13 additions & 6 deletions components/ArticleDigest/Actions/CommentCount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import Link from 'next/link'

import { Icon, TextIcon } from '~/components'

import { numAbbr, toPath } from '~/common/utils'
import { ANALYTICS_EVENTS } from '~/common/enums'
import { analytics, numAbbr, toPath } from '~/common/utils'
import ICON_COMMENT_SM from '~/static/icons/comment-small.svg?sprite'

import { CommentCountArticle } from './__generated__/CommentCountArticle'

const fragments = {
article: gql`
fragment CommentCountArticle on Article {
id
slug
mediaHash
comments(input: { first: 0 }) {
totalCount
}
commentCount
author {
userName
}
Expand Down Expand Up @@ -47,7 +47,14 @@ const CommentCount = ({

return (
<Link {...path}>
<a>
<a
onClick={() => {
analytics.trackEvent(ANALYTICS_EVENTS.OPEN_COMMENTS, {
entrance: article.id,
type: 'article-digest'
})
}}
>
<TextIcon
icon={
<Icon
Expand All @@ -58,7 +65,7 @@ const CommentCount = ({
}
color="grey"
weight="medium"
text={numAbbr(_get(article, 'comments.totalCount', 0))}
text={numAbbr(_get(article, 'commentCount', 0))}
size={size === 'default' ? 'sm' : 'xs'}
spacing="xxtight"
/>
Expand Down
4 changes: 2 additions & 2 deletions components/CollectionEditor/CollectForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { translate } from '~/common/utils'
import styles from './styles.css'

interface Props {
onAdd: (articleId: string) => void
onAdd: (article: SearchArticles_search_edges_node_Article) => void
}

const debouncedSetSearch = _debounce((value, setSearch) => {
Expand Down Expand Up @@ -70,7 +70,7 @@ const CollectForm: FC<Props> = ({ onAdd }) => {
onClick={(
article: SearchArticles_search_edges_node_Article
) => {
onAdd(article.id)
onAdd(article)
setSearch('')
hideDropdown()
}}
Expand Down
25 changes: 11 additions & 14 deletions components/CollectionEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@ import styles from './styles.css'

interface State {
articles: DropdownDigestArticle[]
prevArticleIds: string[]
}

interface Props {
articles: DropdownDigestArticle[]
onEdit: (articleIds: string[]) => void
onEdit: (articles: DropdownDigestArticle[]) => void
}

const reorder = (list: any[], startIndex: number, endIndex: number) => {
Expand All @@ -41,30 +40,28 @@ class CollectionEditor extends React.PureComponent<Props, State> {
super(props)

this.state = {
articles: this.props.articles,
prevArticleIds: this.props.articles.map(({ id }) => id)
articles: this.props.articles
}
}

componentDidUpdate() {
const { prevArticleIds } = this.state
const { articles } = this.state
const prevArticleIds = articles.map(({ id }) => id)
const articleIds = this.props.articles.map(({ id }) => id)

if (_isEqual(prevArticleIds, articleIds)) {
return
}

this.setState({ articles: this.props.articles, prevArticleIds: articleIds })
this.setState({ articles: this.props.articles })
}

onAdd = (articleId: string) => {
const prevArticleIds = this.state.articles.map(({ id }) => id)
this.props.onEdit([...prevArticleIds, articleId])
onAdd = (article: any) => {
this.props.onEdit([...this.state.articles, article])
}

onDelete = (articleId: string) => {
const prevArticleIds = this.state.articles.map(({ id }) => id)
this.props.onEdit(prevArticleIds.filter(id => id !== articleId))
onDelete = (article: any) => {
this.props.onEdit(this.state.articles.filter(({ id }) => id !== article.id))
}

onDragEnd = (result: DropResult) => {
Expand All @@ -85,7 +82,7 @@ class CollectionEditor extends React.PureComponent<Props, State> {
result.destination.index
)
this.setState({ articles: newItems })
this.props.onEdit(newItems.map(({ id }) => id))
this.props.onEdit(newItems)
}

render() {
Expand Down Expand Up @@ -132,7 +129,7 @@ class CollectionEditor extends React.PureComponent<Props, State> {
type="button"
className="delete-handler"
aria-label="刪除"
onClick={() => this.onDelete(article.id)}
onClick={() => this.onDelete(article)}
>
<Icon
id={ICON_DELETE_BLACK_CIRCLE.id}
Expand Down
2 changes: 1 addition & 1 deletion components/CollectionEditor/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ ul {
background: var(--color-bg-green);
}

@media (--sm-up) {
@media (--lg-up) {
margin-right: 0;
margin-left: 0;

Expand Down
71 changes: 71 additions & 0 deletions components/NoticeDigest/ArticleNewCollectedNotice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import classNames from 'classnames'
import gql from 'graphql-tag'

import { Translate } from '~/components'

import { ArticleNewCollectedNotice as NoticeType } from './__generated__/ArticleNewCollectedNotice'
import NoticeActorAvatar from './NoticeActorAvatar'
import NoticeActorName from './NoticeActorName'
import NoticeArticle from './NoticeArticle'
import NoticeDate from './NoticeDate'
import styles from './styles.css'

const ArticleNewCollectedNotice = ({ notice }: { notice: NoticeType }) => {
if (!notice || !notice.actor) {
return null
}

const avatarWrapClasses = classNames({
'avatar-wrap': true
})

return (
<section className="container">
<section className={avatarWrapClasses}>
<NoticeActorAvatar user={notice.actor} size={'default'} />
</section>

<section className="content-wrap">
<h4>
<Translate zh_hant="恭喜!你的大作" zh_hans="恭喜!你的大作" />{' '}
<NoticeArticle article={notice.target} />{' '}
<Translate zh_hant="已被" zh_hans="已被" />{' '}
<NoticeActorName user={notice.actor} />{' '}
<Translate zh_hant="在其作品" zh_hans="在其作品" />{' '}
<NoticeArticle article={notice.collection} />{' '}
<Translate zh_hant="中關聯推薦" zh_hans="中关联推荐" />
</h4>

<NoticeDate notice={notice} />
</section>
<style jsx>{styles}</style>
</section>
)
}

ArticleNewCollectedNotice.fragments = {
notice: gql`
fragment ArticleNewCollectedNotice on ArticleNewCollectedNotice {
id
unread
__typename
...NoticeDate
actor {
...NoticeActorAvatarUser
...NoticeActorNameUser
}
collection {
...NoticeArticle
}
target {
...NoticeArticle
}
}
${NoticeActorAvatar.fragments.user}
${NoticeActorName.fragments.user}
${NoticeArticle.fragments.article}
${NoticeDate.fragments.notice}
`
}

export default ArticleNewCollectedNotice
7 changes: 7 additions & 0 deletions components/NoticeDigest/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import gql from 'graphql-tag'
import { DigestNotice } from './__generated__/DigestNotice'
import ArticleMentionedYouNotice from './ArticleMentionedYouNotice'
import ArticleNewAppreciationNotice from './ArticleNewAppreciationNotice'
import ArticleNewCollectedNotice from './ArticleNewCollectedNotice'
import ArticleNewCommentNotice from './ArticleNewCommentNotice'
import ArticleNewDownstreamNotice from './ArticleNewDownstreamNotice'
import ArticleNewSubscriberNotice from './ArticleNewSubscriberNotice'
Expand All @@ -29,6 +30,9 @@ const fragments = {
... on ArticleNewDownstreamNotice {
...ArticleNewDownstreamNotice
}
... on ArticleNewCollectedNotice {
...ArticleNewCollectedNotice
}
... on ArticleNewAppreciationNotice {
...ArticleNewAppreciationNotice
}
Expand Down Expand Up @@ -69,6 +73,7 @@ const fragments = {
${ArticleNewAppreciationNotice.fragments.notice}
${ArticleNewCommentNotice.fragments.notice}
${ArticleNewDownstreamNotice.fragments.notice}
${ArticleNewCollectedNotice.fragments.notice}
${ArticleNewSubscriberNotice.fragments.notice}
${ArticlePublishedNotice.fragments.notice}
${ArticleMentionedYouNotice.fragments.notice}
Expand All @@ -92,6 +97,8 @@ const FeedDigest = ({ notice }: { notice: DigestNotice }) => {
return <ArticleNewCommentNotice notice={notice} />
case 'ArticleNewDownstreamNotice':
return <ArticleNewDownstreamNotice notice={notice} />
case 'ArticleNewCollectedNotice':
return <ArticleNewCollectedNotice notice={notice} />
case 'ArticleNewSubscriberNotice':
return <ArticleNewSubscriberNotice notice={notice} />
case 'ArticlePublishedNotice':
Expand Down
Loading

0 comments on commit 6ba4598

Please sign in to comment.