···55 created TIMESTAMP NOT NULL,
66 indexed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
77 author TEXT NOT NULL,
88- rkey TEXT NOT NULL
88+ rkey TEXT NOT NULL,
99+ cid TEXT NOT NULL
910);
+2-1
migrations/20260423190103_reposts.sql
···66 indexed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
77 author TEXT NOT NULL,
88 rkey TEXT NOT NULL,
99- subject TEXT NOT NULL
99+ subject TEXT NOT NULL,
1010+ cid TEXT NOT NULL
1011);
+5-3
readme.md
···2424 - [x] For each user call the `/repos/add` endpoint on tap to add the follow to be tracked
2525 - [x] Call `/repos/add` for the user of the appview
2626- [ ] - Handle the events for tracked users
2727- - [ ] Ignore anything other than the post lexicon types for the follows (work out what lexicon types need to be used for the user using the appview)
2727+ - [x] Ignore anything other than the post lexicon types for the follows (work out what lexicon types need to be used for the user using the appview)
2828 - [ ] Ignore if older than x amount of days (configurable number of days) - appview doesn't really need full history, only fairly recent and live
2929- - [ ] Store and index the data in sqlite (schema TBD)
3030- - [ ] MAYBE..... If the post is part of a reply, quote etc, maybe all relevant posts should be fetched too? Not sure how that will look yet, but that will be needed to render the posts in the app correctly I think.
2929+ - [x] Store and index the data in sqlite (schema TBD)
3030+ - [x] If it's a repost, store the subject too
3131+ - [ ] If it's a reply store the parent and root
3232+ - [ ] If it's a quote store the post that's quoted
3133- [ ] - Start to implement the endpoints required to make this an appview (looking at a [similar project konbini](https://tangled.org/why.bsky.team/konbini/) by [@why.bsky.team](https://bsky.app/profile/why.bsky.team))
3234 - [x] `GET /.well-known/did.json`
3335 - [ ] `GET /xrpc/com.atproto.identity.resolveHandle`
+24-10
src/tap.rs
···118118async fn handle_post_event(record: &RecordEvent, pool: &sqlx::SqlitePool) {
119119 match record.action {
120120 RecordAction::Create => {
121121+ let cid: String = match record.cid.clone() {
122122+ Some(x) => x.to_string(),
123123+ None => "".to_string(),
124124+ };
121125 let mut post = PostRecord {
122126 created: Utc::now(),
123127 indexed: Utc::now(),
124128 author: record.did.clone().to_string(),
125129 rkey: record.rkey.to_string(),
130130+ cid: cid,
126131 };
127132128133 let tap_post: TapPost = record.parse_record().unwrap(); // TODO: better error handling here
···150155 match record.action {
151156 RecordAction::Create => {
152157 let tap_post: TapRepost = record.parse_record().unwrap(); // TODO: better error handling here
153153-158158+ let cid: String = match record.cid.clone() {
159159+ Some(x) => x.to_string(),
160160+ None => "".to_string(),
161161+ };
154162 let mut repost = RepostRecord {
155163 created: Utc::now(),
156164 indexed: Utc::now(),
157165 author: record.did.clone().to_string(),
158166 rkey: record.rkey.to_string(),
159167 subject: tap_post.subject.uri,
168168+ cid: cid,
160169 };
161170162171 let created_at = DateTime::parse_from_rfc3339(&tap_post.created_at);
···224233 indexed: chrono::DateTime<chrono::Utc>,
225234 author: String,
226235 rkey: String,
236236+ cid: String,
227237 // TODO: other fields like reply to etc
228238}
229239···234244 author: String,
235245 rkey: String,
236246 subject: String,
247247+ cid: String,
237248 // TODO: other fields like reply to etc
238249}
239250240251async fn insert_post(post: PostRecord, pool: &sqlx::SqlitePool) {
241241- let result =
242242- sqlx::query("INSERT INTO posts (created, indexed, author, rkey) VALUES ($1, $2, $3, $4)")
243243- .bind(post.created)
244244- .bind(post.indexed)
245245- .bind(post.author)
246246- .bind(post.rkey)
247247- .execute(pool)
248248- .await;
252252+ let result = sqlx::query(
253253+ "INSERT INTO posts (created, indexed, author, rkey, cid) VALUES ($1, $2, $3, $4, $5)",
254254+ )
255255+ .bind(post.created)
256256+ .bind(post.indexed)
257257+ .bind(post.author)
258258+ .bind(post.rkey)
259259+ .bind(post.cid)
260260+ .execute(pool)
261261+ .await;
249262250263 if result.is_err() {
251264 println!("Error inserting post into the database: {result:?}");
···254267255268async fn insert_repost(repost: RepostRecord, pool: &sqlx::SqlitePool) {
256269 let result = sqlx::query(
257257- "INSERT INTO reposts (created, indexed, author, rkey, subject) VALUES ($1, $2, $3, $4, $5)",
270270+ "INSERT INTO reposts (created, indexed, author, rkey, subject, cid) VALUES ($1, $2, $3, $4, $5, $6)",
258271 )
259272 .bind(repost.created)
260273 .bind(repost.indexed)
261274 .bind(repost.author)
262275 .bind(repost.rkey)
263276 .bind(repost.subject)
277277+ .bind(repost.cid)
264278 .execute(pool)
265279 .await;
266280