diff options
Diffstat (limited to 'app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt')
-rw-r--r-- | app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt new file mode 100644 index 00000000..8afeadd1 --- /dev/null +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt @@ -0,0 +1,304 @@ +/* + * 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.page + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.support.v4.content.ContextCompat +import android.text.Editable +import android.text.Spannable +import android.text.TextUtils +import android.text.TextWatcher +import android.text.method.ArrowKeyMovementMethod +import android.view.* +import android.widget.* +import com.twitter.Validator +import net.lacolaco.smileessence.R +import net.lacolaco.smileessence.World +import net.lacolaco.smileessence.activity.MainActivity +import net.lacolaco.smileessence.data.PostState +import net.lacolaco.smileessence.entity.Tweet +import net.lacolaco.smileessence.logging.Logger +import net.lacolaco.smileessence.preference.UserPreferenceHelper +import net.lacolaco.smileessence.twitter.task.Tweets +import net.lacolaco.smileessence.util.BitmapThumbnailTask +import net.lacolaco.smileessence.util.IntentUtils +import net.lacolaco.smileessence.util.SystemServiceHelper +import net.lacolaco.smileessence.util.UIHandler +import net.lacolaco.smileessence.view.Partials + +import java.io.File + +class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChangeListener, View.OnClickListener, PostState.OnPostStateChangeListener { + private var editText: EditText? = null + private var textViewCount: TextView? = null + private var buttonTweet: Button? = null + private var viewGroupReply: ViewGroup? = null + private var viewGroupMedia: ViewGroup? = null + + override fun refresh() {} + + // --------------------- Interface OnClickListener --------------------- + + override fun onClick(v: View) { + when (v.id) { + R.id.button_post_delete -> { + deletePost() + } + R.id.button_post_media -> { + setImage() + } + R.id.button_post_tweet -> { + submitPost() + } + R.id.button_post_reply_delete -> { + deleteReply() + } + R.id.button_post_media_delete -> { + removeImage() + } + R.id.image_post_media -> { + displayImage() + } + } + } + + // --------------------- Interface OnFocusChangeListener --------------------- + + override fun onFocusChange(v: View, hasFocus: Boolean) { + if (hasFocus) { + SystemServiceHelper.showIM(activity, editText) + } else { + SystemServiceHelper.hideIM(activity, editText) + } + } + + // --------------------- Interface OnPostStateChangeListener --------------------- + + + override fun onPostStateChange(postState: PostState) { + Logger.debug("onPostStateChange") + val activity = activity as MainActivity + if (editText != null) { + val start = postState.selectionStart + val end = postState.selectionEnd + editText!!.removeTextChangedListener(this) + editText!!.setTextKeepState(postState.text) + editText!!.addTextChangedListener(this) + updateTextCount(editText!!.text) + UIHandler().postAtFrontOfQueue { editText!!.setSelection(start, end) } + } + if (viewGroupReply != null) { + if (postState.inReplyTo != null) { + viewGroupReply!!.visibility = View.VISIBLE + val imageButtonDeleteReply = viewGroupReply!!.findViewById(R.id.button_post_reply_delete) as ImageButton + imageButtonDeleteReply.setOnClickListener(this) + + val tweet = postState.inReplyTo + var header = viewGroupReply!!.findViewById(R.id.layout_post_reply_status) + header = Partials.getTweetView(tweet!!, activity, header, true) + header.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.transparent)) + header.isClickable = false + } else { + viewGroupReply!!.visibility = View.GONE + } + } + if (viewGroupMedia != null) { + val imageViewMedia = viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView + if (TextUtils.isEmpty(postState.mediaFilePath)) { + viewGroupMedia!!.visibility = View.GONE + } else { + viewGroupMedia!!.visibility = View.VISIBLE + + } + BitmapThumbnailTask(postState.mediaFilePath, imageViewMedia).execute() + } + } + + // --------------------- Interface TextWatcher --------------------- + + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + updateTextCount(s) + } + + private fun updateTextCount(s: CharSequence) { + val validator = Validator() + var remainingCount = 140 - validator.getTweetLength(s.toString()) + if (!TextUtils.isEmpty(world.postState.mediaFilePath)) { + remainingCount -= validator.shortUrlLength + } + textViewCount!!.text = remainingCount.toString() + if (remainingCount == 140 || remainingCount < 0) { + textViewCount!!.setTextColor(ContextCompat.getColor(activity, R.color.red)) + } else { + textViewCount!!.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView) + } + setStateFromView() + } + + override fun afterTextChanged(s: Editable) {} + + // ------------------------ OVERRIDE METHODS ------------------------ + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + super.onCreateOptionsMenu(menu, inflater) + SystemServiceHelper.showIM(activity, editText) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + Logger.debug("onCreateView") + setHasOptionsMenu(true) + world.postState.setListener(this) + val v = inflater.inflate(R.layout.fragment_post, container, false) + buttonTweet = getTweetButton(v) + buttonTweet!!.setOnClickListener(this) + editText = getEditText(v) + textViewCount = getCountTextView(v) + val textSize = UserPreferenceHelper.instance.textSize + editText!!.addTextChangedListener(this) + editText!!.onFocusChangeListener = this + editText!!.textSize = (textSize + 4).toFloat() + editText!!.movementMethod = object : ArrowKeyMovementMethod() { + override fun right(widget: TextView, buffer: Spannable): Boolean { + //Don't back to Home + return widget.selectionEnd == widget.length() || super.right(widget, buffer) + } + } + val imageButtonDeleteText = v.findViewById(R.id.button_post_delete) as ImageButton + imageButtonDeleteText.setOnClickListener(this) + val imageButtonMedia = v.findViewById(R.id.button_post_media) as ImageButton + imageButtonMedia.setOnClickListener(this) + //Reply view + viewGroupReply = getReplyViewGroup(v) + val imageButtonDeleteReply = viewGroupReply!!.findViewById(R.id.button_post_reply_delete) as ImageButton + imageButtonDeleteReply.setOnClickListener(this) + //Media view + viewGroupMedia = getMediaViewGroup(v) + val imageViewMedia = viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView + val imageButtonDeleteMedia = viewGroupMedia!!.findViewById(R.id.button_post_media_delete) as ImageButton + imageViewMedia.setOnClickListener(this) + imageButtonDeleteMedia.setOnClickListener(this) + editText!!.requestFocus() + return v + } + + override fun onDestroyView() { + Logger.debug("onDestroyView") + super.onDestroyView() + setStateFromView() + world.postState.removeListener() + } + + override fun onViewStateRestored(savedInstanceState: Bundle?) { + Logger.debug("onViewStateRestored") + super.onViewStateRestored(savedInstanceState) + val state = world.postState + onPostStateChange(state) + } + + private fun deletePost() { + editText!!.setText("") + world.postState.beginTransaction().setText("").setCursor(0).commit() + deleteReply() + } + + private fun deleteReply() { + viewGroupReply!!.visibility = View.GONE + world.postState.beginTransaction().setInReplyTo(null).commit() + } + + private fun displayImage() { + val intent = Intent() + intent.action = Intent.ACTION_VIEW + intent.addCategory(Intent.CATEGORY_DEFAULT) + intent.setDataAndType(Uri.fromFile(File(world.postState.mediaFilePath)), "image/*") + IntentUtils.startActivityIfFound(activity, intent) + } + + private fun getCountTextView(v: View): TextView { + return v.findViewById(R.id.post_text_count) as TextView + } + + private fun getEditText(v: View): EditText { + return v.findViewById(R.id.post_edit_text) as EditText + } + + private fun getMediaViewGroup(v: View): ViewGroup { + return v.findViewById(R.id.post_media_parent) as ViewGroup + } + + private fun getReplyViewGroup(v: View): ViewGroup { + return v.findViewById(R.id.post_inreplyto_parent) as ViewGroup + } + + private fun getTweetButton(v: View): Button { + return v.findViewById(R.id.button_post_tweet) as Button + } + + private fun removeImage() { + SystemServiceHelper.hideIM(activity, editText) + viewGroupMedia!!.visibility = View.GONE + (viewGroupMedia!!.findViewById(R.id.image_post_media) as ImageView).setImageBitmap(null) + world.postState.beginTransaction().setMediaFilePath("").commit() + } + + private fun setImage() { + setStateFromView() + SystemServiceHelper.hideIM(activity, editText) + + val intent = Intent(Intent.ACTION_PICK) + intent.type = "image/*" + IntentUtils.startActivityForResultIfFound(activity, intent, MainActivity.REQUEST_GET_PICTURE_FROM_GALLERY) + } + + private fun setStateFromView() { + val state = world.postState + state.removeListener() + state.beginTransaction() + .setText(editText!!.text.toString()) + .setSelection(editText!!.selectionStart, editText!!.selectionEnd) + .commit() + state.setListener(this) + } + + private fun submitPost() { + SystemServiceHelper.hideIM(activity, editText) + setStateFromView() + val state = world.postState + val mainActivity = activity as MainActivity + val resizeFlag = UserPreferenceHelper.instance.get(R.string.key_setting_resize_post_image, false) + Tweets.CreateTask(world.account, state.toStatusUpdate(), state.mediaFilePath, resizeFlag) + .onDoneUI { t -> + world.notify(R.string.notice_tweet_succeeded) + world.postState.beginTransaction().clear().commit() + } + .onFail { e -> world.notifyError(R.string.notice_tweet_failed, e) } + .execute() + mainActivity.openHomePage() + } +} |