code cleanup

This commit is contained in:
Mariotaku Lee 2016-12-16 23:21:50 +08:00
parent 940f366fcb
commit dbb61b7032
6 changed files with 22 additions and 257 deletions

View File

@ -41,7 +41,7 @@ android {
buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("true")' buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("true")'
buildConfigField 'boolean', 'SHOW_CUSTOM_TOKEN_DIALOG', 'Boolean.parseBoolean("false")' buildConfigField 'boolean', 'SHOW_CUSTOM_TOKEN_DIALOG', 'Boolean.parseBoolean("false")'
buildConfigField 'boolean', 'HOTMOBI_LOG_ENABLED', 'Boolean.parseBoolean("true")' buildConfigField 'boolean', 'HOTMOBI_LOG_ENABLED', 'Boolean.parseBoolean("false")'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }

View File

@ -1,103 +0,0 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package edu.tsinghua.hotmobi.model;
import android.support.annotation.NonNull;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.mariotaku.twidere.model.UserKey;
/**
* Created by mariotaku on 15/8/8.
*/
@JsonObject
public class ScrollRecord implements LogModel {
@JsonField(name = "id")
String id;
@JsonField(name = "account_id")
String accountId;
@JsonField(name = "account_host")
String accountHost;
@JsonField(name = "timestamp")
long timestamp;
@JsonField(name = "time_offset")
long timeOffset;
@JsonField(name = "scroll_state")
int scrollState;
public static ScrollRecord create(String id, UserKey accountKey, long timestamp, long timeOffset, int scrollState) {
final ScrollRecord record = new ScrollRecord();
record.setId(id);
record.setAccountId(accountKey.getId());
record.setAccountHost(accountKey.getHost());
record.setTimestamp(timestamp);
record.setTimeOffset(timeOffset);
record.setScrollState(scrollState);
return record;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public void setAccountHost(String accountHost) {
this.accountHost = accountHost;
}
public void setTimeOffset(long timeOffset) {
this.timeOffset = timeOffset;
}
public void setId(String id) {
this.id = id;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public void setScrollState(int scrollState) {
this.scrollState = scrollState;
}
@Override
public String toString() {
return "ScrollRecord{" +
"id=" + id +
", mAccountKey=" + accountId +
", timestamp=" + timestamp +
", timeOffset=" + timeOffset +
", scrollState=" + scrollState +
'}';
}
@NonNull
@Override
public String getLogFileName() {
return "scroll";
}
@Override
public boolean isEnabled() {
return false;
}
}

View File

@ -58,6 +58,9 @@ class AccountSelectorActivity : BaseActivity(), OnClickListener, OnItemClickList
return intent.getBooleanExtra(EXTRA_OAUTH_ONLY, false) return intent.getBooleanExtra(EXTRA_OAUTH_ONLY, false)
} }
/**
* If not null, account selector will only show accounts matched this host.
*/
private val accountHost: String? private val accountHost: String?
get() { get() {
return intent.getStringExtra(EXTRA_ACCOUNT_HOST) return intent.getStringExtra(EXTRA_ACCOUNT_HOST)
@ -73,6 +76,9 @@ class AccountSelectorActivity : BaseActivity(), OnClickListener, OnItemClickList
return intent.getBooleanExtra(EXTRA_SINGLE_SELECTION, false) return intent.getBooleanExtra(EXTRA_SINGLE_SELECTION, false)
} }
/**
* True if you want account picked automatically if there are only one match.
*/
private val isSelectOnlyItemAutomatically: Boolean private val isSelectOnlyItemAutomatically: Boolean
get() = intent.getBooleanExtra(EXTRA_SELECT_ONLY_ITEM_AUTOMATICALLY, false) get() = intent.getBooleanExtra(EXTRA_SELECT_ONLY_ITEM_AUTOMATICALLY, false)

View File

