|
@@ -23,10 +23,11 @@ import { P2pDatabaseGunProvider } from "../../providers/p2p-database-gun/p2p-dat
|
|
|
templateUrl: "profile.html"
|
|
|
})
|
|
|
export class ProfilePage {
|
|
|
- userId: string;
|
|
|
user: any = [];
|
|
|
tweets: any[];
|
|
|
+ oldestLoadedTweetId;
|
|
|
enableRefresh: boolean = true;
|
|
|
+ enableInfiniteScroll: boolean = true;
|
|
|
|
|
|
@ViewChild(Content)
|
|
|
content: Content;
|
|
@@ -40,39 +41,115 @@ export class ProfilePage {
|
|
|
) {}
|
|
|
|
|
|
ionViewDidLoad() {
|
|
|
- this.userId = this.navParams.get("userId");
|
|
|
+ const userId = this.navParams.get("userId");
|
|
|
|
|
|
- this.twitter.fetchUser(this.userId).then(res => (this.user = res));
|
|
|
+ this.twitter.fetchUser(userId).then(res => (this.user = res));
|
|
|
|
|
|
- this.twitter
|
|
|
- .fetchUserTimeline(this.userId)
|
|
|
- .then(res => (this.tweets = res));
|
|
|
+ this.loadTimeline(userId, null).then(res => {
|
|
|
+ if (res.length > 0) {
|
|
|
+ // Save tweets
|
|
|
+ this.tweets = res;
|
|
|
|
|
|
- this.checkP2pTweets("username");
|
|
|
+ // Save oldest tweet's id for next load more
|
|
|
+ this.oldestLoadedTweetId = res
|
|
|
+ .filter(tweet => !tweet.private_tweet)
|
|
|
+ .reduce((acc, cur) => (acc.id < cur.id ? acc : cur))["id"];
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
doRefresh(refresher) {
|
|
|
- this.twitter.fetchUserTimeline(this.userId).then(res => {
|
|
|
- this.tweets = res;
|
|
|
+ this.loadTimeline(this.user.id, null).then(res => {
|
|
|
+ if (res.length > 0) {
|
|
|
+ // Replace tweets
|
|
|
+ this.tweets = res;
|
|
|
+
|
|
|
+ // Save oldest tweet's id for next load more
|
|
|
+ this.oldestLoadedTweetId = res
|
|
|
+ .filter(tweet => !tweet.private_tweet)
|
|
|
+ .reduce((acc, cur) => (acc.id < cur.id ? acc : cur))["id"];
|
|
|
+ }
|
|
|
+
|
|
|
+ // Hide loading icon
|
|
|
refresher.complete();
|
|
|
});
|
|
|
}
|
|
|
|
|
|
loadMore(infiniteScroll: InfiniteScroll) {
|
|
|
- this.twitter
|
|
|
- .fetchUserTimelineSince(
|
|
|
- this.userId,
|
|
|
- this.tweets[this.tweets.length - 1].id
|
|
|
- )
|
|
|
- .then(res => {
|
|
|
+ this.loadTimeline(this.user.id, this.oldestLoadedTweetId).then(res => {
|
|
|
+ if (res.length > 0) {
|
|
|
+ // Append loaded tweets
|
|
|
this.tweets = this.tweets.concat(res);
|
|
|
- infiniteScroll.complete();
|
|
|
- });
|
|
|
+
|
|
|
+ // Save oldest tweet's id for next load more
|
|
|
+ this.oldestLoadedTweetId = res
|
|
|
+ .filter(tweet => !tweet.private_tweet)
|
|
|
+ .reduce((acc, cur) => (acc.id < cur.id ? acc : cur))["id"];
|
|
|
+ }
|
|
|
+
|
|
|
+ // Hide loading icon
|
|
|
+ infiniteScroll.complete();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private async loadTimeline(userId, oldestLoadedTweetId) {
|
|
|
+ // Fetch tweets from Twitter
|
|
|
+ const tweets =
|
|
|
+ oldestLoadedTweetId == null
|
|
|
+ ? await this.twitter.fetchUserTimeline(userId)
|
|
|
+ : await this.twitter.fetchUserTimelineSince(
|
|
|
+ userId,
|
|
|
+ oldestLoadedTweetId
|
|
|
+ );
|
|
|
+
|
|
|
+ // Determine end of time interval to look for private tweets
|
|
|
+ let intervalEnd;
|
|
|
+ if (tweets.length < 20) {
|
|
|
+ // End of timeline is reached
|
|
|
+ this.enableInfiniteScroll = false;
|
|
|
+ intervalEnd = new Date("2018-04-01T00:00:00");
|
|
|
+ } else {
|
|
|
+ const lastTweetTimestamp = tweets[tweets.length - 1].created_at;
|
|
|
+ intervalEnd = new Date(lastTweetTimestamp);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fetch private tweet hashs from P2P DB for corresponding interval
|
|
|
+ const privateTweetHashs: string[] = await this.gun.fetchPrivateTweetHashsForUserInInterval(
|
|
|
+ userId,
|
|
|
+ new Date(),
|
|
|
+ intervalEnd
|
|
|
+ );
|
|
|
+
|
|
|
+ // Load private tweets from P2P storage
|
|
|
+ let privateTweets = await this.ipfs.fetchTweets(privateTweetHashs);
|
|
|
+
|
|
|
+ // Add user object to private tweets
|
|
|
+ privateTweets = await Promise.all(
|
|
|
+ privateTweets.map(async tweet => await this.addUserToTweet(tweet))
|
|
|
+ );
|
|
|
+
|
|
|
+ // Combine and sort tweets
|
|
|
+ return tweets
|
|
|
+ .concat(privateTweets)
|
|
|
+ .sort((a, b) => this.sortByDateAsc(a, b));
|
|
|
+ }
|
|
|
+
|
|
|
+ private sortByDateAsc(a, b) {
|
|
|
+ const dateA = new Date(a.created_at);
|
|
|
+ const dateB = new Date(b.created_at);
|
|
|
+
|
|
|
+ if (dateA > dateB) {
|
|
|
+ return -1;
|
|
|
+ } else if (dateA < dateB) {
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private async checkP2pTweets(userId) {
|
|
|
- const lastTweetHash = await this.gun.getLastTweetFromUser(userId);
|
|
|
- const res = await this.ipfs.fetchTweet(lastTweetHash);
|
|
|
+ private async addUserToTweet(tweet) {
|
|
|
+ tweet.user = await this.twitter.fetchUser(tweet.user_id);
|
|
|
+ return tweet;
|
|
|
}
|
|
|
|
|
|
onScroll(event) {
|