aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-10-05 15:58:59 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-10-05 15:58:59 +0900
commit9db537d339faa3ad44dfdcadb23f4c14bd8aceb4 (patch)
tree6b151cdfd0ca7dc44b9a189045b2b2cbc5aefc21 /app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
parent52ad6edcb217762154a80990c34ca94772393848 (diff)
downloadSmileEssence-9db537d339faa3ad44dfdcadb23f4c14bd8aceb4.tar.gz
kotlin work part. 1
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt')
-rw-r--r--app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt339
1 files changed, 339 insertions, 0 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
new file mode 100644
index 00000000..c18b6b4d
--- /dev/null
+++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt
@@ -0,0 +1,339 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2012-2014 lacolaco.net
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package net.lacolaco.smileessence.view.dialog
+
+import android.app.AlertDialog
+import android.app.Dialog
+import android.graphics.drawable.ColorDrawable
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.ListView
+import android.widget.TextView
+import net.lacolaco.smileessence.Application
+import net.lacolaco.smileessence.R
+import net.lacolaco.smileessence.activity.MainActivity
+import net.lacolaco.smileessence.command.Command
+import net.lacolaco.smileessence.command.CommandAddHashtag
+import net.lacolaco.smileessence.command.CommandOpenURL
+import net.lacolaco.smileessence.command.CommandOpenUserDetail
+import net.lacolaco.smileessence.data.Account
+import net.lacolaco.smileessence.entity.RBinding
+import net.lacolaco.smileessence.entity.Tweet
+import net.lacolaco.smileessence.preference.UserPreferenceHelper
+import net.lacolaco.smileessence.twitter.task.TweetReactions
+import net.lacolaco.smileessence.twitter.task.Tweets
+import net.lacolaco.smileessence.util.IntentUtils
+import net.lacolaco.smileessence.util.SystemServiceHelper
+import net.lacolaco.smileessence.util.UIObserverBundle
+import net.lacolaco.smileessence.view.DialogHelper
+import net.lacolaco.smileessence.view.Partials
+import net.lacolaco.smileessence.view.ToggleableImageButton
+import net.lacolaco.smileessence.view.adapter.CustomListAdapter
+import net.lacolaco.smileessence.view.adapter.TimelineAdapter
+
+import java.lang.ref.WeakReference
+import java.util.ArrayList
+import java.util.LinkedHashSet
+
+class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListener {
+ private lateinit var tweet: Tweet
+
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.button_status_detail_reply -> {
+ val originalTweet = tweet.originalTweet
+
+ val builder = StringBuilder()
+ builder.append("@" + originalTweet.user.screenName + " ")
+
+ for (screenName in originalTweet.mentions) {
+ if (screenName != world.account.user.screenName)
+ builder.append("@$screenName ")
+ }
+ val text = builder.toString()
+ val selStart = originalTweet.user.screenName.length + 2 // "@" and " "
+
+ world.postState.beginTransaction()
+ .clear()
+ .insertText(0, text)
+ .setInReplyTo(originalTweet)
+ .setSelection(selStart, text.length)
+ .commitWithOpen(activity as MainActivity)
+ }
+ R.id.button_status_detail_retweet -> {
+ val account = world.account
+ confirm({
+ if (tweet.isRetweetedBy(account.userId)) {
+ Tweets.DestroyTask(account, tweet.getRetweetIdBy(account.userId))
+ .onDone { t -> world.notify(R.string.notice_status_delete_succeeded) }
+ .onFail { e -> world.notifyError(R.string.notice_status_delete_failed) }
+ .execute()
+ dismiss()
+ } else {
+ TweetReactions.RetweetTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_retweet_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_retweet_failed) }
+ .execute()
+ }
+ })
+ }
+ R.id.button_status_detail_favorite -> {
+ val account = world.account
+ if (tweet.isFavoritedBy(account.userId)) {
+ TweetReactions.UnfavoriteTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_unfavorite_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_unfavorite_failed) }
+ .execute()
+ } else {
+ TweetReactions.FavoriteTask(account, tweet.id)
+ .onDone { x -> world.notify(R.string.notice_favorite_succeeded) }
+ .onFail { x -> world.notifyError(R.string.notice_favorite_failed) }
+ .execute()
+ }
+ }
+ R.id.button_status_detail_delete -> {
+ confirm({
+ Tweets.DestroyTask(world.account, tweet.originalTweet.id)
+ .onDone { t -> world.notify(R.string.notice_status_delete_succeeded) }
+ .onFail { e -> world.notifyError(R.string.notice_status_delete_failed) }
+ .execute()
+ dismiss()
+ })
+ }
+ R.id.button_status_detail_menu -> {
+ val builder = AlertDialog.Builder(activity)
+ builder.setTitle("@" + tweet.user.screenName + ": " + tweet.text)
+ .setItems(R.array.status_commands) { dialog, which ->
+ when (which) {
+ 0 -> {
+ val text = String.format("@%s ", tweet.originalTweet.user.screenName)
+ world.postState.beginTransaction().insertText(0, text).moveCursor(text.length).commit()
+ world.notify(R.string.notice_add_to_reply)
+ }
+ 1 -> {
+ DialogHelper.showDialog(activity, TalkChainDialogFragment.newInstance(tweet))
+ }
+ 2 -> IntentUtils.openUri(activity, tweet.originalTweet.twitterUrl)
+ 3 -> {
+ SystemServiceHelper.copyToClipboard(activity, "tweet text", tweet.originalTweet.text)
+ world.notify(R.string.notice_copy_clipboard)
+ }
+ 4 -> {
+ val statusURL = tweet.originalTweet.twitterUrl
+ SystemServiceHelper.copyToClipboard(activity, "tweet url", statusURL)
+ world.notify(R.string.notice_copy_clipboard)
+ }
+ else -> throw IllegalStateException()
+ }
+ }
+ val dialog = builder.create()
+ dialog.show()
+ }
+ else -> {
+ dismiss()
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val found = Tweet.fetch(arguments.getLong(KEY_STATUS_ID))
+ if (found == null) { // trying to open deleted tweet?
+ world.notifyError(R.string.notice_error_show_status)
+ return DisposeDialog(activity)
+ }
+ tweet = found
+
+ val view = activity.layoutInflater.inflate(R.layout.dialog_status_detail, null)
+ val bundle = UIObserverBundle()
+ view.tag = bundle
+
+ val statusHeader = Partials.getTweetView(tweet, activity, view.findViewById(R.id.layout_status_header), true)
+ statusHeader.isClickable = false
+
+ view.setBackgroundColor((statusHeader.background as ColorDrawable).color)
+ updateViewReactions(view)
+ updateViewButtons(view)
+ setupViewMenu(view)
+
+ val weakView = WeakReference(view)
+ bundle.attach(tweet.originalTweet) { changes ->
+ val strongView = weakView.get()
+ if (strongView != null && activity != null) {
+ if (changes.contains(RBinding.REACTION_COUNT))
+ updateViewReactions(strongView)
+ if (changes.contains(RBinding.FAVORITERS) || changes.contains(RBinding.RETWEETERS))
+ updateViewButtons(strongView)
+ }
+ }
+
+ val listView = view.findViewById(R.id.listview_status_detail_reply_to) as ListView
+ val adapter = TimelineAdapter(activity)
+ listView.adapter = adapter
+
+ val replyDivider = view.findViewById(R.id.detail_dialog_divider_top)
+
+ if (tweet.inReplyToStatusId != -1L) {
+ replyDivider.visibility = View.VISIBLE
+ listView.visibility = View.VISIBLE
+ Tweet.fetchTask(tweet.inReplyToStatusId, world.account)
+ .onDoneUI { replyTo ->
+ adapter.add(replyTo)
+ adapter.update()
+ }
+ .execute()
+ } else {
+ replyDivider.visibility = View.GONE
+ listView.visibility = View.GONE
+ }
+
+ return AlertDialog.Builder(activity).setView(view).create()
+ }
+
+ private fun updateViewReactions(view: View) {
+ val favCountIcon = view.findViewById(R.id.image_status_detail_fav_count) as ImageView
+ val favCountText = view.findViewById(R.id.textview_status_detail_fav_count) as TextView
+ if (tweet.favoriteCount > 0) {
+ favCountText.text = Integer.toString(tweet.favoriteCount)
+ favCountIcon.visibility = View.VISIBLE
+ favCountText.visibility = View.VISIBLE
+ } else {
+ favCountIcon.visibility = View.GONE
+ favCountText.visibility = View.GONE
+ }
+
+ val rtCountIcon = view.findViewById(R.id.image_status_detail_rt_count) as ImageView
+ val rtCountText = view.findViewById(R.id.textview_status_detail_rt_count) as TextView
+ if (tweet.retweetCount > 0) {
+ rtCountText.text = Integer.toString(tweet.retweetCount)
+ rtCountIcon.visibility = View.VISIBLE
+ rtCountText.visibility = View.VISIBLE
+ } else {
+ rtCountIcon.visibility = View.GONE
+ rtCountText.visibility = View.GONE
+ }
+ }
+
+ private fun updateViewButtons(view: View) {
+ val account = world.account
+
+ //--- buttons
+ val reply = view.findViewById(R.id.button_status_detail_reply) as ImageButton
+ reply.setOnClickListener(this)
+
+ val retweet = view.findViewById(R.id.button_status_detail_retweet) as ToggleableImageButton
+ retweet.setOnClickListener(this)
+ retweet.setState(tweet.isRetweetedBy(account.userId))
+
+ val favorite = view.findViewById(R.id.button_status_detail_favorite) as ToggleableImageButton
+ favorite.setOnClickListener(this)
+ favorite.setState(tweet.isFavoritedBy(account.userId))
+
+ val delete = view.findViewById(R.id.button_status_detail_delete) as ImageButton
+ delete.setOnClickListener(this)
+ delete.visibility = if (tweet.originalTweet.user === account.user) View.VISIBLE else View.GONE
+
+ val menu = view.findViewById(R.id.button_status_detail_menu) as ImageButton
+ menu.setOnClickListener(this)
+ }
+
+ private fun setupViewMenu(view: View) {
+ val divider = view.findViewById(R.id.detail_dialog_divider_bottom)
+ val listView = view.findViewById(R.id.listview_status_detail_menu) as ListView
+ val commands = commands
+ if (commands.size > 0) {
+ divider.visibility = View.VISIBLE
+ listView.visibility = View.VISIBLE
+ val adapter = object : CustomListAdapter<Command>() {
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
+ var convertView = convertView
+ if (convertView == null) {
+ convertView = activity.layoutInflater.inflate(R.layout.menu_item_simple_text, null)
+ }
+ val textView = convertView!!.findViewById(R.id.list_item_textview) as TextView
+ textView.textSize = UserPreferenceHelper.instance.textSize.toFloat()
+ textView.text = getItem(position).text
+ return convertView
+ }
+
+ override val list: List<Command>
+ get() = commands
+ }
+ adapter.update()
+ listView.adapter = adapter
+ listView.setOnItemClickListener { parent, view1, position, id ->
+ val command = parent.getItemAtPosition(position) as Command
+ command.execute()
+ }
+ } else {
+ divider.visibility = View.GONE
+ listView.visibility = View.GONE
+ }
+ }
+
+ private fun confirm(onYes: () -> Unit) {
+ ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands), onYes)
+ }
+
+ private // Retweeter
+ // Mentions
+ // Array#uniq
+ // Hashtags
+ // URL
+ val commands: List<Command>
+ get() {
+ val activity = activity as MainActivity
+ val commands = ArrayList<Command>()
+ if (tweet.retweetedTweet != null && tweet.user !== tweet.retweetedTweet!!.user)
+ commands.add(CommandOpenUserDetail(activity, tweet.user.screenName))
+ for (screenName in ArrayList(LinkedHashSet(tweet.mentions))) {
+ commands.add(CommandOpenUserDetail(activity, screenName))
+ }
+ for (hashtag in tweet.hashtags) {
+ commands.add(CommandAddHashtag(activity, hashtag))
+ }
+ for (url in tweet.urlsExpanded) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ for (url in tweet.mediaUrls) {
+ commands.add(CommandOpenURL(activity, url))
+ }
+ return commands
+ }
+
+ companion object {
+ private val KEY_STATUS_ID = "status_id"
+
+ fun newInstance(tweet: Tweet): StatusDetailDialogFragment {
+ val obj = StatusDetailDialogFragment()
+ val args = Bundle()
+ args.putLong(KEY_STATUS_ID, tweet.id)
+ obj.arguments = args
+ return obj
+ }
+ }
+}