diff options
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt')
-rw-r--r-- | app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt b/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt new file mode 100644 index 00000000..437e69c7 --- /dev/null +++ b/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt @@ -0,0 +1,197 @@ +package net.lacolaco.smileessence.entity + +import android.net.Uri +import net.lacolaco.smileessence.data.Account +import net.lacolaco.smileessence.twitter.task.Tweets +import net.lacolaco.smileessence.util.BackgroundTask +import twitter4j.Status + +import java.util.* +import java.util.concurrent.ConcurrentHashMap + +class Tweet private constructor(st: twitter4j.Status, myUserId: Long) : EntitySupport(), IdObject { + override val id: Long = st.id + val user: User = User.fromTwitter(st.user) + val text: String = extractText(st, false) + get() { + return if (isRetweet) originalTweet.text else field + } + val createdAt: Date = st.createdAt + val source: String = st.source + val isRetweet: Boolean = st.isRetweet + val retweetedTweet: Tweet? = if (st.isRetweet) Tweet.fromTwitter(st.retweetedStatus, myUserId) else null + val originalTweet: Tweet + get() = retweetedTweet ?: this + val inReplyToStatusId: Long = st.inReplyToStatusId + get() = if (isRetweet) originalTweet.inReplyToStatusId else field + var favoriteCount: Int = st.favoriteCount + get() = if (isRetweet) originalTweet.originalTweet.favoriteCount else field + private set + var retweetCount: Int = st.retweetCount + get() = if (isRetweet) originalTweet.originalTweet.retweetCount else field + private set + private val favoriters: MutableSet<Long> = Collections.newSetFromMap(ConcurrentHashMap()) + private val retweets: MutableMap<Long, Long> = ConcurrentHashMap() + + protected fun finalize() { + retweetedTweet?.retweets?.remove(id) + } + + init { + updateEntities(st) + update(st, myUserId) + } + + private fun update(status: twitter4j.Status, myUserId: Long) { + User.fromTwitter(status.user) + if (retweetedTweet != null) { + Tweet.fromTwitter(status.retweetedStatus, myUserId) + if (status.isFavorited) { + retweetedTweet.favoriters.add(myUserId) + } + if (status.currentUserRetweetId > 0) { + retweetedTweet.retweets.put(myUserId, status.currentUserRetweetId) + } + } else { + if (favoriteCount != status.favoriteCount || retweetCount != status.retweetCount) { + favoriteCount = status.favoriteCount + retweetCount = status.retweetCount + notifyChange(RBinding.REACTION_COUNT) + } + + if (status.isFavorited) + favoriters.add(myUserId) + else + favoriters.remove(myUserId) + if (status.currentUserRetweetId > 0) + retweets.put(myUserId, status.currentUserRetweetId) + } + } + + val twitterUrl: String + get() = String.format("https://twitter.com/%s/status/%s", user.screenName, id) + + fun isFavoritedBy(id: Long): Boolean { + return originalTweet.favoriters.contains(id) + } + + fun addFavoriter(id: Long): Boolean { + val changed = originalTweet.favoriters.add(id) + if (changed) notifyChange(RBinding.FAVORITERS) + return changed + } + + fun removeFavoriter(id: Long): Boolean { + val changed = originalTweet.favoriters.remove(id) + if (changed) notifyChange(RBinding.FAVORITERS) + return changed + } + + fun isRetweetedBy(id: Long): Boolean { + return originalTweet.retweets[id] != null + } + + fun getRetweetIdBy(id: Long): Long { + return originalTweet.retweets[id]!! + } + + // helper methods:: + val embeddedStatusIDs: List<Long> + get() { + val list = ArrayList<Long>() + for (url in urlsExpanded) { + val uri = Uri.parse(url) + if ("twitter.com" == uri.host) { + val arr = uri.toString().split("/".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray() + if (arr.size > 2 && "status" == arr[arr.size - 2]) { + list.add(java.lang.Long.parseLong(arr[arr.size - 1].split("\\?".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[0])) + } + } + } + return list + } + + // override EntitySupport + override var mentions: List<String> + get() = if (isRetweet) originalTweet.mentions else super.mentions + set(value) { + super.mentions = value + } + + override var hashtags: List<String> + get() = if (isRetweet) originalTweet.hashtags else super.hashtags + set(value) { + super.hashtags = value + } + + override var mediaUrls: List<String> + get() = if (isRetweet) { + originalTweet.mediaUrls + } else { + super.mediaUrls + } + set(value) { + super.mediaUrls = value + } + + override var urlsExpanded: List<String> + get() = if (isRetweet) { + originalTweet.urlsExpanded + } else { + super.urlsExpanded + } + set(value) { + super.urlsExpanded = value + } + + override var symbols: List<String> + get() = if (isRetweet) { + originalTweet.symbols + } else { + super.symbols + } + set(value) { + super.symbols = value + } + + companion object { + private val storage = HashMap<Long, Tweet>() + + @Synchronized + fun fetch(statusId: Long): Tweet? { + return storage[statusId] + } + + @Synchronized + fun fetchTask(statusId: Long, account: Account): BackgroundTask<Tweet, Void> { + val tweet = fetch(statusId) + return if (tweet != null) { + object : BackgroundTask<Tweet, Void>() { + @Throws(Exception::class) + override fun doInBackground(): Tweet { + return tweet + } + } + } else { + Tweets.GetTask(account, statusId) + } + } + + @Synchronized + fun fromTwitter(st: twitter4j.Status, myUserId: Long): Tweet { + var t = fetch(st.id) + if (t == null) { + t = Tweet(st, myUserId) + storage.put(st.id, t) + } else { + t.update(st, myUserId) + } + return t + } + + @Synchronized + fun fromTwitter(sts: List<Status>, myUserId: Long): List<Tweet> { + return sts.map { st -> fromTwitter(st, myUserId) } + } + } +} |