@@ -5,8 +5,10 @@ const { customAlphabet } = require("nanoid");
5
5
const geolib = require ( "geolib" ) ;
6
6
const { isPointWithinRadius } = geolib ;
7
7
const Beacon = require ( "../models/beacon.js" ) ;
8
+ const Group = require ( "../models/group.js" ) ;
8
9
const Landmark = require ( "../models/landmark.js" ) ;
9
10
const { User } = require ( "../models/user.js" ) ;
11
+ const { MongoServerError } = require ( "mongodb" ) ;
10
12
11
13
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
12
14
// even if we generate 10 IDs per hour,
@@ -17,7 +19,7 @@ const resolvers = {
17
19
Query : {
18
20
hello : ( ) => "Hello world!" ,
19
21
me : async ( _parent , _args , { user } ) => {
20
- await user . populate ( "beacons.leader beacons.landmarks" ) ;
22
+ await user . populate ( "groups beacons.leader beacons.landmarks" ) ;
21
23
return user ;
22
24
} ,
23
25
beacon : async ( _parent , { id } , { user } ) => {
@@ -115,6 +117,35 @@ const resolvers = {
115
117
return newBeacon ;
116
118
} ,
117
119
120
+ createGroup : async ( _ , { group } , { user } ) => {
121
+ console . log ( group ) ;
122
+ //since there is a very minute chance of shortcode colliding, we try to make the group 2 times if 1st one results in a collision.
123
+ for ( let i = 0 ; i < 2 ; i ++ ) {
124
+ try {
125
+ const groupDoc = new Group ( {
126
+ leader : user . id ,
127
+ shortcode : nanoid ( ) ,
128
+ ...group ,
129
+ } ) ;
130
+ const newGroup = await groupDoc . save ( ) . then ( g => g . populate ( "leader" ) ) ;
131
+ user . groups . push ( newGroup . id ) ;
132
+ await user . save ( ) ;
133
+ console . log ( newGroup ) ;
134
+ return newGroup ;
135
+ } catch ( e ) {
136
+ //try again only if shortcode collides.
137
+ if ( e instanceof MongoServerError && e . keyValue [ "shortcode" ] ) {
138
+ console . error ( e ) ;
139
+ } else {
140
+ //else return the error;
141
+ return new Error ( e ) ;
142
+ }
143
+ }
144
+ }
145
+ //if shortcode collides two times then return an error saying please try again.
146
+ return new Error ( "Please try again!" ) ;
147
+ } ,
148
+
118
149
changeBeaconDuration : async ( _ , { newExpiresAt, beaconID } , { user } ) => {
119
150
const beacon = await Beacon . findById ( beaconID ) ;
120
151
@@ -147,6 +178,26 @@ const resolvers = {
147
178
return beacon ;
148
179
} ,
149
180
181
+ joinGroup : async ( _ , { shortcode } , { user, pubsub } ) => {
182
+ const group = await Group . findOne ( { shortcode } ) ;
183
+
184
+ if ( ! group ) return new UserInputError ( "No group exists with that shortcode!" ) ;
185
+ if ( group . members . includes ( user . id ) ) return new Error ( "Already a member of the group!" ) ;
186
+ if ( group . leader == user . id ) return new Error ( "You are the leader of the group!" ) ;
187
+
188
+ group . members . push ( user . id ) ;
189
+ console . log ( "user joined group: " , user ) ;
190
+ await group . save ( ) ;
191
+ await group . populate ( "leader" ) ;
192
+
193
+ //publish this change over GROUP_JOINED subscription.
194
+ pubsub . publish ( "GROUP_JOINED" , { groupJoined : user , groupID : group . id } ) ;
195
+
196
+ user . groups . push ( group . id ) ;
197
+ await user . save ( ) ;
198
+ return group ;
199
+ } ,
200
+
150
201
createLandmark : async ( _ , { landmark, beaconID } , { user } ) => {
151
202
const beacon = await Beacon . findById ( beaconID ) ;
152
203
// to save on a db call to populate leader, we just use the stored id to compare
@@ -223,6 +274,12 @@ const resolvers = {
223
274
( payload , variables ) => payload . beaconID === variables . id
224
275
) ,
225
276
} ,
277
+ groupJoined : {
278
+ subscribe : withFilter (
279
+ ( _ , __ , { pubsub } ) => pubsub . asyncIterator ( [ "GROUP_JOINED" ] ) ,
280
+ ( payload , variables ) => payload . groupID === variables . groupID
281
+ ) ,
282
+ } ,
226
283
} ,
227
284
} ) ,
228
285
} ;
0 commit comments