diff options
Diffstat (limited to 'app/src')
54 files changed, 713 insertions, 1461 deletions
diff --git a/app/src/main/java/net/lacolaco/smileessence/Application.kt b/app/src/main/java/net/lacolaco/smileessence/Application.kt index 7950d62a..796d3984 100644 --- a/app/src/main/java/net/lacolaco/smileessence/Application.kt +++ b/app/src/main/java/net/lacolaco/smileessence/Application.kt @@ -43,42 +43,35 @@ import java.util.HashMap * MainActivity の onCreate で resetState を呼び、保持しているデータを破棄すること */ class Application : android.app.Application() { - override fun onCreate() { super.onCreate() - if (LeakCanary.isInAnalyzerProcess(this)) { + if (LeakCanary.isInAnalyzerProcess(this)) return - } LeakCanary.install(this) Fabric.with(this, Crashlytics.Builder().core(CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build()) - OrmaHolder.initialize(this) - // Load eagarly + instance = this + OrmaHolder.initialize(this) Account.load() - instancex = this // プロセスの寿命の間 1 度しか呼ばれないので安全 - Logger.debug("onCreate") } companion object { - private var instancex: Application? = null + @Deprecated("") + lateinit var instance: Application + private set private var lastWorld: WeakReference<World>? = null private val worlds = HashMap<Long, WeakReference<World>>() // XXX - @Deprecated("") - fun getInstance(): Application { - val obj = instancex - return obj ?: throw IllegalStateException("[BUG] Application is not initialized?") - } // --------------------- get instance --------------------- fun toast(@StringRes id: Int) { - Toast.makeText(instancex, id, Toast.LENGTH_LONG).show() + Toast.makeText(instance, id, Toast.LENGTH_LONG).show() } fun toast(text: String) { - Toast.makeText(instancex, text, Toast.LENGTH_LONG).show() + Toast.makeText(instance, text, Toast.LENGTH_LONG).show() } val currentWorld: World? diff --git a/app/src/main/java/net/lacolaco/smileessence/World.kt b/app/src/main/java/net/lacolaco/smileessence/World.kt index b18522e5..1522b465 100644 --- a/app/src/main/java/net/lacolaco/smileessence/World.kt +++ b/app/src/main/java/net/lacolaco/smileessence/World.kt @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap /** * World contains data that are specific to an account. */ -class World(var account: Account) { +class World(val account: Account) { private val resId: Int = 0 // XXX: Fetch from Account // XXX: Move to MainActivity val postState = PostState() @@ -88,6 +88,10 @@ class World(var account: Account) { directMessageNotifiers.forEach { o, c -> c(entity) } } + fun addDirectMessage(entities: Iterable<DirectMessage>) { + entities.forEach { addDirectMessage(it) } + } + // Events @Synchronized diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/EditExtractionActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/EditExtractionActivity.kt index c621b6f7..2aab728f 100644 --- a/app/src/main/java/net/lacolaco/smileessence/activity/EditExtractionActivity.kt +++ b/app/src/main/java/net/lacolaco/smileessence/activity/EditExtractionActivity.kt @@ -33,6 +33,8 @@ import android.view.* import android.widget.AbsListView import android.widget.ListView import android.widget.TextView +import kotlinx.android.synthetic.main.layout_edit_list.* +import kotlinx.android.synthetic.main.list_item_simple_text.view.* import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R import net.lacolaco.smileessence.data.ExtractionWord @@ -47,9 +49,6 @@ class EditExtractionActivity : Activity(), AbsListView.MultiChoiceModeListener { private lateinit var list: MutableList<ExtractionWord> private lateinit var adapter: CustomListAdapter<ExtractionWord> - private val listView: ListView - get() = findViewById(R.id.listview_edit_list) as ListView - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { menu.clear() val inflater = mode.menuInflater @@ -83,13 +82,9 @@ class EditExtractionActivity : Activity(), AbsListView.MultiChoiceModeListener { list = ArrayList() adapter = object : CustomListAdapter<ExtractionWord>() { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - var convertView = convertView - if (convertView == null) { - convertView = this@EditExtractionActivity.layoutInflater.inflate(R.layout.list_item_simple_text, null) - } - val textView = convertView!!.findViewById(R.id.list_item_textview) as TextView - textView.text = getItem(position).patternString - return convertView + val view = convertView ?: this@EditExtractionActivity.layoutInflater.inflate(R.layout.list_item_simple_text, parent, false) + view.list_item_textview.text = getItem(position).patternString + return view } override val list: List<ExtractionWord> @@ -97,9 +92,9 @@ class EditExtractionActivity : Activity(), AbsListView.MultiChoiceModeListener { } list.addAll(ExtractionWord.cached()) adapter.update() - listView.adapter = adapter - listView.choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL - listView.setMultiChoiceModeListener(this) + listview_edit_list.adapter = adapter + listview_edit_list.choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL + listview_edit_list.setMultiChoiceModeListener(this) } override fun onCreateOptionsMenu(menu: Menu): Boolean { @@ -125,7 +120,7 @@ class EditExtractionActivity : Activity(), AbsListView.MultiChoiceModeListener { // -------------------------- OTHER METHODS -------------------------- fun deleteSelectedItems() { - val checkedItems = listView.checkedItemPositions + val checkedItems = listview_edit_list.checkedItemPositions for (i in adapter.count - 1 downTo -1 + 1) { if (checkedItems.get(i)) { val ew = adapter.getItem(i) diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/LicenseActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/LicenseActivity.kt index 58bcc08c..3428cc0a 100644 --- a/app/src/main/java/net/lacolaco/smileessence/activity/LicenseActivity.kt +++ b/app/src/main/java/net/lacolaco/smileessence/activity/LicenseActivity.kt @@ -30,6 +30,7 @@ import android.support.v4.app.NavUtils import android.view.MenuItem import android.widget.LinearLayout import android.widget.TextView +import kotlinx.android.synthetic.main.layout_license.* import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R @@ -70,12 +71,11 @@ class LicenseActivity : Activity() { } private fun setFiles() { - val files = findViewById(R.id.linear_license_files) as LinearLayout val apacheFiles = fileNames for (apacheFile in apacheFiles) { val name = TextView(this) name.text = String.format("- %s", apacheFile) - files.addView(name) + linear_license_files.addView(name) } } }
\ No newline at end of file diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt index 8b8da33f..1ff2464b 100644 --- a/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt +++ b/app/src/main/java/net/lacolaco/smileessence/activity/MainActivity.kt @@ -35,6 +35,7 @@ import android.view.Menu import android.view.MenuItem import android.widget.ImageView import de.keyboardsurfer.android.widget.crouton.Crouton +import kotlinx.android.synthetic.main.layout_main.* import net.lacolaco.smileessence.* import net.lacolaco.smileessence.data.ExtractionWord import net.lacolaco.smileessence.entity.RBinding @@ -55,7 +56,6 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener { val userId = java.lang.Long.parseLong(userIdValue) Application.getWorld(userId) } - private lateinit var viewPager: ViewPager private lateinit var pagerAdapter: PageListAdapter private lateinit var currentAccountIconImageView: ImageView @@ -138,7 +138,7 @@ class MainActivity : Activity(), ViewPager.OnPageChangeListener { setTheme(if (account.themeIndex == 0) R.style.theme_dark else R.style.theme_light) setContentView(R.layout.layout_main) - viewPager = findViewById(R.id.viewPager) as ViewPager + pagerAdapter = PageListAdapter(this) viewPager.addOnPageChangeListener(this) actionBar.setDisplayHomeAsUpEnabled(true) diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt index 2ef184fc..cddad891 100644 --- a/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt +++ b/app/src/main/java/net/lacolaco/smileessence/activity/ManageAccountsActivity.kt @@ -36,7 +36,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import android.widget.* -import com.android.volley.toolbox.NetworkImageView import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R import net.lacolaco.smileessence.World @@ -45,11 +44,13 @@ import net.lacolaco.smileessence.data.ImageCache import net.lacolaco.smileessence.logging.Logger import net.lacolaco.smileessence.twitter.OAuthSession import net.lacolaco.smileessence.view.dialog.ConfirmDialogFragment +import kotlinx.android.synthetic.main.layout_edit_list.* +import kotlinx.android.synthetic.main.list_item_account.view.* import java.util.ArrayList class ManageAccountsActivity : Activity(), AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { - private var adapter: EditAccountsAdapter? = null + private lateinit var adapter: EditAccountsAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -71,10 +72,10 @@ class ManageAccountsActivity : Activity(), AdapterView.OnItemClickListener, Adap setContentView(R.layout.layout_edit_list) adapter = EditAccountsAdapter() - val listView = findViewById(R.id.listview_edit_list) as ListView - listView.adapter = adapter - listView.onItemClickListener = this - listView.onItemLongClickListener = this + + listview_edit_list.adapter = adapter + listview_edit_list.onItemClickListener = this + listview_edit_list.onItemLongClickListener = this } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { @@ -111,16 +112,16 @@ class ManageAccountsActivity : Activity(), AdapterView.OnItemClickListener, Adap } override fun onItemClick(adapterView: AdapterView<*>, view: View, i: Int, l: Long) { - val account = adapter!!.getItem(i) + val account = adapter.getItem(i) goToWorld(Application.getWorld(account.userId)) } override fun onItemLongClick(adapterView: AdapterView<*>, view: View, i: Int, l: Long): Boolean { - if (adapter!!.count > 1) { + if (adapter.count > 1) { // remove account from application - val account = adapter!!.getItem(i) + val account = adapter.getItem(i) ConfirmDialogFragment.show(this, getString(R.string.dialog_confirm_clear_account, account.user.screenName), { - adapter!!.removeAt(i) + adapter.removeAt(i) Account.unregister(account.userId) }, false) return true @@ -174,7 +175,7 @@ class ManageAccountsActivity : Activity(), AdapterView.OnItemClickListener, Adap data.getStringExtra(OAuthSession.KEY_TOKEN_SECRET), data.getLongExtra(OAuthSession.KEY_USER_ID, -1L), data.getStringExtra(OAuthSession.KEY_SCREEN_NAME)) - adapter!!.add(account) + adapter.add(account) } else { Logger.error(requestCode) Application.toast(R.string.notice_error_authenticate) @@ -201,19 +202,11 @@ class ManageAccountsActivity : Activity(), AdapterView.OnItemClickListener, Adap } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - var convertView = convertView - if (convertView == null) { - convertView = layoutInflater.inflate(R.layout.list_item_account, null) - } + val view = convertView ?: layoutInflater.inflate(R.layout.list_item_account, parent, false) val account = getItem(position) - val iconView = convertView!!.findViewById(R.id.account_icon) as NetworkImageView - iconView.setImageUrl(account.user.profileImageUrl, ImageCache.getImageLoader()) - - val textView = convertView.findViewById(R.id.account_text_view) as TextView - val text = "@" + account.user.screenName - textView.text = text - - return convertView + view.account_icon.setImageUrl(account.user.profileImageUrl, ImageCache.getImageLoader()) + view.account_text_view.text = "@" + account.user.screenName + return view } fun add(account: Account): Int { diff --git a/app/src/main/java/net/lacolaco/smileessence/activity/OAuthActivity.kt b/app/src/main/java/net/lacolaco/smileessence/activity/OAuthActivity.kt index c2388bbf..52f9adf8 100644 --- a/app/src/main/java/net/lacolaco/smileessence/activity/OAuthActivity.kt +++ b/app/src/main/java/net/lacolaco/smileessence/activity/OAuthActivity.kt @@ -34,31 +34,27 @@ import android.view.View import android.widget.Button import android.widget.EditText import android.widget.TextView +import kotlinx.android.synthetic.main.layout_oauth.* import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R import net.lacolaco.smileessence.twitter.OAuthSession import twitter4j.auth.AccessToken class OAuthActivity : Activity(), View.OnClickListener, TextWatcher { - private lateinit var pinEditText: EditText - private lateinit var authButton: Button private lateinit var oauthSession: OAuthSession public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.layout_oauth) - val linkTextView = findViewById(R.id.textView_oauth_link) as TextView - pinEditText = findViewById(R.id.editText_oauth_pin) as EditText - pinEditText.addTextChangedListener(this) - authButton = findViewById(R.id.button_oauth_auth) as Button - authButton.setOnClickListener(this) - authButton.isEnabled = false + editText_oauth_pin.addTextChangedListener(this) + button_oauth_auth.setOnClickListener(this) + button_oauth_auth.isEnabled = false oauthSession = OAuthSession() val url = oauthSession.authorizationURL if (!TextUtils.isEmpty(url)) { - linkTextView.text = url + textView_oauth_link.text = url } else { Application.toast(R.string.notice_error_authenticate_request) finish() @@ -68,7 +64,7 @@ class OAuthActivity : Activity(), View.OnClickListener, TextWatcher { override fun onClick(v: View) { when (v.id) { R.id.button_oauth_auth -> { - val accessToken = oauthSession.getAccessToken(pinEditText.text.toString()) + val accessToken = oauthSession.getAccessToken(editText_oauth_pin.text.toString()) if (accessToken != null) { val intent = Intent() intent.putExtra(OAuthSession.KEY_TOKEN, accessToken.token) @@ -88,7 +84,7 @@ class OAuthActivity : Activity(), View.OnClickListener, TextWatcher { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - authButton.isEnabled = s.length > 0 + button_oauth_auth.isEnabled = s.length > 0 } override fun afterTextChanged(s: Editable) {} diff --git a/app/src/main/java/net/lacolaco/smileessence/command/CommandOpenUserDetail.kt b/app/src/main/java/net/lacolaco/smileessence/command/CommandOpenUserDetail.kt index 89d5d2ef..a835ffa1 100644 --- a/app/src/main/java/net/lacolaco/smileessence/command/CommandOpenUserDetail.kt +++ b/app/src/main/java/net/lacolaco/smileessence/command/CommandOpenUserDetail.kt @@ -30,21 +30,10 @@ import net.lacolaco.smileessence.twitter.task.Users import net.lacolaco.smileessence.view.DialogHelper import net.lacolaco.smileessence.view.dialog.UserDetailDialogFragment -class CommandOpenUserDetail -// --------------------------- CONSTRUCTORS --------------------------- - -(activity: MainActivity, - // ------------------------------ FIELDS ------------------------------ - - private val screenName: String) : Command(activity) { - - // --------------------- GETTER / SETTER METHODS --------------------- - +class CommandOpenUserDetail(activity: MainActivity, private val screenName: String) : Command(activity) { override val text: String get() = String.format("@%s", screenName) - // -------------------------- OTHER METHODS -------------------------- - override fun execute(): Boolean { Users.GetTask(activity.world.account, screenName) .onDoneUI { user -> diff --git a/app/src/main/java/net/lacolaco/smileessence/data/ImageCache.kt b/app/src/main/java/net/lacolaco/smileessence/data/ImageCache.kt index d7b4eeac..6dc3f6f1 100644 --- a/app/src/main/java/net/lacolaco/smileessence/data/ImageCache.kt +++ b/app/src/main/java/net/lacolaco/smileessence/data/ImageCache.kt @@ -36,7 +36,7 @@ class ImageCache private constructor() { init { val cacheSizeInBytes = 64 * 1024 * 1024 // 64MB - val diskCache = DiskBasedCache(Application.getInstance().cacheDir, cacheSizeInBytes) + val diskCache = DiskBasedCache(Application.instance.cacheDir, cacheSizeInBytes) val requestQueue = RequestQueue(diskCache, BasicNetwork(HurlStack())) imageLoader = ImageLoader(requestQueue, ImageLruCache()) requestQueue.start() diff --git a/app/src/main/java/net/lacolaco/smileessence/entity/DirectMessage.kt b/app/src/main/java/net/lacolaco/smileessence/entity/DirectMessage.kt index e89868f8..290773aa 100644 --- a/app/src/main/java/net/lacolaco/smileessence/entity/DirectMessage.kt +++ b/app/src/main/java/net/lacolaco/smileessence/entity/DirectMessage.kt @@ -3,17 +3,13 @@ package net.lacolaco.smileessence.entity import java.util.Date import java.util.HashMap -class DirectMessage private constructor(message: twitter4j.DirectMessage) : EntitySupport(), IdObject { +class DirectMessage private constructor(message: twitter4j.DirectMessage) : EntitySupport(message), IdObject { override val id: Long = message.id val sender: User = User.fromTwitter(message.sender) val recipient: User = User.fromTwitter(message.recipient) val text: String = extractText(message, false) val createdAt: Date = message.createdAt - init { - updateEntities(message) - } - companion object { private val storage = HashMap<Long, DirectMessage>() diff --git a/app/src/main/java/net/lacolaco/smileessence/entity/EntitySupport.kt b/app/src/main/java/net/lacolaco/smileessence/entity/EntitySupport.kt index c1b3e4a3..3b42587a 100644 --- a/app/src/main/java/net/lacolaco/smileessence/entity/EntitySupport.kt +++ b/app/src/main/java/net/lacolaco/smileessence/entity/EntitySupport.kt @@ -5,25 +5,12 @@ import twitter4j.* import java.util.* -abstract class EntitySupport : UIObservable() { - open lateinit var mentions: List<String> - protected set - open lateinit var hashtags: List<String> - protected set - open lateinit var mediaUrls: List<String> - protected set - open lateinit var urlsExpanded: List<String> - protected set - open lateinit var symbols: List<String> - protected set - - protected fun updateEntities(status: twitter4j.EntitySupport) { - mentions = extractMentions(status.userMentionEntities) - hashtags = extractHashtags(status.hashtagEntities) - mediaUrls = extractMediaUrls(status.mediaEntities) - urlsExpanded = extractExpandedUrls(status.urlEntities) - symbols = extractSymbols(status.symbolEntities) - } +abstract class EntitySupport(status: twitter4j.EntitySupport) : UIObservable() { + open val mentions: List<String> = extractMentions(status.userMentionEntities) + open val hashtags: List<String> = extractHashtags(status.hashtagEntities) + open val mediaUrls: List<String> = extractMediaUrls(status.mediaEntities) + open val urlsExpanded: List<String> = extractExpandedUrls(status.urlEntities) + open val symbols: List<String> = extractSymbols(status.symbolEntities) private fun extractMentions(entities: Array<UserMentionEntity>?): List<String> { val names = ArrayList<String>() diff --git a/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt b/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt index 437e69c7..6dbd6398 100644 --- a/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt +++ b/app/src/main/java/net/lacolaco/smileessence/entity/Tweet.kt @@ -9,26 +9,21 @@ import twitter4j.Status import java.util.* import java.util.concurrent.ConcurrentHashMap -class Tweet private constructor(st: twitter4j.Status, myUserId: Long) : EntitySupport(), IdObject { +class Tweet private constructor(st: twitter4j.Status, myUserId: Long) : EntitySupport(st), 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 + val isRetweet = retweetedTweet != null + val originalTweet = retweetedTweet ?: this + val text: String = if (isRetweet) originalTweet.text else extractText(st, false) + val inReplyToStatusId: Long = if (isRetweet) originalTweet.inReplyToStatusId else st.inReplyToStatusId var favoriteCount: Int = st.favoriteCount - get() = if (isRetweet) originalTweet.originalTweet.favoriteCount else field + get() = if (isRetweet) originalTweet.favoriteCount else field private set var retweetCount: Int = st.retweetCount - get() = if (isRetweet) originalTweet.originalTweet.retweetCount else field + get() = if (isRetweet) originalTweet.retweetCount else field private set private val favoriters: MutableSet<Long> = Collections.newSetFromMap(ConcurrentHashMap()) private val retweets: MutableMap<Long, Long> = ConcurrentHashMap() @@ -38,7 +33,6 @@ class Tweet private constructor(st: twitter4j.Status, myUserId: Long) : EntitySu } init { - updateEntities(st) update(st, myUserId) } @@ -96,63 +90,26 @@ class Tweet private constructor(st: twitter4j.Status, myUserId: Long) : EntitySu } // 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])) - } + val embeddedStatusIDs: List<Long> by lazy { + 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 } + 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 - } + override val mentions: List<String> = originalTweet@super.mentions + override val hashtags: List<String> = originalTweet@super.hashtags + override val mediaUrls: List<String> = originalTweet@super.mediaUrls + override val urlsExpanded: List<String> = originalTweet@super.urlsExpanded + override val symbols: List<String> = originalTweet@super.symbols companion object { private val storage = HashMap<Long, Tweet>() diff --git a/app/src/main/java/net/lacolaco/smileessence/entity/User.kt b/app/src/main/java/net/lacolaco/smileessence/entity/User.kt index 6a92b54e..71afe69b 100644 --- a/app/src/main/java/net/lacolaco/smileessence/entity/User.kt +++ b/app/src/main/java/net/lacolaco/smileessence/entity/User.kt @@ -25,11 +25,11 @@ class User private constructor(override val id: Long, screenName: String) : UIOb private set var profileBannerUrl: String? = null private set - var description: String? = null + var description: String = "<not set>" private set - var location: String? = null + var location: String = "<not set>" private set - var url: String? = null + var url: String = "<not set>" private set var favoritesCount: Int = 0 private set diff --git a/app/src/main/java/net/lacolaco/smileessence/logging/Logger.kt b/app/src/main/java/net/lacolaco/smileessence/logging/Logger.kt index 7e898c1b..db21abe1 100644 --- a/app/src/main/java/net/lacolaco/smileessence/logging/Logger.kt +++ b/app/src/main/java/net/lacolaco/smileessence/logging/Logger.kt @@ -27,13 +27,8 @@ package net.lacolaco.smileessence.logging import android.util.Log object Logger { - - // ------------------------------ FIELDS ------------------------------ - private val TAG = "SmileEssence" - // -------------------------- STATIC METHODS -------------------------- - fun debug(message: Any) { Log.d(tag, message.toString()) } diff --git a/app/src/main/java/net/lacolaco/smileessence/preference/InternalPreferenceHelper.kt b/app/src/main/java/net/lacolaco/smileessence/preference/InternalPreferenceHelper.kt deleted file mode 100644 index 1353eb2a..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/preference/InternalPreferenceHelper.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.preference - -import android.content.Context -import android.content.SharedPreferences -import net.lacolaco.smileessence.Application - -class InternalPreferenceHelper private constructor() : SharedPreferenceHelper() { - - // --------------------------- OVERRIDE --------------------------- - override val preferences: SharedPreferences - get() = Application.getInstance().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE) - - companion object { - - // ------------------------------ FIELDS ------------------------------ - - private val FILE_NAME = "AppPreference" - val instance = InternalPreferenceHelper() - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/preference/SharedPreferenceHelper.kt b/app/src/main/java/net/lacolaco/smileessence/preference/SharedPreferenceHelper.kt deleted file mode 100644 index 6702f1c3..00000000 --- a/app/src/main/java/net/lacolaco/smileessence/preference/SharedPreferenceHelper.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.preference - -import android.content.SharedPreferences -import net.lacolaco.smileessence.Application - -abstract class SharedPreferenceHelper { - // --------------------- GETTER / SETTER METHODS --------------------- - - protected abstract val preferences: SharedPreferences - - // -------------------------- OTHER METHODS -------------------------- - - operator fun get(key: Int, defaultValue: String): String { - return preferences.getString(getString(key), defaultValue) - } - - // int, long, float value may be stored in String format (old versions) - operator fun get(key: Int, defaultValue: Int): Int { - try { - return preferences.getInt(getString(key), defaultValue) - } catch (ex: ClassCastException) { - val ret = Integer.parseInt(get(key, defaultValue.toString())) - set(key, ret) - return ret - } - - } - - operator fun get(key: Int, defaultValue: Long): Long { - try { - return preferences.getLong(getString(key), defaultValue) - } catch (ex: ClassCastException) { - val ret = java.lang.Long.parseLong(get(key, defaultValue.toString())) - set(key, ret) - return ret - } - - } - - operator fun get(key: Int, defaultValue: Float): Float { - try { - return preferences.getFloat(getString(key), defaultValue) - } catch (ex: ClassCastException) { - val ret = java.lang.Float.parseFloat(get(key, defaultValue.toString())) - set(key, ret) - return ret - } - - } - - operator fun get(key: Int, defaultValue: Boolean): Boolean { - return preferences.getBoolean(getString(key), defaultValue) - } - - operator fun get(key: Int, defaultValue: Set<String>): Set<String> { - return preferences.getStringSet(getString(key), defaultValue) - } - - operator fun set(key: Int, value: String): Boolean { - return preferences.edit() - .putString(getString(key), value) - .commit() - } - - operator fun set(key: Int, value: Int): Boolean { - return preferences.edit() - .putInt(getString(key), value) - .commit() - } - - operator fun set(key: Int, value: Long): Boolean { - return preferences.edit() - .putLong(getString(key), value) - .commit() - } - - operator fun set(key: Int, value: Float): Boolean { - return preferences.edit() - .putFloat(getString(key), value) - .commit() - } - - operator fun set(key: Int, value: Boolean): Boolean { - return preferences.edit() - .putBoolean(getString(key), value) - .commit() - } - - operator fun set(key: Int, value: Set<String>): Boolean { - return preferences.edit() - .putStringSet(getString(key), value) - .commit() - } - - private fun getString(resID: Int): String? { - try { - return Application.getInstance().getString(resID) - } catch (e: Exception) { - return null - } - - } -} diff --git a/app/src/main/java/net/lacolaco/smileessence/preference/UserPreferenceHelper.kt b/app/src/main/java/net/lacolaco/smileessence/preference/UserPreferenceHelper.kt index 41f7f019..8a8d10eb 100644 --- a/app/src/main/java/net/lacolaco/smileessence/preference/UserPreferenceHelper.kt +++ b/app/src/main/java/net/lacolaco/smileessence/preference/UserPreferenceHelper.kt @@ -29,11 +29,9 @@ import android.preference.PreferenceManager import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R -class UserPreferenceHelper private constructor() : SharedPreferenceHelper() { - - // --------------------- GETTER / SETTER METHODS --------------------- - override val preferences: SharedPreferences - get() = PreferenceManager.getDefaultSharedPreferences(Application.getInstance()) +class UserPreferenceHelper private constructor() { + private val preferences: SharedPreferences + get() = PreferenceManager.getDefaultSharedPreferences(Application.instance) // --------------------- HELPER METHODS --------------------- val themeIndex: Int @@ -42,9 +40,50 @@ class UserPreferenceHelper private constructor() : SharedPreferenceHelper() { val textSize: Int get() = get(R.string.key_setting_text_size, 10) - companion object { - // --------------------------- CONSTRUCTORS --------------------------- + operator fun get(key: Int, defaultValue: String): String { + return preferences.getString(getString(key), defaultValue) + } + + operator fun get(key: Int, defaultValue: Int): Int { + try { + return preferences.getInt(getString(key), defaultValue) + } catch (ex: ClassCastException) { + val ret = Integer.parseInt(get(key, defaultValue.toString())) + set(key, ret) + return ret + } + + } + + operator fun get(key: Int, defaultValue: Boolean): Boolean { + return preferences.getBoolean(getString(key), defaultValue) + } + + operator fun set(key: Int, value: String): Boolean { + return preferences.edit() + .putString(getString(key), value) + .commit() + } + + operator fun set(key: Int, value: Int): Boolean { + return preferences.edit() + .putInt(getString(key), value) + .commit() + } + + operator fun set(key: Int, value: Boolean): Boolean { + return preferences.edit() + .putBoolean(getString(key), value) + .commit() + } + + private fun getString(resID: Int): String? { + return Application.instance.getString(resID) + + } + + companion object { val instance = UserPreferenceHelper() } } diff --git a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Accounts.kt b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Accounts.kt index 22a90374..fc76784f 100644 --- a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Accounts.kt +++ b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Accounts.kt @@ -12,24 +12,18 @@ import java.util.ArrayList class Accounts { class AccessTokenTask(private val twitter: Twitter, private val requestToken: RequestToken, private val pinCode: String) : BackgroundTask<AccessToken, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): AccessToken { return twitter.getOAuthAccessToken(requestToken, pinCode) } } class RequestTokenTask(private val twitter: Twitter) : BackgroundTask<RequestToken, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): RequestToken { return twitter.getOAuthRequestToken("oob") } } class BlockIDsTask(private val account: Account) : BackgroundTask<List<Long>, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): List<Long> { val idList = ArrayList<Long>() var cursor: Long = -1 @@ -47,8 +41,6 @@ class Accounts { } class MutesIDsTask(private val account: Account) : BackgroundTask<List<Long>, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): List<Long> { val idList = ArrayList<Long>() var cursor: Long = -1 diff --git a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Messages.kt b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Messages.kt index b5553c32..e6fdd180 100644 --- a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Messages.kt +++ b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Messages.kt @@ -3,36 +3,27 @@ package net.lacolaco.smileessence.twitter.task import net.lacolaco.smileessence.data.Account import net.lacolaco.smileessence.entity.DirectMessage import net.lacolaco.smileessence.util.BackgroundTask -import twitter4j.TwitterException class Messages { class CreateTask(private val account: Account, private val userID: Long, private val text: String) : BackgroundTask<DirectMessage, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): DirectMessage { return DirectMessage.fromTwitter(account.twitter.directMessages().sendDirectMessage(userID, text)) } } class DestroyTask(private val account: Account, private val messageID: Long) : BackgroundTask<DirectMessage, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): DirectMessage { return DirectMessage.fromTwitter(account.twitter.directMessages().destroyDirectMessage(messageID)) } } class GetAllReceived(private val account: Account) : TimelineTask<DirectMessage>() { - - @Throws(TwitterException::class) override fun doInBackground(): List<DirectMessage> { return DirectMessage.fromTwitter(account.twitter.directMessages().getDirectMessages(paging)) } } class GetAllSent(private val account: Account) : TimelineTask<DirectMessage>() { - - @Throws(TwitterException::class) override fun doInBackground(): List<DirectMessage> { return DirectMessage.fromTwitter(account.twitter.directMessages().getSentDirectMessages(paging)) } diff --git a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Timelines.kt b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Timelines.kt index 6893319c..7e145968 100644 --- a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Timelines.kt +++ b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Timelines.kt @@ -5,65 +5,25 @@ import net.lacolaco.smileessence.entity.Tweet import twitter4j.TwitterException class Timelines { - class HomeTimelineTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account) : TimelineTask<Tweet>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class HomeTimelineTask(private val account: Account) : TimelineTask<Tweet>() { override fun doInBackground(): List<Tweet> { return Tweet.fromTwitter(account.twitter.timelines().getHomeTimeline(paging), account.userId) } } - class MentionsTimelineTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account) : TimelineTask<Tweet>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class MentionsTimelineTask(private val account: Account) : TimelineTask<Tweet>() { override fun doInBackground(): List<Tweet> { return Tweet.fromTwitter(account.twitter.timelines().getMentionsTimeline(paging), account.userId) } } - class UserTimelineTask - // --------------------------- CONSTRUCTORS --------------------------- - - (private val account: Account, - // ------------------------------ FIELDS ------------------------------ - - private val userID: Long) : TimelineTask<Tweet>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class UserTimelineTask(private val account: Account, private val userID: Long) : TimelineTask<Tweet>() { override fun doInBackground(): List<Tweet> { return Tweet.fromTwitter(account.twitter.timelines().getUserTimeline(userID, paging), account.userId) } } - class UserListStatusesTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account, private val listFullName: String) : TimelineTask<Tweet>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class UserListStatusesTask(private val account: Account, private val listFullName: String) : TimelineTask<Tweet>() { override fun doInBackground(): List<Tweet> { val strings = listFullName.split("/".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray() return Tweet.fromTwitter(account.twitter.list().getUserListStatuses(strings[0], strings[1], paging), account.userId) diff --git a/app/src/main/java/net/lacolaco/smileessence/twitter/task/TweetReactions.kt b/app/src/main/java/net/lacolaco/smileessence/twitter/task/TweetReactions.kt index bffcd832..3fd14c75 100644 --- a/app/src/main/java/net/lacolaco/smileessence/twitter/task/TweetReactions.kt +++ b/app/src/main/java/net/lacolaco/smileessence/twitter/task/TweetReactions.kt @@ -3,52 +3,21 @@ package net.lacolaco.smileessence.twitter.task import net.lacolaco.smileessence.data.Account import net.lacolaco.smileessence.entity.Tweet import net.lacolaco.smileessence.util.BackgroundTask -import twitter4j.TwitterException class TweetReactions { - class RetweetTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class RetweetTask(private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { override fun doInBackground(): Tweet { return Tweet.fromTwitter(account.twitter.tweets().retweetStatus(statusID), account.userId) } } - class FavoriteTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class FavoriteTask(private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { override fun doInBackground(): Tweet { return Tweet.fromTwitter(account.twitter.favorites().createFavorite(statusID), account.userId) } } - class UnfavoriteTask - // --------------------------- CONSTRUCTORS --------------------------- - - ( - // ------------------------------ FIELDS ------------------------------ - - private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - - @Throws(TwitterException::class) + class UnfavoriteTask(private val account: Account, private val statusID: Long) : BackgroundTask<Tweet, Void>() { override fun doInBackground(): Tweet { return Tweet.fromTwitter(account.twitter.favorites().destroyFavorite(statusID), account.userId) } diff --git a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Users.kt b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Users.kt index c435b560..3554a9c4 100644 --- a/app/src/main/java/net/lacolaco/smileessence/twitter/task/Users.kt +++ b/app/src/main/java/net/lacolaco/smileessence/twitter/task/Users.kt @@ -24,7 +24,6 @@ class Users { this.userID = -1 } - @Throws(TwitterException::class) override fun doInBackground(): User { return if (screenName != null) { User.fromTwitter(account.twitter.users().showUser(screenName)) @@ -35,56 +34,42 @@ class Users { } class GetManyTask(private val account: Account) : BackgroundTask<List<String>, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): List<String> { return account.twitter.list().getUserLists(account.userId).map { it.fullName } } } class FollowTask(private val account: Account, private val userID: Long) : BackgroundTask<User, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): User { return User.fromTwitter(account.twitter.friendsFollowers().createFriendship(userID)) } } class UnfollowTask(private val account: Account, private val userID: Long) : BackgroundTask<User, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): User { return User.fromTwitter(account.twitter.friendsFollowers().destroyFriendship(userID)) } } class BlockTask(private val account: Account, private val userID: Long) : BackgroundTask<User, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): User { return User.fromTwitter(account.twitter.users().createBlock(userID)) } } class ReportForSpamTask(private val account: Account, private val userID: Long) : BackgroundTask<User, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): User { return User.fromTwitter(account.twitter.spamReporting().reportSpam(userID)) } } class UnblockTask(private val account: Account, private val userID: Long) : BackgroundTask<User, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): User { return User.fromTwitter(account.twitter.users().destroyBlock(userID)) } } class ShowFriendshipTask(private val account: Account, private val userID: Long) : BackgroundTask<Relationship, Void>() { - - @Throws(TwitterException::class) override fun doInBackground(): Relationship { return account.twitter.friendsFollowers().showFriendship(account.twitter.id, userID) } diff --git a/app/src/main/java/net/lacolaco/smileessence/util/BackgroundTask.kt b/app/src/main/java/net/lacolaco/smileessence/util/BackgroundTask.kt index 7b9e188a..d5d16cc4 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/BackgroundTask.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/BackgroundTask.kt @@ -91,9 +91,9 @@ abstract class BackgroundTask<Result, Progress> { protected abstract fun doInBackground(): Result private inner class InnerAsyncTask : AsyncTask<Void, Progress, Result>() { - override fun onPostExecute(result: Result) { + override fun onPostExecute(result: Result?) { if (!isCancelled && exception == null && cbThen != null) { - cbThen!!(result) + cbThen!!(result!!) } if (cbFinish != null) { cbFinish!!() diff --git a/app/src/main/java/net/lacolaco/smileessence/util/BitmapThumbnailTask.kt b/app/src/main/java/net/lacolaco/smileessence/util/BitmapThumbnailTask.kt index 6e353716..8ea16838 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/BitmapThumbnailTask.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/BitmapThumbnailTask.kt @@ -30,16 +30,7 @@ import android.media.ThumbnailUtils import android.os.AsyncTask import android.widget.ImageView -class BitmapThumbnailTask -// --------------------------- CONSTRUCTORS --------------------------- - -( - // ------------------------------ FIELDS ------------------------------ - - private val filePath: String, private val imageView: ImageView?) : AsyncTask<Void, Void, Bitmap?>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - +class BitmapThumbnailTask(private val filePath: String, private val imageView: ImageView?) : AsyncTask<Void, Void, Bitmap?>() { override fun onPostExecute(bitmap: Bitmap?) { if (bitmap != null && imageView != null) { imageView.setImageBitmap(bitmap) diff --git a/app/src/main/java/net/lacolaco/smileessence/util/BitmapURLTask.kt b/app/src/main/java/net/lacolaco/smileessence/util/BitmapURLTask.kt index f71e4afb..49ffc5fb 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/BitmapURLTask.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/BitmapURLTask.kt @@ -33,18 +33,9 @@ import java.io.IOException import java.io.InputStream import java.net.URL -class BitmapURLTask -// --------------------------- CONSTRUCTORS --------------------------- - -( - // ------------------------------ FIELDS ------------------------------ - - private val url: String, private val imageView: ImageView?) : AsyncTask<Void, Void, Bitmap>() { - - // ------------------------ OVERRIDE METHODS ------------------------ - +class BitmapURLTask(private val url: String, private val imageView: ImageView) : AsyncTask<Void, Void, Bitmap>() { override fun onPostExecute(bitmap: Bitmap) { - imageView?.setImageBitmap(bitmap) + imageView.setImageBitmap(bitmap) } override fun doInBackground(vararg params: Void): Bitmap? { diff --git a/app/src/main/java/net/lacolaco/smileessence/util/StringUtils.kt b/app/src/main/java/net/lacolaco/smileessence/util/StringUtils.kt index cdfe59f5..cd2fff42 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/StringUtils.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/StringUtils.kt @@ -31,10 +31,6 @@ import java.util.Calendar import java.util.Date object StringUtils { - - // -------------------------- STATIC METHODS -------------------------- - - @SuppressLint("SimpleDateFormat") fun dateToString(date: Date): String { val current = Calendar.getInstance() val cal = Calendar.getInstance() diff --git a/app/src/main/java/net/lacolaco/smileessence/util/SystemServiceHelper.kt b/app/src/main/java/net/lacolaco/smileessence/util/SystemServiceHelper.kt index efed67ca..adb0a642 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/SystemServiceHelper.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/SystemServiceHelper.kt @@ -32,18 +32,14 @@ import android.view.View import android.view.inputmethod.InputMethodManager object SystemServiceHelper { - fun hideIM(context: Context, view: View?) { - if (view != null) { - val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN) - } + fun hideIM(context: Context, view: View) { + val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(view.windowToken, InputMethodManager.RESULT_UNCHANGED_SHOWN) } - fun showIM(context: Context, view: View?) { - if (view != null) { - val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager - imm.showSoftInput(view, InputMethodManager.RESULT_UNCHANGED_SHOWN) - } + fun showIM(context: Context, view: View) { + val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.showSoftInput(view, InputMethodManager.RESULT_UNCHANGED_SHOWN) } fun copyToClipboard(context: Context, label: String, text: String) { diff --git a/app/src/main/java/net/lacolaco/smileessence/util/UIObserverBundle.kt b/app/src/main/java/net/lacolaco/smileessence/util/UIObserverBundle.kt index f6c8403b..e4386852 100644 --- a/app/src/main/java/net/lacolaco/smileessence/util/UIObserverBundle.kt +++ b/app/src/main/java/net/lacolaco/smileessence/util/UIObserverBundle.kt @@ -7,11 +7,12 @@ import java.util.* class UIObserverBundle { private val map = HashMap<UIObservable, (EnumSet<RBinding>) -> Unit>() - fun detachAll() { + fun detachAll(): UIObserverBundle { for ((key) in map) { key.removeObserver(this) } map.clear() + return this } fun attach(observable: UIObservable, observer: (EnumSet<RBinding>) -> Unit): (EnumSet<RBinding>) -> Unit { diff --git a/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt b/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt index 27d8c3cd..ba0bb54d 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/Partials.kt @@ -4,18 +4,15 @@ import android.app.Activity import android.text.Html import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.ListView -import android.widget.TextView -import com.android.volley.toolbox.NetworkImageView -import net.lacolaco.smileessence.Application +import kotlinx.android.synthetic.main.list_item_status.view.* import net.lacolaco.smileessence.R +import net.lacolaco.smileessence.World import net.lacolaco.smileessence.activity.MainActivity -import net.lacolaco.smileessence.data.Account import net.lacolaco.smileessence.data.ImageCache import net.lacolaco.smileessence.entity.DirectMessage import net.lacolaco.smileessence.entity.RBinding import net.lacolaco.smileessence.entity.Tweet +import net.lacolaco.smileessence.entity.User import net.lacolaco.smileessence.preference.UserPreferenceHelper import net.lacolaco.smileessence.util.StringUtils import net.lacolaco.smileessence.util.UIObserverBundle @@ -29,109 +26,99 @@ import java.lang.ref.WeakReference import java.util.ArrayList object Partials { - fun getTweetView(tweet: Tweet, activity: Activity, convertView: View?, expandEmbeddedTweets: Boolean): View { - var convertView: View = convertView ?: activity.layoutInflater.inflate(R.layout.list_item_status, null) - var bundle: UIObserverBundle? = convertView.tag as UIObserverBundle? + fun getTweetView(tweet: Tweet, world: World, activity: Activity, convertView: View?, expandEmbeddedTweets: Boolean = true): View { + val view: View = convertView ?: activity.layoutInflater.inflate(R.layout.list_item_status, null) + var bundle: UIObserverBundle? = view.tag as UIObserverBundle? if (bundle != null) { bundle.detachAll() } else { bundle = UIObserverBundle() - convertView.tag = bundle + view.tag = bundle } - convertView.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, StatusDetailDialogFragment.newInstance(tweet)) }) + view.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, StatusDetailDialogFragment.newInstance(tweet)) }) - updateViewUser(tweet, activity, convertView) - updateViewBody(tweet, activity, convertView) - updateViewFavorited(tweet, convertView) - updateViewEmbeddeds(tweet, activity, convertView, expandEmbeddedTweets) + (view as ColoredRelativeLayout).setAccentVisibility(tweet.user === world.account.user) - val weakView = WeakReference(convertView) + updateViewUser(tweet.originalTweet.user, activity, view) + updateViewBody(tweet, world, activity, view) + updateViewFavorited(tweet, world, view) + updateViewEmbeddeds(tweet, world, activity, view, expandEmbeddedTweets) + + val weakView = WeakReference(view) val weakActivity = WeakReference(activity) bundle.attach(tweet.originalTweet) { changes -> val strongView = weakView.get() if (strongView != null && changes.contains(RBinding.FAVORITERS)) - updateViewFavorited(tweet, strongView) + updateViewFavorited(tweet, world, strongView) } - bundle.attach(tweet.user) { changes -> + bundle.attach(tweet.originalTweet.user) { changes -> val strongView = weakView.get() val strongActivity = weakActivity.get() if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC)) - updateViewUser(tweet, strongActivity, strongView) + updateViewUser(tweet.originalTweet.user, strongActivity, strongView) } - return convertView + return view } - private fun updateViewEmbeddeds(tweet: Tweet, activity: Activity, convertView: View, expandEmbeddedTweets: Boolean) { - val embeddedStatus = convertView.findViewById(R.id.listview_status_embedded_status) as ListView + private fun updateViewEmbeddeds(tweet: Tweet, world: World, activity: Activity, view: View, expandEmbeddedTweets: Boolean) { if (expandEmbeddedTweets) { val list = ArrayList<Tweet>() val embeddedTweetsAdapter = object : CustomListAdapter<Tweet>() { override val list: List<Tweet> get() = list - override fun getView(position: Int, convertView: View, parent: ViewGroup): View { - return Partials.getTweetView(getItem(position), activity, convertView, false) + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + return Partials.getTweetView(getItem(position), world, activity, convertView, false) } } - val account = Application.currentWorld!!.account for (id in tweet.embeddedStatusIDs) { - Tweet.fetchTask(id, account).onDone { t -> list.add(t) }.execute() + Tweet.fetchTask(id, world.account).onDone { t -> list.add(t); embeddedTweetsAdapter.update() }.execute() } - embeddedStatus.adapter = embeddedTweetsAdapter - embeddedStatus.visibility = View.VISIBLE + view.listview_status_embedded_status.adapter = embeddedTweetsAdapter + view.listview_status_embedded_status.visibility = View.VISIBLE } else { - embeddedStatus.adapter = null // view may be reused, set null explicitly - embeddedStatus.visibility = View.GONE + view.listview_status_embedded_status.adapter = null // view may be reused, set null explicitly + view.listview_status_embedded_status.visibility = View.GONE } } - private fun updateViewUser(tweet: Tweet, activity: Activity, convertView: View) { + private fun updateViewUser(user: User, activity: Activity, view: View) { val textSize = UserPreferenceHelper.instance.textSize - val icon = convertView.findViewById(R.id.imageview_status_icon) as NetworkImageView - val iconUrl = tweet.originalTweet.user.profileImageUrl - icon.setImageUrl(iconUrl, ImageCache.getImageLoader()) - icon.setOnClickListener { v -> onIconClick(tweet, activity) } - - val header = convertView.findViewById(R.id.textview_status_header) as TextView - header.textSize = textSize.toFloat() - header.text = tweet.originalTweet.user.formattedName + val iconUrl = user.profileImageUrl + view.imageview_status_icon.setImageUrl(iconUrl, ImageCache.getImageLoader()) + view.imageview_status_icon.setOnClickListener { v -> + DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(user)) + } - (convertView as ColoredRelativeLayout).setAccentVisibility(tweet.user === Application.currentWorld!!.account.user) + view.textview_status_header.textSize = textSize.toFloat() + view.textview_status_header.text = user.formattedName } - private fun updateViewBody(tweet: Tweet, activity: Activity, convertView: View) { + private fun updateViewBody(tweet: Tweet, world: World, activity: Activity, view: View) { val textSize = UserPreferenceHelper.instance.textSize - val content = convertView.findViewById(R.id.textview_status_text) as TextView - content.textSize = textSize.toFloat() - val rawText = tweet.originalTweet.text - content.text = rawText - val footer = convertView.findViewById(R.id.textview_status_footer) as TextView - footer.textSize = (textSize - 2).toFloat() - footer.text = getFooterText(tweet) + view.textview_status_text.textSize = textSize.toFloat() + view.textview_status_text.text = tweet.text + view.textview_status_footer.textSize = (textSize - 2).toFloat() + view.textview_status_footer.text = getFooterText(tweet) - val typedView = convertView as ColoredRelativeLayout + val typedView = view as ColoredRelativeLayout if (tweet.isRetweet) { typedView.setHighlight(2) - } else if (tweet.originalTweet.mentions.contains(Application.currentWorld!!.account.user.screenName)) { + } else if (tweet.mentions.contains(world.account.user.screenName)) { typedView.setHighlight(1) } else { typedView.setHighlight(0) } } - private fun updateViewFavorited(tweet: Tweet, convertView: View) { - val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView - favorited.visibility = if (tweet.isFavoritedBy(Application.currentWorld!!.account.userId)) View.VISIBLE else View.GONE - } - - private fun onIconClick(tweet: Tweet, activity: Activity) { - DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(tweet.originalTweet.user)) + private fun updateViewFavorited(tweet: Tweet, world: World, view: View) { + view.imageview_status_favorited.visibility = if (tweet.isFavoritedBy(world.account.userId)) View.VISIBLE else View.GONE } private fun getFooterText(tweet: Tweet): String { @@ -148,73 +135,53 @@ object Partials { return builder.toString() } - fun getDirectMessageView(directMessage: DirectMessage, activity: Activity, convertView: View?): View { - var convertView = convertView - if (convertView == null) { - convertView = activity.layoutInflater.inflate(R.layout.list_item_status, null) - } - var bundle: UIObserverBundle? = convertView!!.tag as UIObserverBundle? + fun getDirectMessageView(directMessage: DirectMessage, world: World, activity: Activity, convertView: View?): View { + val view = convertView ?: activity.layoutInflater.inflate(R.layout.list_item_status, null) + var bundle: UIObserverBundle? = view.tag as UIObserverBundle? if (bundle != null) { bundle.detachAll() } else { bundle = UIObserverBundle() - convertView.tag = bundle + view.tag = bundle } - convertView.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, MessageDetailDialogFragment.newInstance(directMessage)) }) + view.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, MessageDetailDialogFragment.newInstance(directMessage)) }) + + view.imageview_status_favorited.visibility = View.GONE - val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView - favorited.visibility = View.GONE + (view as ColoredRelativeLayout).setAccentVisibility(directMessage.sender === world.account.user) - updateViewSender(directMessage, activity, convertView) - updateViewBody(directMessage, activity, convertView) + updateViewUser(directMessage.sender, activity, view) + updateViewBody(directMessage, world, view) - val weakView = WeakReference(convertView) + val weakView = WeakReference(view) val weakActivity = WeakReference(activity as MainActivity) bundle.attach(directMessage.sender) { changes -> val strongView = weakView.get() val strongActivity = weakActivity.get() if (strongView != null && strongActivity != null && changes.contains(RBinding.BASIC)) - updateViewSender(directMessage, strongActivity, strongView) + updateViewUser(directMessage.sender, strongActivity, strongView) } - return convertView + return view } - private fun getFooterText(directMessage: DirectMessage, account: Account): String { + private fun getFooterText(directMessage: DirectMessage, world: World): String { val builder = StringBuilder() builder.append(StringUtils.dateToString(directMessage.createdAt)) - if (directMessage.sender.id == account.userId) { + if (directMessage.sender == world.account.user) { builder.append(" to @").append(directMessage.recipient.screenName) } return builder.toString() } - private fun updateViewSender(directMessage: DirectMessage, activity: Activity, convertView: View) { - val textSize = UserPreferenceHelper.instance.textSize - - val icon = convertView.findViewById(R.id.imageview_status_icon) as NetworkImageView - val iconUrl = directMessage.sender.profileImageUrl - icon.setImageUrl(iconUrl, ImageCache.getImageLoader()) - icon.setOnClickListener { v -> - DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(directMessage.sender)) - } - - val header = convertView.findViewById(R.id.textview_status_header) as TextView - header.textSize = textSize.toFloat() - header.text = directMessage.sender.formattedName - - (convertView as ColoredRelativeLayout).setAccentVisibility(directMessage.sender === Application.currentWorld!!.account.user) - } - private fun updateViewBody(directMessage: DirectMessage, activity: Activity, convertView: View) { + private fun updateViewBody(directMessage: DirectMessage, world: World, view: View) { val textSize = UserPreferenceHelper.instance.textSize - val content = convertView.findViewById(R.id.textview_status_text) as TextView - content.textSize = textSize.toFloat() - content.text = directMessage.text - val footer = convertView.findViewById(R.id.textview_status_footer) as TextView - footer.textSize = (textSize - 2).toFloat() - footer.text = getFooterText(directMessage, Application.currentWorld!!.account) + view.textview_status_text.textSize = textSize.toFloat() + view.textview_status_text.text = directMessage.text + view.textview_status_footer.textSize = (textSize - 2).toFloat() + view.textview_status_footer.text = getFooterText(directMessage, world) } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt index 05490f97..495db525 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/SettingFragment.kt @@ -42,6 +42,7 @@ import net.lacolaco.smileessence.R import net.lacolaco.smileessence.activity.LicenseActivity import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import kotlinx.android.synthetic.main.dialog_app_info.view.* class SettingFragment : PreferenceFragment(), OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { @@ -121,8 +122,7 @@ class SettingFragment : PreferenceFragment(), OnSharedPreferenceChangeListener, private fun openAppInfoDialog() { val inflater = activity.layoutInflater val contentView = inflater.inflate(R.layout.dialog_app_info, null) - val versionTextView = contentView.findViewById(R.id.versionTextView) as TextView - versionTextView.text = BuildConfig.VERSION_NAME + " (rev: " + BuildConfig.VERSION_CODE + "; upstream: " + getString(R.string.app_version_full) + ")" + contentView.versionTextView.text = BuildConfig.VERSION_NAME + " (rev: " + BuildConfig.VERSION_CODE + "; upstream: " + getString(R.string.app_version_full) + ")" AlertDialog.Builder(activity) .setTitle(R.string.dialog_title_about) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt index 547aa84d..16e40447 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/ThreeStateButton.kt @@ -8,7 +8,6 @@ import android.widget.Button import net.lacolaco.smileessence.R class ThreeStateButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.buttonStyle, defStyleRes: Int = 0) : Button(context, attrs, defStyleAttr, defStyleRes) { - var state = STATE_OFF set(s) { field = s @@ -20,7 +19,6 @@ class ThreeStateButton @JvmOverloads constructor(context: Context, attrs: Attrib private val backgrounds = arrayOfNulls<Drawable>(3) init { - val ta = context.obtainStyledAttributes(attrs, R.styleable.ThreeStateButton) texts[STATE_OFF] = ta.getString(R.styleable.ThreeStateButton_off_text) texts[STATE_ON] = ta.getString(R.styleable.ThreeStateButton_on_text) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt b/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt index 47a1821a..945eeb61 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/ToggleableImageButton.kt @@ -12,7 +12,6 @@ class ToggleableImageButton @JvmOverloads constructor(context: Context, attrs: A private val offSrc: Drawable init { - val ta = context.obtainStyledAttributes(attrs, R.styleable.ToggleableImageButton) offSrc = ta.getDrawable(R.styleable.ToggleableImageButton_offSrc) onSrc = ta.getDrawable(R.styleable.ToggleableImageButton_onSrc) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt index 1c19d4ec..f3c507ac 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/EventListAdapter.kt @@ -27,9 +27,7 @@ package net.lacolaco.smileessence.view.adapter import android.app.Activity import android.view.View import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import com.android.volley.toolbox.NetworkImageView +import kotlinx.android.synthetic.main.list_item_status.view.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.World import net.lacolaco.smileessence.data.ImageCache @@ -49,54 +47,44 @@ class EventListAdapter(private val world: World, private val activity: Activity) get() = world.events override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - var convertView = convertView + val view = convertView ?: activity.layoutInflater.inflate(R.layout.list_item_status, parent, false) val event = getItem(position) - if (convertView == null) { - convertView = activity.layoutInflater.inflate(R.layout.list_item_status, null) - } - var bundle: UIObserverBundle? = convertView!!.tag as UIObserverBundle? + var bundle: UIObserverBundle? = view!!.tag as UIObserverBundle? if (bundle != null) { bundle.detachAll() } else { bundle = UIObserverBundle() - convertView.tag = bundle + view.tag = bundle } val textSize = UserPreferenceHelper.instance.textSize - val header = convertView.findViewById(R.id.textview_status_header) as TextView - header.textSize = textSize.toFloat() + view.textview_status_header.textSize = textSize.toFloat() - updateViewUser(event, convertView) + updateViewUser(event, view) - val content = convertView.findViewById(R.id.textview_status_text) as TextView - content.textSize = textSize.toFloat() - content.text = event.targetObject?.text ?: "" - val footer = convertView.findViewById(R.id.textview_status_footer) as TextView - footer.textSize = (textSize - 2).toFloat() - footer.text = StringUtils.dateToString(event.createdAt) - val favorited = convertView.findViewById(R.id.imageview_status_favorited) as ImageView - favorited.visibility = View.GONE - convertView.setOnClickListener(ListItemClickListener(activity) { + view.textview_status_text.textSize = textSize.toFloat() + view.textview_status_text.text = event.targetObject?.text ?: "" + view.textview_status_footer.textSize = (textSize - 2).toFloat() + view.textview_status_footer.text = StringUtils.dateToString(event.createdAt) + view.imageview_status_favorited.visibility = View.GONE + view.setOnClickListener(ListItemClickListener(activity) { DialogHelper.showDialog(activity, UserDetailDialogFragment.newInstance(event.source)) }) - val weakView = WeakReference(convertView) + val weakView = WeakReference(view) bundle.attach(event.source) { changes -> val strongView = weakView.get() if (strongView != null && changes.contains(RBinding.BASIC)) updateViewUser(event, strongView) } - return convertView + return view } - private fun updateViewUser(event: Event, convertedView: View) { - val icon = convertedView.findViewById(R.id.imageview_status_icon) as NetworkImageView + private fun updateViewUser(event: Event, view: View) { val iconUrl = event.source.profileImageUrl - icon.setImageUrl(iconUrl, ImageCache.getImageLoader()) - - val header = convertedView.findViewById(R.id.textview_status_header) as TextView - header.text = event.formattedString + view.imageview_status_icon.setImageUrl(iconUrl, ImageCache.getImageLoader()) + view.textview_status_header.text = event.formattedString } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt index d72ab564..90a17c90 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/MessageListAdapter.kt @@ -27,10 +27,11 @@ package net.lacolaco.smileessence.view.adapter import android.app.Activity import android.view.View import android.view.ViewGroup +import net.lacolaco.smileessence.World import net.lacolaco.smileessence.entity.DirectMessage import net.lacolaco.smileessence.view.Partials -class MessageListAdapter(private val activity: Activity) : OrderedCustomListAdapter<DirectMessage>() { +class MessageListAdapter(private val activity: Activity, private val world: World) : OrderedCustomListAdapter<DirectMessage>() { val lastID: Long get() = if (count > 0) getItem(count - 1).id else -1 @@ -38,6 +39,6 @@ class MessageListAdapter(private val activity: Activity) : OrderedCustomListAdap get() = if (count > 0) getItem(0).id else -1 override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - return Partials.getDirectMessageView(getItem(position), activity, convertView) + return Partials.getDirectMessageView(getItem(position), world, activity, convertView) } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt index 34d158f0..d400ac4f 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/PageListAdapter.kt @@ -34,18 +34,12 @@ import java.lang.ref.WeakReference import java.util.ArrayList import java.util.HashMap -class PageListAdapter -// --------------------------- FragmentPagerAdapter --------------------------- - -(_activity: MainActivity) : FragmentPagerAdapter(_activity.fragmentManager) { - - // ------------------------------ FIELDS ------------------------------ - +class PageListAdapter(_activity: MainActivity) : FragmentPagerAdapter(_activity.fragmentManager) { private val pages = ArrayList<PageInfo>() - private val fragmentCache = HashMap<Int, WeakReference<PageFragment<*>>>() + private val fragmentCache = HashMap<Int, WeakReference<PageFragment>>() - @Synchronized override fun getItem(position: Int): PageFragment<*> { - val pf: PageFragment<*> + @Synchronized override fun getItem(position: Int): PageFragment { + val pf: PageFragment val info = pages[position] try { pf = info.fragmentClass.newInstance() @@ -61,7 +55,7 @@ class PageListAdapter } @Synchronized - fun getCachedFragment(pos: Int): PageFragment<*>? { + fun getCachedFragment(pos: Int): PageFragment? { val wpf = fragmentCache[pos] return wpf?.get() } @@ -70,15 +64,11 @@ class PageListAdapter return pages.size } - // ------------------------ INTERFACE METHODS ------------------------ - - // -------------------------- OTHER METHODS -------------------------- - - fun addPage(klass: Class<out PageFragment<*>>, name: String, args: Bundle) { + fun addPage(klass: Class<out PageFragment>, name: String, args: Bundle) { this.addPage(klass, name, args, true) } - fun addPage(klass: Class<out PageFragment<*>>, name: String, args: Bundle, notifyChanged: Boolean) { + fun addPage(klass: Class<out PageFragment>, name: String, args: Bundle, notifyChanged: Boolean) { pages.add(PageInfo(klass, name, args)) if (notifyChanged) notifyDataSetChanged() } @@ -97,7 +87,7 @@ class PageListAdapter } @Deprecated("") - fun getIndex(fragmentClass: Class<out PageFragment<*>>): Int { + fun getIndex(fragmentClass: Class<out PageFragment>): Int { for (i in pages.indices) { if (pages[i].fragmentClass == fragmentClass) { return i @@ -106,5 +96,5 @@ class PageListAdapter return -1 } - private class PageInfo internal constructor(val fragmentClass: Class<out PageFragment<*>>, val name: String, val args: Bundle) + private class PageInfo internal constructor(val fragmentClass: Class<out PageFragment>, val name: String, val args: Bundle) } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt index 750b63a0..511db35e 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/adapter/TimelineAdapter.kt @@ -5,10 +5,9 @@ import android.view.View import android.view.ViewGroup import net.lacolaco.smileessence.entity.Tweet import net.lacolaco.smileessence.view.Partials +import net.lacolaco.smileessence.World -import java.util.* - -class TimelineAdapter(private val activity: Activity) : OrderedCustomListAdapter<Tweet>() { +class TimelineAdapter(private val activity: Activity, private val world: World) : OrderedCustomListAdapter<Tweet>() { val lastID: Long get() = if (count > 0) { getItem(count - 1).id @@ -24,6 +23,6 @@ class TimelineAdapter(private val activity: Activity) : OrderedCustomListAdapter } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - return Partials.getTweetView(getItem(position), activity, convertView, true) + return Partials.getTweetView(getItem(position), world, activity, convertView, true) } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt index 094aa18a..445995b1 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/ConfirmDialogFragment.kt @@ -34,25 +34,7 @@ import net.lacolaco.smileessence.preference.UserPreferenceHelper import net.lacolaco.smileessence.view.DialogHelper abstract class ConfirmDialogFragment : StackableDialogFragment() { - private var text: String? = null - - // --------------------- GETTER / SETTER METHODS --------------------- - - fun setText(text: String) { - val args = Bundle() - args.putString(ARG_TEXT, text) - arguments = args - } - - // ------------------------ OVERRIDE METHODS ------------------------ - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val args = arguments - if (args != null) { - text = args.getString(ARG_TEXT) - } - } + private val text: String by lazy { arguments.getString(ARG_TEXT) ?: throw IllegalStateException("ARG_TEXT not set") } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return AlertDialog.Builder(activity).setTitle(text) @@ -73,13 +55,8 @@ abstract class ConfirmDialogFragment : StackableDialogFragment() { protected abstract fun onButtonClick(which: Int) companion object { - - // ------------------------------ FIELDS ------------------------------ - private val ARG_TEXT = "text" - // -------------------------- STATIC METHODS -------------------------- - fun show(activity: Activity, text: String, onYes: () -> Unit) { show(activity, text, onYes, null, true) } @@ -112,7 +89,9 @@ abstract class ConfirmDialogFragment : StackableDialogFragment() { } } } - fragment.setText(text) + val args = Bundle() + args.putString(ARG_TEXT, text) + fragment.arguments = args DialogHelper.showDialog(activity, fragment) } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt index 399b84ad..9d277cd7 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/EditTextDialogFragment.kt @@ -28,54 +28,38 @@ import android.app.AlertDialog import android.app.Dialog import android.app.DialogFragment import android.os.Bundle -import android.view.View -import android.widget.EditText +import kotlinx.android.synthetic.main.part_edittext.view.* import net.lacolaco.smileessence.R abstract class EditTextDialogFragment : DialogFragment() { - private lateinit var title: String - private lateinit var text: String - - // ------------------------ OVERRIDE METHODS ------------------------ - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val args = arguments - text = args.getString(textKey) - title = args.getString(titleKey) - } + private val title by lazy { arguments.getString(KEY_TITLE) } + private val text by lazy { arguments.getString(KEY_TEXT) } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val view = activity.layoutInflater.inflate(R.layout.part_edittext, null) - val editText = view.findViewById(R.id.part_edittext) as EditText - editText.setText(text) + view.part_edittext.setText(text) return AlertDialog.Builder(activity) .setTitle(title) .setView(view) .setPositiveButton(R.string.alert_dialog_ok) { dialog, which -> - onTextInput(editText.text.toString()) + onTextInput(view.part_edittext.text.toString()) dialog.dismiss() } .setNegativeButton(R.string.alert_dialog_cancel) { dialog, which -> dialog.dismiss() } .create() } - // -------------------------- OTHER METHODS -------------------------- - abstract fun onTextInput(text: String) fun setParams(title: String, text: String) { val args = Bundle() - args.putString(titleKey, title) - args.putString(textKey, text) + args.putString(KEY_TITLE, title) + args.putString(KEY_TEXT, text) arguments = args } companion object { - - // ------------------------------ FIELDS ------------------------------ - - private val titleKey = "title" - private val textKey = "text" + private val KEY_TITLE = "title" + private val KEY_TEXT = "text" } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt index 36f7584f..08be80dc 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/MessageDetailDialogFragment.kt @@ -30,9 +30,8 @@ import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.view.View import android.view.ViewGroup -import android.widget.ImageButton -import android.widget.ListView -import android.widget.TextView +import kotlinx.android.synthetic.main.dialog_status_detail.view.* +import kotlinx.android.synthetic.main.menu_item_simple_text.view.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.activity.MainActivity import net.lacolaco.smileessence.command.Command @@ -78,10 +77,69 @@ class MessageDetailDialogFragment : StackableDialogFragment(), View.OnClickListe } message = found - val header = titleView - val listView = header.findViewById(R.id.listview_status_detail_reply_to) as ListView - val adapter = MessageListAdapter(activity) - listView.adapter = adapter + val view = activity.layoutInflater.inflate(R.layout.dialog_status_detail, null) + + val messageHeader = Partials.getDirectMessageView(message, world, activity, view.layout_status_header) + messageHeader.isClickable = false + + view.setBackgroundColor((messageHeader.background as ColorDrawable).color) + //--- buttons + view.button_status_detail_reply.setOnClickListener(this) + view.button_status_detail_delete.setOnClickListener(this) + view.button_status_detail_delete.visibility = View.VISIBLE + // -- menu dialog + view.button_status_detail_menu.setOnClickListener(this) + + // -- menu embedded in dialog + val activity = activity as MainActivity + val commands = ArrayList<Command>() + if (message.sender !== message.recipient) { + commands.add(CommandOpenUserDetail(activity, message.recipient.screenName)) + } + for (screenName in message.mentions) { + commands.add(CommandOpenUserDetail(activity, screenName)) + } + for (hashtag in message.hashtags) { + commands.add(CommandAddHashtag(activity, hashtag)) + } + for (url in message.urlsExpanded) { + commands.add(CommandOpenURL(activity, url)) + } + for (url in message.mediaUrls) { + commands.add(CommandOpenURL(activity, url)) + } + if (commands.size > 0) { + view.detail_dialog_divider_bottom.visibility = View.VISIBLE + view.listview_status_detail_menu.visibility = View.VISIBLE + val adapter = object : CustomListAdapter<Command>() { + override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + val itemView = convertView ?: activity.layoutInflater.inflate(R.layout.menu_item_simple_text, parent, false) + itemView.list_item_textview.textSize = UserPreferenceHelper.instance.textSize.toFloat() + itemView.list_item_textview.text = getItem(position).text + return itemView + } + + override val list: List<Command> + get() = commands + } + adapter.update() + view.listview_status_detail_menu.adapter = adapter + view.listview_status_detail_menu.setOnItemClickListener { parent, view1, position, id -> + val command = parent.getItemAtPosition(position) as Command + command.execute() + } + } else { + view.detail_dialog_divider_bottom.visibility = View.GONE + view.listview_status_detail_menu.visibility = View.GONE + } + view.detail_dialog_divider_top.visibility = View.GONE + view.button_status_detail_retweet.visibility = View.GONE + view.button_status_detail_favorite.visibility = View.GONE + view.image_status_detail_fav_count.visibility = View.GONE + view.image_status_detail_rt_count.visibility = View.GONE + + val adapter = MessageListAdapter(activity, world) + view.listview_status_detail_reply_to.adapter = adapter // TODO: 効率的な探索どうする val replyTo: DirectMessage? = null @@ -95,14 +153,14 @@ class MessageDetailDialogFragment : StackableDialogFragment(), View.OnClickListe // } // } if (replyTo != null) { - listView.visibility = View.VISIBLE + view.listview_status_detail_reply_to.visibility = View.VISIBLE adapter.add(replyTo) adapter.updateForce() } else { - listView.visibility = View.GONE + view.listview_status_detail_reply_to.visibility = View.GONE } - return AlertDialog.Builder(activity).setView(header).create() + return AlertDialog.Builder(activity).setView(view).create() } // -------------------------- OTHER METHODS -------------------------- @@ -121,101 +179,6 @@ class MessageDetailDialogFragment : StackableDialogFragment(), View.OnClickListe DialogHelper.showDialog(activity, SendMessageDialogFragment.newInstance(message.sender)) } - private // status only parts - val titleView: View - get() { - val activity = activity as MainActivity - - val view = activity.layoutInflater.inflate(R.layout.dialog_status_detail, null) - - val messageHeader = Partials.getDirectMessageView(message, activity, view.findViewById(R.id.layout_status_header)) - messageHeader.isClickable = false - - view.setBackgroundColor((messageHeader.background as ColorDrawable).color) - updateViewButtons(view) - updateViewMenu(view) - view.findViewById(R.id.detail_dialog_divider_top).visibility = View.GONE - view.findViewById(R.id.button_status_detail_retweet).visibility = View.GONE - view.findViewById(R.id.button_status_detail_favorite).visibility = View.GONE - view.findViewById(R.id.image_status_detail_fav_count).visibility = View.GONE - view.findViewById(R.id.image_status_detail_rt_count).visibility = View.GONE - - return view - } - - private fun updateViewButtons(view: View) { - //--- buttons - val reply = view.findViewById(R.id.button_status_detail_reply) as ImageButton - reply.setOnClickListener(this) - - val delete = view.findViewById(R.id.button_status_detail_delete) as ImageButton - delete.setOnClickListener(this) - delete.visibility = View.VISIBLE - } - - private fun updateViewMenu(view: View) { - // -- menu dialog - val menu = view.findViewById(R.id.button_status_detail_menu) as ImageButton - menu.setOnClickListener(this) - - // -- menu embedded in dialog - 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 // Mentions - // URL - val commands: List<Command> - get() { - val activity = activity as MainActivity - val commands = ArrayList<Command>() - if (message.sender !== message.recipient) { - commands.add(CommandOpenUserDetail(activity, message.recipient.screenName)) - } - for (screenName in message.mentions) { - commands.add(CommandOpenUserDetail(activity, screenName)) - } - for (hashtag in message.hashtags) { - commands.add(CommandAddHashtag(activity, hashtag)) - } - for (url in message.urlsExpanded) { - commands.add(CommandOpenURL(activity, url)) - } - for (url in message.mediaUrls) { - commands.add(CommandOpenURL(activity, url)) - } - return commands - } - private fun openMenu() { val builder = AlertDialog.Builder(activity) builder.setTitle("@" + message.sender.screenName + ": " + message.text) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt index fb7e9d2f..16bef540 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/SendMessageDialogFragment.kt @@ -29,25 +29,18 @@ import android.app.Dialog import android.os.Bundle import android.support.v4.content.ContextCompat import android.text.Editable -import android.text.TextUtils import android.text.TextWatcher import android.view.View -import android.widget.Button -import android.widget.EditText -import android.widget.ImageButton -import android.widget.TextView import com.twitter.Validator -import net.lacolaco.smileessence.Application +import kotlinx.android.synthetic.main.dialog_send_message.view.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.entity.User import net.lacolaco.smileessence.twitter.task.Messages import net.lacolaco.smileessence.util.SystemServiceHelper class SendMessageDialogFragment : StackableDialogFragment(), TextWatcher, View.OnClickListener { - private var recipient: User? = null - private var editText: EditText? = null - private var textViewCount: TextView? = null - private var buttonSend: Button? = null + private lateinit var recipient: User + override fun onClick(v: View) { val id = v.id when (id) { @@ -55,7 +48,7 @@ class SendMessageDialogFragment : StackableDialogFragment(), TextWatcher, View.O sendMessage() } R.id.button_send_message_delete -> { - deleteMessage() + view.edittext_send_message.setText("") } } } @@ -67,11 +60,11 @@ class SendMessageDialogFragment : StackableDialogFragment(), TextWatcher, View.O override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { val validator = Validator() val remainingCount = 140 - validator.getTweetLength(s.toString()) - textViewCount!!.text = remainingCount.toString() + view.textview_send_message_count.text = remainingCount.toString() if (remainingCount == 140 || remainingCount < 0) { - textViewCount!!.setTextColor(ContextCompat.getColor(activity, R.color.red)) + view.textview_send_message_count.setTextColor(ContextCompat.getColor(activity, R.color.red)) } else { - textViewCount!!.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView) + view.textview_send_message_count.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView) } } @@ -79,31 +72,28 @@ class SendMessageDialogFragment : StackableDialogFragment(), TextWatcher, View.O } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - recipient = User.fetch(arguments.getLong(KEY_RECIPIENT_ID)) + val found = User.fetch(arguments.getLong(KEY_RECIPIENT_ID)) + if (found == null) { + world.notifyError(R.string.notice_error_show_user) + return DisposeDialog(activity) + } + recipient = found + val view = activity.layoutInflater.inflate(R.layout.dialog_send_message, null) - val textViewName = view.findViewById(R.id.textview_send_message_name) as TextView - textViewName.text = "To: @" + recipient!!.screenName - textViewCount = view.findViewById(R.id.textview_send_message_count) as TextView - editText = view.findViewById(R.id.edittext_send_message) as EditText - editText!!.addTextChangedListener(this) - buttonSend = view.findViewById(R.id.button_send_message) as Button - buttonSend!!.setOnClickListener(this) - val buttonDelete = view.findViewById(R.id.button_send_message_delete) as ImageButton - buttonDelete.setOnClickListener(this) - editText!!.setText("") + view.textview_send_message_name.text = "To: @" + recipient.screenName + view.edittext_send_message.addTextChangedListener(this) + view.button_send_message.setOnClickListener(this) + view.button_send_message_delete.setOnClickListener(this) + view.edittext_send_message.setText("") return AlertDialog.Builder(activity) .setView(view) .create() } - private fun deleteMessage() { - editText!!.setText("") - } - private fun sendMessage() { - SystemServiceHelper.hideIM(activity, editText) - val text = editText!!.text.toString() - Messages.CreateTask(world.account, recipient!!.id, text) + SystemServiceHelper.hideIM(activity, view.edittext_send_message) + val text = view.edittext_send_message.text.toString() + Messages.CreateTask(world.account, recipient.id, text) .onDoneUI { m -> world.addDirectMessage(m) world.notify(R.string.notice_message_send_succeeded) 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 index c18b6b4d..91f5cbf6 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/StatusDetailDialogFragment.kt @@ -30,18 +30,14 @@ 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 kotlinx.android.synthetic.main.dialog_status_detail.view.* +import kotlinx.android.synthetic.main.menu_item_simple_text.view.* 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 @@ -52,7 +48,6 @@ 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 @@ -172,7 +167,7 @@ class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListen val bundle = UIObserverBundle() view.tag = bundle - val statusHeader = Partials.getTweetView(tweet, activity, view.findViewById(R.id.layout_status_header), true) + val statusHeader = Partials.getTweetView(tweet, world, activity, view.layout_status_header) statusHeader.isClickable = false view.setBackgroundColor((statusHeader.background as ColorDrawable).color) @@ -191,15 +186,12 @@ class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListen } } - 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) + val adapter = TimelineAdapter(activity, world) + view.listview_status_detail_reply_to.adapter = adapter if (tweet.inReplyToStatusId != -1L) { - replyDivider.visibility = View.VISIBLE - listView.visibility = View.VISIBLE + view.detail_dialog_divider_top.visibility = View.VISIBLE + view.listview_status_detail_reply_to.visibility = View.VISIBLE Tweet.fetchTask(tweet.inReplyToStatusId, world.account) .onDoneUI { replyTo -> adapter.add(replyTo) @@ -207,34 +199,30 @@ class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListen } .execute() } else { - replyDivider.visibility = View.GONE - listView.visibility = View.GONE + view.detail_dialog_divider_top.visibility = View.GONE + view.listview_status_detail_reply_to.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 + view.textview_status_detail_fav_count.text = Integer.toString(tweet.favoriteCount) + view.image_status_detail_fav_count.visibility = View.VISIBLE + view.textview_status_detail_fav_count.visibility = View.VISIBLE } else { - favCountIcon.visibility = View.GONE - favCountText.visibility = View.GONE + view.image_status_detail_fav_count.visibility = View.GONE + view.textview_status_detail_fav_count.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 + view.textview_status_detail_rt_count.text = Integer.toString(tweet.retweetCount) + view.image_status_detail_rt_count.visibility = View.VISIBLE + view.textview_status_detail_rt_count.visibility = View.VISIBLE } else { - rtCountIcon.visibility = View.GONE - rtCountText.visibility = View.GONE + view.image_status_detail_rt_count.visibility = View.GONE + view.textview_status_detail_rt_count.visibility = View.GONE } } @@ -242,56 +230,61 @@ class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListen val account = world.account //--- buttons - val reply = view.findViewById(R.id.button_status_detail_reply) as ImageButton - reply.setOnClickListener(this) + view.button_status_detail_reply.setOnClickListener(this) - val retweet = view.findViewById(R.id.button_status_detail_retweet) as ToggleableImageButton - retweet.setOnClickListener(this) - retweet.setState(tweet.isRetweetedBy(account.userId)) + view.button_status_detail_retweet.setOnClickListener(this) + view.button_status_detail_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)) + view.button_status_detail_favorite.setOnClickListener(this) + view.button_status_detail_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 + view.button_status_detail_delete.setOnClickListener(this) + view.button_status_detail_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) + view.button_status_detail_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 + 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)) + } + if (commands.size > 0) { - divider.visibility = View.VISIBLE - listView.visibility = View.VISIBLE + view.detail_dialog_divider_bottom.visibility = View.VISIBLE + view.listview_status_detail_menu.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 + val itemView = convertView ?: activity.layoutInflater.inflate(R.layout.menu_item_simple_text, parent, false) + itemView.list_item_textview.textSize = UserPreferenceHelper.instance.textSize.toFloat() + itemView.list_item_textview.text = getItem(position).text + return itemView } override val list: List<Command> get() = commands } adapter.update() - listView.adapter = adapter - listView.setOnItemClickListener { parent, view1, position, id -> + view.listview_status_detail_menu.adapter = adapter + view.listview_status_detail_menu.setOnItemClickListener { parent, view1, position, id -> val command = parent.getItemAtPosition(position) as Command command.execute() } } else { - divider.visibility = View.GONE - listView.visibility = View.GONE + view.detail_dialog_divider_bottom.visibility = View.GONE + view.listview_status_detail_menu.visibility = View.GONE } } @@ -299,32 +292,6 @@ class StatusDetailDialogFragment : StackableDialogFragment(), View.OnClickListen 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" diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt index 1b39e50a..1f70002c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/TalkChainDialogFragment.kt @@ -29,7 +29,7 @@ import android.app.Dialog import android.os.Bundle import android.view.View import android.view.ViewGroup -import android.widget.ListView +import kotlinx.android.synthetic.main.dialog_talk_list.view.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.entity.Tweet import net.lacolaco.smileessence.twitter.task.Tweets @@ -40,24 +40,21 @@ import java.util.ArrayList class TalkChainDialogFragment : StackableDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val account = world.account - val view = activity.layoutInflater.inflate(R.layout.dialog_talk_list, null) - val listView = view.findViewById(R.id.listview_dialog_talk_list) as ListView val list = ArrayList<Tweet>() val adapter = object : CustomListAdapter<Tweet>() { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - return Partials.getTweetView(getItem(position), activity, convertView, true) + return Partials.getTweetView(getItem(position), world, activity, convertView) } override val list: List<Tweet> get() = list } - listView.adapter = adapter + view.listview_dialog_talk_list.adapter = adapter - Tweets.GetTalkTask(account, arguments.getLong(KEY_STATUS_ID)).onProgressUI { tweet -> + Tweets.GetTalkTask(world.account, arguments.getLong(KEY_STATUS_ID)).onProgressUI { tweet -> list.add(tweet) - adapter.updateForce() + adapter.update() }.execute() return AlertDialog.Builder(activity) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt index 228a000a..ca634d92 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/dialog/UserDetailDialogFragment.kt @@ -33,13 +33,9 @@ import android.text.method.LinkMovementMethod import android.view.View import android.widget.AbsListView import android.widget.ListView -import android.widget.TabHost -import android.widget.TextView -import com.android.volley.toolbox.NetworkImageView import com.handmark.pulltorefresh.library.PullToRefreshBase -import com.handmark.pulltorefresh.library.PullToRefreshListView +import kotlinx.android.synthetic.main.dialog_user_detail.view.* import net.lacolaco.smileessence.R -import net.lacolaco.smileessence.activity.MainActivity import net.lacolaco.smileessence.data.ImageCache import net.lacolaco.smileessence.entity.RBinding import net.lacolaco.smileessence.entity.User @@ -53,30 +49,54 @@ import net.lacolaco.smileessence.view.ThreeStateButton import net.lacolaco.smileessence.view.adapter.TimelineAdapter class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener, PullToRefreshBase.OnRefreshListener2<ListView> { - private lateinit var adapter: TimelineAdapter - private lateinit var textViewScreenName: TextView - private lateinit var textViewName: TextView - private lateinit var textViewURL: TextView - private lateinit var textViewLocate: TextView - private lateinit var textViewFollowed: TextView - private lateinit var textViewProtected: TextView - private lateinit var textViewDescription: TextView - private lateinit var textViewTweetCount: TextView - private lateinit var textViewFriendCount: TextView - private lateinit var textViewFollowerCount: TextView - private lateinit var textViewFavoriteCount: TextView - private lateinit var imageViewIcon: NetworkImageView - private lateinit var imageViewHeader: NetworkImageView - private lateinit var buttonFollow: ThreeStateButton - private lateinit var listViewTimeline: PullToRefreshListView - private lateinit var tabHost: TabHost - private lateinit var observerBundle: UIObserverBundle + private val adapter by lazy { TimelineAdapter(activity, world) } + private val observerBundle by lazy { UIObserverBundle() } private lateinit var user: User override fun onClick(v: View) { when (v.id) { R.id.imageview_user_detail_menu -> { - openUserMenu() + val v = view + val builder = AlertDialog.Builder(activity) + builder.setTitle("@" + user.screenName) + .setItems(R.array.user_commands) { dialog, which -> + // XXX + UIHandler().postDelayed({ + if (this@UserDetailDialogFragment.isAdded) { + updateRelationship(v) + } + }, 1000) + when (which) { + 0 -> { + val text = String.format("@%s ", user.screenName) + world.postState.beginTransaction().insertText(0, text).moveCursor(text.length).commit() + world.notify(R.string.notice_add_to_reply) + } + 1 -> DialogHelper.showDialog(activity, SendMessageDialogFragment.newInstance(user)) + 2 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { + Users.BlockTask(world.account, user.id) + .onDone { user -> world.notify(R.string.notice_block_succeeded) } + .onFail { ex -> world.notifyError(R.string.notice_block_failed) } + .execute() + } + 3 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { + Users.UnblockTask(world.account, user.id) + .onDone { user -> world.notify(R.string.notice_unblock_succeeded) } + .onFail { x -> world.notifyError(R.string.notice_unblock_failed) } + .execute() + } + 4 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { + Users.ReportForSpamTask(world.account, user.id) + .onDone { user -> world.notify(R.string.notice_r4s_succeeded) } + .onFail { ex -> world.notifyError(R.string.notice_r4s_failed) } + .execute() + } + 5 -> IntentUtils.openUri(activity, user.aclogTimelineURL) + else -> throw IllegalStateException() + } + } + val dialog = builder.create() + dialog.show() } R.id.imageview_user_detail_icon -> { IntentUtils.openUri(activity, user.profileImageUrl!!) @@ -94,7 +114,29 @@ class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener IntentUtils.openUri(activity, String.format("%s/favorites", user.userHomeURL)) } R.id.button_user_detail_follow -> { - ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { this.toggleFollowing() } + val v = view + ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { + val account = world.account + val isFollowing = v.button_user_detail_follow.state == ThreeStateButton.STATE_ON + v.button_user_detail_follow.state = ThreeStateButton.STATE_LOCKED + if (isFollowing) { + Users.UnfollowTask(account, user.id) + .onDoneUI { result -> + world.notify(R.string.notice_unfollow_succeeded) + updateRelationship(v) + } + .onFail { x -> world.notifyError(R.string.notice_unfollow_failed) } + .execute() + } else { + Users.FollowTask(account, user.id) + .onDoneUI { result -> + world.notify(R.string.notice_follow_succeeded) + updateRelationship(v) + } + .onFail { x -> world.notifyError(R.string.notice_follow_failed) } + .execute() + } + } } } } @@ -129,20 +171,12 @@ class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener .execute() } - // ------------------------ OVERRIDE METHODS ------------------------ - - override fun onCreate(savedInstanceState: Bundle) { - super.onCreate(savedInstanceState) - observerBundle = UIObserverBundle() - } - override fun onDestroy() { - super.onDestroy() observerBundle.detachAll() + super.onDestroy() } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val activity = activity as MainActivity val found = User.fetch(arguments.getLong(KEY_USER_ID)) if (found == null) { world.notify(R.string.notice_error_show_user) @@ -151,42 +185,39 @@ class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener user = found val v = activity.layoutInflater.inflate(R.layout.dialog_user_detail, null) - val menu = v.findViewById(R.id.imageview_user_detail_menu) - menu.setOnClickListener(this) - textViewScreenName = v.findViewById(R.id.textview_user_detail_screenname) as TextView - textViewScreenName.setOnClickListener(this) - textViewName = v.findViewById(R.id.textview_user_detail_name) as TextView - textViewURL = v.findViewById(R.id.textview_user_detail_url) as TextView - textViewLocate = v.findViewById(R.id.textview_user_detail_locate) as TextView - textViewFollowed = v.findViewById(R.id.textview_user_detail_followed) as TextView - textViewProtected = v.findViewById(R.id.texttview_user_detail_protected) as TextView - textViewDescription = v.findViewById(R.id.textview_user_detail_description) as TextView - textViewDescription.movementMethod = LinkMovementMethod.getInstance() - textViewTweetCount = v.findViewById(R.id.textview_user_detail_tweet_count) as TextView - textViewTweetCount.setOnClickListener(this) - textViewFriendCount = v.findViewById(R.id.textview_user_detail_friend_count) as TextView - textViewFriendCount.setOnClickListener(this) - textViewFollowerCount = v.findViewById(R.id.textview_user_detail_follower_count) as TextView - textViewFollowerCount.setOnClickListener(this) - textViewFavoriteCount = v.findViewById(R.id.textview_user_detail_favorite_count) as TextView - textViewFavoriteCount.setOnClickListener(this) - imageViewIcon = v.findViewById(R.id.imageview_user_detail_icon) as NetworkImageView - imageViewIcon.setOnClickListener(this) - imageViewHeader = v.findViewById(R.id.imageview_user_detail_header) as NetworkImageView - buttonFollow = v.findViewById(R.id.button_user_detail_follow) as ThreeStateButton - buttonFollow.setOnClickListener(this) - listViewTimeline = v.findViewById(R.id.listview_user_detail_timeline) as PullToRefreshListView - listViewTimeline.setOnRefreshListener(this) + v.imageview_user_detail_menu.setOnClickListener(this) + v.textview_user_detail_screenname.setOnClickListener(this) + v.textview_user_detail_description.movementMethod = LinkMovementMethod.getInstance() + v.textview_user_detail_tweet_count.setOnClickListener(this) + v.textview_user_detail_friend_count.setOnClickListener(this) + v.textview_user_detail_follower_count.setOnClickListener(this) + v.textview_user_detail_favorite_count.setOnClickListener(this) + v.imageview_user_detail_icon.setOnClickListener(this) + v.button_user_detail_follow.setOnClickListener(this) + v.listview_user_detail_timeline.setOnRefreshListener(this) + + v.tabhost.setup() + val tab1 = v.tabhost.newTabSpec("tab1").setContent(R.id.tab1).setIndicator(getString(R.string.user_detail_tab_info)) + v.tabhost.addTab(tab1) + val tab2 = v.tabhost.newTabSpec("tab2").setContent(R.id.tab2).setIndicator(getString(R.string.user_detail_tab_timeline)) + v.tabhost.addTab(tab2) + v.tabhost.currentTab = 0 - tabHost = v.findViewById(android.R.id.tabhost) as TabHost - tabHost.setup() - val tab1 = tabHost.newTabSpec("tab1").setContent(R.id.tab1).setIndicator(getString(R.string.user_detail_tab_info)) - tabHost.addTab(tab1) - val tab2 = tabHost.newTabSpec("tab2").setContent(R.id.tab2).setIndicator(getString(R.string.user_detail_tab_timeline)) - tabHost.addTab(tab2) - tabHost.currentTab = 0 + updateUserDataBasic(v) + updateUserDataDetail(v) - initUserData() + v.listview_user_detail_timeline.setAdapter(adapter) + executeUserTimelineTask(v, adapter) + updateRelationship(v) + + observerBundle.attach(user) { changes -> + if (activity != null) { + if (changes.contains(RBinding.BASIC)) + updateUserDataBasic(v) + if (changes.contains(RBinding.DETAIL)) + updateUserDataDetail(v) + } + } return AlertDialog.Builder(activity) .setView(v) @@ -194,153 +225,57 @@ class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener .create() } - private fun executeUserTimelineTask(adapter: TimelineAdapter) { + private fun executeUserTimelineTask(v: View, adapter: TimelineAdapter) { val account = world.account - tabHost.tabWidget.getChildTabViewAt(1).visibility = View.GONE + v.tabhost.tabWidget.getChildTabViewAt(1).visibility = View.GONE Timelines.UserTimelineTask(account, user.id) .setCount(200) .onFail { x -> world.notifyError(R.string.notice_error_get_user_timeline) } .onDoneUI { tweets -> adapter.addAll(tweets) adapter.updateForce() - tabHost.tabWidget.getChildTabViewAt(1).visibility = View.VISIBLE + v.tabhost.tabWidget.getChildTabViewAt(1).visibility = View.VISIBLE } .execute() } private val htmlDescription: String? get() { - val description = user.description - if (TextUtils.isEmpty(description)) { - return "" - } - var html = description - html = html!!.replace("https?://[\\w/:%#$&?()~.=+-]+".toRegex(), "<a href=\"$0\">$0</a>") + var html = user.description + html = html.replace("https?://[\\w/:%#$&?()~.=+-]+".toRegex(), "<a href=\"$0\">$0</a>") html = html.replace("@([a-zA-Z0-9_]+)".toRegex(), "<a href=\"https://twitter.com/$1\">$0</a>") html = html.replace("\r\n".toRegex(), "<br />") return html } - private fun updateUserDataBasic() { - textViewName.text = user.name - textViewScreenName.text = user.screenName - textViewProtected.visibility = if (user.isProtected) View.VISIBLE else View.GONE - imageViewIcon.setImageUrl(user.profileImageUrl, ImageCache.getImageLoader()) + private fun updateUserDataBasic(v: View) { + v.textview_user_detail_name.text = user.name + v.textview_user_detail_screenname.text = user.screenName + v.texttview_user_detail_protected.visibility = if (user.isProtected) View.VISIBLE else View.GONE + v.imageview_user_detail_icon.setImageUrl(user.profileImageUrl, ImageCache.getImageLoader()) } - private fun updateUserDataDetail() { + private fun updateUserDataDetail(v: View) { if (TextUtils.isEmpty(user.location)) { - textViewLocate.visibility = View.GONE + v.textview_user_detail_locate.visibility = View.GONE } else { - textViewLocate.text = user.location - textViewLocate.visibility = View.VISIBLE + v.textview_user_detail_locate.text = user.location + v.textview_user_detail_locate.visibility = View.VISIBLE } if (TextUtils.isEmpty(user.url)) { - textViewURL.visibility = View.GONE + v.textview_user_detail_url.visibility = View.GONE } else { - textViewURL.text = user.url - textViewURL.visibility = View.VISIBLE - } - textViewDescription.text = Html.fromHtml(htmlDescription) - - textViewTweetCount.text = user.statusesCount.toString() - textViewFriendCount.text = user.friendsCount.toString() - textViewFollowerCount.text = user.followersCount.toString() - textViewFavoriteCount.text = user.favoritesCount.toString() - - imageViewHeader.setImageUrl(user.profileBannerUrl, ImageCache.getImageLoader()) - } - - private fun initUserData() { - updateUserDataBasic() - updateUserDataDetail() - - val activity = activity as MainActivity - adapter = TimelineAdapter(activity) - listViewTimeline.setAdapter(adapter) - executeUserTimelineTask(adapter) - updateRelationship() - - observerBundle.attach(user) { changes -> - if (getActivity() != null) { - if (changes.contains(RBinding.BASIC)) - updateUserDataBasic() - if (changes.contains(RBinding.DETAIL)) - updateUserDataDetail() - } + v.textview_user_detail_url.text = user.url + v.textview_user_detail_url.visibility = View.VISIBLE } - } - - private fun openUserMenu() { - val builder = AlertDialog.Builder(activity) - builder.setTitle("@" + user.screenName) - .setItems(R.array.user_commands) { dialog, which -> - // XXX - UIHandler().postDelayed({ - if (this@UserDetailDialogFragment.isAdded) { - updateRelationship() - } - }, 1000) - when (which) { - 0 -> { - val text = String.format("@%s ", user.screenName) - world.postState.beginTransaction().insertText(0, text).moveCursor(text.length).commit() - world.notify(R.string.notice_add_to_reply) - } - 1 -> DialogHelper.showDialog(activity, SendMessageDialogFragment.newInstance(user)) - 2 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { - Users.BlockTask(world.account, user.id) - .onDone { user -> world.notify(R.string.notice_block_succeeded) } - .onFail { ex -> world.notifyError(R.string.notice_block_failed) } - .execute() - } - 3 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { - Users.UnblockTask(world.account, user.id) - .onDone { user -> world.notify(R.string.notice_unblock_succeeded) } - .onFail { x -> world.notifyError(R.string.notice_unblock_failed) } - .execute() - } - 4 -> ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_commands)) { - Users.ReportForSpamTask(world.account, user.id) - .onDone { user -> world.notify(R.string.notice_r4s_succeeded) } - .onFail { ex -> world.notifyError(R.string.notice_r4s_failed) } - .execute() - } - 5 -> IntentUtils.openUri(activity, user.aclogTimelineURL) - else -> throw IllegalStateException() - } - } - val dialog = builder.create() - dialog.show() - } + v.textview_user_detail_description.text = Html.fromHtml(htmlDescription) - private fun setFollowButtonState(isFollowing: Boolean) { - if (activity != null) { - buttonFollow.state = if (isFollowing) ThreeStateButton.STATE_ON else ThreeStateButton.STATE_OFF - } - } + v.textview_user_detail_tweet_count.text = user.statusesCount.toString() + v.textview_user_detail_friend_count.text = user.friendsCount.toString() + v.textview_user_detail_follower_count.text = user.followersCount.toString() + v.textview_user_detail_favorite_count.text = user.favoritesCount.toString() - private fun toggleFollowing() { - val account = world.account - val isFollowing = buttonFollow.state == ThreeStateButton.STATE_ON - buttonFollow.state = ThreeStateButton.STATE_LOCKED - if (isFollowing) { - Users.UnfollowTask(account, user.id) - .onDoneUI { result -> - world.notify(R.string.notice_unfollow_succeeded) - updateRelationship() - } - .onFail { x -> world.notifyError(R.string.notice_unfollow_failed) } - .execute() - } else { - Users.FollowTask(account, user.id) - .onDoneUI { result -> - world.notify(R.string.notice_follow_succeeded) - updateRelationship() - } - .onFail { x -> world.notifyError(R.string.notice_follow_failed) } - .execute() - } + v.imageview_user_detail_header.setImageUrl(user.profileBannerUrl, ImageCache.getImageLoader()) } private fun updateListView(absListView: AbsListView, adapter: TimelineAdapter, addedToTop: Boolean) { @@ -359,19 +294,19 @@ class UserDetailDialogFragment : StackableDialogFragment(), View.OnClickListener } } - private fun updateRelationship() { + private fun updateRelationship(v: View) { val account = world.account if (user === account.user) { - textViewFollowed.setText(R.string.user_detail_followed_is_me) - buttonFollow.visibility = View.GONE + v.textview_user_detail_followed.setText(R.string.user_detail_followed_is_me) + v.button_user_detail_follow.visibility = View.GONE } else { - buttonFollow.state = ThreeStateButton.STATE_LOCKED - textViewFollowed.setText(R.string.user_detail_loading) + v.button_user_detail_follow.state = ThreeStateButton.STATE_LOCKED + v.textview_user_detail_followed.setText(R.string.user_detail_loading) Users.ShowFriendshipTask(account, user.id).onDoneUI { relationship -> val isFollowing = relationship.isSourceFollowingTarget val isFollowed = relationship.isSourceFollowedByTarget - setFollowButtonState(isFollowing) - textViewFollowed.setText(if (isFollowed) R.string.user_detail_followed else R.string.user_detail_not_followed) + v.button_user_detail_follow.state = if (isFollowing) ThreeStateButton.STATE_ON else ThreeStateButton.STATE_OFF + v.textview_user_detail_followed.setText(if (isFollowed) R.string.user_detail_followed else R.string.user_detail_not_followed) }.execute() } } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt b/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt index 20404c63..755bc07c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/listener/ListItemClickListener.kt @@ -31,19 +31,7 @@ import android.view.View import net.lacolaco.smileessence.R import net.lacolaco.smileessence.util.UIHandler -class ListItemClickListener -// --------------------------- CONSTRUCTORS --------------------------- - -( - // ------------------------------ FIELDS ------------------------------ - - private val activity: Activity, private val callback: () -> Unit) : View.OnClickListener { - - // ------------------------ INTERFACE METHODS ------------------------ - - - // --------------------- Interface OnClickListener --------------------- - +class ListItemClickListener(private val activity: Activity, private val callback: () -> Unit) : View.OnClickListener { override fun onClick(v: View) { val currentBgColor = (v.background as ColorDrawable).color v.setBackgroundColor(ContextCompat.getColor(activity, R.color.metro_blue)) diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt index d8536263..23174d09 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/CustomListFragment.kt @@ -32,33 +32,26 @@ import android.widget.AbsListView import android.widget.ListView import com.handmark.pulltorefresh.library.PullToRefreshBase import com.handmark.pulltorefresh.library.PullToRefreshListView +import kotlinx.android.synthetic.main.fragment_list.view.* import net.lacolaco.smileessence.R -import net.lacolaco.smileessence.World -import net.lacolaco.smileessence.activity.MainActivity import net.lacolaco.smileessence.view.adapter.CustomListAdapter -abstract class CustomListFragment<T : CustomListAdapter<*>> : PageFragment<T>(), AbsListView.OnScrollListener, PullToRefreshBase.OnRefreshListener2<ListView> { - - // --------------------- GETTER / SETTER METHODS --------------------- +abstract class CustomListFragment<out T : CustomListAdapter<*>> : PageFragment(), + AbsListView.OnScrollListener, PullToRefreshBase.OnRefreshListener2<ListView> { + protected abstract val adapter: T protected open val refreshMode: PullToRefreshBase.Mode get() = PullToRefreshBase.Mode.DISABLED - // ------------------------ INTERFACE METHODS ------------------------ - - - // --------------------- Interface OnRefreshListener2 --------------------- - override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) {} override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) {} - // --------------------- Interface OnScrollListener --------------------- - override fun onScrollStateChanged(absListView: AbsListView, scrollState: Int) { val adapter = adapter if (scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL && - absListView.firstVisiblePosition == 0 && (absListView.getChildAt(0) == null || absListView.getChildAt(0).top == 0)) { + absListView.firstVisiblePosition == 0 && (absListView.getChildAt(0) == null || + absListView.getChildAt(0).top == 0)) { adapter.setNotifiable(true) updateListViewWithNotice(absListView, true) } else { @@ -68,20 +61,21 @@ abstract class CustomListFragment<T : CustomListAdapter<*>> : PageFragment<T>(), override fun onScroll(absListView: AbsListView, i: Int, i2: Int, i3: Int) {} - // ------------------------ OVERRIDE METHODS ------------------------ - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View { - val page = inflater.inflate(R.layout.fragment_list, container, false) - val listView = getListView(page) + return inflater.inflate(R.layout.fragment_list, container, false) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val listView = getListView(view!!) listView.setAdapter(adapter) listView.setOnScrollListener(this) listView.setOnRefreshListener(this) listView.mode = refreshMode - return page } protected open fun getListView(page: View): PullToRefreshListView { - return page.findViewById(R.id.fragment_list_listview) as PullToRefreshListView + return page.fragment_list_listview } protected fun updateListViewWithNotice(absListView: AbsListView, addedToTop: Boolean) { diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt index 70cae02f..20643aa5 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HistoryFragment.kt @@ -30,10 +30,10 @@ import net.lacolaco.smileessence.World import net.lacolaco.smileessence.view.adapter.EventListAdapter class HistoryFragment : CustomListFragment<EventListAdapter>() { + override val adapter by lazy { EventListAdapter(world, activity) } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - adapter = EventListAdapter(world, activity) world.addEventNotifier(this) { adapter.update() } // XXX } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt index a9bd8fe4..505efd22 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/HomeFragment.kt @@ -38,12 +38,10 @@ import net.lacolaco.smileessence.util.UIHandler import net.lacolaco.smileessence.view.adapter.TimelineAdapter class HomeFragment : CustomListFragment<TimelineAdapter>() { - override val refreshMode: PullToRefreshBase.Mode - get() = PullToRefreshBase.Mode.BOTH + override val adapter by lazy { TimelineAdapter(activity, world) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adapter = TimelineAdapter(activity) world.addTimeline(this) { tweet -> adapter.add(tweet) @@ -57,7 +55,8 @@ class HomeFragment : CustomListFragment<TimelineAdapter>() { runRefreshTask(Timelines.HomeTimelineTask(world.account), { adapter.updateForce() }) } - // --------------------- Interface OnRefreshListener2 --------------------- + override val refreshMode: PullToRefreshBase.Mode + get() = PullToRefreshBase.Mode.BOTH override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) { if (world.isStreaming) { @@ -66,31 +65,25 @@ class HomeFragment : CustomListFragment<TimelineAdapter>() { refreshView.onRefreshComplete() } } else { - runRefreshTask( - Timelines.HomeTimelineTask(world.account) - .setSinceId(adapter.topID), - { - updateListViewWithNotice(refreshView.refreshableView, true) - refreshView.onRefreshComplete() - }) + runRefreshTask(Timelines.HomeTimelineTask(world.account).setSinceId(adapter.topID)) { + updateListViewWithNotice(refreshView.refreshableView, true) + refreshView.onRefreshComplete() + } } } override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) { - runRefreshTask( - Timelines.HomeTimelineTask(world.account) - .setMaxId(adapter.lastID - 1), - { - updateListViewWithNotice(refreshView.refreshableView, false) - refreshView.onRefreshComplete() - }) + runRefreshTask(Timelines.HomeTimelineTask(world.account).setMaxId(adapter.lastID - 1)) { + updateListViewWithNotice(refreshView.refreshableView, false) + refreshView.onRefreshComplete() + } } private fun runRefreshTask(task: TimelineTask<Tweet>, onFinish: () -> Unit) { task .setCount(200) .onFail { e -> world.notifyError(R.string.notice_error_get_home) } - .onDoneUI { tweets -> world.addTweetAll(tweets) } + .onDone { tweets -> world.addTweetAll(tweets) } .onFinishUI(onFinish) .execute() } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt index d8442ac7..7c047a51 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MentionsFragment.kt @@ -37,19 +37,13 @@ import net.lacolaco.smileessence.twitter.task.Timelines import net.lacolaco.smileessence.view.adapter.TimelineAdapter class MentionsFragment : CustomListFragment<TimelineAdapter>() { - override val refreshMode: PullToRefreshBase.Mode - get() = PullToRefreshBase.Mode.BOTH + override val adapter by lazy { TimelineAdapter(activity, world) } - // ------------------------ INTERFACE METHODS ------------------------ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adapter = TimelineAdapter(activity) - - // Prevent calling getWorld() on null - val self = world.account.user - world.addTimeline(this) { tweet -> - if (tweet.mentions.contains(self.screenName)) { + world.addTimeline(this) { tweet -> + if (tweet.mentions.contains(world.account.user.screenName)) { adapter.add(tweet) adapter.update() } else { @@ -69,26 +63,21 @@ class MentionsFragment : CustomListFragment<TimelineAdapter>() { runRefreshTask(Timelines.MentionsTimelineTask(world.account), { adapter.updateForce() }) } - // --------------------- Interface OnRefreshListener2 --------------------- + override val refreshMode: PullToRefreshBase.Mode + get() = PullToRefreshBase.Mode.BOTH override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) { - runRefreshTask( - Timelines.MentionsTimelineTask(world.account) - .setSinceId(adapter.topID), - { - updateListViewWithNotice(refreshView.refreshableView, true) - refreshView.onRefreshComplete() - }) + runRefreshTask(Timelines.MentionsTimelineTask(world.account).setSinceId(adapter.topID)) { + updateListViewWithNotice(refreshView.refreshableView, true) + refreshView.onRefreshComplete() + } } override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) { - runRefreshTask( - Timelines.MentionsTimelineTask(world.account) - .setMaxId(adapter.lastID - 1), - { - updateListViewWithNotice(refreshView.refreshableView, false) - refreshView.onRefreshComplete() - }) + runRefreshTask(Timelines.MentionsTimelineTask(world.account).setMaxId(adapter.lastID - 1)) { + updateListViewWithNotice(refreshView.refreshableView, false) + refreshView.onRefreshComplete() + } } private fun runRefreshTask(task: TimelineTask<Tweet>, onFinish: () -> Unit) { diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt index ea756d09..89ac7853 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/MessagesFragment.kt @@ -27,7 +27,6 @@ package net.lacolaco.smileessence.view.page import android.os.Bundle import android.widget.ListView import com.handmark.pulltorefresh.library.PullToRefreshBase -import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.R import net.lacolaco.smileessence.entity.DirectMessage import net.lacolaco.smileessence.twitter.task.Messages @@ -35,12 +34,10 @@ import net.lacolaco.smileessence.twitter.task.TimelineTask import net.lacolaco.smileessence.view.adapter.MessageListAdapter class MessagesFragment : CustomListFragment<MessageListAdapter>() { - override val refreshMode: PullToRefreshBase.Mode - get() = PullToRefreshBase.Mode.BOTH + override val adapter by lazy { MessageListAdapter(activity, world) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adapter = MessageListAdapter(activity) world.addDirectMessageTimeline(this) { message -> adapter.add(message) @@ -51,39 +48,32 @@ class MessagesFragment : CustomListFragment<MessageListAdapter>() { } override fun refresh() { - runRefreshTask(Messages.GetAllReceived(world.account), { adapter.updateForce() }) - runRefreshTask(Messages.GetAllSent(world.account), { adapter.updateForce() }) + runRefreshTask(Messages.GetAllReceived(world.account)) { adapter.updateForce() } + runRefreshTask(Messages.GetAllSent(world.account)) { adapter.updateForce() } } + override val refreshMode: PullToRefreshBase.Mode + get() = PullToRefreshBase.Mode.BOTH + override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) { - runRefreshTask( - Messages.GetAllReceived(world.account) - .setSinceId(adapter.topID), - { - updateListViewWithNotice(refreshView.refreshableView, true) - refreshView.onRefreshComplete() - }) // TODO: sent? + runRefreshTask(Messages.GetAllReceived(world.account).setSinceId(adapter.topID)) { + updateListViewWithNotice(refreshView.refreshableView, true) + refreshView.onRefreshComplete() + } } override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) { - runRefreshTask( - Messages.GetAllReceived(world.account) - .setMaxId(adapter.lastID - 1), - { - updateListViewWithNotice(refreshView.refreshableView, false) - refreshView.onRefreshComplete() - }) // TODO: sent? + runRefreshTask(Messages.GetAllReceived(world.account).setMaxId(adapter.lastID - 1)) { + updateListViewWithNotice(refreshView.refreshableView, false) + refreshView.onRefreshComplete() + } } private fun runRefreshTask(task: TimelineTask<DirectMessage>, onFinish: () -> Unit) { task .setCount(200) .onFail { x -> world.notifyError(R.string.notice_error_get_messages) } - .onDoneUI { messages -> - for (message in messages) { - world.addDirectMessage(message) - } - } + .onDone { messages -> world.addDirectMessage(messages) } .onFinishUI(onFinish) .execute() } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt index 596f4107..b3814d05 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PageFragment.kt @@ -7,13 +7,8 @@ import net.lacolaco.smileessence.Application import net.lacolaco.smileessence.World import net.lacolaco.smileessence.activity.MainActivity -abstract class PageFragment<T : Adapter> : Fragment() { - private var _adapter: T? = null - protected var adapter: T - get() = _adapter ?: throw IllegalStateException("adapter is not initialized") - set(value) { _adapter = value } - - protected val world: World by lazy { +abstract class PageFragment : Fragment() { + protected val world by lazy { Application.getWorld(arguments.getLong(KEY_USER_ID)) } 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 index 8afeadd1..a6af4881 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/PostFragment.kt @@ -36,11 +36,10 @@ import android.text.method.ArrowKeyMovementMethod import android.view.* import android.widget.* import com.twitter.Validator +import kotlinx.android.synthetic.main.fragment_post.* 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 @@ -52,17 +51,7 @@ 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 --------------------- - +class PostFragment : PageFragment(), TextWatcher, View.OnFocusChangeListener, View.OnClickListener, PostState.OnPostStateChangeListener { override fun onClick(v: View) { when (v.id) { R.id.button_post_delete -> { @@ -86,13 +75,15 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang } } + override fun refresh() { } + // --------------------- Interface OnFocusChangeListener --------------------- override fun onFocusChange(v: View, hasFocus: Boolean) { if (hasFocus) { - SystemServiceHelper.showIM(activity, editText) + SystemServiceHelper.showIM(activity, post_edit_text) } else { - SystemServiceHelper.hideIM(activity, editText) + SystemServiceHelper.hideIM(activity, post_edit_text) } } @@ -102,40 +93,32 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang 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 - } + val start = postState.selectionStart + val end = postState.selectionEnd + post_edit_text.removeTextChangedListener(this) + post_edit_text.setTextKeepState(postState.text) + post_edit_text.addTextChangedListener(this) + updateTextCount(post_edit_text.text) + UIHandler().postAtFrontOfQueue { post_edit_text.setSelection(start, end) } + + if (postState.inReplyTo != null) { + post_inreplyto_parent.visibility = View.VISIBLE + button_post_reply_delete.setOnClickListener(this) + + val tweet = postState.inReplyTo + val header = Partials.getTweetView(tweet!!, world, activity, layout_post_reply_status) + header.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.transparent)) + header.isClickable = false + } else { + post_inreplyto_parent.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 + if (TextUtils.isEmpty(postState.mediaFilePath)) { + post_media_parent.visibility = View.GONE + } else { + post_media_parent.visibility = View.VISIBLE - } - BitmapThumbnailTask(postState.mediaFilePath, imageViewMedia).execute() } + BitmapThumbnailTask(postState.mediaFilePath, image_post_media).execute() } // --------------------- Interface TextWatcher --------------------- @@ -152,11 +135,11 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang if (!TextUtils.isEmpty(world.postState.mediaFilePath)) { remainingCount -= validator.shortUrlLength } - textViewCount!!.text = remainingCount.toString() + post_text_count.text = remainingCount.toString() if (remainingCount == 140 || remainingCount < 0) { - textViewCount!!.setTextColor(ContextCompat.getColor(activity, R.color.red)) + post_text_count.setTextColor(ContextCompat.getColor(activity, R.color.red)) } else { - textViewCount!!.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView) + post_text_count.setTextAppearance(activity, android.R.style.TextAppearance_Widget_TextView) } setStateFromView() } @@ -167,44 +150,36 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) - SystemServiceHelper.showIM(activity, editText) + SystemServiceHelper.showIM(activity, post_edit_text) } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - Logger.debug("onCreateView") setHasOptionsMenu(true) + return inflater.inflate(R.layout.fragment_post, container, false) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) 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) + button_post_tweet.setOnClickListener(this) val textSize = UserPreferenceHelper.instance.textSize - editText!!.addTextChangedListener(this) - editText!!.onFocusChangeListener = this - editText!!.textSize = (textSize + 4).toFloat() - editText!!.movementMethod = object : ArrowKeyMovementMethod() { + post_edit_text.addTextChangedListener(this) + post_edit_text.onFocusChangeListener = this + post_edit_text.textSize = (textSize + 4).toFloat() + post_edit_text.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) + button_post_delete.setOnClickListener(this) + button_post_media.setOnClickListener(this) //Reply view - viewGroupReply = getReplyViewGroup(v) - val imageButtonDeleteReply = viewGroupReply!!.findViewById(R.id.button_post_reply_delete) as ImageButton - imageButtonDeleteReply.setOnClickListener(this) + button_post_reply_delete.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 + image_post_media.setOnClickListener(this) + button_post_media_delete.setOnClickListener(this) + post_edit_text.requestFocus() } override fun onDestroyView() { @@ -222,13 +197,13 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang } private fun deletePost() { - editText!!.setText("") + post_edit_text.setText("") world.postState.beginTransaction().setText("").setCursor(0).commit() deleteReply() } private fun deleteReply() { - viewGroupReply!!.visibility = View.GONE + post_inreplyto_parent.visibility = View.GONE world.postState.beginTransaction().setInReplyTo(null).commit() } @@ -240,36 +215,16 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang 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) + SystemServiceHelper.hideIM(activity, post_edit_text) + post_media_parent.visibility = View.GONE + image_post_media.setImageBitmap(null) world.postState.beginTransaction().setMediaFilePath("").commit() } private fun setImage() { setStateFromView() - SystemServiceHelper.hideIM(activity, editText) + SystemServiceHelper.hideIM(activity, post_edit_text) val intent = Intent(Intent.ACTION_PICK) intent.type = "image/*" @@ -280,14 +235,14 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang val state = world.postState state.removeListener() state.beginTransaction() - .setText(editText!!.text.toString()) - .setSelection(editText!!.selectionStart, editText!!.selectionEnd) + .setText(post_edit_text.text.toString()) + .setSelection(post_edit_text.selectionStart, post_edit_text.selectionEnd) .commit() state.setListener(this) } private fun submitPost() { - SystemServiceHelper.hideIM(activity, editText) + SystemServiceHelper.hideIM(activity, post_edit_text) setStateFromView() val state = world.postState val mainActivity = activity as MainActivity @@ -301,4 +256,4 @@ class PostFragment : PageFragment<BaseAdapter>(), TextWatcher, View.OnFocusChang .execute() mainActivity.openHomePage() } -} +}
\ No newline at end of file diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt index de06a133..d24a562c 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/SearchFragment.kt @@ -34,15 +34,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo -import android.widget.EditText -import android.widget.ImageButton import android.widget.ListView import android.widget.TextView import com.handmark.pulltorefresh.library.PullToRefreshBase import com.handmark.pulltorefresh.library.PullToRefreshListView +import kotlinx.android.synthetic.main.fragment_search.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.activity.MainActivity -import net.lacolaco.smileessence.preference.InternalPreferenceHelper +import net.lacolaco.smileessence.preference.UserPreferenceHelper import net.lacolaco.smileessence.twitter.task.Searches import net.lacolaco.smileessence.util.SystemServiceHelper import net.lacolaco.smileessence.util.UIHandler @@ -53,27 +52,13 @@ import twitter4j.Query import java.util.ArrayList class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListener, View.OnLongClickListener, View.OnFocusChangeListener { - - // ------------------------------ FIELDS ------------------------------ - + override val adapter by lazy { TimelineAdapter(activity, world) } private lateinit var queryString: String - private var editText: EditText? = null - - // --------------------- GETTER / SETTER METHODS --------------------- - - override val refreshMode: PullToRefreshBase.Mode - get() = PullToRefreshBase.Mode.BOTH - - // ------------------------ INTERFACE METHODS ------------------------ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - - queryString = InternalPreferenceHelper.instance.get(R.string.key_last_used_search_query, "") - adapter = TimelineAdapter(activity) - - refresh() + queryString = UserPreferenceHelper.instance.get(R.string.key_last_used_search_query, "") } override fun refresh() { //TODO @@ -82,8 +67,6 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen } } - // --------------------- Interface OnClickListener --------------------- - override fun onClick(v: View) { when (v.id) { R.id.button_search_queries -> { @@ -101,7 +84,7 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen override fun onLongClick(v: View): Boolean { when (v.id) { R.id.button_search_save -> { - val text = editText!!.text.toString() + val text = edittext_search.text.toString() for (ss in world.savedSearches.values) { if (ss.query == text) { ConfirmDialogFragment.show(activity, getString(R.string.dialog_confirm_delete_query), { @@ -122,15 +105,13 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen return false } - // --------------------- Interface OnFocusChangeListener --------------------- - override fun onFocusChange(v: View, hasFocus: Boolean) { if (!hasFocus) { - SystemServiceHelper.hideIM(activity, editText) + SystemServiceHelper.hideIM(activity, edittext_search) } } - - // --------------------- Interface OnRefreshListener2 --------------------- + override val refreshMode: PullToRefreshBase.Mode + get() = PullToRefreshBase.Mode.BOTH override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) { if (TextUtils.isEmpty(queryString)) { @@ -147,10 +128,10 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen if (adapter.count > 0) { query.sinceId = adapter.topID } - runRefreshTask(query, { + runRefreshTask(query) { updateListViewWithNotice(refreshView.refreshableView, true) refreshView.onRefreshComplete() - }) + } } override fun onPullUpToRefresh(refreshView: PullToRefreshBase<ListView>) { @@ -168,35 +149,33 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen if (adapter.count > 0) { query.maxId = adapter.lastID - 1 } - runRefreshTask(query, { + runRefreshTask(query) { updateListViewWithNotice(refreshView.refreshableView, false) refreshView.onRefreshComplete() - }) + } } - // ------------------------ OVERRIDE METHODS ------------------------ - override fun getListView(page: View): PullToRefreshListView { - return page.findViewById(R.id.listview_search) as PullToRefreshListView + return listview_search } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View { - val page = inflater.inflate(R.layout.fragment_search, container, false) - val listView = getListView(page) - listView.setAdapter(adapter) - listView.setOnScrollListener(this) - listView.setOnRefreshListener(this) - listView.mode = refreshMode - val buttonQueries = getQueriesButton(page) - buttonQueries.setOnClickListener(this) - val buttonExecute = getExecuteButton(page) - buttonExecute.setOnClickListener(this) - val buttonSave = getSaveButton(page) - buttonSave.setOnClickListener(this) - editText = getEditText(page) - editText!!.onFocusChangeListener = this - editText!!.setText(queryString) - editText!!.setOnEditorActionListener { textView, i, keyEvent -> + super.onCreateView(inflater, container, savedInstanceState) + return inflater.inflate(R.layout.fragment_search, container, false) + } + + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + listview_search.setAdapter(adapter) + listview_search.setOnScrollListener(this) + listview_search.setOnRefreshListener(this) + listview_search.mode = refreshMode + button_search_queries.setOnClickListener(this) + button_search_execute.setOnClickListener(this) + button_search_save.setOnClickListener(this) + edittext_search.onFocusChangeListener = this + edittext_search.setText(queryString) + edittext_search.setOnEditorActionListener { textView, i, keyEvent -> if (i == EditorInfo.IME_ACTION_SEARCH || keyEvent != null && keyEvent.action == KeyEvent.ACTION_DOWN && keyEvent.keyCode == KeyEvent.KEYCODE_ENTER) { @@ -204,7 +183,7 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen } true } - editText!!.movementMethod = object : ArrowKeyMovementMethod() { + edittext_search.movementMethod = object : ArrowKeyMovementMethod() { override fun right(widget: TextView, buffer: Spannable): Boolean { //Don't move page return widget.selectionEnd == widget.length() || super.right(widget, buffer) @@ -215,23 +194,8 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen return widget.selectionStart == 0 || super.left(widget, buffer) } } - return page - } - - private fun getEditText(page: View): EditText { - return page.findViewById(R.id.edittext_search) as EditText - } - - private fun getExecuteButton(page: View): ImageButton { - return page.findViewById(R.id.button_search_execute) as ImageButton - } - private fun getQueriesButton(page: View): ImageButton { - return page.findViewById(R.id.button_search_queries) as ImageButton - } - - private fun getSaveButton(page: View): ImageButton { - return page.findViewById(R.id.button_search_save) as ImageButton + refresh() } private fun notifyTextEmpty() { @@ -250,7 +214,7 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen } private fun saveQuery() { - val text = editText!!.text.toString() + val text = edittext_search.text.toString() if (TextUtils.isEmpty(text)) { world.notifyError(R.string.notice_query_is_empty) } else { @@ -262,21 +226,19 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen } private fun search() { - if (editText != null) { - val text = editText!!.text.toString() - if (TextUtils.isEmpty(text)) { - world.notifyError(R.string.notice_query_is_empty) - } else { - startSearch(text) - SystemServiceHelper.hideIM(activity, editText) - } + val text = edittext_search.text.toString() + if (TextUtils.isEmpty(text)) { + world.notifyError(R.string.notice_query_is_empty) + } else { + startSearch(text) + SystemServiceHelper.hideIM(activity, edittext_search) } + } fun startSearch(queryString: String) { - InternalPreferenceHelper.instance.set(R.string.key_last_used_search_query, queryString) - if (editText != null) - editText!!.setText(queryString) + UserPreferenceHelper.instance.set(R.string.key_last_used_search_query, queryString) + edittext_search.setText(queryString) this.queryString = queryString adapter.clear() adapter.updateForce() @@ -292,7 +254,7 @@ class SearchFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListen private fun runRefreshTask(query: Query, onFinish: () -> Unit) { Searches.SearchTask(world.account, query) .onFail { x -> world.notifyError(R.string.notice_error_search) } - .onDoneUI { tweets -> adapter.addAll(tweets.filter { t -> !t.isRetweet }) } + .onDone { tweets -> adapter.addAll(tweets.filter { t -> !t.isRetweet }) } .onFinishUI(onFinish) .execute() } diff --git a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt index 3fb7ef49..abcdb01d 100644 --- a/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt +++ b/app/src/main/java/net/lacolaco/smileessence/view/page/UserListFragment.kt @@ -30,37 +30,31 @@ import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.ImageButton import android.widget.ListView -import android.widget.TextView import com.handmark.pulltorefresh.library.PullToRefreshBase import com.handmark.pulltorefresh.library.PullToRefreshListView -import net.lacolaco.smileessence.Application +import kotlinx.android.synthetic.main.fragment_userlist.* import net.lacolaco.smileessence.R import net.lacolaco.smileessence.activity.MainActivity import net.lacolaco.smileessence.entity.Tweet -import net.lacolaco.smileessence.preference.InternalPreferenceHelper +import net.lacolaco.smileessence.preference.UserPreferenceHelper import net.lacolaco.smileessence.twitter.task.TimelineTask import net.lacolaco.smileessence.twitter.task.Timelines import net.lacolaco.smileessence.util.UIHandler import net.lacolaco.smileessence.view.adapter.TimelineAdapter class UserListFragment : CustomListFragment<TimelineAdapter>(), View.OnClickListener { - private var textListName: TextView? = null + override val adapter by lazy { TimelineAdapter(activity, world) } private var listFullName: String? = null - override val refreshMode: PullToRefreshBase.Mode - get() = PullToRefreshBase.Mode.BOTH - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - adapter = TimelineAdapter(activity) refresh() } override fun refresh() {//TODO - val lastUserList = InternalPreferenceHelper.instance.get(R.string.key_last_used_user_list, "") + val lastUserList = UserPreferenceHelper.instance.get(R.string.key_last_used_user_list, "") if (!TextUtils.isEmpty(lastUserList)) { startUserList(lastUserList) } @@ -75,6 +69,9 @@ class UserListFragment : CustomListFragment<TimelineAdapter>(), View.OnClickList } } + override val refreshMode: PullToRefreshBase.Mode + get() = PullToRefreshBase.Mode.BOTH + override fun onPullDownToRefresh(refreshView: PullToRefreshBase<ListView>) { if (listFullName == null) { UIHandler().post { @@ -112,30 +109,17 @@ class UserListFragment : CustomListFragment<TimelineAdapter>(), View.OnClickList // ------------------------ OVERRIDE METHODS ------------------------ override fun getListView(page: View): PullToRefreshListView { - return page.findViewById(R.id.listview_userlist) as PullToRefreshListView + return listview_userlist } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View { - val page = inflater.inflate(R.layout.fragment_userlist, container, false) - val listView = getListView(page) - val adapter = adapter - listView.setAdapter(adapter) - listView.setOnScrollListener(this) - listView.setOnRefreshListener(this) - listView.mode = refreshMode - val buttonUserLists = getUserListsButton(page) - buttonUserLists.setOnClickListener(this) - textListName = getTextListName(page) - textListName!!.text = if (listFullName != null) listFullName else "<none>" - return page - } - - private fun getTextListName(page: View): TextView { - return page.findViewById(R.id.textview_userlist_name) as TextView + return inflater.inflate(R.layout.fragment_userlist, container, false) } - private fun getUserListsButton(page: View): ImageButton { - return page.findViewById(R.id.button_userlist_lists) as ImageButton + override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + button_userlist_lists.setOnClickListener(this) + textview_userlist_name.text = if (listFullName != null) listFullName else "<none>" } private fun notifyTextEmpty() { @@ -149,14 +133,14 @@ class UserListFragment : CustomListFragment<TimelineAdapter>(), View.OnClickList .setItems(ary) { dialog, which -> val activity = activity as MainActivity activity.openUserListPage(ary[which]) - textListName!!.text = ary[which] + textview_userlist_name.text = ary[which] } val dialog = builder.create() dialog.show() } fun startUserList(listFullName: String) { - InternalPreferenceHelper.instance.set(R.string.key_last_used_user_list, listFullName) + UserPreferenceHelper.instance.set(R.string.key_last_used_user_list, listFullName) val adapter = adapter this.listFullName = listFullName adapter.clear() diff --git a/app/src/main/res/layout/dialog_user_detail.xml b/app/src/main/res/layout/dialog_user_detail.xml index 0fb8c7b0..b3474288 100644 --- a/app/src/main/res/layout/dialog_user_detail.xml +++ b/app/src/main/res/layout/dialog_user_detail.xml @@ -27,7 +27,7 @@ <TabHost xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@android:id/tabhost" + android:id="@+id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> |