aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt
diff options
context:
space:
mode:
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.kt304
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()
+ }
+}