aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt
diff options
context:
space:
mode:
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.kt197
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) }
+ }
+ }
+}