+16
parakeet/src/db.rs
+16
parakeet/src/db.rs
···
180
180
.load(conn)
181
181
.await
182
182
}
183
+
184
+
pub async fn get_pinned_post_uri(
185
+
conn: &mut AsyncPgConnection,
186
+
did: &str,
187
+
) -> QueryResult<Option<String>> {
188
+
schema::profiles::table
189
+
.select(schema::profiles::pinned_uri.assume_not_null())
190
+
.filter(
191
+
schema::profiles::did
192
+
.eq(did)
193
+
.and(schema::profiles::pinned_uri.is_not_null()),
194
+
)
195
+
.get_result(conn)
196
+
.await
197
+
.optional()
198
+
}
+21
-1
parakeet/src/xrpc/app_bsky/feed/posts.rs
+21
-1
parakeet/src/xrpc/app_bsky/feed/posts.rs
···
207
207
208
208
let hyd = StatefulHydrator::new(&state.dataloaders, &state.cdn, &labelers, maybe_auth);
209
209
210
+
let pin = match query.include_pins && query.cursor.is_none() {
211
+
false => None,
212
+
true => match crate::db::get_pinned_post_uri(&mut conn, &did).await? {
213
+
Some(post) => hyd.hydrate_post(post).await,
214
+
None => None,
215
+
},
216
+
};
217
+
210
218
let limit = query.limit.unwrap_or(50).clamp(1, 100);
211
219
212
220
let mut posts_query = schema::posts::table
···
259
267
260
268
let mut posts = hyd.hydrate_feed_posts(at_uris).await;
261
269
262
-
let feed = results
270
+
let mut feed: Vec<_> = results
263
271
.into_iter()
264
272
.filter_map(|(_, uri)| posts.remove(&uri))
265
273
.collect();
274
+
275
+
if let Some(post) = pin {
276
+
feed.insert(
277
+
0,
278
+
FeedViewPost {
279
+
post,
280
+
reply: None,
281
+
reason: Some(FeedViewPostReason::Pin),
282
+
feed_context: None,
283
+
},
284
+
);
285
+
}
266
286
267
287
Ok(Json(FeedRes { cursor, feed }))
268
288
}