implemented delete single dm
This commit is contained in:
parent
20e5e70564
commit
eee0227074
|
@ -17,3 +17,4 @@
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
org.gradle.jvmargs=-Xmx2048M
|
org.gradle.jvmargs=-Xmx2048M
|
||||||
|
kotlin.incremental=true
|
|
@ -54,6 +54,9 @@ public interface PrivateDirectMessagesResources extends PrivateResources {
|
||||||
@POST("/dm/new.json")
|
@POST("/dm/new.json")
|
||||||
DMResponse sendDm(@Param NewDm newDm) throws MicroBlogException;
|
DMResponse sendDm(@Param NewDm newDm) throws MicroBlogException;
|
||||||
|
|
||||||
|
@POST("/dm/destroy.json")
|
||||||
|
ResponseCode destroyDm(@Param("dm_id") String id) throws MicroBlogException;
|
||||||
|
|
||||||
@GET("/dm/user_inbox.json")
|
@GET("/dm/user_inbox.json")
|
||||||
UserInbox getUserInbox(@Query Paging paging) throws MicroBlogException;
|
UserInbox getUserInbox(@Query Paging paging) throws MicroBlogException;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,10 @@ import org.apache.commons.lang3.ObjectUtils
|
||||||
import org.mariotaku.abstask.library.AbstractTask
|
import org.mariotaku.abstask.library.AbstractTask
|
||||||
import org.mariotaku.abstask.library.TaskStarter
|
import org.mariotaku.abstask.library.TaskStarter
|
||||||
import org.mariotaku.kpreferences.get
|
import org.mariotaku.kpreferences.get
|
||||||
import org.mariotaku.ktextension.*
|
import org.mariotaku.ktextension.checkAnySelfPermissionsGranted
|
||||||
|
import org.mariotaku.ktextension.getTypedArray
|
||||||
|
import org.mariotaku.ktextension.setItemChecked
|
||||||
|
import org.mariotaku.ktextension.toTypedArray
|
||||||
import org.mariotaku.pickncrop.library.MediaPickerActivity
|
import org.mariotaku.pickncrop.library.MediaPickerActivity
|
||||||
import org.mariotaku.twidere.Constants.*
|
import org.mariotaku.twidere.Constants.*
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
|
@ -651,26 +654,33 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) {
|
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) {
|
||||||
if (v === attachedMediaPreview) {
|
if (menuInfo !is ExtendedRecyclerView.ContextMenuInfo) return
|
||||||
|
when (menuInfo.recyclerViewId) {
|
||||||
|
R.id.attachedMediaPreview -> {
|
||||||
menu.setHeaderTitle(R.string.edit_media)
|
menu.setHeaderTitle(R.string.edit_media)
|
||||||
supportMenuInflater.inflate(R.menu.menu_attached_media_edit, menu)
|
supportMenuInflater.inflate(R.menu.menu_attached_media_edit, menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onContextItemSelected(item: MenuItem): Boolean {
|
override fun onContextItemSelected(item: MenuItem): Boolean {
|
||||||
val menuInfo = item.menuInfo
|
val menuInfo = item.menuInfo as? ExtendedRecyclerView.ContextMenuInfo ?: run {
|
||||||
if (menuInfo is ExtendedRecyclerView.ContextMenuInfo) {
|
return super.onContextItemSelected(item)
|
||||||
|
}
|
||||||
when (menuInfo.recyclerViewId) {
|
when (menuInfo.recyclerViewId) {
|
||||||
R.id.attachedMediaPreview -> {
|
R.id.attachedMediaPreview -> {
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.edit_description -> {
|
||||||
val position = menuInfo.position
|
val position = menuInfo.position
|
||||||
val altText = mediaPreviewAdapter.getItem(position).alt_text
|
val altText = mediaPreviewAdapter.getItem(position).alt_text
|
||||||
executeAfterFragmentResumed { activity ->
|
executeAfterFragmentResumed { activity ->
|
||||||
EditAltTextDialogFragment.show(activity.supportFragmentManager, position,
|
EditAltTextDialogFragment.show(activity.supportFragmentManager, position,
|
||||||
altText)
|
altText)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onContextItemSelected(item)
|
return super.onContextItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,15 @@ import org.mariotaku.ktextension.convert
|
||||||
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
|
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
|
||||||
import org.mariotaku.twidere.Constants.*
|
import org.mariotaku.twidere.Constants.*
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity
|
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
|
||||||
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
import org.mariotaku.twidere.adapter.SupportTabsAdapter
|
||||||
import org.mariotaku.twidere.annotation.CustomTabType
|
import org.mariotaku.twidere.annotation.CustomTabType
|
||||||
import org.mariotaku.twidere.annotation.ReadPositionTag
|
import org.mariotaku.twidere.annotation.ReadPositionTag
|
||||||
import org.mariotaku.twidere.constant.*
|
import org.mariotaku.twidere.constant.*
|
||||||
import org.mariotaku.twidere.extension.applyTheme
|
import org.mariotaku.twidere.extension.applyTheme
|
||||||
import org.mariotaku.twidere.fragment.*
|
import org.mariotaku.twidere.fragment.AccountsDashboardFragment
|
||||||
|
import org.mariotaku.twidere.fragment.BaseDialogFragment
|
||||||
|
import org.mariotaku.twidere.fragment.CustomTabsFragment
|
||||||
import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment
|
import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment
|
||||||
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface
|
||||||
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
import org.mariotaku.twidere.fragment.iface.SupportFragmentCallback
|
||||||
|
@ -87,7 +89,6 @@ import org.mariotaku.twidere.model.AccountDetails
|
||||||
import org.mariotaku.twidere.model.SupportTabSpec
|
import org.mariotaku.twidere.model.SupportTabSpec
|
||||||
import org.mariotaku.twidere.model.Tab
|
import org.mariotaku.twidere.model.Tab
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
import org.mariotaku.twidere.model.event.TaskStateChangedEvent
|
|
||||||
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||||
|
@ -112,7 +113,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
|
|
||||||
private var updateUnreadCountTask: UpdateUnreadCountTask? = null
|
private var updateUnreadCountTask: UpdateUnreadCountTask? = null
|
||||||
private val readStateChangeListener = OnSharedPreferenceChangeListener { sharedPreferences, key -> updateUnreadCount() }
|
private val readStateChangeListener = OnSharedPreferenceChangeListener { sharedPreferences, key -> updateUnreadCount() }
|
||||||
private val controlBarShowHideHelper = IControlBarActivity.ControlBarShowHideHelper(this)
|
private val controlBarShowHideHelper = ControlBarShowHideHelper(this)
|
||||||
|
|
||||||
private val homeDrawerToggleDelegate = object : ActionBarDrawerToggle.Delegate {
|
private val homeDrawerToggleDelegate = object : ActionBarDrawerToggle.Delegate {
|
||||||
override fun setActionBarUpIndicator(upDrawable: Drawable, @StringRes contentDescRes: Int) {
|
override fun setActionBarUpIndicator(upDrawable: Drawable, @StringRes contentDescRes: Int) {
|
||||||
|
@ -172,133 +173,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
val leftDrawerFragment: Fragment?
|
val leftDrawerFragment: Fragment?
|
||||||
get() = supportFragmentManager.findFragmentById(R.id.leftDrawer)
|
get() = supportFragmentManager.findFragmentById(R.id.leftDrawer)
|
||||||
|
|
||||||
override fun getSystemWindowsInsets(insets: Rect): Boolean {
|
|
||||||
if (mainTabs == null || homeContent == null) return false
|
|
||||||
val height = mainTabs.height
|
|
||||||
if (height != 0) {
|
|
||||||
insets.top = height
|
|
||||||
} else {
|
|
||||||
insets.top = ThemeUtils.getActionBarHeight(this)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setControlBarVisibleAnimate(visible: Boolean, listener: IControlBarActivity.ControlBarShowHideHelper.ControlBarAnimationListener?) {
|
|
||||||
controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
|
||||||
if (drawerToggle.onOptionsItemSelected(item)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
when (item.itemId) {
|
|
||||||
android.R.id.home -> {
|
|
||||||
val fm = supportFragmentManager
|
|
||||||
val count = fm.backStackEntryCount
|
|
||||||
if (homeMenu.isDrawerOpen(GravityCompat.START) || homeMenu.isDrawerOpen(GravityCompat.END)) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
return true
|
|
||||||
} else if (count == 0) {
|
|
||||||
homeMenu.openDrawer(GravityCompat.START)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.search -> {
|
|
||||||
openSearchView(selectedAccountToSearch)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.actions -> {
|
|
||||||
triggerActionsClick()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
||||||
if (handleFragmentKeyboardShortcutSingle(handler, keyCode, event, metaState)) return true
|
|
||||||
var action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_HOME, keyCode, event, metaState)
|
|
||||||
if (action != null) {
|
|
||||||
when (action) {
|
|
||||||
KeyboardShortcutConstants.ACTION_HOME_ACCOUNTS_DASHBOARD -> {
|
|
||||||
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
} else {
|
|
||||||
homeMenu.openDrawer(GravityCompat.START)
|
|
||||||
setControlBarVisibleAnimate(true)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
|
||||||
if (action != null) {
|
|
||||||
when (action) {
|
|
||||||
KeyboardShortcutConstants.ACTION_NAVIGATION_PREVIOUS_TAB -> {
|
|
||||||
val previous = mainPager.currentItem - 1
|
|
||||||
if (previous < 0 && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.START) != null) {
|
|
||||||
homeMenu.openDrawer(GravityCompat.START)
|
|
||||||
setControlBarVisibleAnimate(true)
|
|
||||||
} else if (previous < pagerAdapter.count) {
|
|
||||||
if (homeMenu.isDrawerOpen(GravityCompat.END)) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
} else {
|
|
||||||
mainPager.setCurrentItem(previous, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
KeyboardShortcutConstants.ACTION_NAVIGATION_NEXT_TAB -> {
|
|
||||||
val next = mainPager.currentItem + 1
|
|
||||||
if (next >= pagerAdapter.count && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.END) != null) {
|
|
||||||
homeMenu.openDrawer(GravityCompat.END)
|
|
||||||
setControlBarVisibleAnimate(true)
|
|
||||||
} else if (next >= 0) {
|
|
||||||
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
} else {
|
|
||||||
mainPager.setCurrentItem(next, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return handler.handleKey(this, null, keyCode, event, metaState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
||||||
if (isFragmentKeyboardShortcutHandled(handler, keyCode, event, metaState)) return true
|
|
||||||
return super.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int, repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
|
||||||
if (handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState))
|
|
||||||
return true
|
|
||||||
return super.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
|
||||||
when (keyCode) {
|
|
||||||
KeyEvent.KEYCODE_MENU -> {
|
|
||||||
if (isDrawerOpen) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
} else {
|
|
||||||
homeMenu.openDrawer(GravityCompat.START)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
KeyEvent.KEYCODE_BACK -> {
|
|
||||||
if (isDrawerOpen) {
|
|
||||||
homeMenu.closeDrawers()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.onKeyUp(keyCode, event)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val isDrawerOpen: Boolean
|
private val isDrawerOpen: Boolean
|
||||||
get() {
|
get() {
|
||||||
val drawer = homeMenu ?: return false
|
val drawer = homeMenu ?: return false
|
||||||
|
@ -405,6 +279,12 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPostCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onPostCreate(savedInstanceState)
|
||||||
|
// Sync the toggle state after onRestoreInstanceState has occurred.
|
||||||
|
drawerToggle.syncState()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
multiSelectHandler.dispatchOnStart()
|
multiSelectHandler.dispatchOnStart()
|
||||||
|
@ -431,23 +311,33 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyAccountsChanged() {
|
override fun onDestroy() {
|
||||||
|
stopService(Intent(this, StreamingService::class.java))
|
||||||
|
|
||||||
|
// Delete unused items in databases.
|
||||||
|
|
||||||
|
val context = applicationContext
|
||||||
|
TaskStarter.execute(object : AbstractTask<Any?, Any?, Any?>() {
|
||||||
|
override fun doLongOperation(o: Any?): Any? {
|
||||||
|
DataStoreUtils.cleanDatabasesByItemLimit(context)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAttachFragment(fragment: Fragment?) {
|
||||||
|
super.onAttachFragment(fragment)
|
||||||
|
// Must exclude fragments not belongs tabs, otherwise it will crash
|
||||||
|
if (fragment !is AccountsDashboardFragment) {
|
||||||
|
updateActionsButton()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
fun notifyTaskStateChanged(event: TaskStateChangedEvent) {
|
|
||||||
updateActionsButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
fun notifyUnreadCountUpdated(event: UnreadCountUpdatedEvent) {
|
|
||||||
updateUnreadCount()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClick(v: View) {
|
override fun onClick(v: View) {
|
||||||
when (v) {
|
when (v) {
|
||||||
actionsButton -> {
|
actionsButton -> {
|
||||||
|
@ -499,11 +389,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun openSearchView(account: AccountDetails?) {
|
|
||||||
selectedAccountToSearch = account
|
|
||||||
onSearchRequested()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFitSystemWindows(insets: Rect) {
|
override fun onFitSystemWindows(insets: Rect) {
|
||||||
super.onFitSystemWindows(insets)
|
super.onFitSystemWindows(insets)
|
||||||
val fragment = leftDrawerFragment
|
val fragment = leftDrawerFragment
|
||||||
|
@ -512,6 +397,158 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent) {
|
||||||
|
val tabPosition = handleIntent(intent, false)
|
||||||
|
if (tabPosition >= 0) {
|
||||||
|
mainPager.currentItem = tabPosition.coerceInOr(0 until pagerAdapter.count, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSystemWindowsInsets(insets: Rect): Boolean {
|
||||||
|
if (mainTabs == null || homeContent == null) return false
|
||||||
|
val height = mainTabs.height
|
||||||
|
if (height != 0) {
|
||||||
|
insets.top = height
|
||||||
|
} else {
|
||||||
|
insets.top = ThemeUtils.getActionBarHeight(this)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setControlBarVisibleAnimate(visible: Boolean,
|
||||||
|
listener: ControlBarShowHideHelper.ControlBarAnimationListener?) {
|
||||||
|
controlBarShowHideHelper.setControlBarVisibleAnimate(visible, listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
if (drawerToggle.onOptionsItemSelected(item)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
when (item.itemId) {
|
||||||
|
android.R.id.home -> {
|
||||||
|
val fm = supportFragmentManager
|
||||||
|
val count = fm.backStackEntryCount
|
||||||
|
if (homeMenu.isDrawerOpen(GravityCompat.START) || homeMenu.isDrawerOpen(GravityCompat.END)) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
return true
|
||||||
|
} else if (count == 0) {
|
||||||
|
homeMenu.openDrawer(GravityCompat.START)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.search -> {
|
||||||
|
openSearchView(selectedAccountToSearch)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
R.id.actions -> {
|
||||||
|
triggerActionsClick()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handleKeyboardShortcutSingle(handler: KeyboardShortcutsHandler, keyCode: Int,
|
||||||
|
event: KeyEvent, metaState: Int): Boolean {
|
||||||
|
if (handleFragmentKeyboardShortcutSingle(handler, keyCode, event, metaState)) return true
|
||||||
|
var action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_HOME, keyCode, event, metaState)
|
||||||
|
if (action != null) {
|
||||||
|
when (action) {
|
||||||
|
KeyboardShortcutConstants.ACTION_HOME_ACCOUNTS_DASHBOARD -> {
|
||||||
|
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
} else {
|
||||||
|
homeMenu.openDrawer(GravityCompat.START)
|
||||||
|
setControlBarVisibleAnimate(true)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action = handler.getKeyAction(KeyboardShortcutConstants.CONTEXT_TAG_NAVIGATION, keyCode, event, metaState)
|
||||||
|
if (action != null) {
|
||||||
|
when (action) {
|
||||||
|
KeyboardShortcutConstants.ACTION_NAVIGATION_PREVIOUS_TAB -> {
|
||||||
|
val previous = mainPager.currentItem - 1
|
||||||
|
if (previous < 0 && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.START) != null) {
|
||||||
|
homeMenu.openDrawer(GravityCompat.START)
|
||||||
|
setControlBarVisibleAnimate(true)
|
||||||
|
} else if (previous < pagerAdapter.count) {
|
||||||
|
if (homeMenu.isDrawerOpen(GravityCompat.END)) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
} else {
|
||||||
|
mainPager.setCurrentItem(previous, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
KeyboardShortcutConstants.ACTION_NAVIGATION_NEXT_TAB -> {
|
||||||
|
val next = mainPager.currentItem + 1
|
||||||
|
if (next >= pagerAdapter.count && DrawerLayoutAccessor.findDrawerWithGravity(homeMenu, Gravity.END) != null) {
|
||||||
|
homeMenu.openDrawer(GravityCompat.END)
|
||||||
|
setControlBarVisibleAnimate(true)
|
||||||
|
} else if (next >= 0) {
|
||||||
|
if (homeMenu.isDrawerOpen(GravityCompat.START)) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
} else {
|
||||||
|
mainPager.setCurrentItem(next, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return handler.handleKey(this, null, keyCode, event, metaState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isKeyboardShortcutHandled(handler: KeyboardShortcutsHandler, keyCode: Int,
|
||||||
|
event: KeyEvent, metaState: Int): Boolean {
|
||||||
|
if (isFragmentKeyboardShortcutHandled(handler, keyCode, event, metaState)) return true
|
||||||
|
return super.isKeyboardShortcutHandled(handler, keyCode, event, metaState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handleKeyboardShortcutRepeat(handler: KeyboardShortcutsHandler, keyCode: Int,
|
||||||
|
repeatCount: Int, event: KeyEvent, metaState: Int): Boolean {
|
||||||
|
if (handleFragmentKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState))
|
||||||
|
return true
|
||||||
|
return super.handleKeyboardShortcutRepeat(handler, keyCode, repeatCount, event, metaState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
|
||||||
|
when (keyCode) {
|
||||||
|
KeyEvent.KEYCODE_MENU -> {
|
||||||
|
if (isDrawerOpen) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
} else {
|
||||||
|
homeMenu.openDrawer(GravityCompat.START)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
KeyEvent.KEYCODE_BACK -> {
|
||||||
|
if (isDrawerOpen) {
|
||||||
|
homeMenu.closeDrawers()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onKeyUp(keyCode, event)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun notifyAccountsChanged() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
fun notifyUnreadCountUpdated(event: UnreadCountUpdatedEvent) {
|
||||||
|
updateUnreadCount()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openSearchView(account: AccountDetails?) {
|
||||||
|
selectedAccountToSearch = account
|
||||||
|
onSearchRequested()
|
||||||
|
}
|
||||||
|
|
||||||
fun updateUnreadCount() {
|
fun updateUnreadCount() {
|
||||||
if (mainTabs == null || updateUnreadCountTask != null && updateUnreadCountTask!!.status == AsyncTask.Status.RUNNING)
|
if (mainTabs == null || updateUnreadCountTask != null && updateUnreadCountTask!!.status == AsyncTask.Status.RUNNING)
|
||||||
return
|
return
|
||||||
|
@ -524,34 +561,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
val tabs: List<SupportTabSpec>
|
val tabs: List<SupportTabSpec>
|
||||||
get() = pagerAdapter.tabs
|
get() = pagerAdapter.tabs
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent) {
|
|
||||||
val tabPosition = handleIntent(intent, false)
|
|
||||||
if (tabPosition >= 0) {
|
|
||||||
mainPager.currentItem = tabPosition.coerceInOr(0 until pagerAdapter.count, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
stopService(Intent(this, StreamingService::class.java))
|
|
||||||
|
|
||||||
// Delete unused items in databases.
|
|
||||||
|
|
||||||
val context = applicationContext
|
|
||||||
TaskStarter.execute(object : AbstractTask<Any?, Any?, Any?>() {
|
|
||||||
override fun doLongOperation(o: Any?): Any? {
|
|
||||||
DataStoreUtils.cleanDatabasesByItemLimit(context)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPostCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onPostCreate(savedInstanceState)
|
|
||||||
// Sync the toggle state after onRestoreInstanceState has occurred.
|
|
||||||
drawerToggle.syncState()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
super.onConfigurationChanged(newConfig)
|
super.onConfigurationChanged(newConfig)
|
||||||
// Pass any configuration change to the drawer toggle
|
// Pass any configuration change to the drawer toggle
|
||||||
|
@ -842,9 +851,15 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateActionsButton() {
|
private fun updateActionsButton() {
|
||||||
|
val fragment = run {
|
||||||
|
if (pagerAdapter.count == 0) return@run null
|
||||||
val position = mainPager.currentItem
|
val position = mainPager.currentItem
|
||||||
if (pagerAdapter.count == 0) return
|
val f = pagerAdapter.instantiateItem(mainPager, position) as? IFloatingActionButtonFragment
|
||||||
val fragment = pagerAdapter.instantiateItem(mainPager, position) as? IFloatingActionButtonFragment
|
if (f is Fragment && (f.isDetached || f.host == null)) {
|
||||||
|
return@run null
|
||||||
|
}
|
||||||
|
return@run f
|
||||||
|
}
|
||||||
val info = fragment?.getActionInfo("home") ?: run {
|
val info = fragment?.getActionInfo("home") ?: run {
|
||||||
actionsButton.setImageResource(R.drawable.ic_action_status_compose)
|
actionsButton.setImageResource(R.drawable.ic_action_status_compose)
|
||||||
actionsButton.contentDescription = getString(R.string.action_compose)
|
actionsButton.contentDescription = getString(R.string.action_compose)
|
||||||
|
|
|
@ -164,7 +164,11 @@ class MessagesConversationAdapter(context: Context) : LoadMoreSupportAdapter<Rec
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Listener {
|
interface Listener {
|
||||||
|
|
||||||
fun onMediaClick(position: Int, media: ParcelableMedia, accountKey: UserKey?)
|
fun onMediaClick(position: Int, media: ParcelableMedia, accountKey: UserKey?)
|
||||||
|
|
||||||
|
fun onMessageLongClick(position: Int, holder: RecyclerView.ViewHolder): Boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -33,6 +33,7 @@ import android.support.v7.widget.RecyclerView
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.squareup.otto.Subscribe
|
import com.squareup.otto.Subscribe
|
||||||
|
import kotlinx.android.synthetic.main.activity_premium_dashboard.*
|
||||||
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
|
import kotlinx.android.synthetic.main.fragment_messages_conversation.*
|
||||||
import org.mariotaku.abstask.library.TaskStarter
|
import org.mariotaku.abstask.library.TaskStarter
|
||||||
import org.mariotaku.kpreferences.get
|
import org.mariotaku.kpreferences.get
|
||||||
|
@ -50,7 +51,9 @@ import org.mariotaku.twidere.adapter.MessagesConversationAdapter
|
||||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
|
||||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
|
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
|
||||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_CONVERSATION_ID
|
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_CONVERSATION_ID
|
||||||
|
import org.mariotaku.twidere.constant.nameFirstKey
|
||||||
import org.mariotaku.twidere.constant.newDocumentApiKey
|
import org.mariotaku.twidere.constant.newDocumentApiKey
|
||||||
|
import org.mariotaku.twidere.extension.model.getSummaryText
|
||||||
import org.mariotaku.twidere.extension.model.isOfficial
|
import org.mariotaku.twidere.extension.model.isOfficial
|
||||||
import org.mariotaku.twidere.fragment.AbsContentListRecyclerViewFragment
|
import org.mariotaku.twidere.fragment.AbsContentListRecyclerViewFragment
|
||||||
import org.mariotaku.twidere.fragment.EditAltTextDialogFragment
|
import org.mariotaku.twidere.fragment.EditAltTextDialogFragment
|
||||||
|
@ -62,9 +65,11 @@ import org.mariotaku.twidere.model.event.SendMessageTaskEvent
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||||
import org.mariotaku.twidere.service.LengthyOperationsService
|
import org.mariotaku.twidere.service.LengthyOperationsService
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask
|
|
||||||
import org.mariotaku.twidere.task.compose.AbsAddMediaTask
|
import org.mariotaku.twidere.task.compose.AbsAddMediaTask
|
||||||
import org.mariotaku.twidere.task.compose.AbsDeleteMediaTask
|
import org.mariotaku.twidere.task.compose.AbsDeleteMediaTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.message.DestroyMessageTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
|
import org.mariotaku.twidere.util.ClipboardUtils
|
||||||
import org.mariotaku.twidere.util.DataStoreUtils
|
import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.IntentUtils
|
import org.mariotaku.twidere.util.IntentUtils
|
||||||
import org.mariotaku.twidere.util.PreviewGridItemDecoration
|
import org.mariotaku.twidere.util.PreviewGridItemDecoration
|
||||||
|
@ -108,6 +113,10 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
|
||||||
media = message.media, current = media,
|
media = message.media, current = media,
|
||||||
newDocument = preferences[newDocumentApiKey], message = message)
|
newDocument = preferences[newDocumentApiKey], message = message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMessageLongClick(position: Int, holder: RecyclerView.ViewHolder): Boolean {
|
||||||
|
return recyclerView.showContextMenuForChild(holder.itemView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaPreviewAdapter = MediaPreviewAdapter(context)
|
mediaPreviewAdapter = MediaPreviewAdapter(context)
|
||||||
|
|
||||||
|
@ -125,6 +134,8 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
|
||||||
attachedMediaPreview.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
attachedMediaPreview.layoutManager = FixedLinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||||
attachedMediaPreview.adapter = mediaPreviewAdapter
|
attachedMediaPreview.adapter = mediaPreviewAdapter
|
||||||
attachedMediaPreview.addItemDecoration(PreviewGridItemDecoration(resources.getDimensionPixelSize(R.dimen.element_spacing_small)))
|
attachedMediaPreview.addItemDecoration(PreviewGridItemDecoration(resources.getDimensionPixelSize(R.dimen.element_spacing_small)))
|
||||||
|
|
||||||
|
registerForContextMenu(recyclerView)
|
||||||
registerForContextMenu(attachedMediaPreview)
|
registerForContextMenu(attachedMediaPreview)
|
||||||
|
|
||||||
sendMessage.setOnClickListener {
|
sendMessage.setOnClickListener {
|
||||||
|
@ -220,26 +231,54 @@ class MessagesConversationFragment : AbsContentListRecyclerViewFragment<Messages
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) {
|
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) {
|
||||||
if (v === attachedMediaPreview) {
|
if (menuInfo !is ExtendedRecyclerView.ContextMenuInfo) return
|
||||||
|
when (menuInfo.recyclerViewId) {
|
||||||
|
R.id.recyclerView -> {
|
||||||
|
val message = adapter.getMessage(menuInfo.position) ?: return
|
||||||
|
val conversation = adapter.conversation
|
||||||
|
menu.setHeaderTitle(message.getSummaryText(context, userColorNameManager, conversation,
|
||||||
|
preferences[nameFirstKey]))
|
||||||
|
activity.menuInflater.inflate(R.menu.menu_conversation_message_item, menu)
|
||||||
|
}
|
||||||
|
R.id.attachedMediaPreview -> {
|
||||||
menu.setHeaderTitle(R.string.edit_media)
|
menu.setHeaderTitle(R.string.edit_media)
|
||||||
activity.menuInflater.inflate(R.menu.menu_attached_media_edit, menu)
|
activity.menuInflater.inflate(R.menu.menu_attached_media_edit, menu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onContextItemSelected(item: MenuItem): Boolean {
|
override fun onContextItemSelected(item: MenuItem): Boolean {
|
||||||
val menuInfo = item.menuInfo
|
val menuInfo = item.menuInfo as? ExtendedRecyclerView.ContextMenuInfo ?: run {
|
||||||
if (menuInfo is ExtendedRecyclerView.ContextMenuInfo) {
|
return super.onContextItemSelected(item)
|
||||||
|
}
|
||||||
when (menuInfo.recyclerViewId) {
|
when (menuInfo.recyclerViewId) {
|
||||||
|
R.id.recyclerView -> {
|
||||||
|
val message = adapter.getMessage(menuInfo.position) ?: return true
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.copy -> {
|
||||||
|
ClipboardUtils.setText(context, message.text_unescaped)
|
||||||
|
}
|
||||||
|
R.id.delete -> {
|
||||||
|
val task = DestroyMessageTask(context, message.account_key,
|
||||||
|
message.conversation_id, message.id)
|
||||||
|
TaskStarter.execute(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
R.id.attachedMediaPreview -> {
|
R.id.attachedMediaPreview -> {
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.edit_description -> {
|
||||||
val position = menuInfo.position
|
val position = menuInfo.position
|
||||||
val altText = mediaPreviewAdapter.getItem(position).alt_text
|
val altText = mediaPreviewAdapter.getItem(position).alt_text
|
||||||
executeAfterFragmentResumed { fragment ->
|
executeAfterFragmentResumed { fragment ->
|
||||||
EditAltTextDialogFragment.show(fragment.childFragmentManager, position,
|
EditAltTextDialogFragment.show(fragment.childFragmentManager, position,
|
||||||
altText)
|
altText)
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return super.onContextItemSelected(item)
|
return super.onContextItemSelected(item)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ import org.mariotaku.twidere.model.ParcelableMessageConversationCursorIndices
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
import org.mariotaku.twidere.util.DataStoreUtils
|
import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.ErrorInfoStore
|
import org.mariotaku.twidere.util.ErrorInfoStore
|
||||||
import org.mariotaku.twidere.util.IntentUtils
|
import org.mariotaku.twidere.util.IntentUtils
|
||||||
|
|
|
@ -62,7 +62,7 @@ import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
|
||||||
import org.mariotaku.twidere.task.CreateFavoriteTask
|
import org.mariotaku.twidere.task.CreateFavoriteTask
|
||||||
import org.mariotaku.twidere.task.RetweetStatusTask
|
import org.mariotaku.twidere.task.RetweetStatusTask
|
||||||
import org.mariotaku.twidere.task.message.SendMessageTask
|
import org.mariotaku.twidere.task.twitter.message.SendMessageTask
|
||||||
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
||||||
import org.mariotaku.twidere.util.NotificationManagerWrapper
|
import org.mariotaku.twidere.util.NotificationManagerWrapper
|
||||||
import org.mariotaku.twidere.util.Utils
|
import org.mariotaku.twidere.util.Utils
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
package org.mariotaku.twidere.task
|
|
||||||
|
|
||||||
import android.accounts.AccountManager
|
|
||||||
import android.content.ContentResolver
|
|
||||||
import android.content.ContentValues
|
|
||||||
import android.content.Context
|
|
||||||
import android.net.Uri
|
|
||||||
import android.support.v4.util.ArraySet
|
|
||||||
import org.mariotaku.microblog.library.MicroBlog
|
|
||||||
import org.mariotaku.microblog.library.MicroBlogException
|
|
||||||
import org.mariotaku.microblog.library.twitter.model.Trends
|
|
||||||
import org.mariotaku.sqliteqb.library.Expression
|
|
||||||
import org.mariotaku.twidere.TwidereConstants.LOGTAG
|
|
||||||
import org.mariotaku.twidere.annotation.AccountType
|
|
||||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
|
||||||
import org.mariotaku.twidere.model.ParcelableTrend
|
|
||||||
import org.mariotaku.twidere.model.ParcelableTrendValuesCreator
|
|
||||||
import org.mariotaku.twidere.model.UserKey
|
|
||||||
import org.mariotaku.twidere.model.event.TrendsRefreshedEvent
|
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends
|
|
||||||
import org.mariotaku.twidere.util.DebugLog
|
|
||||||
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mariotaku on 16/2/24.
|
|
||||||
*/
|
|
||||||
class GetTrendsTask(
|
|
||||||
context: Context,
|
|
||||||
private val accountKey: UserKey,
|
|
||||||
private val woeId: Int
|
|
||||||
) : BaseAbstractTask<Any?, Unit, Any?>(context) {
|
|
||||||
|
|
||||||
override fun doLongOperation(param: Any?) {
|
|
||||||
val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?: return
|
|
||||||
val twitter = details.newMicroBlogInstance(context, cls = MicroBlog::class.java)
|
|
||||||
try {
|
|
||||||
val trends = when {
|
|
||||||
details.type == AccountType.FANFOU -> twitter.fanfouTrends
|
|
||||||
else -> twitter.getLocationTrends(woeId).firstOrNull()
|
|
||||||
} ?: return
|
|
||||||
storeTrends(context.contentResolver, CachedTrends.Local.CONTENT_URI, trends)
|
|
||||||
} catch (e: MicroBlogException) {
|
|
||||||
DebugLog.w(LOGTAG, tr = e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun afterExecute(handler: Any?, result: Unit) {
|
|
||||||
bus.post(TrendsRefreshedEvent())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun storeTrends(cr: ContentResolver, uri: Uri, trends: Trends) {
|
|
||||||
val hashtags = ArraySet<String>()
|
|
||||||
val deleteWhere = Expression.and(Expression.equalsArgs(CachedTrends.ACCOUNT_KEY),
|
|
||||||
Expression.equalsArgs(CachedTrends.WOEID)).sql
|
|
||||||
val deleteWhereArgs = arrayOf(accountKey.toString(), woeId.toString())
|
|
||||||
cr.delete(CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs)
|
|
||||||
|
|
||||||
val allTrends = ArrayList<ParcelableTrend>()
|
|
||||||
|
|
||||||
trends.trends.forEachIndexed { idx, trend ->
|
|
||||||
val hashtag = trend.name.replaceFirst("#", "")
|
|
||||||
hashtags.add(hashtag)
|
|
||||||
allTrends.add(ParcelableTrend().apply {
|
|
||||||
this.account_key = accountKey
|
|
||||||
this.woe_id = woeId
|
|
||||||
this.name = trend.name
|
|
||||||
this.timestamp = System.currentTimeMillis()
|
|
||||||
this.trend_order = idx
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ContentResolverUtils.bulkInsert(cr, uri, allTrends.map(ParcelableTrendValuesCreator::create))
|
|
||||||
ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false,
|
|
||||||
hashtags, null, null)
|
|
||||||
ContentResolverUtils.bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map {
|
|
||||||
val values = ContentValues()
|
|
||||||
values.put(CachedHashtags.NAME, it)
|
|
||||||
return@map values
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,23 @@
|
||||||
package org.mariotaku.twidere.task
|
/*
|
||||||
|
* 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.task.twitter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
|
@ -1,4 +1,23 @@
|
||||||
package org.mariotaku.twidere.task
|
/*
|
||||||
|
* 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.task.twitter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
|
@ -1,4 +1,23 @@
|
||||||
package org.mariotaku.twidere.task
|
/*
|
||||||
|
* 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.task.twitter
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.abstask.library.AbstractTask
|
import org.mariotaku.abstask.library.AbstractTask
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* 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.task.twitter
|
||||||
|
|
||||||
|
import android.accounts.AccountManager
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.support.v4.util.ArraySet
|
||||||
|
import org.mariotaku.microblog.library.MicroBlog
|
||||||
|
import org.mariotaku.microblog.library.MicroBlogException
|
||||||
|
import org.mariotaku.microblog.library.twitter.model.Trends
|
||||||
|
import org.mariotaku.sqliteqb.library.Expression
|
||||||
|
import org.mariotaku.twidere.TwidereConstants.LOGTAG
|
||||||
|
import org.mariotaku.twidere.annotation.AccountType
|
||||||
|
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||||
|
import org.mariotaku.twidere.model.ParcelableTrend
|
||||||
|
import org.mariotaku.twidere.model.ParcelableTrendValuesCreator
|
||||||
|
import org.mariotaku.twidere.model.UserKey
|
||||||
|
import org.mariotaku.twidere.model.event.TrendsRefreshedEvent
|
||||||
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags
|
||||||
|
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends
|
||||||
|
import org.mariotaku.twidere.util.DebugLog
|
||||||
|
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 16/2/24.
|
||||||
|
*/
|
||||||
|
class GetTrendsTask(
|
||||||
|
context: android.content.Context,
|
||||||
|
private val accountKey: org.mariotaku.twidere.model.UserKey,
|
||||||
|
private val woeId: Int
|
||||||
|
) : org.mariotaku.twidere.task.BaseAbstractTask<Any?, Unit, Any?>(context) {
|
||||||
|
|
||||||
|
override fun doLongOperation(param: Any?) {
|
||||||
|
val details = org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails(android.accounts.AccountManager.get(context), accountKey, true) ?: return
|
||||||
|
val twitter = details.newMicroBlogInstance(context, cls = org.mariotaku.microblog.library.MicroBlog::class.java)
|
||||||
|
try {
|
||||||
|
val trends = when {
|
||||||
|
details.type == org.mariotaku.twidere.annotation.AccountType.FANFOU -> twitter.fanfouTrends
|
||||||
|
else -> twitter.getLocationTrends(woeId).firstOrNull()
|
||||||
|
} ?: return
|
||||||
|
storeTrends(context.contentResolver, org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, trends)
|
||||||
|
} catch (e: org.mariotaku.microblog.library.MicroBlogException) {
|
||||||
|
org.mariotaku.twidere.util.DebugLog.w(LOGTAG, tr = e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterExecute(handler: Any?, result: Unit) {
|
||||||
|
bus.post(org.mariotaku.twidere.model.event.TrendsRefreshedEvent())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun storeTrends(cr: android.content.ContentResolver, uri: android.net.Uri, trends: org.mariotaku.microblog.library.twitter.model.Trends) {
|
||||||
|
val hashtags = android.support.v4.util.ArraySet<String>()
|
||||||
|
val deleteWhere = org.mariotaku.sqliteqb.library.Expression.and(org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.ACCOUNT_KEY),
|
||||||
|
org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.WOEID)).sql
|
||||||
|
val deleteWhereArgs = arrayOf(accountKey.toString(), woeId.toString())
|
||||||
|
cr.delete(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs)
|
||||||
|
|
||||||
|
val allTrends = java.util.ArrayList<org.mariotaku.twidere.model.ParcelableTrend>()
|
||||||
|
|
||||||
|
trends.trends.forEachIndexed { idx, trend ->
|
||||||
|
val hashtag = trend.name.replaceFirst("#", "")
|
||||||
|
hashtags.add(hashtag)
|
||||||
|
allTrends.add(org.mariotaku.twidere.model.ParcelableTrend().apply {
|
||||||
|
this.account_key = accountKey
|
||||||
|
this.woe_id = woeId
|
||||||
|
this.name = trend.name
|
||||||
|
this.timestamp = System.currentTimeMillis()
|
||||||
|
this.trend_order = idx
|
||||||
|
})
|
||||||
|
}
|
||||||
|
org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert(cr, uri, allTrends.map(org.mariotaku.twidere.model.ParcelableTrendValuesCreator::create))
|
||||||
|
ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false,
|
||||||
|
hashtags, null, null)
|
||||||
|
ContentResolverUtils.bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map {
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(CachedHashtags.NAME, it)
|
||||||
|
return@map values
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.twidere.task.message
|
package org.mariotaku.twidere.task.twitter.message
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.microblog.library.MicroBlogException
|
import org.mariotaku.microblog.library.MicroBlogException
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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.task.twitter.message
|
||||||
|
|
||||||
|
import android.accounts.AccountManager
|
||||||
|
import android.content.Context
|
||||||
|
import org.mariotaku.microblog.library.MicroBlog
|
||||||
|
import org.mariotaku.microblog.library.MicroBlogException
|
||||||
|
import org.mariotaku.sqliteqb.library.Expression
|
||||||
|
import org.mariotaku.twidere.annotation.AccountType
|
||||||
|
import org.mariotaku.twidere.extension.model.isOfficial
|
||||||
|
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||||
|
import org.mariotaku.twidere.model.AccountDetails
|
||||||
|
import org.mariotaku.twidere.model.UserKey
|
||||||
|
import org.mariotaku.twidere.model.util.AccountUtils
|
||||||
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||||
|
import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 2017/2/16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DestroyMessageTask(
|
||||||
|
context: Context,
|
||||||
|
val accountKey: UserKey,
|
||||||
|
val conversationId: String?,
|
||||||
|
val messageId: String
|
||||||
|
) : ExceptionHandlingAbstractTask<Unit?, Boolean, MicroBlogException, Unit?>(context) {
|
||||||
|
override fun onExecute(params: Unit?): Boolean {
|
||||||
|
val account = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?:
|
||||||
|
throw MicroBlogException("No account")
|
||||||
|
val microBlog = account.newMicroBlogInstance(context, cls = MicroBlog::class.java)
|
||||||
|
if (!performDestroyMessage(microBlog, account)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val deleteWhere: String
|
||||||
|
val deleteWhereArgs: Array<String>
|
||||||
|
if (conversationId != null) {
|
||||||
|
deleteWhere = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
|
||||||
|
Expression.equalsArgs(Messages.CONVERSATION_ID),
|
||||||
|
Expression.equalsArgs(Messages.MESSAGE_ID)).sql
|
||||||
|
deleteWhereArgs = arrayOf(accountKey.toString(), conversationId, messageId)
|
||||||
|
} else {
|
||||||
|
deleteWhere = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY),
|
||||||
|
Expression.equalsArgs(Messages.MESSAGE_ID)).sql
|
||||||
|
deleteWhereArgs = arrayOf(accountKey.toString(), messageId)
|
||||||
|
}
|
||||||
|
context.contentResolver.delete(Messages.CONTENT_URI, deleteWhere, deleteWhereArgs)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performDestroyMessage(microBlog: MicroBlog, account: AccountDetails): Boolean {
|
||||||
|
when (account.type) {
|
||||||
|
AccountType.TWITTER -> {
|
||||||
|
if (account.isOfficial(context)) {
|
||||||
|
return microBlog.destroyDm(messageId).isSuccessful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
microBlog.destroyDirectMessage(messageId)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.mariotaku.twidere.task.message
|
package org.mariotaku.twidere.task.twitter.message
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.ktextension.isNotNullOrEmpty
|
import org.mariotaku.ktextension.isNotNullOrEmpty
|
||||||
|
@ -38,9 +38,9 @@ import org.mariotaku.twidere.model.event.SendMessageTaskEvent
|
||||||
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask
|
import org.mariotaku.twidere.task.ExceptionHandlingAbstractTask
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask.Companion.addConversation
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addConversation
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask.Companion.addLocalConversations
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.addLocalConversations
|
||||||
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
import org.mariotaku.twidere.task.twitter.UpdateStatusTask
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -1,35 +1,45 @@
|
||||||
package org.mariotaku.twidere.task
|
/*
|
||||||
|
* 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.task.twitter.message
|
||||||
|
|
||||||
import android.accounts.AccountManager
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.mariotaku.ktextension.toInt
|
import org.mariotaku.ktextension.toInt
|
||||||
import org.mariotaku.ktextension.useCursor
|
import org.mariotaku.ktextension.useCursor
|
||||||
import org.mariotaku.microblog.library.MicroBlog
|
|
||||||
import org.mariotaku.microblog.library.MicroBlogException
|
|
||||||
import org.mariotaku.microblog.library.twitter.model.DMResponse
|
import org.mariotaku.microblog.library.twitter.model.DMResponse
|
||||||
import org.mariotaku.microblog.library.twitter.model.Paging
|
|
||||||
import org.mariotaku.microblog.library.twitter.model.User
|
import org.mariotaku.microblog.library.twitter.model.User
|
||||||
import org.mariotaku.microblog.library.twitter.model.fixMedia
|
import org.mariotaku.microblog.library.twitter.model.fixMedia
|
||||||
import org.mariotaku.sqliteqb.library.Expression
|
import org.mariotaku.sqliteqb.library.Expression
|
||||||
import org.mariotaku.twidere.annotation.AccountType
|
|
||||||
import org.mariotaku.twidere.extension.model.applyFrom
|
import org.mariotaku.twidere.extension.model.applyFrom
|
||||||
import org.mariotaku.twidere.extension.model.isOfficial
|
import org.mariotaku.twidere.extension.model.isOfficial
|
||||||
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
|
||||||
import org.mariotaku.twidere.extension.model.timestamp
|
import org.mariotaku.twidere.extension.model.timestamp
|
||||||
import org.mariotaku.twidere.model.*
|
import org.mariotaku.twidere.model.*
|
||||||
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
|
import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType
|
||||||
import org.mariotaku.twidere.model.event.GetMessagesTaskEvent
|
|
||||||
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
|
import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils
|
|
||||||
import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
|
import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails
|
||||||
import org.mariotaku.twidere.model.util.ParcelableMessageUtils
|
|
||||||
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
import org.mariotaku.twidere.model.util.ParcelableUserUtils
|
||||||
import org.mariotaku.twidere.model.util.UserKeyUtils
|
import org.mariotaku.twidere.model.util.UserKeyUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
import org.mariotaku.twidere.util.DataStoreUtils
|
|
||||||
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
import org.mariotaku.twidere.util.content.ContentResolverUtils
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -38,35 +48,35 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GetMessagesTask(
|
class GetMessagesTask(
|
||||||
context: Context
|
context: android.content.Context
|
||||||
) : BaseAbstractTask<GetMessagesTask.RefreshMessagesTaskParam, Unit, (Boolean) -> Unit>(context) {
|
) : org.mariotaku.twidere.task.BaseAbstractTask<GetMessagesTask.RefreshMessagesTaskParam, Unit, (Boolean) -> Unit>(context) {
|
||||||
override fun doLongOperation(param: RefreshMessagesTaskParam) {
|
override fun doLongOperation(param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam) {
|
||||||
val accountKeys = param.accountKeys
|
val accountKeys = param.accountKeys
|
||||||
val am = AccountManager.get(context)
|
val am = android.accounts.AccountManager.get(context)
|
||||||
accountKeys.forEachIndexed { i, accountKey ->
|
accountKeys.forEachIndexed { i, accountKey ->
|
||||||
val details = getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
|
val details = getAccountDetails(am, accountKey, true) ?: return@forEachIndexed
|
||||||
val microBlog = details.newMicroBlogInstance(context, true, cls = MicroBlog::class.java)
|
val microBlog = details.newMicroBlogInstance(context, true, cls = org.mariotaku.microblog.library.MicroBlog::class.java)
|
||||||
val messages = try {
|
val messages = try {
|
||||||
getMessages(microBlog, details, param, i)
|
getMessages(microBlog, details, param, i)
|
||||||
} catch (e: MicroBlogException) {
|
} catch (e: org.mariotaku.microblog.library.MicroBlogException) {
|
||||||
return@forEachIndexed
|
return@forEachIndexed
|
||||||
}
|
}
|
||||||
storeMessages(context, messages, details)
|
org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.storeMessages(context, messages, details)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Unit) {
|
override fun afterExecute(callback: ((Boolean) -> Unit)?, result: Unit) {
|
||||||
callback?.invoke(true)
|
callback?.invoke(true)
|
||||||
bus.post(GetMessagesTaskEvent(Messages.CONTENT_URI, params?.taskTag, false, null))
|
bus.post(org.mariotaku.twidere.model.event.GetMessagesTaskEvent(org.mariotaku.twidere.provider.TwidereDataStore.Messages.CONTENT_URI, params?.taskTag, false, null))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails, param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
when (details.type) {
|
when (details.type) {
|
||||||
AccountType.FANFOU -> {
|
org.mariotaku.twidere.annotation.AccountType.FANFOU -> {
|
||||||
// Use fanfou DM api, disabled since it's conversation api is not suitable for paging
|
// Use fanfou DM api, disabled since it's conversation api is not suitable for paging
|
||||||
// return getFanfouMessages(microBlog, details, param, index)
|
// return getFanfouMessages(microBlog, details, param, index)
|
||||||
}
|
}
|
||||||
AccountType.TWITTER -> {
|
org.mariotaku.twidere.annotation.AccountType.TWITTER -> {
|
||||||
// Use official DM api
|
// Use official DM api
|
||||||
if (details.isOfficial(context)) {
|
if (details.isOfficial(context)) {
|
||||||
return getTwitterOfficialMessages(microBlog, details, param, index)
|
return getTwitterOfficialMessages(microBlog, details, param, index)
|
||||||
|
@ -77,8 +87,8 @@ class GetMessagesTask(
|
||||||
return getDefaultMessages(microBlog, details, param, index)
|
return getDefaultMessages(microBlog, details, param, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialMessages(microBlog: MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails,
|
||||||
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val conversationId = param.conversationId
|
val conversationId = param.conversationId
|
||||||
if (conversationId == null) {
|
if (conversationId == null) {
|
||||||
return getTwitterOfficialUserInbox(microBlog, details, param, index)
|
return getTwitterOfficialUserInbox(microBlog, details, param, index)
|
||||||
|
@ -87,22 +97,22 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFanfouMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getFanfouMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails, param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val conversationId = param.conversationId
|
val conversationId = param.conversationId
|
||||||
if (conversationId == null) {
|
if (conversationId == null) {
|
||||||
return getFanfouConversations(microBlog, details, param, index)
|
return getFanfouConversations(microBlog, details, param, index)
|
||||||
} else {
|
} else {
|
||||||
return DatabaseUpdateData(emptyList(), emptyList())
|
return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDefaultMessages(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getDefaultMessages(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails, param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val accountKey = details.key
|
val accountKey = details.key
|
||||||
|
|
||||||
val sinceIds = if (param.hasSinceIds) param.sinceIds else null
|
val sinceIds = if (param.hasSinceIds) param.sinceIds else null
|
||||||
val maxIds = if (param.hasMaxIds) param.maxIds else null
|
val maxIds = if (param.hasMaxIds) param.maxIds else null
|
||||||
|
|
||||||
val received = microBlog.getDirectMessages(Paging().apply {
|
val received = microBlog.getDirectMessages(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
||||||
count(100)
|
count(100)
|
||||||
val maxId = maxIds?.get(index)
|
val maxId = maxIds?.get(index)
|
||||||
val sinceId = sinceIds?.get(index)
|
val sinceId = sinceIds?.get(index)
|
||||||
|
@ -113,7 +123,7 @@ class GetMessagesTask(
|
||||||
sinceId(sinceId)
|
sinceId(sinceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
val sent = microBlog.getSentDirectMessages(Paging().apply {
|
val sent = microBlog.getSentDirectMessages(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
||||||
count(100)
|
count(100)
|
||||||
val accountsCount = param.accountKeys.size
|
val accountsCount = param.accountKeys.size
|
||||||
val maxId = maxIds?.get(accountsCount + index)
|
val maxId = maxIds?.get(accountsCount + index)
|
||||||
|
@ -127,75 +137,75 @@ class GetMessagesTask(
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
val insertMessages = arrayListOf<ParcelableMessage>()
|
val insertMessages = arrayListOf<org.mariotaku.twidere.model.ParcelableMessage>()
|
||||||
val conversations = hashMapOf<String, ParcelableMessageConversation>()
|
val conversations = hashMapOf<String, org.mariotaku.twidere.model.ParcelableMessageConversation>()
|
||||||
|
|
||||||
val conversationIds = hashSetOf<String>()
|
val conversationIds = hashSetOf<String>()
|
||||||
received.forEach {
|
received.forEach {
|
||||||
conversationIds.add(ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
conversationIds.add(org.mariotaku.twidere.model.util.ParcelableMessageUtils.incomingConversationId(it.senderId, it.recipientId))
|
||||||
}
|
}
|
||||||
sent.forEach {
|
sent.forEach {
|
||||||
conversationIds.add(ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId))
|
conversationIds.add(org.mariotaku.twidere.model.util.ParcelableMessageUtils.outgoingConversationId(it.senderId, it.recipientId))
|
||||||
}
|
}
|
||||||
|
|
||||||
conversations.addLocalConversations(context, accountKey, conversationIds)
|
conversations.addLocalConversations(context, accountKey, conversationIds)
|
||||||
|
|
||||||
received.forEachIndexed { i, dm ->
|
received.forEachIndexed { i, dm ->
|
||||||
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, false,
|
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, false,
|
||||||
1.0 - (i.toDouble() / received.size))
|
1.0 - (i.toDouble() / received.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
||||||
}
|
}
|
||||||
sent.forEachIndexed { i, dm ->
|
sent.forEachIndexed { i, dm ->
|
||||||
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, true,
|
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, true,
|
||||||
1.0 - (i.toDouble() / sent.size))
|
1.0 - (i.toDouble() / sent.size))
|
||||||
insertMessages.add(message)
|
insertMessages.add(message)
|
||||||
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
conversations.addConversation(message.conversation_id, details, message, setOf(dm.sender, dm.recipient))
|
||||||
}
|
}
|
||||||
return DatabaseUpdateData(conversations.values, insertMessages)
|
return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData(conversations.values, insertMessages)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialConversation(microBlog: MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialConversation(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails,
|
||||||
conversationId: String, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
conversationId: String, param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val maxId = param.maxIds?.get(index) ?: return DatabaseUpdateData(emptyList(), emptyList())
|
val maxId = param.maxIds?.get(index) ?: return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData(emptyList(), emptyList())
|
||||||
val paging = Paging().apply {
|
val paging = org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
||||||
maxId(maxId)
|
maxId(maxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
val response = microBlog.getDmConversation(conversationId, paging).conversationTimeline
|
val response = microBlog.getDmConversation(conversationId, paging).conversationTimeline
|
||||||
response.fixMedia(microBlog)
|
response.fixMedia(microBlog)
|
||||||
return createDatabaseUpdateData(context, details, response)
|
return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.createDatabaseUpdateData(context, details, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTwitterOfficialUserInbox(microBlog: MicroBlog, details: AccountDetails,
|
private fun getTwitterOfficialUserInbox(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails,
|
||||||
param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val maxId = if (param.hasMaxIds) param.maxIds?.get(index) else null
|
val maxId = if (param.hasMaxIds) param.maxIds?.get(index) else null
|
||||||
val cursor = if (param.hasCursors) param.cursors?.get(index) else null
|
val cursor = if (param.hasCursors) param.cursors?.get(index) else null
|
||||||
val response = if (cursor != null) {
|
val response = if (cursor != null) {
|
||||||
microBlog.getUserUpdates(cursor).userEvents
|
microBlog.getUserUpdates(cursor).userEvents
|
||||||
} else {
|
} else {
|
||||||
microBlog.getUserInbox(Paging().apply {
|
microBlog.getUserInbox(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
||||||
if (maxId != null) {
|
if (maxId != null) {
|
||||||
maxId(maxId)
|
maxId(maxId)
|
||||||
}
|
}
|
||||||
}).userInbox
|
}).userInbox
|
||||||
}
|
}
|
||||||
response.fixMedia(microBlog)
|
response.fixMedia(microBlog)
|
||||||
return createDatabaseUpdateData(context, details, response)
|
return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.Companion.createDatabaseUpdateData(context, details, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getFanfouConversations(microBlog: MicroBlog, details: AccountDetails, param: RefreshMessagesTaskParam, index: Int): DatabaseUpdateData {
|
private fun getFanfouConversations(microBlog: org.mariotaku.microblog.library.MicroBlog, details: org.mariotaku.twidere.model.AccountDetails, param: org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam, index: Int): org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val accountKey = details.key
|
val accountKey = details.key
|
||||||
val cursor = param.cursors?.get(index)
|
val cursor = param.cursors?.get(index)
|
||||||
val page = cursor?.substringAfter("page:").toInt(-1)
|
val page = cursor?.substringAfter("page:").toInt(-1)
|
||||||
val result = microBlog.getConversationList(Paging().apply {
|
val result = microBlog.getConversationList(org.mariotaku.microblog.library.twitter.model.Paging().apply {
|
||||||
count(60)
|
count(60)
|
||||||
if (page >= 0) {
|
if (page >= 0) {
|
||||||
page(page)
|
page(page)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
val conversations = hashMapOf<String, ParcelableMessageConversation>()
|
val conversations = hashMapOf<String, org.mariotaku.twidere.model.ParcelableMessageConversation>()
|
||||||
|
|
||||||
val conversationIds = hashSetOf<String>()
|
val conversationIds = hashSetOf<String>()
|
||||||
result.mapTo(conversationIds) { "${accountKey.id}-${it.otherId}" }
|
result.mapTo(conversationIds) { "${accountKey.id}-${it.otherId}" }
|
||||||
|
@ -203,32 +213,32 @@ class GetMessagesTask(
|
||||||
result.forEachIndexed { i, item ->
|
result.forEachIndexed { i, item ->
|
||||||
val dm = item.dm
|
val dm = item.dm
|
||||||
// Sender is our self, treat as outgoing message
|
// Sender is our self, treat as outgoing message
|
||||||
val message = ParcelableMessageUtils.fromMessage(accountKey, dm, dm.senderId == accountKey.id,
|
val message = org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromMessage(accountKey, dm, dm.senderId == accountKey.id,
|
||||||
1.0 - (i.toDouble() / result.size))
|
1.0 - (i.toDouble() / result.size))
|
||||||
val mc = conversations.addConversation(message.conversation_id, details, message,
|
val mc = conversations.addConversation(message.conversation_id, details, message,
|
||||||
setOf(dm.sender, dm.recipient))
|
setOf(dm.sender, dm.recipient))
|
||||||
mc.request_cursor = "page:$page"
|
mc.request_cursor = "page:$page"
|
||||||
}
|
}
|
||||||
return DatabaseUpdateData(conversations.values, emptyList())
|
return org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData(conversations.values, emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
data class DatabaseUpdateData(
|
data class DatabaseUpdateData(
|
||||||
val conversations: Collection<ParcelableMessageConversation>,
|
val conversations: Collection<org.mariotaku.twidere.model.ParcelableMessageConversation>,
|
||||||
val messages: Collection<ParcelableMessage>,
|
val messages: Collection<org.mariotaku.twidere.model.ParcelableMessage>,
|
||||||
val deleteConversations: List<String> = emptyList(),
|
val deleteConversations: List<String> = emptyList(),
|
||||||
val deleteMessages: Map<String, List<String>> = emptyMap(),
|
val deleteMessages: Map<String, List<String>> = emptyMap(),
|
||||||
val conversationRequestCursor: String? = null
|
val conversationRequestCursor: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
abstract class RefreshNewTaskParam(
|
abstract class RefreshNewTaskParam(
|
||||||
context: Context
|
context: android.content.Context
|
||||||
) : RefreshMessagesTaskParam(context) {
|
) : org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam(context) {
|
||||||
|
|
||||||
override val sinceIds: Array<String?>?
|
override val sinceIds: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val incomingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
val incomingIds = org.mariotaku.twidere.util.DataStoreUtils.getNewestMessageIds(context, org.mariotaku.twidere.provider.TwidereDataStore.Messages.CONTENT_URI,
|
||||||
defaultKeys, false)
|
defaultKeys, false)
|
||||||
val outgoingIds = DataStoreUtils.getNewestMessageIds(context, Messages.CONTENT_URI,
|
val outgoingIds = org.mariotaku.twidere.util.DataStoreUtils.getNewestMessageIds(context, org.mariotaku.twidere.provider.TwidereDataStore.Messages.CONTENT_URI,
|
||||||
defaultKeys, true)
|
defaultKeys, true)
|
||||||
return incomingIds + outgoingIds
|
return incomingIds + outgoingIds
|
||||||
}
|
}
|
||||||
|
@ -236,8 +246,8 @@ class GetMessagesTask(
|
||||||
override val cursors: Array<String?>?
|
override val cursors: Array<String?>?
|
||||||
get() {
|
get() {
|
||||||
val cursors = arrayOfNulls<String>(defaultKeys.size)
|
val cursors = arrayOfNulls<String>(defaultKeys.size)
|
||||||
val newestConversations = DataStoreUtils.getNewestConversations(context,
|
val newestConversations = org.mariotaku.twidere.util.DataStoreUtils.getNewestConversations(context,
|
||||||
Messages.Conversations.CONTENT_URI, twitterOfficialKeys)
|
org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations.CONTENT_URI, twitterOfficialKeys)
|
||||||
newestConversations.forEachIndexed { i, conversation ->
|
newestConversations.forEachIndexed { i, conversation ->
|
||||||
cursors[i] = conversation?.request_cursor
|
cursors[i] = conversation?.request_cursor
|
||||||
}
|
}
|
||||||
|
@ -250,18 +260,18 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class LoadMoreEntriesTaskParam(
|
abstract class LoadMoreEntriesTaskParam(
|
||||||
context: Context
|
context: android.content.Context
|
||||||
) : RefreshMessagesTaskParam(context) {
|
) : org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam(context) {
|
||||||
|
|
||||||
override val maxIds: Array<String?>? by lazy {
|
override val maxIds: Array<String?>? by lazy {
|
||||||
val incomingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
val incomingIds = org.mariotaku.twidere.util.DataStoreUtils.getOldestMessageIds(context, org.mariotaku.twidere.provider.TwidereDataStore.Messages.CONTENT_URI,
|
||||||
defaultKeys, false)
|
defaultKeys, false)
|
||||||
val outgoingIds = DataStoreUtils.getOldestMessageIds(context, Messages.CONTENT_URI,
|
val outgoingIds = org.mariotaku.twidere.util.DataStoreUtils.getOldestMessageIds(context, org.mariotaku.twidere.provider.TwidereDataStore.Messages.CONTENT_URI,
|
||||||
defaultKeys, true)
|
defaultKeys, true)
|
||||||
val oldestConversations = DataStoreUtils.getOldestConversations(context,
|
val oldestConversations = org.mariotaku.twidere.util.DataStoreUtils.getOldestConversations(context,
|
||||||
Messages.Conversations.CONTENT_URI, twitterOfficialKeys)
|
org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations.CONTENT_URI, twitterOfficialKeys)
|
||||||
oldestConversations.forEachIndexed { i, conversation ->
|
oldestConversations.forEachIndexed { i, conversation ->
|
||||||
val extras = conversation?.conversation_extras as? TwitterOfficialConversationExtras ?: return@forEachIndexed
|
val extras = conversation?.conversation_extras as? org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras ?: return@forEachIndexed
|
||||||
incomingIds[i] = extras.maxEntryId
|
incomingIds[i] = extras.maxEntryId
|
||||||
}
|
}
|
||||||
return@lazy incomingIds + outgoingIds
|
return@lazy incomingIds + outgoingIds
|
||||||
|
@ -272,19 +282,19 @@ class GetMessagesTask(
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoadMoreMessageTaskParam(
|
class LoadMoreMessageTaskParam(
|
||||||
context: Context,
|
context: android.content.Context,
|
||||||
accountKey: UserKey,
|
accountKey: org.mariotaku.twidere.model.UserKey,
|
||||||
override val conversationId: String,
|
override val conversationId: String,
|
||||||
maxId: String
|
maxId: String
|
||||||
) : RefreshMessagesTaskParam(context) {
|
) : org.mariotaku.twidere.task.twitter.message.GetMessagesTask.RefreshMessagesTaskParam(context) {
|
||||||
override val accountKeys: Array<UserKey> = arrayOf(accountKey)
|
override val accountKeys: Array<org.mariotaku.twidere.model.UserKey> = arrayOf(accountKey)
|
||||||
override val maxIds: Array<String?>? = arrayOf(maxId)
|
override val maxIds: Array<String?>? = arrayOf(maxId)
|
||||||
override val hasMaxIds: Boolean = true
|
override val hasMaxIds: Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RefreshMessagesTaskParam(
|
abstract class RefreshMessagesTaskParam(
|
||||||
val context: Context
|
val context: android.content.Context
|
||||||
) : SimpleRefreshTaskParam() {
|
) : org.mariotaku.twidere.model.SimpleRefreshTaskParam() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `conversationId` has value, load messages in conversationId
|
* If `conversationId` has value, load messages in conversationId
|
||||||
|
@ -293,21 +303,21 @@ class GetMessagesTask(
|
||||||
|
|
||||||
var taskTag: String? = null
|
var taskTag: String? = null
|
||||||
|
|
||||||
protected val accounts: Array<AccountDetails?> by lazy {
|
protected val accounts: Array<org.mariotaku.twidere.model.AccountDetails?> by lazy {
|
||||||
AccountUtils.getAllAccountDetails(AccountManager.get(context), accountKeys, false)
|
org.mariotaku.twidere.model.util.AccountUtils.getAllAccountDetails(android.accounts.AccountManager.get(context), accountKeys, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val defaultKeys: Array<UserKey?>by lazy {
|
protected val defaultKeys: Array<org.mariotaku.twidere.model.UserKey?>by lazy {
|
||||||
return@lazy accounts.map { account ->
|
return@lazy accounts.map { account ->
|
||||||
account ?: return@map null
|
account ?: return@map null
|
||||||
if (account.isOfficial(context) || account.type == AccountType.FANFOU) {
|
if (account.isOfficial(context) || account.type == org.mariotaku.twidere.annotation.AccountType.FANFOU) {
|
||||||
return@map null
|
return@map null
|
||||||
}
|
}
|
||||||
return@map account.key
|
return@map account.key
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val twitterOfficialKeys: Array<UserKey?> by lazy {
|
protected val twitterOfficialKeys: Array<org.mariotaku.twidere.model.UserKey?> by lazy {
|
||||||
return@lazy accounts.map { account ->
|
return@lazy accounts.map { account ->
|
||||||
account ?: return@map null
|
account ?: return@map null
|
||||||
if (!account.isOfficial(context)) {
|
if (!account.isOfficial(context)) {
|
||||||
|
@ -321,22 +331,22 @@ class GetMessagesTask(
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun createDatabaseUpdateData(context: Context, account: AccountDetails, response: DMResponse):
|
fun createDatabaseUpdateData(context: android.content.Context, account: org.mariotaku.twidere.model.AccountDetails, response: org.mariotaku.microblog.library.twitter.model.DMResponse):
|
||||||
DatabaseUpdateData {
|
org.mariotaku.twidere.task.twitter.message.GetMessagesTask.DatabaseUpdateData {
|
||||||
val respConversations = response.conversations.orEmpty()
|
val respConversations = response.conversations.orEmpty()
|
||||||
val respEntries = response.entries.orEmpty()
|
val respEntries = response.entries.orEmpty()
|
||||||
val respUsers = response.users.orEmpty()
|
val respUsers = response.users.orEmpty()
|
||||||
|
|
||||||
val conversations = hashMapOf<String, ParcelableMessageConversation>()
|
val conversations = hashMapOf<String, org.mariotaku.twidere.model.ParcelableMessageConversation>()
|
||||||
|
|
||||||
conversations.addLocalConversations(context, account.key, respConversations.keys)
|
conversations.addLocalConversations(context, account.key, respConversations.keys)
|
||||||
val messages = ArrayList<ParcelableMessage>()
|
val messages = java.util.ArrayList<org.mariotaku.twidere.model.ParcelableMessage>()
|
||||||
val messageDeletionsMap = HashMap<String, ArrayList<String>>()
|
val messageDeletionsMap = java.util.HashMap<String, java.util.ArrayList<String>>()
|
||||||
val conversationDeletions = ArrayList<String>()
|
val conversationDeletions = java.util.ArrayList<String>()
|
||||||
respEntries.mapNotNullTo(messages) { entry ->
|
respEntries.mapNotNullTo(messages) { entry ->
|
||||||
when {
|
when {
|
||||||
entry.messageDelete != null -> {
|
entry.messageDelete != null -> {
|
||||||
val list = messageDeletionsMap.getOrPut(entry.messageDelete.conversationId) { ArrayList<String>() }
|
val list = messageDeletionsMap.getOrPut(entry.messageDelete.conversationId) { java.util.ArrayList<String>() }
|
||||||
entry.messageDelete.messages?.forEach {
|
entry.messageDelete.messages?.forEach {
|
||||||
list.add(it.messageId)
|
list.add(it.messageId)
|
||||||
}
|
}
|
||||||
|
@ -347,11 +357,11 @@ class GetMessagesTask(
|
||||||
return@mapNotNullTo null
|
return@mapNotNullTo null
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
return@mapNotNullTo ParcelableMessageUtils.fromEntry(account.key, entry, respUsers)
|
return@mapNotNullTo org.mariotaku.twidere.model.util.ParcelableMessageUtils.fromEntry(account.key, entry, respUsers)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val messagesMap = messages.groupBy(ParcelableMessage::conversation_id)
|
val messagesMap = messages.groupBy(org.mariotaku.twidere.model.ParcelableMessage::conversation_id)
|
||||||
for ((k, v) in respConversations) {
|
for ((k, v) in respConversations) {
|
||||||
val message = messagesMap[k]?.maxBy(ParcelableMessage::message_timestamp) ?: continue
|
val message = messagesMap[k]?.maxBy(ParcelableMessage::message_timestamp) ?: continue
|
||||||
val participants = respUsers.filterKeys { userId ->
|
val participants = respUsers.filterKeys { userId ->
|
|
@ -45,6 +45,11 @@ import org.mariotaku.twidere.model.event.*
|
||||||
import org.mariotaku.twidere.model.util.ParcelableUserListUtils
|
import org.mariotaku.twidere.model.util.ParcelableUserListUtils
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
import org.mariotaku.twidere.provider.TwidereDataStore.*
|
||||||
import org.mariotaku.twidere.task.*
|
import org.mariotaku.twidere.task.*
|
||||||
|
import org.mariotaku.twidere.task.twitter.GetActivitiesAboutMeTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.GetHomeTimelineTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.GetSavedSearchesTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.GetTrendsTask
|
||||||
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
import org.mariotaku.twidere.util.collection.CompactHashSet
|
import org.mariotaku.twidere.util.collection.CompactHashSet
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ import org.mariotaku.twidere.model.SimpleRefreshTaskParam
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||||
import org.mariotaku.twidere.task.GetActivitiesAboutMeTask
|
import org.mariotaku.twidere.task.twitter.GetActivitiesAboutMeTask
|
||||||
import org.mariotaku.twidere.task.GetHomeTimelineTask
|
import org.mariotaku.twidere.task.twitter.GetHomeTimelineTask
|
||||||
import org.mariotaku.twidere.task.GetMessagesTask
|
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
|
||||||
import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask
|
import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,6 +53,11 @@ class MessageViewHolder(itemView: View, adapter: MessagesConversationAdapter) :
|
||||||
val textSize = adapter.textSize
|
val textSize = adapter.textSize
|
||||||
text.textSize = textSize
|
text.textSize = textSize
|
||||||
mediaPreview.style = adapter.mediaPreviewStyle
|
mediaPreview.style = adapter.mediaPreviewStyle
|
||||||
|
|
||||||
|
messageBubble.setOnLongClickListener {
|
||||||
|
val listener = adapter.listener ?: return@setOnLongClickListener false
|
||||||
|
return@setOnLongClickListener listener.onMessageLongClick(layoutPosition, this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun display(message: ParcelableMessage, showDate: Boolean) {
|
override fun display(message: ParcelableMessage, showDate: Boolean) {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ 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/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/copy"
|
||||||
|
android:title="@android:string/copy"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/delete"
|
||||||
|
android:title="@string/action_delete"/>
|
||||||
|
</menu>
|
Loading…
Reference in New Issue