@ -34,10 +34,8 @@ import android.view.*
import com.squareup.otto.Subscribe import com.squareup.otto.Subscribe
import edu.tsinghua.hotmobi.HotMobiLogger import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaEvent import edu.tsinghua.hotmobi.model.MediaEvent
import edu.tsinghua.hotmobi.model.ScrollRecord
import kotlinx.android.synthetic.main.fragment_content_recyclerview.* import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.kpreferences.get
import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants.* import org.mariotaku.twidere.Constants.*
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
@ -52,6 +50,7 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.annotation.ReadPositionTag import org.mariotaku.twidere.annotation.ReadPositionTag
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.constant.KeyboardShortcutConstants.* import org.mariotaku.twidere.constant.KeyboardShortcutConstants.*
import org.mariotaku.twidere.constant.readFromBottomKey
import org.mariotaku.twidere.fragment.AbsStatusesFragment.DefaultOnLikedListener import org.mariotaku.twidere.fragment.AbsStatusesFragment.DefaultOnLikedListener
import org.mariotaku.twidere.loader.iface.IExtendedLoader import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.* import org.mariotaku.twidere.model.*
@ -73,50 +72,7 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
private lateinit var activitiesBusCallback: Any private lateinit var activitiesBusCallback: Any
private lateinit var navigationHelper: RecyclerViewNavigationHelper private lateinit var navigationHelper: RecyclerViewNavigationHelper
private var pauseOnScrollListener: OnScrollListener? = null private lateinit var pauseOnScrollListener: OnScrollListener
private var activeHotMobiScrollTracker: OnScrollListener? = null
private val hotMobiScrollTracker = object : OnScrollListener() {
var records: MutableList<ScrollRecord>? = null
private var firstVisibleTimestamp: Long = -1
private var firstVisibleAccountId: UserKey? = null
private var firstVisiblePosition = -1
private var scrollState: Int = 0
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
val layoutManager = recyclerView!!.layoutManager as LinearLayoutManager
val pos = layoutManager.findFirstVisibleItemPosition()
if (pos != firstVisiblePosition && pos >= 0) {
//noinspection unchecked
val adapter = recyclerView.adapter as ParcelableActivitiesAdapter
val activity = adapter.getActivity(pos)
if (activity != null) {
val timestamp = activity.timestamp
val accountKey = activity.account_key
if (timestamp != firstVisibleTimestamp || accountKey != firstVisibleAccountId) {
if (records == null) records = ArrayList<ScrollRecord>()
val time = System.currentTimeMillis()
records!!.add(ScrollRecord.create(timestamp.toString(), accountKey, time,
TimeZone.getDefault().getOffset(time).toLong(), scrollState))
}
firstVisibleTimestamp = timestamp
firstVisibleAccountId = accountKey
}
}
firstVisiblePosition = pos
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
scrollState = newState
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (records != null) {
HotMobiLogger.getInstance(activity).logList(records, null, "scroll")
}
records = null
}
}
}
private val onScrollListener = object : OnScrollListener() { private val onScrollListener = object : OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
@ -131,8 +87,7 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
activitiesBusCallback = createMessageBusCallback() activitiesBusCallback = createMessageBusCallback()
scrollListener!!.reversed = preferences.getBoolean(KEY_READ_FROM_BOTTOM) scrollListener.reversed = preferences[readFromBottomKey]
val layoutManager = layoutManager
adapter.setListener(this) adapter.setListener(this)
registerForContextMenu(recyclerView) registerForContextMenu(recyclerView)
navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter, navigationHelper = RecyclerViewNavigationHelper(recyclerView, layoutManager, adapter,
@ -153,13 +108,11 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
triggerRefresh() triggerRefresh()
return true return true
} }
val layoutManager = layoutManager
if (recyclerView == null || layoutManager == null) return false
val focusedChild = RecyclerViewUtils.findRecyclerViewChild(recyclerView, val focusedChild = RecyclerViewUtils.findRecyclerViewChild(recyclerView,
layoutManager.focusedChild) layoutManager.focusedChild)
var position = RecyclerView.NO_POSITION var position = RecyclerView.NO_POSITION
if (focusedChild != null && focusedChild.parent === recyclerView) { if (focusedChild != null && focusedChild.parent === recyclerView) {
position = recyclerView!!.getChildLayoutPosition(focusedChild) position = recyclerView.getChildLayoutPosition(focusedChild)
} }
if (position != RecyclerView.NO_POSITION) { if (position != RecyclerView.NO_POSITION) {
val activity = adapter.getActivity(position) ?: return false val activity = adapter.getActivity(position) ?: return false
@ -394,34 +347,11 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
super.onStart() super.onStart()
recyclerView.addOnScrollListener(onScrollListener) recyclerView.addOnScrollListener(onScrollListener)
recyclerView.addOnScrollListener(pauseOnScrollListener) recyclerView.addOnScrollListener(pauseOnScrollListener)
val task = object : AbstractTask<Any?, Boolean, RecyclerView>() {
public override fun doLongOperation(params: Any?): Boolean {
val context = context ?: return false
val prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE)
if (!prefs.getBoolean(KEY_USAGE_STATISTICS, false)) return false
val logFile = HotMobiLogger.getLogFile(context, null, "scroll")
return logFile.length() < 131072
}
public override fun afterExecute(recyclerView: RecyclerView?, result: Boolean?) {
if (result!!) {
activeHotMobiScrollTracker = hotMobiScrollTracker
recyclerView!!.addOnScrollListener(activeHotMobiScrollTracker)
}
}
}
task.callback = recyclerView
TaskStarter.execute(task)
bus.register(activitiesBusCallback) bus.register(activitiesBusCallback)
} }
override fun onStop() { override fun onStop() {
bus.unregister(activitiesBusCallback) bus.unregister(activitiesBusCallback)
if (activeHotMobiScrollTracker != null) {
recyclerView.removeOnScrollListener(activeHotMobiScrollTracker)
}
activeHotMobiScrollTracker = null
recyclerView.removeOnScrollListener(pauseOnScrollListener) recyclerView.removeOnScrollListener(pauseOnScrollListener)
recyclerView.removeOnScrollListener(onScrollListener) recyclerView.removeOnScrollListener(onScrollListener)
if (userVisibleHint) { if (userVisibleHint) {
@ -513,14 +443,13 @@ abstract class AbsActivitiesFragment protected constructor() : AbsContentListRec
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) { override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) {
if (!userVisibleHint || menuInfo == null) return if (!userVisibleHint || menuInfo == null) return
val inflater = MenuInflater(context) val inflater = MenuInflater(context)
val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo? val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo
val position = contextMenuInfo!!.position val position = contextMenuInfo.position
when (adapter.getItemViewType(position)) { when (adapter.getItemViewType(position)) {
ITEM_VIEW_TYPE_STATUS -> { ITEM_VIEW_TYPE_STATUS -> {
val status = getActivityStatus(position) ?: return val status = getActivityStatus(position) ?: return
inflater.inflate(R.menu.action_status, menu) inflater.inflate(R.menu.action_status, menu)
MenuUtils.setupForStatus(context, preferences, menu, status, MenuUtils.setupForStatus(context, preferences, menu, status, twitterWrapper)
twitterWrapper)
} }
} }
} }

View File

@ -43,8 +43,10 @@ import org.mariotaku.twidere.view.iface.IExtendedView
/** /**
* Created by mariotaku on 15/10/26. * Created by mariotaku on 15/10/26.
*/ */
abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>, L : RecyclerView.LayoutManager> : BaseSupportFragment(), SwipeRefreshLayout.OnRefreshListener, HeaderDrawerLayout.DrawerCallback, RefreshScrollTopInterface, IControlBarActivity.ControlBarOffsetListener, ContentScrollHandler.ContentListSupport, ControlBarShowHideHelper.ControlBarAnimationListener { abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>,
L : RecyclerView.LayoutManager> : BaseSupportFragment(), SwipeRefreshLayout.OnRefreshListener,
HeaderDrawerLayout.DrawerCallback, RefreshScrollTopInterface, IControlBarActivity.ControlBarOffsetListener,
ContentScrollHandler.ContentListSupport, ControlBarShowHideHelper.ControlBarAnimationListener {
lateinit var layoutManager: L lateinit var layoutManager: L
protected set protected set
@ -55,7 +57,7 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
// Callbacks and listeners // Callbacks and listeners
private lateinit var drawerCallback: SimpleDrawerCallback private lateinit var drawerCallback: SimpleDrawerCallback
var scrollListener: RecyclerViewScrollHandler? = null lateinit var scrollListener: RecyclerViewScrollHandler
// Data fields // Data fields
private val systemWindowsInsets = Rect() private val systemWindowsInsets = Rect()
@ -201,8 +203,8 @@ abstract class AbsContentRecyclerViewFragment<A : LoadMoreSupportAdapter<Recycle
recyclerView.adapter = adapter recyclerView.adapter = adapter
scrollListener = RecyclerViewScrollHandler(this, RecyclerViewScrollHandler.RecyclerViewCallback(recyclerView)) scrollListener = RecyclerViewScrollHandler(this, RecyclerViewScrollHandler.RecyclerViewCallback(recyclerView))
scrollListener!!.touchSlop = ViewConfiguration.get(context).scaledTouchSlop scrollListener.touchSlop = ViewConfiguration.get(context).scaledTouchSlop
recyclerView.setOnTouchListener(scrollListener!!.touchListener) recyclerView.setOnTouchListener(scrollListener.touchListener)
} }
protected open fun setupRecyclerView(context: Context, recyclerView: RecyclerView) { protected open fun setupRecyclerView(context: Context, recyclerView: RecyclerView) {

View File

@ -29,19 +29,14 @@ import android.support.v4.content.Loader
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.OnScrollListener import android.support.v7.widget.RecyclerView.OnScrollListener
import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.* import android.view.*
import com.squareup.otto.Subscribe import com.squareup.otto.Subscribe
import edu.tsinghua.hotmobi.HotMobiLogger import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.MediaEvent import edu.tsinghua.hotmobi.model.MediaEvent
import edu.tsinghua.hotmobi.model.ScrollRecord
import kotlinx.android.synthetic.main.fragment_content_recyclerview.* import kotlinx.android.synthetic.main.fragment_content_recyclerview.*
import org.mariotaku.abstask.library.AbstractTask
import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants import org.mariotaku.twidere.TwidereConstants
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter
@ -64,7 +59,6 @@ import org.mariotaku.twidere.view.ExtendedRecyclerView
import org.mariotaku.twidere.view.holder.GapViewHolder import org.mariotaku.twidere.view.holder.GapViewHolder
import org.mariotaku.twidere.view.holder.StatusViewHolder import org.mariotaku.twidere.view.holder.StatusViewHolder
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
import java.util.*
/** /**
* Created by mariotaku on 14/11/5. * Created by mariotaku on 14/11/5.
@ -77,50 +71,9 @@ abstract class AbsStatusesFragment protected constructor() :
private lateinit var statusesBusCallback: Any private lateinit var statusesBusCallback: Any
private lateinit var navigationHelper: RecyclerViewNavigationHelper private lateinit var navigationHelper: RecyclerViewNavigationHelper
private var pauseOnScrollListener: OnScrollListener? = null private var pauseOnScrollListener: OnScrollListener? = null
private var activeHotMobiScrollTracker: OnScrollListener? = null
var loaderInitialized: Boolean = false var loaderInitialized: Boolean = false
private set private set
private val hotMobiScrollTracker = object : OnScrollListener() {
var records: MutableList<ScrollRecord>? = null
private var firstVisibleId: String? = null
private var firstVisibleAccountId: UserKey? = null
private var firstVisiblePosition = -1
private var scrollState: Int = 0
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
val layoutManager = recyclerView!!.layoutManager as LinearLayoutManager
val position = layoutManager.findFirstVisibleItemPosition()
if (position != position && position >= 0) {
//noinspection unchecked
val adapter = recyclerView.adapter as ParcelableStatusesAdapter
val status = adapter.getStatus(position)
if (status != null) {
val id = status.id
val accountId = status.account_key
if (!TextUtils.equals(id, firstVisibleId) || accountId != firstVisibleAccountId) {
if (records == null) records = ArrayList<ScrollRecord>()
val time = System.currentTimeMillis()
records!!.add(ScrollRecord.create(id, accountId, time,
TimeZone.getDefault().getOffset(time).toLong(), scrollState))
}
firstVisibleId = id
firstVisibleAccountId = accountId
}
}
firstVisiblePosition = position
}
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
scrollState = newState
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (records != null) {
HotMobiLogger.getInstance(activity).logList(records, null, "scroll")
}
records = null
}
}
}
private val onScrollListener = object : OnScrollListener() { private val onScrollListener = object : OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (newState == RecyclerView.SCROLL_STATE_IDLE) {
@ -184,33 +137,11 @@ abstract class AbsStatusesFragment protected constructor() :
super.onStart() super.onStart()
recyclerView.addOnScrollListener(onScrollListener) recyclerView.addOnScrollListener(onScrollListener)
recyclerView.addOnScrollListener(pauseOnScrollListener) recyclerView.addOnScrollListener(pauseOnScrollListener)
val task = object : AbstractTask<Any?, Boolean, AbsStatusesFragment>() {
public override fun doLongOperation(params: Any?): Boolean {
val context = callback?.context ?: return false
val prefs = callback?.preferences ?: return false
if (!prefs.getBoolean(Constants.KEY_USAGE_STATISTICS, false)) return false
val logFile = HotMobiLogger.getLogFile(context, null, "scroll")
return logFile.length() < 131072
}
public override fun afterExecute(fragment: AbsStatusesFragment?, result: Boolean) {
if (result && fragment != null) {
fragment.activeHotMobiScrollTracker = fragment.hotMobiScrollTracker
fragment.recyclerView.addOnScrollListener(fragment.activeHotMobiScrollTracker)
}
}
}
task.callback = this
TaskStarter.execute(task)
bus.register(statusesBusCallback) bus.register(statusesBusCallback)
} }
override fun onStop() { override fun onStop() {
bus.unregister(statusesBusCallback) bus.unregister(statusesBusCallback)
if (activeHotMobiScrollTracker != null) {
recyclerView.removeOnScrollListener(activeHotMobiScrollTracker)
}
activeHotMobiScrollTracker = null
recyclerView.removeOnScrollListener(pauseOnScrollListener) recyclerView.removeOnScrollListener(pauseOnScrollListener)
recyclerView.removeOnScrollListener(onScrollListener) recyclerView.removeOnScrollListener(onScrollListener)
if (userVisibleHint) { if (userVisibleHint) {