diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-10-05 15:58:59 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-10-05 15:58:59 +0900 |
commit | 9db537d339faa3ad44dfdcadb23f4c14bd8aceb4 (patch) | |
tree | 6b151cdfd0ca7dc44b9a189045b2b2cbc5aefc21 /app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt | |
parent | 52ad6edcb217762154a80990c34ca94772393848 (diff) | |
download | SmileEssence-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.kt | 339 |
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 + } + } +} |