feed.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { HttpClient } from "@angular/common/http";
  2. import { Injectable } from "@angular/core";
  3. import { TwitterApiProvider } from "../twitter-api/twitter-api";
  4. import { P2pDatabaseGunProvider } from "../p2p-database-gun/p2p-database-gun";
  5. import { P2pStorageIpfsProvider } from "../p2p-storage-ipfs/p2p-storage-ipfs";
  6. @Injectable()
  7. export class FeedProvider {
  8. constructor(
  9. private http: HttpClient,
  10. private twitter: TwitterApiProvider,
  11. private gun: P2pDatabaseGunProvider,
  12. private ipfs: P2pStorageIpfsProvider
  13. ) {}
  14. public async loadUserTimeline(
  15. userId,
  16. oldestPublicTweet?,
  17. oldestPrivateTweet?
  18. ) {
  19. const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined;
  20. // Fetch tweets from Twitter
  21. let tweets = await this.twitter.fetchUserTimeline(userId, maxId);
  22. tweets = tweets.filter(tweet => tweet.id_str != maxId);
  23. // Determine start and end of time interval to look for private tweets
  24. const intervalStart: Date = oldestPrivateTweet
  25. ? new Date(oldestPrivateTweet["created_at"])
  26. : new Date();
  27. const intervalEnd: Date = this.getOldestTweetTimestamp(tweets);
  28. // Fetch private tweet hashs from P2P DB for corresponding interval
  29. const privateTweetHashs: string[] = await this.gun.fetchPrivateTweetHashsForUserInInterval(
  30. userId,
  31. intervalStart,
  32. intervalEnd
  33. );
  34. if (privateTweetHashs.length) {
  35. const privateTweets = await this.fetchPrivateTweets(privateTweetHashs);
  36. // Combine and sort tweets
  37. return tweets
  38. .concat(privateTweets)
  39. .sort((a, b) => this.sortByDateAsc(a, b));
  40. } else {
  41. return tweets;
  42. }
  43. }
  44. public async loadHomeTimeline(
  45. userId,
  46. oldestPublicTweet?,
  47. oldestPrivateTweet?
  48. ) {
  49. // Fetch tweets from Twitter
  50. const maxId = oldestPublicTweet ? oldestPublicTweet["id_str"] : undefined;
  51. let tweets = await this.twitter.fetchHomeFeed(maxId);
  52. tweets = tweets.filter(tweet => tweet.id_str != maxId);
  53. // Determine start and end of time interval to look for private tweets
  54. const intervalStart: Date = oldestPrivateTweet
  55. ? new Date(oldestPrivateTweet["created_at"])
  56. : new Date();
  57. const intervalEnd: Date = this.getOldestTweetTimestamp(tweets);
  58. // Fetch user's friends
  59. const friends = await this.twitter.fetchFriends(userId);
  60. let privateTweetHashs = [];
  61. friends.forEach(async friend => {
  62. privateTweetHashs = privateTweetHashs.concat(
  63. await this.gun.fetchPrivateTweetHashsForUserInInterval(
  64. friend.id_str,
  65. intervalStart,
  66. intervalEnd
  67. )
  68. );
  69. });
  70. // Add users private tweets
  71. privateTweetHashs = privateTweetHashs.concat(
  72. await this.gun.fetchPrivateTweetHashsForUserInInterval(
  73. userId,
  74. intervalStart,
  75. intervalEnd
  76. )
  77. );
  78. if (privateTweetHashs.length) {
  79. const privateTweets = await this.fetchPrivateTweets(privateTweetHashs);
  80. // Combine and sort tweets
  81. return tweets
  82. .concat(privateTweets)
  83. .sort((a, b) => this.sortByDateAsc(a, b));
  84. } else {
  85. return tweets;
  86. }
  87. }
  88. private async fetchPrivateTweets(privateTweetHashs) {
  89. // Load private tweets from P2P storage
  90. const privateTweets = await this.ipfs.fetchTweets(privateTweetHashs);
  91. // Add user object to private tweets
  92. return await Promise.all(
  93. privateTweets.map(async tweet => await this.addUserToTweet(tweet))
  94. );
  95. }
  96. private async addUserToTweet(tweet) {
  97. tweet.user = await this.twitter.fetchUser(tweet.user_id);
  98. return tweet;
  99. }
  100. private getOldestTweetTimestamp(tweets): Date {
  101. if (tweets.length < 15) {
  102. // End of timeline is reached - load all private tweets
  103. return new Date("2018-04-01T00:00:00");
  104. } else {
  105. const lastTweetTimestamp = tweets[tweets.length - 1].created_at;
  106. return new Date(lastTweetTimestamp);
  107. }
  108. }
  109. private sortByDateAsc(a, b) {
  110. const dateA = new Date(a.created_at);
  111. const dateB = new Date(b.created_at);
  112. if (dateA > dateB) {
  113. return -1;
  114. } else if (dateA < dateB) {
  115. return 1;
  116. } else {
  117. return 0;
  118. }
  119. }
  120. }