improved draft deletion

This commit is contained in:
Mariotaku Lee 2017-01-23 23:58:47 +08:00
parent 4e47cbb387
commit ce4d921d7a
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
4 changed files with 55 additions and 46 deletions

View File

@ -34,8 +34,8 @@ android {
applicationId "org.mariotaku.twidere"
minSdkVersion 14
targetSdkVersion 25
versionCode 256
versionName '3.3.38'
versionCode 257
versionName '3.3.39'
multiDexEnabled true
buildConfigField 'boolean', 'LEAK_CANARY_ENABLED', 'Boolean.parseBoolean("true")'

View File

@ -36,7 +36,6 @@ import android.support.v4.app.LoaderManager.LoaderCallbacks
import android.support.v4.content.CursorLoader
import android.support.v4.content.Loader
import android.text.TextUtils
import android.util.Log
import android.view.*
import android.widget.AbsListView.MultiChoiceModeListener
import android.widget.AdapterView
@ -44,7 +43,6 @@ import android.widget.AdapterView.OnItemClickListener
import android.widget.ListView
import kotlinx.android.synthetic.main.fragment_drafts.*
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.toStringArray
import org.mariotaku.sqliteqb.library.Columns.Column
import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.sqliteqb.library.RawItemArray
@ -59,14 +57,13 @@ import org.mariotaku.twidere.extension.selectAll
import org.mariotaku.twidere.extension.selectNone
import org.mariotaku.twidere.extension.updateSelectionItems
import org.mariotaku.twidere.model.Draft
import org.mariotaku.twidere.model.ParcelableMediaUpdate
import org.mariotaku.twidere.model.draft.SendDirectMessageActionExtras
import org.mariotaku.twidere.model.util.ParcelableStatusUpdateUtils
import org.mariotaku.twidere.provider.TwidereDataStore.Drafts
import org.mariotaku.twidere.service.LengthyOperationsService
import org.mariotaku.twidere.util.AsyncTaskUtils
import org.mariotaku.twidere.util.JsonSerializer
import java.io.File
import org.mariotaku.twidere.util.deleteDrafts
import java.lang.ref.WeakReference
import java.util.*
class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickListener, MultiChoiceModeListener {
@ -264,43 +261,19 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
}
private class DeleteDraftsTask(
private val activity: FragmentActivity,
activity: FragmentActivity,
private val ids: LongArray
) : AsyncTask<Any, Any, Unit>() {
private val notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
private val activityRef = WeakReference(activity)
override fun doInBackground(vararg params: Any) {
val resolver = activity.contentResolver
val where = Expression.inArgs(Column(Drafts._ID), ids.size)
val projection = arrayOf(Drafts.MEDIA)
val selection = where.sql
val selectionArgs = ids.toStringArray()
val c = resolver.query(Drafts.CONTENT_URI, projection, selection, selectionArgs, null) ?: return
@Suppress("ConvertTryFinallyToUseCall")
try {
val idxMedia = c.getColumnIndex(Drafts.MEDIA)
c.moveToFirst()
while (!c.isAfterLast) {
val mediaArray = JsonSerializer.parseArray(c.getString(idxMedia), ParcelableMediaUpdate::class.java)
mediaArray?.forEach { media ->
val uri = Uri.parse(media.uri)
if ("file" == uri.scheme) {
val file = File(uri.path)
if (!file.delete()) {
Log.w(LOGTAG, String.format("Unable to delete %s", file))
}
}
}
c.moveToNext()
}
} finally {
c.close()
}
resolver.delete(Drafts.CONTENT_URI, selection, selectionArgs)
val activity = activityRef.get() ?: return
deleteDrafts(activity, ids)
}
override fun onPreExecute() {
super.onPreExecute()
val activity = activityRef.get() ?: return
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity ->
val f = ProgressDialogFragment.show(activity.supportFragmentManager, FRAGMENT_TAG_DELETING_DRAFTS)
f.isCancelable = false
@ -308,7 +281,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
}
override fun onPostExecute(result: Unit) {
super.onPostExecute(result)
val activity = activityRef.get() ?: return
(activity as IExtendedActivity<*>).executeAfterFragmentResumed { activity ->
val fm = activity.supportFragmentManager
val f = fm.findFragmentByTag(FRAGMENT_TAG_DELETING_DRAFTS)
@ -316,6 +289,7 @@ class DraftsFragment : BaseFragment(), LoaderCallbacks<Cursor?>, OnItemClickList
f.dismiss()
}
}
val notificationManager = activity.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
ids.forEach { id ->
val tag = Uri.withAppendedPath(Drafts.CONTENT_URI, id.toString()).toString()
notificationManager.cancel(tag, NOTIFICATION_ID_DRAFTS)

View File

@ -26,7 +26,6 @@ import android.app.Service
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Point
import android.net.Uri
import android.os.Handler
import android.os.Looper
@ -41,6 +40,8 @@ import android.widget.Toast
import edu.tsinghua.hotmobi.HotMobiLogger
import edu.tsinghua.hotmobi.model.TimelineType
import edu.tsinghua.hotmobi.model.TweetEvent
import nl.komponents.kovenant.task
import nl.komponents.kovenant.ui.successUi
import org.mariotaku.abstask.library.ManualTaskStarter
import org.mariotaku.ktextension.configure
import org.mariotaku.ktextension.toLong
@ -70,8 +71,8 @@ import org.mariotaku.twidere.task.twitter.UpdateStatusTask
import org.mariotaku.twidere.util.ContentValuesCreator
import org.mariotaku.twidere.util.NotificationManagerWrapper
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.deleteDrafts
import org.mariotaku.twidere.util.io.ContentLengthInputStream.ReadListener
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit
@ -147,12 +148,17 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
}
}
@SuppressLint("Recycle")
private fun handleDiscardDraftIntent(intent: Intent) {
val data = intent.data ?: return
notificationManager.cancel(data.toString(), NOTIFICATION_ID_DRAFTS)
val id = data.lastPathSegment.toLong(-1)
val where = Expression.equals(Drafts._ID, id)
contentResolver.delete(Drafts.CONTENT_URI, where.sql, null)
task {
if (deleteDrafts(this, longArrayOf(data.lastPathSegment.toLong(-1))) < 1) {
throw IOException()
}
return@task data
}.successUi { uri ->
notificationManager.cancel(data.toString(), NOTIFICATION_ID_DRAFTS)
}
}
private fun handleSendDirectMessageIntent(intent: Intent) {

View File

@ -1,13 +1,18 @@
package org.mariotaku.twidere.util
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.net.Uri
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.useCursor
import org.mariotaku.pickncrop.library.PNCUtils
import org.mariotaku.sqliteqb.library.*
import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey
import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey
import org.mariotaku.twidere.model.DraftCursorIndices
import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags
import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.provider.TwidereDataStore.*
/**
* Created by mariotaku on 2016/12/24.
@ -76,3 +81,27 @@ fun buildStatusFilterWhereClause(preferences: SharedPreferences,
}
return filterExpression
}
@SuppressLint("Recycle")
fun deleteDrafts(context: Context, draftIds: LongArray): Int {
val where = Expression.inArgs(Drafts._ID, draftIds.size).sql
val whereArgs = draftIds.map(Long::toString).toTypedArray()
context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where, whereArgs,
null).useCursor { cursor ->
val indices = DraftCursorIndices(cursor)
cursor.moveToFirst()
while (!cursor.isAfterLast) {
val draft = indices.newObject(cursor)
draft.media?.forEach { item ->
try {
PNCUtils.deleteMedia(context, Uri.parse(item.uri))
} catch (e: SecurityException) {
// Ignore
}
}
cursor.moveToNext()
}
}
return context.contentResolver.delete(Drafts.CONTENT_URI, where, whereArgs)
}