@@ -4,34 +4,89 @@ import { Query, Mutation } from 'react-apollo';
44
55import './App.css' ;
66
7+ const REPOSITORY_FRAGMENT = gql `
8+ fragment repository on Repository {
9+ id
10+ name
11+ url
12+ watchers {
13+ totalCount
14+ }
15+ viewerSubscription
16+ }
17+ ` ;
18+
719const GET_REPOSITORIES_OF_ORGANIZATION = gql `
820 {
921 organization(login: "the-road-to-learn-react") {
1022 repositories(first: 20) {
1123 edges {
1224 node {
13- id
14- name
15- url
16- viewerHasStarred
25+ ...repository
1726 }
1827 }
1928 }
2029 }
2130 }
31+
32+ ${ REPOSITORY_FRAGMENT }
2233` ;
2334
24- const STAR_REPOSITORY = gql `
25- mutation($id: ID!) {
26- addStar(input: { starrableId: $id }) {
27- starrable {
35+ const WATCH_REPOSITORY = gql `
36+ mutation($id: ID!, $viewerSubscription: SubscriptionState!) {
37+ updateSubscription(
38+ input: { state: $viewerSubscription, subscribableId: $id }
39+ ) {
40+ subscribable {
2841 id
29- viewerHasStarred
42+ viewerSubscription
3043 }
3144 }
3245 }
3346` ;
3447
48+ const VIEWER_SUBSCRIPTIONS = {
49+ SUBSCRIBED : 'SUBSCRIBED' ,
50+ UNSUBSCRIBED : 'UNSUBSCRIBED' ,
51+ } ;
52+
53+ const isWatch = viewerSubscription =>
54+ viewerSubscription === VIEWER_SUBSCRIPTIONS . SUBSCRIBED ;
55+
56+ const updateWatch = (
57+ client ,
58+ {
59+ data : {
60+ updateSubscription : {
61+ subscribable : { id, viewerSubscription } ,
62+ } ,
63+ } ,
64+ } ,
65+ ) => {
66+ const repository = client . readFragment ( {
67+ id : `Repository:${ id } ` ,
68+ fragment : REPOSITORY_FRAGMENT ,
69+ } ) ;
70+
71+ let { totalCount } = repository . watchers ;
72+ totalCount =
73+ viewerSubscription === VIEWER_SUBSCRIPTIONS . SUBSCRIBED
74+ ? totalCount + 1
75+ : totalCount - 1 ;
76+
77+ client . writeFragment ( {
78+ id : `Repository:${ id } ` ,
79+ fragment : REPOSITORY_FRAGMENT ,
80+ data : {
81+ ...repository ,
82+ watchers : {
83+ ...repository . watchers ,
84+ totalCount,
85+ } ,
86+ } ,
87+ } ) ;
88+ } ;
89+
3590const App = ( ) => (
3691 < Query query = { GET_REPOSITORIES_OF_ORGANIZATION } >
3792 { ( { data : { organization } , loading } ) => {
@@ -46,79 +101,34 @@ const App = () => (
46101 </ Query >
47102) ;
48103
49- class Repositories extends React . Component {
50- state = {
51- selectedRepositoryIds : [ ] ,
52- } ;
53-
54- toggleSelectRepository = ( id , isSelected ) => {
55- let { selectedRepositoryIds } = this . state ;
56-
57- selectedRepositoryIds = isSelected
58- ? selectedRepositoryIds . filter ( itemId => itemId !== id )
59- : selectedRepositoryIds . concat ( id ) ;
60-
61- this . setState ( { selectedRepositoryIds } ) ;
62- } ;
63-
64- render ( ) {
65- return (
66- < RepositoryList
67- repositories = { this . props . repositories }
68- selectedRepositoryIds = { this . state . selectedRepositoryIds }
69- toggleSelectRepository = { this . toggleSelectRepository }
70- />
71- ) ;
72- }
73- }
74-
75- const RepositoryList = ( {
76- repositories,
77- selectedRepositoryIds,
78- toggleSelectRepository,
79- } ) => (
104+ const Repositories = ( { repositories } ) => (
80105 < ul >
81- { repositories . edges . map ( ( { node } ) => {
82- const isSelected = selectedRepositoryIds . includes ( node . id ) ;
83-
84- const rowClassName = [ 'row' ] ;
85-
86- if ( isSelected ) {
87- rowClassName . push ( 'row_selected' ) ;
88- }
89-
90- return (
91- < li className = { rowClassName . join ( ' ' ) } key = { node . id } >
92- < Select
93- id = { node . id }
94- isSelected = { isSelected }
95- toggleSelectRepository = { toggleSelectRepository }
96- /> { ' ' }
97- < a href = { node . url } > { node . name } </ a > { ' ' }
98- { ! node . viewerHasStarred && < Star id = { node . id } /> }
99- </ li >
100- ) ;
101- } ) }
106+ { repositories . edges . map ( ( { node } ) => (
107+ < li key = { node . id } >
108+ < a href = { node . url } > { node . name } </ a > < Watch repository = { node } />
109+ </ li >
110+ ) ) }
102111 </ ul >
103112) ;
104113
105- const Star = ( { id } ) => (
106- < Mutation mutation = { STAR_REPOSITORY } variables = { { id } } >
107- { starRepository => (
108- < button type = "button" onClick = { starRepository } >
109- Star
114+ const Watch = ( { repository } ) => (
115+ < Mutation
116+ mutation = { WATCH_REPOSITORY }
117+ variables = { {
118+ id : repository . id ,
119+ viewerSubscription : isWatch ( repository . viewerSubscription )
120+ ? VIEWER_SUBSCRIPTIONS . UNSUBSCRIBED
121+ : VIEWER_SUBSCRIPTIONS . SUBSCRIBED ,
122+ } }
123+ update = { updateWatch }
124+ >
125+ { ( updateSubscription , { data, loading, error } ) => (
126+ < button type = "button" onClick = { updateSubscription } >
127+ { repository . watchers . totalCount } { ' ' }
128+ { isWatch ( repository . viewerSubscription ) ? 'Unwatch' : 'Watch' }
110129 </ button >
111130 ) }
112131 </ Mutation >
113132) ;
114133
115- const Select = ( { id, isSelected, toggleSelectRepository } ) => (
116- < button
117- type = "button"
118- onClick = { ( ) => toggleSelectRepository ( id , isSelected ) }
119- >
120- { isSelected ? 'Unselect' : 'Select' }
121- </ button >
122- ) ;
123-
124134export default App ;
0 commit comments