added media searches, close #612
This commit is contained in:
parent
8d6d0ba601
commit
28492d2d12
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 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 org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.app.hasRunningLoadersSafe
|
||||
import android.support.v4.content.Loader
|
||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
||||
import com.bumptech.glide.Glide
|
||||
import org.mariotaku.twidere.adapter.StaggeredGridParcelableStatusesAdapter
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER
|
||||
import org.mariotaku.twidere.extension.reachingEnd
|
||||
import org.mariotaku.twidere.extension.reachingStart
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback
|
||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
abstract class AbsMediaStatusesFragment : AbsContentRecyclerViewFragment<StaggeredGridParcelableStatusesAdapter,
|
||||
StaggeredGridLayoutManager>(), LoaderCallbacks<List<ParcelableStatus>?>, DrawerCallback,
|
||||
IStatusViewHolder.StatusClickListener {
|
||||
|
||||
override final var refreshing: Boolean
|
||||
get() {
|
||||
if (context == null || isDetached) return false
|
||||
return loaderManager.hasRunningLoadersSafe()
|
||||
}
|
||||
set(value) {
|
||||
super.refreshing = value
|
||||
}
|
||||
|
||||
override final val reachingEnd: Boolean
|
||||
get() = layoutManager.reachingEnd
|
||||
|
||||
override final val reachingStart: Boolean
|
||||
get() = layoutManager.reachingStart
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
adapter.statusClickListener = this
|
||||
val loaderArgs = Bundle(arguments)
|
||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
|
||||
loaderManager.initLoader(0, loaderArgs, this)
|
||||
showProgress()
|
||||
}
|
||||
|
||||
override final fun onCreateLayoutManager(context: Context): StaggeredGridLayoutManager {
|
||||
return StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
}
|
||||
|
||||
override final fun scrollToPositionWithOffset(position: Int, offset: Int) {
|
||||
layoutManager.scrollToPositionWithOffset(position, offset)
|
||||
}
|
||||
|
||||
override final fun onCreateAdapter(context: Context): StaggeredGridParcelableStatusesAdapter {
|
||||
return StaggeredGridParcelableStatusesAdapter(context, Glide.with(this))
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableStatus>?> {
|
||||
val fromUser = args.getBoolean(EXTRA_FROM_USER)
|
||||
args.remove(EXTRA_FROM_USER)
|
||||
return onCreateStatusesLoader(activity, args, fromUser)
|
||||
}
|
||||
|
||||
override final fun onLoadFinished(loader: Loader<List<ParcelableStatus>?>, data: List<ParcelableStatus>?) {
|
||||
val changed = adapter.setData(data)
|
||||
if ((loader as IExtendedLoader).fromUser) {
|
||||
adapter.loadMoreSupportedPosition = if (hasMoreData(loader, data, changed)) {
|
||||
ILoadMoreSupportAdapter.END
|
||||
} else {
|
||||
ILoadMoreSupportAdapter.NONE
|
||||
}
|
||||
}
|
||||
loader.fromUser = false
|
||||
refreshing = false
|
||||
showContent()
|
||||
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
|
||||
}
|
||||
|
||||
override final fun onLoaderReset(loader: Loader<List<ParcelableStatus>?>) {
|
||||
adapter.setData(null)
|
||||
}
|
||||
|
||||
override final fun onLoadMoreContents(position: Long) {
|
||||
// Only supports load from end
|
||||
if (ILoadMoreSupportAdapter.END != position) return
|
||||
super.onLoadMoreContents(position)
|
||||
// Get last raw status
|
||||
val startIdx = adapter.statusStartIndex
|
||||
if (startIdx < 0) return
|
||||
val statusCount = adapter.getStatusCount(true)
|
||||
if (statusCount <= 0) return
|
||||
val status = adapter.getStatus(startIdx + statusCount - 1, true)
|
||||
val maxId = status.id
|
||||
getStatuses(maxId, null)
|
||||
}
|
||||
|
||||
override final fun onStatusClick(holder: IStatusViewHolder, position: Int) {
|
||||
val status = adapter.getStatus(position)
|
||||
IntentUtils.openStatus(context, status, null)
|
||||
}
|
||||
|
||||
|
||||
override final fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
|
||||
val status = adapter.getStatus(position)
|
||||
IntentUtils.openStatus(context, status.account_key, status.quoted_id)
|
||||
}
|
||||
|
||||
protected abstract fun onCreateStatusesLoader(context: Context, args: Bundle,
|
||||
fromUser: Boolean): Loader<List<ParcelableStatus>?>
|
||||
|
||||
protected abstract fun hasMoreData(loader: Loader<List<ParcelableStatus>?>,
|
||||
data: List<ParcelableStatus>?, changed: Boolean): Boolean
|
||||
|
||||
protected abstract fun getStatuses(maxId: String?, sinceId: String?): Int
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 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 org.mariotaku.twidere.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.content.Loader
|
||||
import org.mariotaku.twidere.TwidereConstants.*
|
||||
import org.mariotaku.twidere.loader.MediaStatusesSearchLoader
|
||||
import org.mariotaku.twidere.loader.TweetSearchLoader
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.util.Utils
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
class MediaStatusesSearchFragment : AbsMediaStatusesFragment() {
|
||||
|
||||
override fun onCreateStatusesLoader(context: Context, args: Bundle, fromUser: Boolean):
|
||||
Loader<List<ParcelableStatus>?> {
|
||||
refreshing = true
|
||||
val accountKey = Utils.getAccountKey(context, args)
|
||||
val maxId = args.getString(EXTRA_MAX_ID)
|
||||
val sinceId = args.getString(EXTRA_SINCE_ID)
|
||||
val page = args.getInt(EXTRA_PAGE, -1)
|
||||
val query = args.getString(EXTRA_QUERY)
|
||||
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
|
||||
val makeGap = args.getBoolean(EXTRA_MAKE_GAP, true)
|
||||
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
|
||||
return TweetSearchLoader(activity, accountKey, query, sinceId, maxId, page, adapter.getData(),
|
||||
null, tabPosition, fromUser, makeGap, loadingMore)
|
||||
}
|
||||
|
||||
override fun hasMoreData(loader: Loader<List<ParcelableStatus>?>, data: List<ParcelableStatus>?,
|
||||
changed: Boolean): Boolean {
|
||||
if (loader !is MediaStatusesSearchLoader) return false
|
||||
val maxId = loader.maxId?.takeIf(String::isNotEmpty)
|
||||
val sinceId = loader.sinceId?.takeIf(String::isNotEmpty)
|
||||
if (sinceId != null && maxId != null) {
|
||||
if (data != null && !data.isEmpty()) {
|
||||
return changed
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getStatuses(maxId: String?, sinceId: String?): Int {
|
||||
if (context == null) return -1
|
||||
val args = Bundle(arguments)
|
||||
args.putBoolean(EXTRA_MAKE_GAP, false)
|
||||
args.putString(EXTRA_MAX_ID, maxId)
|
||||
args.putString(EXTRA_SINCE_ID, sinceId)
|
||||
args.putBoolean(EXTRA_FROM_USER, true)
|
||||
loaderManager.restartLoader(0, args, this)
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
|
@ -39,6 +39,7 @@ import org.mariotaku.twidere.activity.LinkHandlerActivity
|
|||
import org.mariotaku.twidere.activity.QuickSearchBarActivity
|
||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener
|
||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
||||
import org.mariotaku.twidere.annotation.AccountType
|
||||
import org.mariotaku.twidere.extension.model.getAccountType
|
||||
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
|
||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
||||
|
@ -56,6 +57,18 @@ class SearchFragment : AbsToolbarTabPagesFragment(), RefreshScrollTopInterface,
|
|||
SystemWindowsInsetsCallback, ControlBarOffsetListener, OnPageChangeListener,
|
||||
LinkHandlerActivity.HideUiOnScroll {
|
||||
|
||||
val accountKey: UserKey
|
||||
get() = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
|
||||
val query: String
|
||||
get() = arguments.getString(EXTRA_QUERY)
|
||||
|
||||
private val accountType: String?
|
||||
get() {
|
||||
val am = AccountManager.get(context)
|
||||
return accountKey.let { AccountUtils.findByAccountKey(am, it) }?.getAccountType(am)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
@ -67,10 +80,7 @@ class SearchFragment : AbsToolbarTabPagesFragment(), RefreshScrollTopInterface,
|
|||
val values = ContentValues()
|
||||
values.put(SearchHistory.QUERY, query)
|
||||
context.contentResolver.insert(SearchHistory.CONTENT_URI, values)
|
||||
val am = AccountManager.get(context)
|
||||
Analyzer.log(Search(query, accountKey.let {
|
||||
AccountUtils.findByAccountKey(am, it)
|
||||
}?.getAccountType(am)))
|
||||
Analyzer.log(Search(query, accountType))
|
||||
}
|
||||
|
||||
val activity = this.activity
|
||||
|
@ -144,18 +154,19 @@ class SearchFragment : AbsToolbarTabPagesFragment(), RefreshScrollTopInterface,
|
|||
return false
|
||||
}
|
||||
|
||||
val accountKey: UserKey
|
||||
get() = arguments.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)!!
|
||||
|
||||
val query: String
|
||||
get() = arguments.getString(EXTRA_QUERY)!!
|
||||
|
||||
|
||||
override fun addTabs(adapter: SupportTabsAdapter) {
|
||||
adapter.add(cls = StatusesSearchFragment::class.java, args = arguments,
|
||||
name = getString(R.string.search_type_statuses), icon = DrawableHolder.resource(R.drawable.ic_action_twitter))
|
||||
name = getString(R.string.search_type_statuses),
|
||||
icon = DrawableHolder.resource(R.drawable.ic_action_twitter))
|
||||
if (accountType == AccountType.TWITTER) {
|
||||
adapter.add(cls = MediaStatusesSearchFragment::class.java, args = arguments,
|
||||
name = getString(R.string.search_type_media),
|
||||
icon = DrawableHolder.resource(R.drawable.ic_action_gallery))
|
||||
}
|
||||
adapter.add(cls = SearchUsersFragment::class.java, args = arguments,
|
||||
name = getString(R.string.search_type_users), icon = DrawableHolder.resource(R.drawable.ic_action_user))
|
||||
name = getString(R.string.search_type_users),
|
||||
icon = DrawableHolder.resource(R.drawable.ic_action_user))
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -40,9 +40,8 @@ open class StatusesSearchFragment : ParcelableStatusesFragment() {
|
|||
@TimelineType
|
||||
override val timelineType: String = TimelineType.SEARCH
|
||||
|
||||
override fun onCreateStatusesLoader(context: Context,
|
||||
args: Bundle,
|
||||
fromUser: Boolean): Loader<List<ParcelableStatus>?> {
|
||||
override fun onCreateStatusesLoader(context: Context, args: Bundle, fromUser: Boolean):
|
||||
Loader<List<ParcelableStatus>?> {
|
||||
refreshing = true
|
||||
val accountKey = Utils.getAccountKey(context, args)
|
||||
val maxId = args.getString(EXTRA_MAX_ID)
|
||||
|
|
|
@ -2,136 +2,44 @@ package org.mariotaku.twidere.fragment
|
|||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks
|
||||
import android.support.v4.app.hasRunningLoadersSafe
|
||||
import android.support.v4.content.Loader
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
||||
import android.text.TextUtils
|
||||
import com.bumptech.glide.Glide
|
||||
import org.mariotaku.twidere.adapter.StaggeredGridParcelableStatusesAdapter
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
||||
import org.mariotaku.twidere.constant.IntentConstants.*
|
||||
import org.mariotaku.twidere.extension.reachingEnd
|
||||
import org.mariotaku.twidere.extension.reachingStart
|
||||
import org.mariotaku.twidere.loader.MediaTimelineLoader
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.util.IntentUtils
|
||||
import org.mariotaku.twidere.view.HeaderDrawerLayout.DrawerCallback
|
||||
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/5.
|
||||
*/
|
||||
class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridParcelableStatusesAdapter,
|
||||
StaggeredGridLayoutManager>(), LoaderCallbacks<List<ParcelableStatus>>, DrawerCallback,
|
||||
IStatusViewHolder.StatusClickListener {
|
||||
class UserMediaTimelineFragment : AbsMediaStatusesFragment() {
|
||||
|
||||
override var refreshing: Boolean
|
||||
get() {
|
||||
if (context == null || isDetached) return false
|
||||
return loaderManager.hasRunningLoadersSafe()
|
||||
}
|
||||
set(value) {
|
||||
super.refreshing = value
|
||||
}
|
||||
|
||||
override val reachingEnd: Boolean
|
||||
get() = layoutManager.reachingEnd
|
||||
|
||||
override val reachingStart: Boolean
|
||||
get() = layoutManager.reachingStart
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
adapter.statusClickListener = this
|
||||
val loaderArgs = Bundle(arguments)
|
||||
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
|
||||
loaderManager.initLoader(0, loaderArgs, this)
|
||||
showProgress()
|
||||
}
|
||||
|
||||
override fun setupRecyclerView(context: Context, recyclerView: RecyclerView) {
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateLayoutManager(context: Context): StaggeredGridLayoutManager {
|
||||
return StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||
}
|
||||
|
||||
override fun scrollToPositionWithOffset(position: Int, offset: Int) {
|
||||
layoutManager.scrollToPositionWithOffset(position, offset)
|
||||
}
|
||||
|
||||
override fun onCreateAdapter(context: Context): StaggeredGridParcelableStatusesAdapter {
|
||||
return StaggeredGridParcelableStatusesAdapter(context, Glide.with(this))
|
||||
}
|
||||
|
||||
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableStatus>> {
|
||||
val context = activity
|
||||
override fun onCreateStatusesLoader(context: Context, args: Bundle, fromUser: Boolean):
|
||||
Loader<List<ParcelableStatus>?> {
|
||||
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
|
||||
val maxId = args.getString(EXTRA_MAX_ID)
|
||||
val sinceId = args.getString(EXTRA_SINCE_ID)
|
||||
val userKey = args.getParcelable<UserKey>(EXTRA_USER_KEY)
|
||||
val screenName = args.getString(EXTRA_SCREEN_NAME)
|
||||
val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1)
|
||||
val fromUser = args.getBoolean(EXTRA_FROM_USER)
|
||||
val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false)
|
||||
return MediaTimelineLoader(context, accountKey, userKey, screenName, sinceId, maxId,
|
||||
adapter.getData(), null, tabPosition, fromUser, loadingMore)
|
||||
}
|
||||
|
||||
override fun onLoadFinished(loader: Loader<List<ParcelableStatus>>, data: List<ParcelableStatus>?) {
|
||||
val changed = adapter.setData(data)
|
||||
if ((loader as IExtendedLoader).fromUser && loader is MediaTimelineLoader) {
|
||||
val maxId = loader.maxId
|
||||
val sinceId = loader.sinceId
|
||||
if (TextUtils.isEmpty(sinceId) && !TextUtils.isEmpty(maxId)) {
|
||||
if (data != null && !data.isEmpty()) {
|
||||
adapter.loadMoreSupportedPosition = if (changed) ILoadMoreSupportAdapter.END else ILoadMoreSupportAdapter.NONE
|
||||
}
|
||||
} else {
|
||||
adapter.loadMoreSupportedPosition = ILoadMoreSupportAdapter.END
|
||||
override fun hasMoreData(loader: Loader<List<ParcelableStatus>?>, data: List<ParcelableStatus>?,
|
||||
changed: Boolean): Boolean {
|
||||
if (loader !is MediaTimelineLoader) return false
|
||||
val maxId = loader.maxId?.takeIf(String::isNotEmpty)
|
||||
val sinceId = loader.sinceId?.takeIf(String::isNotEmpty)
|
||||
if (sinceId != null && maxId != null) {
|
||||
if (data != null && !data.isEmpty()) {
|
||||
return changed
|
||||
}
|
||||
}
|
||||
loader.fromUser = false
|
||||
refreshing = false
|
||||
showContent()
|
||||
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onLoaderReset(loader: Loader<List<ParcelableStatus>>) {
|
||||
adapter.setData(null)
|
||||
}
|
||||
|
||||
override fun onLoadMoreContents(position: Long) {
|
||||
// Only supports load from end
|
||||
if (ILoadMoreSupportAdapter.END != position) return
|
||||
super.onLoadMoreContents(position)
|
||||
// Get last raw status
|
||||
val startIdx = adapter.statusStartIndex
|
||||
if (startIdx < 0) return
|
||||
val statusCount = adapter.getStatusCount(true)
|
||||
if (statusCount <= 0) return
|
||||
val status = adapter.getStatus(startIdx + statusCount - 1, true)
|
||||
val maxId = status.id
|
||||
getStatuses(maxId, null)
|
||||
}
|
||||
|
||||
|
||||
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
|
||||
val status = adapter.getStatus(position)
|
||||
IntentUtils.openStatus(context, status, null)
|
||||
}
|
||||
|
||||
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
|
||||
val status = adapter.getStatus(position)
|
||||
IntentUtils.openStatus(context, status.account_key, status.quoted_id)
|
||||
}
|
||||
|
||||
fun getStatuses(maxId: String?, sinceId: String?): Int {
|
||||
override fun getStatuses(maxId: String?, sinceId: String?): Int {
|
||||
if (context == null) return -1
|
||||
val args = Bundle(arguments)
|
||||
args.putBoolean(EXTRA_MAKE_GAP, false)
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2017 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 org.mariotaku.twidere.loader
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.support.annotation.WorkerThread
|
||||
import org.mariotaku.ktextension.isNullOrEmpty
|
||||
import org.mariotaku.microblog.library.MicroBlog
|
||||
import org.mariotaku.microblog.library.MicroBlogException
|
||||
import org.mariotaku.microblog.library.twitter.model.Paging
|
||||
import org.mariotaku.microblog.library.twitter.model.SearchQuery
|
||||
import org.mariotaku.microblog.library.twitter.model.Status
|
||||
import org.mariotaku.microblog.library.twitter.model.UniversalSearchQuery
|
||||
import org.mariotaku.twidere.annotation.AccountType
|
||||
import org.mariotaku.twidere.extension.model.official
|
||||
import org.mariotaku.twidere.model.AccountDetails
|
||||
import org.mariotaku.twidere.model.ParcelableStatus
|
||||
import org.mariotaku.twidere.model.UserKey
|
||||
import org.mariotaku.twidere.util.InternalTwitterContentUtils
|
||||
|
||||
open class MediaStatusesSearchLoader(
|
||||
context: Context,
|
||||
accountKey: UserKey?,
|
||||
private val query: String?,
|
||||
sinceId: String?,
|
||||
maxId: String?,
|
||||
page: Int,
|
||||
adapterData: List<ParcelableStatus>?,
|
||||
savedStatusesArgs: Array<String>?,
|
||||
tabPosition: Int,
|
||||
fromUser: Boolean,
|
||||
override val isGapEnabled: Boolean,
|
||||
loadingMore: Boolean
|
||||
) : MicroBlogAPIStatusesLoader(context, accountKey, sinceId, maxId, page, adapterData, savedStatusesArgs,
|
||||
tabPosition, fromUser, loadingMore) {
|
||||
|
||||
@Throws(MicroBlogException::class)
|
||||
override fun getStatuses(microBlog: MicroBlog,
|
||||
details: AccountDetails,
|
||||
paging: Paging): List<Status> {
|
||||
if (query == null) throw MicroBlogException("Empty query")
|
||||
val queryText = processQuery(details, query)
|
||||
when (details.type) {
|
||||
AccountType.TWITTER -> {
|
||||
if (details.extras?.official ?: false) {
|
||||
val universalQuery = UniversalSearchQuery(queryText)
|
||||
universalQuery.setModules(UniversalSearchQuery.Module.TWEET)
|
||||
universalQuery.setResultType(UniversalSearchQuery.ResultType.RECENT)
|
||||
universalQuery.setPaging(paging)
|
||||
val searchResult = microBlog.universalSearch(universalQuery)
|
||||
return searchResult.modules.mapNotNull { it.status?.data }
|
||||
}
|
||||
|
||||
val searchQuery = SearchQuery(queryText)
|
||||
searchQuery.paging(paging)
|
||||
return microBlog.search(searchQuery)
|
||||
}
|
||||
}
|
||||
throw MicroBlogException("Not implemented")
|
||||
}
|
||||
|
||||
protected open fun processQuery(details: AccountDetails, query: String): String {
|
||||
if (details.type == AccountType.TWITTER) {
|
||||
if (details.extras?.official ?: false) {
|
||||
return smQuery(query)
|
||||
}
|
||||
return "$query exclude:retweets filter:media"
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
protected fun smQuery(query: String): String {
|
||||
var universalQueryText = "$query filter:media"
|
||||
if (maxId != null) {
|
||||
universalQueryText += " max_id:$maxId"
|
||||
}
|
||||
if (sinceId != null) {
|
||||
universalQueryText += " since_id:$sinceId"
|
||||
}
|
||||
return universalQueryText
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun shouldFilterStatus(database: SQLiteDatabase, status: ParcelableStatus): Boolean {
|
||||
if (status.media.isNullOrEmpty()) return true
|
||||
return InternalTwitterContentUtils.isFiltered(database, status, true)
|
||||
}
|
||||
|
||||
override fun processPaging(details: AccountDetails, loadItemLimit: Int, paging: Paging) {
|
||||
if (details.type == AccountType.STATUSNET) {
|
||||
paging.setRpp(loadItemLimit)
|
||||
val page = page
|
||||
if (page > 0) {
|
||||
paging.setPage(page)
|
||||
}
|
||||
} else {
|
||||
super.processPaging(details, loadItemLimit, paging)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1021,6 +1021,7 @@
|
|||
<string name="search_hint_users">Search users</string>
|
||||
<string name="search_statuses">Search Tweets</string>
|
||||
<string name="search_type_statuses">Tweets</string>
|
||||
<string name="search_type_media">Media</string>
|
||||
<string name="search_type_users">Users</string>
|
||||
|
||||
<string name="security_key">Security key</string>
|
||||
|
|
Loading…
Reference in New Issue