diff --git a/.travis.yml b/.travis.yml index f82c5f06f..f125713fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,8 @@ jdk: oraclejdk8 android: components: - tools - - build-tools-26.0.2 - - android-26 + - build-tools-27.0.1 + - android-27 env: global: diff --git a/build.gradle b/build.gradle index fef77851f..09445c770 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,8 @@ allprojects { projectVersionCode = 397 projectVersionName = '3.7.3' - globalCompileSdkVersion = 26 - globalBuildToolsVersion = '26.0.2' + globalCompileSdkVersion = 27 + globalBuildToolsVersion = '27.0.1' } repositories { @@ -35,19 +35,19 @@ allprojects { subprojects { buildscript { ext { - kotlinVersion = '1.1.51' + kotlinVersion = '1.1.60' pluginVersions = [ AndroidSvgDrawable: '3.0.0', PlayServices : '3.1.1', ] libVersions = [ Kotlin : "${kotlinVersion}", - SupportLib : '26.1.0', + SupportLib : '27.0.1', SupportTest : '1.0.0', MariotakuCommons : '0.9.20', RestFu : '0.9.60', ObjectCursor : '0.9.21', - PlayServices : '11.4.2', + PlayServices : '11.6.0', PlayBilling : '1.0', MapsUtils : '0.5', DropboxCoreSdk : '3.0.3', diff --git a/twidere/build.gradle b/twidere/build.gradle index c41d6890e..f2575855e 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -33,7 +33,7 @@ android { defaultConfig { applicationId "org.mariotaku.twidere" minSdkVersion 14 - targetSdkVersion 26 + targetSdkVersion 27 versionCode projectVersionCode versionName projectVersionName multiDexEnabled true diff --git a/twidere/src/.google.commit-id b/twidere/src/.google.commit-id index c53b306f7..2f5fc7967 100644 --- a/twidere/src/.google.commit-id +++ b/twidere/src/.google.commit-id @@ -1 +1 @@ -721ccb074a190dce53db68e6427ea28ba378a0a4 +635f0b286b0394d6aae591245703ed981276d86f diff --git a/twidere/src/main/kotlin/org/mariotaku/ktextension/BundleExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/ktextension/BundleExtensions.kt index 4dadab888..2fbdcfb2b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/ktextension/BundleExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/ktextension/BundleExtensions.kt @@ -2,6 +2,9 @@ package org.mariotaku.ktextension import android.os.Bundle import android.os.Parcelable +import java.lang.ref.WeakReference +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty inline fun Bundle(copyFrom: Bundle? = null, action: Bundle.() -> Unit): Bundle { val bundle = Bundle() diff --git a/twidere/src/main/kotlin/org/mariotaku/ktextension/WeakProperty.kt b/twidere/src/main/kotlin/org/mariotaku/ktextension/WeakProperty.kt index 6f8336074..e2f1bc535 100644 --- a/twidere/src/main/kotlin/org/mariotaku/ktextension/WeakProperty.kt +++ b/twidere/src/main/kotlin/org/mariotaku/ktextension/WeakProperty.kt @@ -30,9 +30,7 @@ class WeakDelegate(obj: T?) { weakRef = if (obj != null) WeakReference(obj) else null } - operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { - return weakRef?.get() - } + operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = weakRef?.get() operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { weakRef = if (value != null) WeakReference(value) else null diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt index a797f525d..fa775aaa8 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt @@ -1908,7 +1908,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val context = activity + val context = context!! val builder = AlertDialog.Builder(context) builder.setMessage(R.string.quote_protected_status_warning_message) builder.setPositiveButton(R.string.send_anyway, this) @@ -1921,7 +1921,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener class DirectMessageConfirmFragment : BaseDialogFragment(), DialogInterface.OnClickListener { - private val screenName: String get() = arguments.getString(EXTRA_SCREEN_NAME) + private val screenName: String get() = arguments!!.getString(EXTRA_SCREEN_NAME) override fun onClick(dialog: DialogInterface, which: Int) { val activity = activity @@ -1942,7 +1942,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val context = activity + val context = context!! val builder = AlertDialog.Builder(context) builder.setMessage(getString(R.string.message_format_compose_message_convert_to_status, "@$screenName")) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt index 8fa1eb571..2b081a1f3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt @@ -1050,7 +1050,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp class AutoRefreshConfirmDialogFragment : BaseDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setTitle(R.string.auto_refresh) builder.setMessage(R.string.message_auto_refresh_confirm) builder.setPositiveButton(android.R.string.ok) { _, _ -> diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/InvalidAccountAlertActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/InvalidAccountAlertActivity.kt index cf46faf80..235606753 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/InvalidAccountAlertActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/InvalidAccountAlertActivity.kt @@ -67,7 +67,7 @@ class InvalidAccountAlertActivity : FragmentActivity(), IBaseActivity @@ -83,6 +83,7 @@ class InvalidAccountAlertActivity : FragmentActivity(), IBaseActivity= adapter.count) return null return adapter.instantiateItem(viewPager, currentItem) as? MediaViewerFragment @@ -112,7 +112,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos private fun getCurrentCacheFileInfo(position: Int): SaveFileTask.FileInfo? { if (position == -1) return null val viewPager = findViewPager() - val adapter = viewPager.adapter + val adapter = viewPager.adapter ?: return null val f = adapter.instantiateItem(viewPager, position) as? MediaViewerFragment ?: return null return f.cacheFileInfo() @@ -219,7 +219,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos override fun onOptionsItemSelected(item: MenuItem): Boolean { val viewPager = findViewPager() - val adapter = viewPager.adapter + val adapter = viewPager.adapter ?: return false val currentItem = viewPager.currentItem if (currentItem < 0 || currentItem >= adapter.count) return false val obj = adapter.instantiateItem(viewPager, currentItem) as? MediaViewerFragment ?: return false @@ -438,7 +438,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { val result = super.onApplyWindowInsets(v, insets) - val adapter = viewPager.adapter + val adapter = viewPager.adapter ?: return result if (adapter.count == 0) return insets val fragment = adapter.instantiateItem(viewPager, viewPager.currentItem) if (fragment is IBaseFragment<*>) { @@ -552,6 +552,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos } private fun MediaViewerFragment.cacheFileInfo(): SaveFileTask.FileInfo? { + val context = this.context ?: return null return when (this) { is CacheDownloadMediaViewerFragment -> { val cacheUri = downloadResult?.cacheUri ?: return null @@ -561,7 +562,7 @@ class MediaViewerActivity : BaseActivity(), IMediaViewerActivity, MediaSwipeClos is GifPageFragment -> CacheFileType.IMAGE else -> return null } - CacheProvider.ContentUriFileInfo(activity, cacheUri, type) + CacheProvider.ContentUriFileInfo(context, cacheUri, type) } is ExoPlayerPageFragment -> { return getRequestFileInfo() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SettingsActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SettingsActivity.kt index 2c015f198..1dbb27989 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SettingsActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SettingsActivity.kt @@ -393,9 +393,12 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF } class RestartConfirmDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener { + private val shouldTerminate: Boolean + get() = arguments!!.getBoolean(EXTRA_SHOULD_TERMINATE) + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(activity) - if (arguments.getBoolean(EXTRA_SHOULD_TERMINATE)) { + val builder = AlertDialog.Builder(context!!) + if (shouldTerminate) { builder.setMessage(R.string.app_terminate_confirm) builder.setNegativeButton(R.string.action_dont_terminate, this) } else { @@ -412,7 +415,7 @@ class SettingsActivity : BaseActivity(), OnItemClickListener, OnPreferenceStartF val activity = activity as SettingsActivity when (which) { DialogInterface.BUTTON_POSITIVE -> { - if (arguments.getBoolean(EXTRA_SHOULD_TERMINATE)) { + if (shouldTerminate) { val intent = Intent(context, SettingsActivity::class.java) intent.putExtra(EXTRA_SHOULD_TERMINATE, true) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SignInActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SignInActivity.kt index b82ee0be9..8d082f71c 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SignInActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/SignInActivity.kt @@ -575,13 +575,13 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, class SignInTypeChooserDialogFragment : BaseDialogFragment(), LoaderManager.LoaderCallbacks> { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setView(R.layout.dialog_expandable_list) val dialog = builder.create() dialog.onShow { it.applyTheme() val listView = it.expandableList - val adapter = LoginTypeAdapter(context) + val adapter = LoginTypeAdapter(it.context) listView.setAdapter(adapter) listView.setOnGroupClickListener { _, _, groupPosition, _ -> val type = adapter.getGroup(groupPosition) @@ -625,7 +625,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, AccountType.MASTODON, AccountType.STATUSNET) val result = supportedAccountTypes.mapNotNullTo(ArrayList()) { type -> if (type == AccountType.MASTODON) return@mapNotNullTo LoginType(type, - listOf(CustomAPIConfig.mastodon(context))) + listOf(CustomAPIConfig.mastodon(context!!))) return@mapNotNullTo configGroup[type]?.let { list -> LoginType(type, list.sortedBy { !it.isDefault }) } @@ -633,9 +633,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, (listView.expandableListAdapter as LoginTypeAdapter).data = result } - override fun onCreateLoader(id: Int, args: Bundle?): Loader> { - return DefaultAPIConfigLoader(context) - } + override fun onCreateLoader(id: Int, args: Bundle?) = DefaultAPIConfigLoader(context!!) override fun onLoaderReset(loader: Loader>) { @@ -696,7 +694,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, var challengeType: String? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setTitle(R.string.login_verification) builder.setView(R.layout.dialog_login_verification_code) builder.positive(android.R.string.ok, this::performVerification) @@ -755,7 +753,7 @@ class SignInActivity : BaseActivity(), OnClickListener, TextWatcher, class PasswordSignInDialogFragment : BaseDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setView(R.layout.dialog_password_sign_in) builder.positive(R.string.action_sign_in, this::onPositiveButton) builder.setNegativeButton(android.R.string.cancel, null) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/TrendsLocationSelectorActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/TrendsLocationSelectorActivity.kt index 54a9cac8f..d0769fa0c 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/TrendsLocationSelectorActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/TrendsLocationSelectorActivity.kt @@ -90,10 +90,11 @@ class TrendsLocationSelectorActivity : BaseActivity() { } class TrendsLocationDialogFragment : BaseDialogFragment() { - private val list: Array get() = arguments.getTypedArray(EXTRA_DATA) + private val list: Array + get() = arguments!!.getTypedArray(EXTRA_DATA) override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val selectorBuilder = AlertDialog.Builder(context) + val selectorBuilder = AlertDialog.Builder(context!!) selectorBuilder.setTitle(R.string.trends_location) selectorBuilder.setView(R.layout.dialog_expandable_list) selectorBuilder.setNegativeButton(android.R.string.cancel, null) @@ -101,7 +102,7 @@ class TrendsLocationSelectorActivity : BaseActivity() { dialog.onShow { it.applyTheme() val listView = it.expandableList - val adapter = ExpandableTrendLocationsListAdapter(context) + val adapter = ExpandableTrendLocationsListAdapter(it.context) adapter.data = list listView.setAdapter(adapter) listView.setOnGroupClickListener(ExpandableListView.OnGroupClickListener { _, _, groupPosition, _ -> diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/RecyclerPagerAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/RecyclerPagerAdapter.kt index 304bd10ae..48a23260e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/RecyclerPagerAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/RecyclerPagerAdapter.kt @@ -19,13 +19,13 @@ abstract class RecyclerPagerAdapter : Page return holder } - final override fun destroyItem(container: ViewGroup, position: Int, obj: Any?) { + final override fun destroyItem(container: ViewGroup, position: Int, obj: Any) { val holder = obj as ViewHolder viewHolders.remove(position) container.removeView(holder.itemView) } - final override fun getItemPosition(obj: Any?): Int { + final override fun getItemPosition(obj: Any): Int { for (i in 0 until viewHolders.size()) { val position = viewHolders.keyAt(i) val holder = viewHolders.valueAt(i) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/StatusDetailsAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/StatusDetailsAdapter.kt index f5cf0301e..362044807 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/StatusDetailsAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/StatusDetailsAdapter.kt @@ -52,7 +52,7 @@ import org.mariotaku.twidere.view.holder.status.DetailStatusViewHolder class StatusDetailsAdapter( val fragment: StatusFragment -) : LoadMoreSupportAdapter(fragment.context, fragment.requestManager), +) : LoadMoreSupportAdapter(fragment.context!!, fragment.requestManager), IStatusesAdapter, IItemCountsAdapter { override val twidereLinkify: TwidereLinkify @@ -148,7 +148,7 @@ class StatusDetailsAdapter( init { setHasStableIds(true) - val context = fragment.activity + val context = fragment.activity!! // There's always a space at the end of the list itemCounts[ITEM_IDX_SPACE] = 1 itemCounts[ITEM_IDX_STATUS] = 1 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt index edad2add5..351188bb5 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt @@ -61,7 +61,7 @@ class SupportTabsAdapter( return this.tabs.size } - override fun getItemPosition(obj: Any?): Int { + override fun getItemPosition(obj: Any): Int { if (obj !is Fragment) return PagerAdapter.POSITION_NONE val args = obj.arguments ?: return PagerAdapter.POSITION_NONE return args.getInt(EXTRA_ADAPTER_POSITION, PagerAdapter.POSITION_NONE) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ContentResolverExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ContentResolverExtensions.kt index 41d376577..a430de1e2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ContentResolverExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/ContentResolverExtensions.kt @@ -24,8 +24,12 @@ import android.content.ContentResolver import android.content.ContentValues import android.database.Cursor import android.net.Uri +import android.provider.BaseColumns +import android.support.annotation.WorkerThread +import android.support.v4.util.LongSparseArray import org.mariotaku.ktextension.map import org.mariotaku.library.objectcursor.ObjectCursor +import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.SQLFunctions import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_LIMIT import org.mariotaku.twidere.model.CursorReference @@ -119,6 +123,29 @@ fun ContentResolver.bulkInsert(uri: Uri, collection: Collection, cl return rowsInserted } +@WorkerThread +fun ContentResolver.update(uri: Uri, columns: Array?, where: String?, + whereArgs: Array?, cls: Class, action: (T) -> T): Int { + val values = LongSparseArray() + + queryReference(uri, columns, where, whereArgs, null)?.use { (c) -> + val ci = ObjectCursor.indicesFrom(c, cls) + val vc = ObjectCursor.valuesCreatorFrom(cls) + c.moveToFirst() + while (!c.isAfterLast) { + val item = action(ci.newObject(c)) + values.put(c.getLong(ci[BaseColumns._ID]), vc.create(item)) + c.moveToNext() + } + } + var numbersUpdated = 0 + for (i in 0 until values.size()) { + val updateWhere = Expression.equals(BaseColumns._ID, values.keyAt(i)).sql + numbersUpdated += update(uri, values.valueAt(i), updateWhere, null) + } + return numbersUpdated +} + fun ContentResolver.copyStream(src: Uri, dest: Uri) { openOutputStream(dest)?.use { os -> openInputStream(src)?.use { st -> diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/APIEditorDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/APIEditorDialogFragment.kt index bcd8d9816..f530cf831 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/APIEditorDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/APIEditorDialogFragment.kt @@ -10,7 +10,6 @@ import android.support.v7.app.AlertDialog import android.view.View import android.view.ViewGroup import android.widget.* -import com.bumptech.glide.Glide import com.rengwuxian.materialedittext.MaterialEditText import org.mariotaku.twidere.R import org.mariotaku.twidere.adapter.ArrayAdapter @@ -43,7 +42,7 @@ class APIEditorDialogFragment : BaseDialogFragment() { private lateinit var apiConfig: CustomAPIConfig override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setView(R.layout.dialog_api_editor) builder.setPositiveButton(R.string.action_save) { _, _ -> val targetFragment = this.targetFragment @@ -64,7 +63,7 @@ class APIEditorDialogFragment : BaseDialogFragment() { val dialog = builder.create() dialog.onShow { it.applyTheme() - if (arguments?.getBoolean(EXTRA_SHOW_LOAD_DEFAULTS) ?: false) { + if (arguments?.getBoolean(EXTRA_SHOW_LOAD_DEFAULTS) == true) { loadDefaults.visibility = View.VISIBLE } else { loadDefaults.visibility = View.GONE @@ -76,8 +75,8 @@ class APIEditorDialogFragment : BaseDialogFragment() { accountTypeSpinner.adapter = AccountTypeSpinnerAdapter(this) - editConsumerKey.addValidator(ConsumerKeySecretValidator(context.getString(R.string.invalid_consumer_key))) - editConsumerSecret.addValidator(ConsumerKeySecretValidator(context.getString(R.string.invalid_consumer_secret))) + editConsumerKey.addValidator(ConsumerKeySecretValidator(getString(R.string.invalid_consumer_key))) + editConsumerSecret.addValidator(ConsumerKeySecretValidator(getString(R.string.invalid_consumer_secret))) editNoVersionSuffix.setOnCheckedChangeListener { _, _ -> editNoVersionSuffixChanged = true } editAuthType.setOnCheckedChangeListener { _, checkedId -> @@ -145,8 +144,8 @@ class APIEditorDialogFragment : BaseDialogFragment() { private lateinit var adapter: ArrayAdapter override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - adapter = CustomAPIConfigArrayAdapter(context) - val builder = AlertDialog.Builder(context) + adapter = CustomAPIConfigArrayAdapter(context!!) + val builder = AlertDialog.Builder(context!!) builder.setAdapter(adapter, this) loaderManager.initLoader(0, null, this) val dialog = builder.create() @@ -161,9 +160,7 @@ class APIEditorDialogFragment : BaseDialogFragment() { dismiss() } - override fun onCreateLoader(id: Int, args: Bundle?): Loader> { - return DefaultAPIConfigLoader(context) - } + override fun onCreateLoader(id: Int, args: Bundle?) = DefaultAPIConfigLoader(context!!) override fun onLoadFinished(loader: Loader>, data: List) { adapter.clear() @@ -189,7 +186,7 @@ class APIEditorDialogFragment : BaseDialogFragment() { private class AccountTypeSpinnerAdapter( fragment: APIEditorDialogFragment - ) : BaseArrayAdapter(fragment.context, R.layout.support_simple_spinner_dropdown_item, + ) : BaseArrayAdapter(fragment.context!!, R.layout.support_simple_spinner_dropdown_item, requestManager = fragment.requestManager) { init { add(AccountType.TWITTER) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentListViewFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentListViewFragment.kt index a726341ae..f2f5eb8eb 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentListViewFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentListViewFragment.kt @@ -33,7 +33,6 @@ import kotlinx.android.synthetic.main.layout_content_fragment_common.* import org.mariotaku.twidere.R import org.mariotaku.twidere.activity.iface.IControlBarActivity import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarOffsetListener -import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.annotation.LoadMorePosition import org.mariotaku.twidere.fragment.iface.RefreshScrollTopInterface import org.mariotaku.twidere.util.ContentScrollHandler.ContentListSupport @@ -56,7 +55,7 @@ abstract class AbsContentListViewFragment : BaseFragment(), } protected open val overrideDivider: Drawable? - get() = ThemeUtils.getDrawableFromThemeAttribute(context, android.R.attr.listDivider) + get() = ThemeUtils.getDrawableFromThemeAttribute(context!!, android.R.attr.listDivider) protected val isProgressShowing: Boolean get() = progressContainer.visibility == View.VISIBLE @@ -128,12 +127,12 @@ abstract class AbsContentListViewFragment : BaseFragment(), override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - val backgroundColor = ThemeUtils.getColorBackground(context) + val backgroundColor = ThemeUtils.getColorBackground(context!!) val colorRes = TwidereColorUtils.getContrastYIQ(backgroundColor, R.color.bg_refresh_progress_color_light, R.color.bg_refresh_progress_color_dark) swipeLayout.setOnRefreshListener(this) swipeLayout.setProgressBackgroundColorSchemeResource(colorRes) - adapter = onCreateAdapter(context, requestManager) + adapter = onCreateAdapter(context!!, requestManager) listView.setOnTouchListener { _, event -> if (event.actionMasked == MotionEvent.ACTION_DOWN) { updateRefreshProgressOffset() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentRecyclerViewFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentRecyclerViewFragment.kt index 0bd48808e..a3e0f5dc6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentRecyclerViewFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsContentRecyclerViewFragment.kt @@ -150,13 +150,13 @@ abstract class AbsContentRecyclerViewFragment, if (data.getBooleanExtra(EXTRA_SHOULD_RESTART, false)) { Utils.restartActivity(activity) } else if (data.getBooleanExtra(EXTRA_SHOULD_RECREATE, false)) { - activity.recreate() + activity!!.recreate() } return } @@ -246,10 +246,10 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, val account = accountsAdapter.selectedAccount ?: return val activity = activity if (account.user != null) { - IntentUtils.openUserProfile(activity, account.user!!, + IntentUtils.openUserProfile(activity!!, account.user!!, preferences[newDocumentApiKey], null) } else { - IntentUtils.openUserProfile(activity, account.key, account.key, + IntentUtils.openUserProfile(activity!!, account.key, account.key, account.user.screen_name, null, preferences[newDocumentApiKey], null) } @@ -258,7 +258,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, } override fun onCreateLoader(id: Int, args: Bundle?): Loader { - return AccountsInfoLoader(activity, accountsAdapter.accounts == null) + return AccountsInfoLoader(activity!!, accountsAdapter.accounts == null) } @@ -367,8 +367,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, menu.setItemAvailability(R.id.likes, !useStarsForLikes) menu.setItemAvailability(R.id.premium_features, extraFeaturesService.isSupported()) if (preferences[extraFeaturesNoticeVersionKey] < EXTRA_FEATURES_NOTICE_VERSION) { - val icon = ContextCompat.getDrawable(context, R.drawable.ic_action_infinity) - val color = ContextCompat.getColor(context, R.color.material_red) + val icon = ContextCompat.getDrawable(activity, R.drawable.ic_action_infinity)!! + val color = ContextCompat.getColor(activity, R.color.material_red) val size = resources.getDimensionPixelSize(R.dimen.element_spacing_msmall) menu.setItemIcon(R.id.premium_features, BadgeDrawable(icon, color, size)) } else { @@ -408,7 +408,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, private fun hasAccountInTab(tab: SupportTabSpec, accountKey: UserKey, isActivated: Boolean): Boolean { if (tab.args == null) return false - val accountKeys = Utils.getAccountKeys(context, tab.args) ?: return isActivated + val accountKeys = Utils.getAccountKeys(context!!, tab.args) ?: return isActivated return accountKey in accountKeys } @@ -467,7 +467,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, private var clickedColors: IntArray? = null override fun onAnimationStart(animation: Animator) { - if (context == null || isDetached || (activity?.isFinishing ?: true)) return + val activity = activity ?: return + if (isDetached || activity.isFinishing) return snapshotView.visibility = View.VISIBLE snapshotView.setImageBitmap(snapshotBitmap) val profileDrawable = profileImageView.drawable @@ -476,7 +477,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, clickedColors = clickedImageView.borderColors val oldSelectedAccount = accountsAdapter.selectedAccount ?: return val profileImageStyle = preferences[profileImageStyleKey] - requestManager.loadProfileImage(context, oldSelectedAccount, + requestManager.loadProfileImage(activity, oldSelectedAccount, profileImageStyle, clickedImageView.cornerRadius, clickedImageView.cornerRadiusRatio) .into(clickedImageView).onLoadStarted(profileDrawable) //TODO complete border color @@ -523,7 +524,8 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, } private fun displayAccountBanner(account: AccountDetails) { - if (context == null || isDetached || (activity?.isFinishing ?: true)) return + val activity = activity ?: return + if (isDetached || activity.isFinishing) return val bannerWidth = accountProfileBanner.width val res = resources val defWidth = res.displayMetrics.widthPixels @@ -538,16 +540,17 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, ColorDrawable(Chameleon.getOverrideTheme(activity, activity).colorPrimary) } - requestManager.loadProfileBanner(context, account.user, width).fallback(fallbackBanner) + requestManager.loadProfileBanner(activity, account.user, width).fallback(fallbackBanner) .into(bannerView) } private fun displayCurrentAccount(profileImageSnapshot: Drawable?) { - if (context == null || isDetached || (activity?.isFinishing ?: true)) return + val activity = activity ?: return + if (isDetached || activity.isFinishing) return val account = accountsAdapter.selectedAccount ?: return accountProfileNameView.spannable = account.user.name accountProfileScreenNameView.spannable = "@${account.user.screen_name}" - requestManager.loadProfileImage(context, account, preferences[profileImageStyleKey], + requestManager.loadProfileImage(activity, account, preferences[profileImageStyleKey], accountProfileImageView.cornerRadius, accountProfileImageView.cornerRadiusRatio, ProfileImageSize.REASONABLY_SMALL).placeholder(profileImageSnapshot).into(accountProfileImageView) //TODO complete border color @@ -559,6 +562,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, } override fun onNavigationItemSelected(item: MenuItem): Boolean { + val activity = this.activity ?: return false val account = accountsAdapter.selectedAccount ?: return false when (item.itemId) { R.id.search -> { @@ -629,7 +633,7 @@ class AccountsDashboardFragment : BaseFragment(), LoaderCallbacks, } fun setStatusBarHeight(height: Int) { - val top = Utils.getInsetsTopWithoutActionBarHeight(activity, height) + val top = Utils.getInsetsTopWithoutActionBarHeight(activity!!, height) profileContainer.setPadding(0, top, 0, 0) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt index e2f588987..0daadb072 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/BaseFragment.kt @@ -91,7 +91,7 @@ open class BaseFragment : Fragment(), IBaseFragment { private set protected val statusScheduleProvider: StatusScheduleProvider? - get() = statusScheduleProviderFactory.newInstance(context) + get() = statusScheduleProviderFactory.newInstance(context!!) protected val timelineSyncManager: TimelineSyncManager? get() = timelineSyncManagerFactory.get() @@ -135,10 +135,10 @@ open class BaseFragment : Fragment(), IBaseFragment { GeneralComponent.get(context).inject(this) } - override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - view?.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> + view.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) { requestApplyInsets() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ColorPickerDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ColorPickerDialogFragment.kt index 6232118f2..e3a122ba4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ColorPickerDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ColorPickerDialogFragment.kt @@ -34,7 +34,7 @@ import org.mariotaku.twidere.fragment.iface.IDialogFragmentCallback class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickListener { - private var mController: ColorPickerDialog.Controller? = null + private var controller: ColorPickerDialog.Controller? = null override fun onCancel(dialog: DialogInterface?) { super.onCancel(dialog) @@ -46,10 +46,10 @@ class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickL override fun onClick(dialog: DialogInterface, which: Int) { val a = activity - if (a !is Callback || mController == null) return + if (a !is Callback || controller == null) return when (which) { DialogInterface.BUTTON_POSITIVE -> { - val color = mController!!.color + val color = controller!!.color a.onColorSelected(color) } DialogInterface.BUTTON_NEUTRAL -> { @@ -60,15 +60,15 @@ class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickL override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val color: Int - val args = arguments - if (savedInstanceState != null) { - color = savedInstanceState.getInt(EXTRA_COLOR, Color.WHITE) + val args = arguments!! + color = if (savedInstanceState != null) { + savedInstanceState.getInt(EXTRA_COLOR, Color.WHITE) } else { - color = args.getInt(EXTRA_COLOR, Color.WHITE) + args.getInt(EXTRA_COLOR, Color.WHITE) } val activity = activity - val builder = AlertDialog.Builder(activity) + val builder = AlertDialog.Builder(activity!!) builder.setView(me.uucky.colorpicker.R.layout.cp__dialog_color_picker) builder.setPositiveButton(android.R.string.ok, this) if (args.getBoolean(EXTRA_CLEAR_BUTTON, false)) { @@ -78,14 +78,14 @@ class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickL val dialog = builder.create() dialog.onShow { it.applyTheme() - mController = ColorPickerDialog.Controller(it.context, it.window.decorView) + controller = ColorPickerDialog.Controller(it.context, it.window.decorView) val showAlphaSlider = args.getBoolean(EXTRA_ALPHA_SLIDER, true) for (presetColor in PRESET_COLORS) { - mController!!.addColor(ContextCompat.getColor(context, presetColor)) + controller!!.addColor(ContextCompat.getColor(it.context, presetColor)) } - mController!!.setAlphaEnabled(showAlphaSlider) - mController!!.setInitialColor(color) + controller!!.setAlphaEnabled(showAlphaSlider) + controller!!.setInitialColor(color) } return dialog } @@ -98,9 +98,9 @@ class ColorPickerDialogFragment : BaseDialogFragment(), DialogInterface.OnClickL } } - override fun onSaveInstanceState(outState: Bundle?) { - if (mController != null) { - outState!!.putInt(EXTRA_COLOR, mController!!.color) + override fun onSaveInstanceState(outState: Bundle) { + if (controller != null) { + outState.putInt(EXTRA_COLOR, controller!!.color) } super.onSaveInstanceState(outState) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CreateUserBlockDialogFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CreateUserBlockDialogFragment.kt index d5506c4d5..6095e39cb 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CreateUserBlockDialogFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CreateUserBlockDialogFragment.kt @@ -25,6 +25,7 @@ import org.mariotaku.twidere.R import org.mariotaku.twidere.constant.IntentConstants.EXTRA_USER import org.mariotaku.twidere.constant.nameFirstKey import org.mariotaku.twidere.model.ParcelableUser +import org.mariotaku.twidere.promise.FriendshipPromises class CreateUserBlockDialogFragment : AbsUserMuteBlockDialogFragment() { override fun getMessage(user: ParcelableUser): String { @@ -43,7 +44,7 @@ class CreateUserBlockDialogFragment : AbsUserMuteBlockDialogFragment() { override fun performUserAction(user: ParcelableUser, filterEverywhere: Boolean) { val accountKey = user.account_key ?: return - twitterWrapper.createBlockAsync(accountKey, user.key, filterEverywhere) + FriendshipPromises.getInstance(context).block(accountKey, user.key, filterEverywhere) } companion object { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableUsersFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableUsersFragment.kt index 2378434e4..d0b6198b3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableUsersFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/ParcelableUsersFragment.kt @@ -222,7 +222,7 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment> { override fun onCreateLoader(id: Int, args: Bundle): Loader> { + val activity = activity!! activity.invalidateOptionsMenu() val accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY) val user = args.getParcelable(EXTRA_USER) @@ -225,7 +226,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } val user = this@UserFragment.user val loadFromCache = user == null || !user.is_cache && user.key.maybeEquals(userKey) - return ParcelableUserLoader(activity, accountKey, userKey, screenName, arguments, + return ParcelableUserLoader(activity!!, accountKey, userKey, screenName, arguments, omitIntentExtra, loadFromCache) } @@ -275,6 +276,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } private fun displayRelationship(relationship: ParcelableRelationship?) { + val activity = activity ?: return val user = this.user ?: run { this.relationship = null return @@ -322,8 +324,9 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } followingYouIndicator.visibility = if (relationship.followed_by) View.VISIBLE else View.GONE - val resolver = context.applicationContext.contentResolver + val weakThis by weak(this) task { + val resolver = weakThis?.context?.contentResolver ?: throw InterruptedException() resolver.insert(CachedUsers.CONTENT_URI, user, ParcelableUser::class.java) resolver.insert(CachedRelationships.CONTENT_URI, relationship, ParcelableRelationship::class.java) } @@ -445,10 +448,10 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, setUiColor(theme.colorPrimary) } val defWidth = resources.displayMetrics.widthPixels - requestManager.loadProfileBanner(context, user, defWidth).into(profileBanner) - requestManager.loadOriginalProfileImage(context, user, profileImage.style, + requestManager.loadProfileBanner(activity, user, defWidth).into(profileBanner) + requestManager.loadOriginalProfileImage(activity, user, profileImage.style, profileImage.cornerRadius, profileImage.cornerRadiusRatio) - .thumbnail(requestManager.loadProfileImage(context, user, profileImage.style, + .thumbnail(requestManager.loadProfileImage(activity, user, profileImage.style, profileImage.cornerRadius, profileImage.cornerRadiusRatio, getString(R.string.profile_image_size))).into(profileImage) val relationship = relationship @@ -551,7 +554,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, @Subscribe fun notifyTaskStateChanged(event: TaskStateChangedEvent) { - activity.invalidateOptionsMenu() + activity?.invalidateOptionsMenu() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -582,7 +585,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, if (account?.type == AccountType.MASTODON && account?.key?.host != selectedAccountKey.host) { userKey = AcctPlaceholderUserKey(user.key.host) } - IntentUtils.openUserProfile(activity, selectedAccountKey, userKey, user.screen_name, + IntentUtils.openUserProfile(context!!, selectedAccountKey, userKey, user.screen_name, user.extras?.statusnet_profile_url, preferences[newDocumentApiKey], null) } @@ -598,12 +601,13 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) linkHandlerTitle = null - val activity = activity + val activity = activity!! + val args = arguments!! + nameFirst = preferences[nameFirstKey] cardBackgroundColor = ThemeUtils.getCardBackgroundColor(activity, preferences[themeBackgroundOptionKey], preferences[themeBackgroundAlphaKey]) actionBarShadowColor = 0xA0000000.toInt() - val args = arguments val accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY) ?: run { activity.finish() return @@ -684,6 +688,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, @UiThread override fun onPrepareOptionsMenu(menu: Menu) { + val context = context ?: return val user = this.user ?: return val accountKey = user.account_key ?: return val account = this.account @@ -768,11 +773,12 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, extras.putParcelable(EXTRA_USER, user) intent.putExtras(extras) menu.removeGroup(MENU_GROUP_USER_EXTENSION) - MenuUtils.addIntentToMenu(activity, menu, intent, MENU_GROUP_USER_EXTENSION) + MenuUtils.addIntentToMenu(context, menu, intent, MENU_GROUP_USER_EXTENSION) } override fun onOptionsItemSelected(item: MenuItem): Boolean { - val context = context + val context = context ?: return false + val fragmentManager = fragmentManager ?: return false val twitter = twitterWrapper val user = user ?: return false val accountKey = user.account_key ?: return false @@ -781,7 +787,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, R.id.block -> { if (userRelationship == null) return true if (userRelationship.blocking) { - twitter.destroyBlockAsync(accountKey, user.key) + BlockPromises.getInstance(context).unblock(accountKey, user.key) } else { CreateUserBlockDialogFragment.show(fragmentManager, user) } @@ -891,15 +897,15 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, return true } R.id.muted_users -> { - IntentUtils.openMutesUsers(activity, accountKey) + IntentUtils.openMutesUsers(context, accountKey) return true } R.id.blocked_users -> { - IntentUtils.openUserBlocks(activity, accountKey) + IntentUtils.openUserBlocks(context, accountKey) return true } R.id.incoming_friendships -> { - IntentUtils.openIncomingFriendships(activity, accountKey) + IntentUtils.openIncomingFriendships(context, accountKey) return true } R.id.user_mentions -> { @@ -1091,7 +1097,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } override fun onClick(view: View) { - val activity = activity ?: return + val context = activity ?: return + val fragmentManager = fragmentManager ?: return val user = user ?: return val accountKey = user.account_key ?: return when (view.id) { @@ -1100,19 +1107,22 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } R.id.follow -> { if (accountKey.maybeEquals(user.key)) { - IntentUtils.openProfileEditor(getActivity(), accountKey) + IntentUtils.openProfileEditor(context, accountKey) } else { - val userRelationship = relationship - val twitter = twitterWrapper - if (userRelationship == null) return - if (userRelationship.blocking) { - twitter.destroyBlockAsync(accountKey, user.key) - } else if (userRelationship.blocked_by) { - CreateUserBlockDialogFragment.show(childFragmentManager, user) - } else if (userRelationship.following) { - DestroyFriendshipDialogFragment.show(fragmentManager, user) - } else { - FriendshipPromises.getInstance(context).create(accountKey, user.key, user.screen_name) + val userRelationship = relationship ?: return + when { + userRelationship.blocking -> { + BlockPromises.getInstance(context).unblock(accountKey, user.key) + } + userRelationship.blocked_by -> { + CreateUserBlockDialogFragment.show(childFragmentManager, user) + } + userRelationship.following -> { + DestroyFriendshipDialogFragment.show(fragmentManager, user) + } + else -> { + FriendshipPromises.getInstance(context).create(accountKey, user.key, user.screen_name) + } } } } @@ -1122,7 +1132,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, profileImage.type = ParcelableMedia.Type.IMAGE profileImage.preview_url = user.profile_image_url val media = arrayOf(profileImage) - IntentUtils.openMedia(activity, accountKey, media, null, false, + IntentUtils.openMedia(context, accountKey, media, null, false, preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey]) } R.id.profileBanner -> { @@ -1130,28 +1140,24 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, val profileBanner = ParcelableMediaUtils.image(url) profileBanner.type = ParcelableMedia.Type.IMAGE val media = arrayOf(profileBanner) - IntentUtils.openMedia(activity, accountKey, media, null, false, + IntentUtils.openMedia(context, accountKey, media, null, false, preferences[newDocumentApiKey], preferences[displaySensitiveContentsKey]) } R.id.listedCount -> { - IntentUtils.openUserLists(getActivity(), accountKey, user.key, - user.screen_name) + IntentUtils.openUserLists(context, accountKey, user.key, user.screen_name) } R.id.groupsCount -> { - IntentUtils.openUserGroups(getActivity(), accountKey, user.key, - user.screen_name) + IntentUtils.openUserGroups(context, accountKey, user.key, user.screen_name) } R.id.followersCount -> { - IntentUtils.openUserFollowers(getActivity(), accountKey, user.key, - user.screen_name) + IntentUtils.openUserFollowers(context, accountKey, user.key, user.screen_name) } R.id.friendsCount -> { - IntentUtils.openUserFriends(getActivity(), accountKey, user.key, - user.screen_name) + IntentUtils.openUserFriends(context, accountKey, user.key, user.screen_name) } R.id.nameContainer -> { if (accountKey == user.key) return - IntentUtils.openProfileEditor(getActivity(), accountKey) + IntentUtils.openProfileEditor(context, accountKey) } R.id.url -> { val uri = user.urlPreferred?.let(Uri::parse) ?: return @@ -1169,6 +1175,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, override fun onLinkClick(link: String, orig: String?, accountKey: UserKey?, extraId: Long, type: Int, sensitive: Boolean, start: Int, end: Int): Boolean { + val activity = activity ?: return false val user = user ?: return false when (type) { TwidereLinkify.LINK_TYPE_MENTION -> { @@ -1258,9 +1265,9 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } private fun setUiColor(color: Int) { + val activity = activity as? BaseActivity ?: return val theme = Chameleon.getOverrideTheme(activity, activity) uiColor = if (color != 0) color else theme.colorPrimary - val activity = activity as BaseActivity primaryColor = if (theme.isToolbarColored) { color } else { @@ -1320,22 +1327,21 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } private fun setupUserPages() { - val args = arguments - val tabArgs = Bundle() + val args = arguments!! val user = args.getParcelable(EXTRA_USER) - val userKey: UserKey? - if (user != null) { - userKey = user.account_key - tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userKey) - tabArgs.putParcelable(EXTRA_USER_KEY, user.key) - tabArgs.putString(EXTRA_SCREEN_NAME, user.screen_name) - tabArgs.putString(EXTRA_PROFILE_URL, user.extras?.statusnet_profile_url) - } else { - userKey = args.getParcelable(EXTRA_ACCOUNT_KEY) - tabArgs.putParcelable(EXTRA_ACCOUNT_KEY, userKey) - tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable(EXTRA_USER_KEY)) - tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME)) - tabArgs.putString(EXTRA_PROFILE_URL, args.getString(EXTRA_PROFILE_URL)) + val accountKey = user.account_key ?: args.getParcelable(EXTRA_ACCOUNT_KEY) + val tabArgs = Bundle { + if (user != null) { + this[EXTRA_ACCOUNT_KEY] = accountKey + this[EXTRA_USER_KEY] = user.key + this[EXTRA_SCREEN_NAME] = user.screen_name + this[EXTRA_PROFILE_URL] = user.extras?.statusnet_profile_url + } else { + this[EXTRA_ACCOUNT_KEY] = accountKey + this[EXTRA_USER_KEY] = accountKey + this[EXTRA_SCREEN_NAME] = args.getString(EXTRA_SCREEN_NAME) + this[EXTRA_PROFILE_URL] = args.getString(EXTRA_PROFILE_URL) + } } pagerAdapter.add(cls = UserTimelineFragment::class.java, args = Bundle(tabArgs) { @@ -1345,7 +1351,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, pagerAdapter.add(cls = UserMediaTimelineFragment::class.java, args = Bundle(tabArgs) { this[EXTRA_TIMELINE_STYLE] = TimelineStyle.STAGGERED }, name = getString(R.string.media), type = TAB_TYPE_MEDIA, position = TAB_POSITION_MEDIA) - if (account?.type != AccountType.MASTODON || account?.key == userKey) { + if (account?.type != AccountType.MASTODON || account?.key == accountKey) { if (preferences[iWantMyStarsBackKey]) { pagerAdapter.add(cls = FavoritesTimelineFragment::class.java, args = tabArgs, name = getString(R.string.title_favorites), type = TAB_TYPE_FAVORITES, @@ -1369,17 +1375,17 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, val followButton = followContainer.follow followButton.setImageResource(icon) ViewCompat.setBackgroundTintMode(followButton, PorterDuff.Mode.SRC_ATOP) - ViewCompat.setBackgroundTintList(followButton, ContextCompat.getColorStateList(context, color)) + ViewCompat.setBackgroundTintList(followButton, ContextCompat.getColorStateList(context!!, color)) followButton.contentDescription = getString(label) } private fun showAddToListDialog(user: ParcelableUser) { val accountKey = user.account_key ?: return - val weakThis = toWeak() + val weakThis by weak(this) executeAfterFragmentResumed { ProgressDialogFragment.show(it.childFragmentManager, "get_list_progress") }.then { - val fragment = weakThis.get() ?: throw InterruptedException() + val context = weakThis?.context ?: throw InterruptedException() fun MicroBlog.getUserListOwnerMemberships(id: String): ArrayList { val result = ArrayList() var nextCursor: Long @@ -1395,7 +1401,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, return result } - val microBlog = MicroBlogAPIFactory.getInstance(fragment.context, accountKey) + val microBlog = MicroBlogAPIFactory.getInstance(context, accountKey) val ownedLists = ArrayList() val listMemberships = microBlog.getUserListOwnerMemberships(user.key.id) val paging = Paging() @@ -1413,12 +1419,12 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, } while (nextCursor > 0) return@then ownedLists.toTypedArray() }.alwaysUi { - val fragment = weakThis.get() ?: return@alwaysUi + val fragment = weakThis ?: return@alwaysUi fragment.executeAfterFragmentResumed { it.childFragmentManager.dismissDialogFragment("get_list_progress") } }.successUi { result -> - val fragment = weakThis.get() ?: return@successUi + val fragment = weakThis ?: return@successUi fragment.executeAfterFragmentResumed { f -> val df = AddRemoveUserListDialogFragment() df.arguments = Bundle { @@ -1429,9 +1435,8 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, df.show(f.childFragmentManager, "add_remove_list") } }.failUi { - val fragment = weakThis.get() ?: return@failUi - Toast.makeText(fragment.context, it.getErrorMessage(fragment.context), - Toast.LENGTH_SHORT).show() + val context = weakThis?.context ?: return@failUi + Toast.makeText(context, it.getErrorMessage(context), Toast.LENGTH_SHORT).show() } } @@ -1500,10 +1505,11 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, class AddRemoveUserListDialogFragment : BaseDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val lists = arguments.getTypedArray(EXTRA_USER_LISTS) - val userKey = arguments.getParcelable(EXTRA_USER_KEY) - val accountKey = arguments.getParcelable(EXTRA_ACCOUNT_KEY) - val builder = AlertDialog.Builder(context) + val args = arguments!! + val lists = args.getTypedArray(EXTRA_USER_LISTS) + val userKey = args.getParcelable(EXTRA_USER_KEY) + val accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY) + val builder = AlertDialog.Builder(context!!) builder.setTitle(R.string.title_add_or_remove_from_list) val entries = Array(lists.size) { idx -> lists[idx].name @@ -1521,11 +1527,11 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, d.applyTheme() d.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener { val checkedPositions = d.listView.checkedItemPositions - val weakActivity = activity.toWeak() + val weakActivity by weak(activity) (activity as IBaseActivity<*>).executeAfterFragmentResumed { ProgressDialogFragment.show(it.supportFragmentManager, "update_lists_progress") }.then { - val activity = weakActivity.get() ?: throw IllegalStateException() + val activity = weakActivity ?: throw IllegalStateException() val twitter = MicroBlogAPIFactory.getInstance(activity, accountKey) val successfulStates = SparseBooleanArray() try { @@ -1545,7 +1551,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, throw UpdateListsException(e, successfulStates) } }.alwaysUi { - val activity = weakActivity.get() as? IBaseActivity<*> ?: return@alwaysUi + val activity = weakActivity as? IBaseActivity<*> ?: return@alwaysUi activity.executeAfterFragmentResumed { a -> val manager = a.supportFragmentManager val df = manager.findFragmentByTag("update_lists_progress") as? DialogFragment @@ -1554,6 +1560,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, }.successUi { dismiss() }.failUi { e -> + val activity = weakActivity ?: return@failUi if (e is UpdateListsException) { val successfulStates = e.successfulStates for (i in 0 until successfulStates.size()) { @@ -1563,7 +1570,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, states[pos] = checked } } - Toast.makeText(context, e.getErrorMessage(context), Toast.LENGTH_SHORT).show() + Toast.makeText(activity, e.getErrorMessage(activity), Toast.LENGTH_SHORT).show() } } d.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/media/VideoPageFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/media/VideoPageFragment.kt index e45947977..14c98846e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/media/VideoPageFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/media/VideoPageFragment.kt @@ -180,7 +180,7 @@ class VideoPageFragment : CacheDownloadMediaViewerFragment(), IBaseFragment(EXTRA_USER_KEY) + get() = arguments!!.getParcelable(EXTRA_USER_KEY) override fun onCreateUserListsLoader(context: Context, args: Bundle, fromUser: Boolean): Loader> { val accountKey = args.getParcelable(EXTRA_ACCOUNT_KEY) val userKey = args.getParcelable(EXTRA_USER_KEY) val screenName = args.getString(EXTRA_SCREEN_NAME) - return UserListOwnershipsLoader(activity, accountKey, userKey, screenName, data).apply { + return UserListOwnershipsLoader(activity!!, accountKey, userKey, screenName, data).apply { pagination = args.getParcelable(EXTRA_PAGINATION) } } @@ -84,7 +84,7 @@ class UserListsOwnershipsFragment : ParcelableUserListsFragment() { menu.setItemAvailability(R.id.new_user_list, true) } else { menu.setItemAvailability(R.id.new_user_list, screenName != null && - Utils.isMyAccount(activity, screenName)) + Utils.isMyAccount(activity!!, screenName)) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/users/UserListMembersFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/users/UserListMembersFragment.kt index 61ff7424e..31278b706 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/users/UserListMembersFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/users/UserListMembersFragment.kt @@ -56,6 +56,11 @@ class UserListMembersFragment : ParcelableUsersFragment() { return null } + private val accountKey: UserKey? + get() = arguments!!.getParcelable(EXTRA_ACCOUNT_KEY) + private val userKey: UserKey? + get() = arguments!!.getParcelable(EXTRA_USER_KEY) + override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) linkHandlerTitle = getString(R.string.list_members) @@ -94,9 +99,8 @@ class UserListMembersFragment : ParcelableUsersFragment() { override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo?) { if (!userVisibleHint || menuInfo == null) return - val accountKey = arguments.getParcelable(EXTRA_ACCOUNT_KEY) - val userKey = arguments.getParcelable(EXTRA_USER_KEY) - if (accountKey == null || accountKey != userKey) return + val accountKey = accountKey ?: return + if (accountKey != userKey) return val inflater = MenuInflater(context) val contextMenuInfo = menuInfo as ExtendedRecyclerView.ContextMenuInfo? val user = adapter.getUser(contextMenuInfo!!.position) ?: return @@ -111,7 +115,7 @@ class UserListMembersFragment : ParcelableUsersFragment() { val user = adapter.getUser(contextMenuInfo.position) ?: return false when (item.itemId) { R.id.delete_from_list -> { - DeleteUserListMembersDialogFragment.show(fragmentManager, userList, user) + DeleteUserListMembersDialogFragment.show(fragmentManager!!, userList, user) return true } } @@ -121,11 +125,11 @@ class UserListMembersFragment : ParcelableUsersFragment() { @Subscribe fun onUserListMembersChanged(event: UserListMembersChangedEvent) { val userList = event.userList - val accountKey = arguments.getParcelable(EXTRA_ACCOUNT_KEY) ?: return - val listId = arguments.getString(EXTRA_LIST_ID) - val userKey = arguments.getParcelable(EXTRA_USER_KEY) - val screenName = arguments.getString(EXTRA_SCREEN_NAME) - val listName = arguments.getString(EXTRA_LIST_NAME) + val accountKey = accountKey ?: return + val userKey = userKey ?: return + val listId = arguments!!.getString(EXTRA_LIST_ID) + val screenName = arguments!!.getString(EXTRA_SCREEN_NAME) + val listName = arguments!!.getString(EXTRA_LIST_NAME) if (!ParcelableUserListUtils.check(userList, accountKey, listId, userKey, screenName, listName)) { return } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt index 1f870b945..402d41596 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt @@ -195,9 +195,9 @@ class ParcelableUserLoader( forceLoad() } - override fun deliverResult(data: SingleResponse) { + override fun deliverResult(data: SingleResponse?) { super.deliverResult(data) - val user = data.data ?: return + val user = data?.data ?: return if (user.is_cache) return val account = data.extras.getParcelable(EXTRA_ACCOUNT) if (account != null) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/users/UserBlocksLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/users/UserBlocksLoader.kt index 0d3dae397..87d418b35 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/users/UserBlocksLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/users/UserBlocksLoader.kt @@ -70,7 +70,7 @@ class UserBlocksLoader( } } - override fun onLoadInBackground(): List { + override fun onLoadInBackground(): List? { filteredUsers = context.contentResolver.getFilteredUserKeys(FilterScope.ALL) return super.onLoadInBackground() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableRelationshipUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableRelationshipUtils.kt index dc9eab281..7c0408a88 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableRelationshipUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/model/util/ParcelableRelationshipUtils.kt @@ -24,11 +24,11 @@ import android.support.v4.util.ArraySet import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.extension.bulkInsert +import org.mariotaku.twidere.extension.update import org.mariotaku.twidere.model.ParcelableRelationship import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships -import org.mariotaku.twidere.util.updateItems object ParcelableRelationshipUtils { @@ -72,9 +72,9 @@ object ParcelableRelationshipUtils { relationships.forEach { if (it._id > 0) { val where = Expression.equals(CachedRelationships._ID, it._id).sql - cr.updateItems(CachedRelationships.CONTENT_URI, CachedRelationships.COLUMNS, where, null, + cr.update(CachedRelationships.CONTENT_URI, CachedRelationships.COLUMNS, where, null, ParcelableRelationship::class.java) { - return@updateItems it + return@update it } } else { insertItems.add(it) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt index 404792984..0689b72a8 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/ColorPickerPreference.kt @@ -96,7 +96,7 @@ class ColorPickerPreference(context: Context, attrs: AttributeSet? = null) : override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val preference = preference as ColorPickerPreference - val context = context + val context = context!! val builder = AlertDialog.Builder(context) builder.setTitle(preference.dialogTitle) builder.setView(R.layout.cp__dialog_color_picker) @@ -125,7 +125,7 @@ class ColorPickerPreference(context: Context, attrs: AttributeSet? = null) : controller = ColorPickerDialog.Controller(context, windowView) controller.setAlphaEnabled(preference.isAlphaSliderEnabled) for (presetColor in PRESET_COLORS) { - controller.addColor(ContextCompat.getColor(context, presetColor)) + controller.addColor(ContextCompat.getColor(context!!, presetColor)) } controller.setInitialColor(preference.value) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt index e80198756..b77f35421 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/KeyboardShortcutPreference.kt @@ -120,7 +120,7 @@ class KeyboardShortcutPreference(context: Context, attrs: AttributeSet? = null) keySpec = spec keysLabel.text = spec.toKeyString() val oldAction = handler.findAction(spec) - val context = context + val context = context!! if (action == oldAction || TextUtils.isEmpty(oldAction)) { conflictLabel.visibility = View.GONE (dialog as? AlertDialog)?.getButton(DialogInterface.BUTTON_POSITIVE)?.setText(android.R.string.ok) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt index 3108593bf..dbe5095c6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/preference/RandomizeAccountNamePreference.kt @@ -21,16 +21,10 @@ import org.mariotaku.twidere.preference.iface.IDialogPreference import org.mariotaku.twidere.util.generateAccountName import java.util.* -/** - * Created by mariotaku on 2016/12/16. - */ - -class RandomizeAccountNamePreference @JvmOverloads constructor( +class RandomizeAccountNamePreference( context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = R.attr.switchPreferenceCompatStyle, - defStyleRes: Int = 0 -) : DialogPreference(context, attrs, defStyleAttr, defStyleRes), IDialogPreference { + attrs: AttributeSet? = null +) : DialogPreference(context, attrs, R.attr.switchPreferenceCompatStyle), IDialogPreference { init { dialogTitle = title @@ -65,7 +59,7 @@ class RandomizeAccountNamePreference @JvmOverloads constructor( override fun onDialogClosed(positiveResult: Boolean) { val am = AccountManager.get(context) - val enabled = arguments.getBoolean(ARG_VALUE) + val enabled = arguments!!.getBoolean(ARG_VALUE) if (enabled) { val usedNames = ArraySet() am.ownedAccounts.forEach { oldAccount -> diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/BlockPromises.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/BlockPromises.kt new file mode 100644 index 000000000..7683b3b34 --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/BlockPromises.kt @@ -0,0 +1,176 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * 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 . + */ + +package org.mariotaku.twidere.promise + +import android.app.Application +import android.content.SharedPreferences +import android.widget.Toast +import nl.komponents.kovenant.Promise +import nl.komponents.kovenant.then +import nl.komponents.kovenant.ui.successUi +import org.mariotaku.kpreferences.get +import org.mariotaku.microblog.library.MicroBlog +import org.mariotaku.microblog.library.mastodon.Mastodon +import org.mariotaku.sqliteqb.library.Expression +import org.mariotaku.twidere.R +import org.mariotaku.twidere.annotation.AccountType +import org.mariotaku.twidere.constant.nameFirstKey +import org.mariotaku.twidere.exception.APINotSupportedException +import org.mariotaku.twidere.extension.insert +import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable +import org.mariotaku.twidere.extension.model.api.toParcelable +import org.mariotaku.twidere.extension.model.newMicroBlogInstance +import org.mariotaku.twidere.model.ParcelableRelationship +import org.mariotaku.twidere.model.ParcelableUser +import org.mariotaku.twidere.model.UserKey +import org.mariotaku.twidere.provider.TwidereDataStore +import org.mariotaku.twidere.util.DataStoreUtils +import org.mariotaku.twidere.util.UserColorNameManager +import org.mariotaku.twidere.util.Utils +import org.mariotaku.twidere.util.dagger.GeneralComponent +import org.mariotaku.twidere.util.lang.ApplicationContextSingletonHolder +import javax.inject.Inject + + +class BlockPromises private constructor(private val application: Application) { + private val profileImageSize: String = application.getString(R.string.profile_image_size) + + @Inject + lateinit var preferences: SharedPreferences + @Inject + lateinit var manager: UserColorNameManager + + init { + GeneralComponent.get(application).inject(this) + } + + fun block(accountKey: UserKey, userKey: UserKey, filterEverywhere: Boolean = false): Promise = accountTask(application, accountKey) { account -> + when (account.type) { + AccountType.MASTODON -> { + val mastodon = account.newMicroBlogInstance(application, Mastodon::class.java) + mastodon.blockUser(userKey.id) + return@accountTask mastodon.getAccount(userKey.id).toParcelable(account) + } + AccountType.FANFOU -> { + val fanfou = account.newMicroBlogInstance(application, MicroBlog::class.java) + return@accountTask fanfou.createFanfouBlock(userKey.id).toParcelable(account, + profileImageSize = profileImageSize) + } + else -> { + val twitter = account.newMicroBlogInstance(application, MicroBlog::class.java) + return@accountTask twitter.createBlock(userKey.id).toParcelable(account, + profileImageSize = profileImageSize) + } + } + }.thenUpdateRelationship(accountKey, userKey) { relationship -> + relationship.account_key = accountKey + relationship.user_key = userKey + relationship.blocking = true + relationship.following = false + relationship.followed_by = false + }.successUi { user -> + val nameFirst = preferences[nameFirstKey] + val message = application.getString(R.string.message_blocked_user, + manager.getDisplayName(user, nameFirst)) + Toast.makeText(application, message, Toast.LENGTH_SHORT).show() + }.then { user -> + if (filterEverywhere) { + DataStoreUtils.addToFilter(application, listOf(user), true) + } + return@then user + }.toastOnFail(application) + + fun unblock(accountKey: UserKey, userKey: UserKey): Promise = accountTask(application, accountKey) { account -> + when (account.type) { + AccountType.MASTODON -> { + val mastodon = account.newMicroBlogInstance(application, Mastodon::class.java) + mastodon.unblockUser(userKey.id) + return@accountTask mastodon.getAccount(userKey.id).toParcelable(account) + } + AccountType.FANFOU -> { + val fanfou = account.newMicroBlogInstance(application, MicroBlog::class.java) + return@accountTask fanfou.destroyFanfouBlock(userKey.id).toParcelable(account, + profileImageSize = profileImageSize) + } + else -> { + val twitter = account.newMicroBlogInstance(application, MicroBlog::class.java) + return@accountTask twitter.destroyBlock(userKey.id).toParcelable(account, + profileImageSize = profileImageSize) + } + } + }.thenUpdateRelationship(accountKey, userKey) { relationship -> + relationship.account_key = accountKey + relationship.user_key = userKey + relationship.blocking = false + relationship.following = false + relationship.followed_by = false + }.successUi { user -> + val nameFirst = preferences[nameFirstKey] + val message = application.getString(R.string.unblocked_user, + manager.getDisplayName(user, nameFirst)) + Toast.makeText(application, message, Toast.LENGTH_SHORT).show() + }.toastOnFail(application) + + fun report(accountKey: UserKey, userKey: UserKey, filterEverywhere: Boolean = false): Promise = accountTask(application, accountKey) { account -> + when (account.type) { + AccountType.MASTODON -> { + throw APINotSupportedException(api = "Report spam", platform = account.type) + } + else -> { + val twitter = account.newMicroBlogInstance(application, MicroBlog::class.java) + return@accountTask twitter.reportSpam(userKey.id).toParcelable(account, + profileImageSize = profileImageSize) + } + } + }.thenUpdateRelationship(accountKey, userKey) { relationship -> + relationship.account_key = accountKey + relationship.user_key = userKey + relationship.blocking = true + relationship.following = false + relationship.followed_by = false + }.successUi { + Toast.makeText(application, R.string.reported_user_for_spam, Toast.LENGTH_SHORT).show() + }.then { user -> + if (filterEverywhere) { + DataStoreUtils.addToFilter(application, listOf(user), true) + } + return@then user + }.toastOnFail(application) + + private fun Promise.thenUpdateRelationship(accountKey: UserKey, + userKey: UserKey, update: (ParcelableRelationship) -> Unit): Promise = then { user -> + val resolver = application.contentResolver + Utils.setLastSeen(application, userKey, -1) + for (uri in DataStoreUtils.STATUSES_ACTIVITIES_URIS) { + val where = Expression.and( + Expression.equalsArgs(TwidereDataStore.Statuses.ACCOUNT_KEY), + Expression.equalsArgs(TwidereDataStore.Statuses.USER_KEY) + ) + val whereArgs = arrayOf(accountKey.toString(), userKey.toString()) + resolver.delete(uri, where.sql, whereArgs) + } + // I bet you don't want to see this user in your auto complete list. + val relationship = ParcelableRelationship().apply(update) + resolver.insert(TwidereDataStore.CachedRelationships.CONTENT_URI, relationship, ParcelableRelationship::class.java) + return@then user + } + + companion object : ApplicationContextSingletonHolder(::BlockPromises) +} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/FriendshipPromises.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/FriendshipPromises.kt index 3977e321d..8b4421d5e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/FriendshipPromises.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/FriendshipPromises.kt @@ -41,6 +41,7 @@ import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.Statuses import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.Utils +import org.mariotaku.twidere.util.dagger.GeneralComponent import org.mariotaku.twidere.util.lang.ApplicationContextSingletonHolder import javax.inject.Inject @@ -53,6 +54,10 @@ class FriendshipPromises private constructor(val application: Application) { @Inject lateinit var manager: UserColorNameManager + init { + GeneralComponent.get(application).inject(this) + } + fun accept(accountKey: UserKey, userKey: UserKey): Promise = accountTask(application, accountKey) { details -> when (details.type) { AccountType.FANFOU -> { @@ -143,7 +148,7 @@ class FriendshipPromises private constructor(val application: Application) { manager.getDisplayName(user, nameFirst)) } Toast.makeText(application, message, Toast.LENGTH_SHORT).show() - } + }.toastOnFail(application) fun destroy(accountKey: UserKey, userKey: UserKey): Promise = accountTask(application, accountKey) { account -> when (account.type) { @@ -178,7 +183,7 @@ class FriendshipPromises private constructor(val application: Application) { val message = application.getString(R.string.unfollowed_user, manager.getDisplayName(user, nameFirst)) Toast.makeText(application, message, Toast.LENGTH_SHORT).show() - } + }.toastOnFail(application) companion object : ApplicationContextSingletonHolder(::FriendshipPromises) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt index cee1f992b..f75c2010e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/promise/MessagePromises.kt @@ -42,6 +42,7 @@ import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.timestamp import org.mariotaku.twidere.extension.queryOne import org.mariotaku.twidere.extension.queryReference +import org.mariotaku.twidere.extension.update import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableMessage import org.mariotaku.twidere.model.ParcelableMessageConversation @@ -56,7 +57,6 @@ import org.mariotaku.twidere.util.content.ContentResolverUtils import org.mariotaku.twidere.util.dagger.GeneralComponent import org.mariotaku.twidere.util.getUnreadMessagesEntriesCursorReference import org.mariotaku.twidere.util.lang.ApplicationContextSingletonHolder -import org.mariotaku.twidere.util.updateItems import javax.inject.Inject class MessagePromises private constructor(private val application: Application) { @@ -204,7 +204,7 @@ class MessagePromises private constructor(private val application: Application) val conversationWhere = Expression.and(Expression.equalsArgs(Messages.Conversations.ACCOUNT_KEY), Expression.equalsArgs(Messages.Conversations.CONVERSATION_ID)).sql val conversationWhereArgs = arrayOf(account.key.toString(), conversationId) - application.contentResolver.updateItems(Messages.Conversations.CONTENT_URI, + application.contentResolver.update(Messages.Conversations.CONTENT_URI, Messages.Conversations.COLUMNS, conversationWhere, conversationWhereArgs, cls = ParcelableMessageConversation::class.java) { item -> item.message_extras = null @@ -212,7 +212,7 @@ class MessagePromises private constructor(private val application: Application) item.message_timestamp = -1L item.text_unescaped = null item.media = null - return@updateItems item + return@update item } return allSuccess } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/AbsFriendshipOperationTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/AbsFriendshipOperationTask.kt index b477fdbb3..c85639a3c 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/AbsFriendshipOperationTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/AbsFriendshipOperationTask.kt @@ -65,9 +65,9 @@ abstract class AbsFriendshipOperationTask( } @Throws(MicroBlogException::class) - protected abstract fun perform(details: AccountDetails, args: Arguments): ParcelableUser + protected abstract fun perform(account: AccountDetails, args: Arguments): ParcelableUser - protected abstract fun succeededWorker(details: AccountDetails, args: Arguments, + protected abstract fun succeededWorker(account: AccountDetails, args: Arguments, user: ParcelableUser) protected abstract fun showSucceededMessage(params: Arguments, user: ParcelableUser) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserBlockTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserBlockTask.kt deleted file mode 100644 index fe8afb086..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserBlockTask.kt +++ /dev/null @@ -1,87 +0,0 @@ -package org.mariotaku.twidere.task - -import android.content.ContentValues -import android.content.Context -import android.widget.Toast -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.microblog.library.mastodon.Mastodon -import org.mariotaku.sqliteqb.library.Expression -import org.mariotaku.twidere.Constants -import org.mariotaku.twidere.R -import org.mariotaku.twidere.annotation.AccountType -import org.mariotaku.twidere.constant.nameFirstKey -import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable -import org.mariotaku.twidere.extension.model.api.toParcelable -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableUser -import org.mariotaku.twidere.model.event.FriendshipTaskEvent -import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships -import org.mariotaku.twidere.provider.TwidereDataStore.Statuses -import org.mariotaku.twidere.util.DataStoreUtils -import org.mariotaku.twidere.util.Utils - -/** - * Created by mariotaku on 16/3/11. - */ -open class CreateUserBlockTask( - context: Context, - val filterEverywhere: Boolean = false -) : AbsFriendshipOperationTask(context, FriendshipTaskEvent.Action.BLOCK), Constants { - - @Throws(MicroBlogException::class) - override fun perform(details: AccountDetails, args: Arguments): ParcelableUser { - when (details.type) { - AccountType.MASTODON -> { - val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java) - mastodon.blockUser(args.userKey.id) - return mastodon.getAccount(args.userKey.id).toParcelable(details) - } - AccountType.FANFOU -> { - val fanfou = details.newMicroBlogInstance(context, MicroBlog::class.java) - return fanfou.createFanfouBlock(args.userKey.id).toParcelable(details, - profileImageSize = profileImageSize) - } - else -> { - val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) - return twitter.createBlock(args.userKey.id).toParcelable(details, - profileImageSize = profileImageSize) - } - } - } - - override fun succeededWorker(details: AccountDetails, args: Arguments, user: ParcelableUser) { - val resolver = context.contentResolver - Utils.setLastSeen(context, args.userKey, -1) - for (uri in DataStoreUtils.STATUSES_ACTIVITIES_URIS) { - val where = Expression.and( - Expression.equalsArgs(Statuses.ACCOUNT_KEY), - Expression.equalsArgs(Statuses.USER_KEY) - ) - val whereArgs = arrayOf(args.accountKey.toString(), args.userKey.toString()) - resolver.delete(uri, where.sql, whereArgs) - } - // I bet you don't want to see this user in your auto complete list. - val values = ContentValues() - values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()) - values.put(CachedRelationships.USER_KEY, args.userKey.toString()) - values.put(CachedRelationships.BLOCKING, true) - values.put(CachedRelationships.FOLLOWING, false) - values.put(CachedRelationships.FOLLOWED_BY, false) - resolver.insert(CachedRelationships.CONTENT_URI, values) - - if (filterEverywhere) { - DataStoreUtils.addToFilter(context, listOf(user), true) - } - } - - override fun showSucceededMessage(params: Arguments, user: ParcelableUser) { - val nameFirst = kPreferences[nameFirstKey] - val message = context.getString(R.string.message_blocked_user, manager.getDisplayName(user, - nameFirst)) - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - - } - -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserMuteTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserMuteTask.kt index 04f899168..792b5d1e9 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserMuteTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/CreateUserMuteTask.kt @@ -31,23 +31,23 @@ class CreateUserMuteTask( ) : AbsFriendshipOperationTask(context, FriendshipTaskEvent.Action.MUTE) { @Throws(MicroBlogException::class) - override fun perform(details: AccountDetails, args: Arguments): ParcelableUser { - when (details.type) { + override fun perform(account: AccountDetails, args: Arguments): ParcelableUser { + when (account.type) { AccountType.TWITTER -> { - val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) - return twitter.createMute(args.userKey.id).toParcelable(details, + val twitter = account.newMicroBlogInstance(context, MicroBlog::class.java) + return twitter.createMute(args.userKey.id).toParcelable(account, profileImageSize = profileImageSize) } AccountType.MASTODON -> { - val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java) + val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java) mastodon.muteUser(args.userKey.id) - return mastodon.getAccount(args.userKey.id).toParcelable(details) + return mastodon.getAccount(args.userKey.id).toParcelable(account) } - else -> throw APINotSupportedException("API", details.type) + else -> throw APINotSupportedException("API", account.type) } } - override fun succeededWorker(details: AccountDetails, args: Arguments, user: ParcelableUser) { + override fun succeededWorker(account: AccountDetails, args: Arguments, user: ParcelableUser) { val resolver = context.contentResolver Utils.setLastSeen(context, args.userKey, -1) for (uri in DataStoreUtils.STATUSES_URIS) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserBlockTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserBlockTask.kt deleted file mode 100644 index ffd2dd94c..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserBlockTask.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.mariotaku.twidere.task - -import android.content.ContentValues -import android.content.Context -import android.widget.Toast -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.microblog.library.mastodon.Mastodon -import org.mariotaku.twidere.R -import org.mariotaku.twidere.annotation.AccountType -import org.mariotaku.twidere.constant.nameFirstKey -import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable -import org.mariotaku.twidere.extension.model.api.toParcelable -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableUser -import org.mariotaku.twidere.model.event.FriendshipTaskEvent -import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships - -class DestroyUserBlockTask(context: Context) : AbsFriendshipOperationTask(context, FriendshipTaskEvent.Action.UNBLOCK) { - - @Throws(MicroBlogException::class) - override fun perform(details: AccountDetails, args: Arguments): ParcelableUser { - when (details.type) { - AccountType.MASTODON -> { - val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java) - mastodon.unblockUser(args.userKey.id) - return mastodon.getAccount(args.userKey.id).toParcelable(details) - } - AccountType.FANFOU -> { - val fanfou = details.newMicroBlogInstance(context, MicroBlog::class.java) - return fanfou.destroyFanfouBlock(args.userKey.id).toParcelable(details, - profileImageSize = profileImageSize) - } - else -> { - val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) - return twitter.destroyBlock(args.userKey.id).toParcelable(details, - profileImageSize = profileImageSize) - } - } - } - - override fun succeededWorker(details: AccountDetails, args: Arguments, user: ParcelableUser) { - val resolver = context.contentResolver - // I bet you don't want to see this user in your auto complete list. - val values = ContentValues() - values.put(CachedRelationships.ACCOUNT_KEY, args.accountKey.toString()) - values.put(CachedRelationships.USER_KEY, args.userKey.toString()) - values.put(CachedRelationships.BLOCKING, false) - values.put(CachedRelationships.FOLLOWING, false) - values.put(CachedRelationships.FOLLOWED_BY, false) - resolver.insert(CachedRelationships.CONTENT_URI, values) - } - - override fun showSucceededMessage(params: AbsFriendshipOperationTask.Arguments, user: ParcelableUser) { - val nameFirst = kPreferences[nameFirstKey] - val message = context.getString(R.string.unblocked_user, manager.getDisplayName(user, nameFirst)) - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() - - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserMuteTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserMuteTask.kt index 612273084..76fe98b98 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserMuteTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/DestroyUserMuteTask.kt @@ -24,23 +24,23 @@ import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships class DestroyUserMuteTask(context: Context) : AbsFriendshipOperationTask(context, FriendshipTaskEvent.Action.UNMUTE) { @Throws(MicroBlogException::class) - override fun perform(details: AccountDetails, args: Arguments): ParcelableUser { - when (details.type) { + override fun perform(account: AccountDetails, args: Arguments): ParcelableUser { + when (account.type) { AccountType.TWITTER -> { - val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) - return twitter.destroyMute(args.userKey.id).toParcelable(details, + val twitter = account.newMicroBlogInstance(context, MicroBlog::class.java) + return twitter.destroyMute(args.userKey.id).toParcelable(account, profileImageSize = profileImageSize) } AccountType.MASTODON -> { - val mastodon = details.newMicroBlogInstance(context, Mastodon::class.java) + val mastodon = account.newMicroBlogInstance(context, Mastodon::class.java) mastodon.unmuteUser(args.userKey.id) - return mastodon.getAccount(args.userKey.id).toParcelable(details) + return mastodon.getAccount(args.userKey.id).toParcelable(account) } - else -> throw APINotSupportedException("API", details.type) + else -> throw APINotSupportedException("API", account.type) } } - override fun succeededWorker(details: AccountDetails, + override fun succeededWorker(account: AccountDetails, args: Arguments, user: ParcelableUser) { val resolver = context.contentResolver diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ReportSpamAndBlockTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/ReportSpamAndBlockTask.kt deleted file mode 100644 index f3709471b..000000000 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/ReportSpamAndBlockTask.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.mariotaku.twidere.task - -import android.content.Context -import org.mariotaku.microblog.library.MicroBlog -import org.mariotaku.microblog.library.MicroBlogException -import org.mariotaku.twidere.annotation.AccountType -import org.mariotaku.twidere.exception.APINotSupportedException -import org.mariotaku.twidere.extension.model.api.toParcelable -import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableUser - -/** - * Created by mariotaku on 16/3/11. - */ -class ReportSpamAndBlockTask(context: Context) : CreateUserBlockTask(context) { - - @Throws(MicroBlogException::class) - override fun perform(details: AccountDetails, args: Arguments): ParcelableUser { - when (details.type) { - AccountType.MASTODON -> { - throw APINotSupportedException("API", details.type) - } - else -> { - val twitter = details.newMicroBlogInstance(context, MicroBlog::class.java) - return twitter.reportSpam(args.userKey.id).toParcelable(details, - profileImageSize = profileImageSize) - } - } - } -} diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt index f6d42700f..c5d3dfd7e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt @@ -12,12 +12,12 @@ import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE import org.mariotaku.twidere.extension.model.setAccountKey import org.mariotaku.twidere.extension.model.setAccountUser +import org.mariotaku.twidere.extension.update import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.Tab import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.* -import org.mariotaku.twidere.util.updateItems class UpdateAccountInfoTask( private val context: Context @@ -59,7 +59,7 @@ class UpdateAccountInfoTask( } private fun updateTabs(resolver: ContentResolver, accountKey: UserKey) { - resolver.updateItems(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, Tab::class.java) { tab -> + resolver.update(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, Tab::class.java) { tab -> val arguments = tab.arguments if (arguments != null) { val accountId = arguments.accountId @@ -68,7 +68,7 @@ class UpdateAccountInfoTask( arguments.accountKeys = arrayOf(accountKey) } } - return@updateItems tab + return@update tab } } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt index e0d7bcbf2..212078ffe 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AsyncTwitterWrapper.kt @@ -118,12 +118,6 @@ class AsyncTwitterWrapper( notificationManager.cancelById(Utils.getNotificationId(notificationId, accountKey)) } - fun createBlockAsync(accountKey: UserKey, userKey: UserKey, filterEverywhere: Boolean) { - val task = CreateUserBlockTask(context, filterEverywhere) - task.setup(accountKey, userKey) - TaskStarter.execute(task) - } - fun createFavoriteAsync(accountKey: UserKey, status: ParcelableStatus) { val task = CreateFavoriteTask(context, accountKey, status) TaskStarter.execute(task) @@ -160,12 +154,6 @@ class AsyncTwitterWrapper( TaskStarter.execute(task) } - fun destroyBlockAsync(accountKey: UserKey, userKey: UserKey) { - val task = DestroyUserBlockTask(context) - task.setup(accountKey, userKey) - TaskStarter.execute(task) - } - fun destroyFavoriteAsync(accountKey: UserKey, statusId: String) { val task = DestroyFavoriteTask(context, accountKey, statusId) TaskStarter.execute(task) @@ -278,12 +266,6 @@ class AsyncTwitterWrapper( // TODO implementation } - fun reportSpamAsync(accountKey: UserKey, userKey: UserKey) { - val task = ReportSpamAndBlockTask(context) - task.setup(accountKey, userKey) - TaskStarter.execute(task) - } - fun retweetStatusAsync(accountKey: UserKey, status: ParcelableStatus) { val task = RetweetStatusTask(context, accountKey, status) TaskStarter.execute, Any>(task) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt index dbb91ce58..7fce1a847 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt @@ -5,9 +5,6 @@ import android.content.ContentValues import android.content.Context import android.database.Cursor import android.net.Uri -import android.provider.BaseColumns -import android.support.annotation.WorkerThread -import android.support.v4.util.LongSparseArray import org.mariotaku.ktextension.mapToArray import org.mariotaku.ktextension.toStringArray import org.mariotaku.library.objectcursor.ObjectCursor @@ -16,11 +13,11 @@ import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.twidere.annotation.FilterScope import org.mariotaku.twidere.extension.queryReference import org.mariotaku.twidere.extension.rawQueryReference +import org.mariotaku.twidere.extension.update import org.mariotaku.twidere.model.* import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.util.DataStoreUtils.ACTIVITIES_URIS -import java.io.IOException fun Context.deleteDrafts(draftIds: LongArray): Int { @@ -126,7 +123,7 @@ fun ContentResolver.deleteActivityStatus(accountKey: UserKey, statusId: String, } for (uri in ACTIVITIES_URIS) { delete(uri, deleteWhere, deleteWhereArgs) - updateItems(uri, Activities.COLUMNS, updateWhere, updateWhereArgs, + update(uri, Activities.COLUMNS, updateWhere, updateWhereArgs, ParcelableActivity::class.java) { activity -> activity.my_retweet_id = null if (statusId == activity.id || statusId == activity.retweet_id || @@ -138,7 +135,7 @@ fun ContentResolver.deleteActivityStatus(accountKey: UserKey, statusId: String, activity.favorite_count = result.favorite_count } } - return@updateItems activity + return@update activity } } } @@ -154,33 +151,7 @@ fun ContentResolver.updateStatusInfo(uris: Array, co ).sql val activityWhereArgs = arrayOf(accountKey.toString(), statusId, statusId) for (uri in uris) { - updateItems(uri, columns, activityWhere, activityWhereArgs, cls, action) - } -} - -@WorkerThread -fun ContentResolver.updateItems(uri: Uri, columns: Array?, where: String?, - whereArgs: Array?, cls: Class, action: (T) -> T) { - val values = LongSparseArray() - - queryReference(uri, columns, where, whereArgs, null)?.use { (c) -> - val ci = ObjectCursor.indicesFrom(c, cls) - val vc = ObjectCursor.valuesCreatorFrom(cls) - c.moveToFirst() - try { - while (!c.isAfterLast) { - val item = action(ci.newObject(c)) - values.put(c.getLong(ci[BaseColumns._ID]), vc.create(item)) - c.moveToNext() - } - - } catch (e: IOException) { - return - } - } - for (i in 0 until values.size()) { - val updateWhere = Expression.equals(BaseColumns._ID, values.keyAt(i)).sql - update(uri, values.valueAt(i), updateWhere, null) + update(uri, columns, activityWhere, activityWhereArgs, cls, action) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt index aeb976b1b..3c36f7e12 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/IntentUtils.kt @@ -1,6 +1,5 @@ package org.mariotaku.twidere.util -import android.app.Activity import android.content.Context import android.content.Intent import android.content.IntentFilter @@ -381,11 +380,10 @@ object IntentUtils { openSearch(context, accountKey, query, QUERY_PARAM_VALUE_TWEETS) } - fun openUserBlocks(activity: Activity?, accountKey: UserKey) { - if (activity == null) return + fun openUserBlocks(context: Context, accountKey: UserKey) { val builder = UriBuilder(AUTHORITY_USER_BLOCKS) builder.appendQueryParameter(QUERY_PARAM_ACCOUNT_KEY, accountKey.toString()) - activity.startActivity(builder.intent()) + context.startActivity(builder.intent()) } fun openUserFavorites(context: Context, accountKey: UserKey?, userKey: UserKey?, diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt index 192d76ccd..8187f36b7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/dagger/GeneralComponent.kt @@ -46,6 +46,8 @@ import org.mariotaku.twidere.preference.KeyboardShortcutPreference import org.mariotaku.twidere.preference.PremiumEntryPreference import org.mariotaku.twidere.preference.PremiumEntryPreferenceCategory import org.mariotaku.twidere.preference.sync.SyncItemPreference +import org.mariotaku.twidere.promise.BlockPromises +import org.mariotaku.twidere.promise.FriendshipPromises import org.mariotaku.twidere.promise.MessagePromises import org.mariotaku.twidere.promise.StatusPromises import org.mariotaku.twidere.provider.CacheProvider @@ -159,6 +161,10 @@ interface GeneralComponent { fun inject(promises: StatusPromises) + fun inject(promises: FriendshipPromises) + + fun inject(promises: BlockPromises) + companion object : SingletonHolder(creation@ { context -> val application = context.applicationContext as Application return@creation DaggerGeneralComponent.builder() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/shortcut/ShortcutCreator.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/shortcut/ShortcutCreator.kt index 082623f52..daa620161 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/shortcut/ShortcutCreator.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/shortcut/ShortcutCreator.kt @@ -34,6 +34,7 @@ import nl.komponents.kovenant.then import nl.komponents.kovenant.ui.alwaysUi import nl.komponents.kovenant.ui.successUi import org.mariotaku.kpreferences.get +import org.mariotaku.ktextension.weak import org.mariotaku.twidere.R import org.mariotaku.twidere.annotation.ImageShapeStyle import org.mariotaku.twidere.constant.iWantMyStarsBackKey @@ -142,15 +143,15 @@ object ShortcutCreator { } inline fun performCreation(fragment: BaseFragment, createPromise: () -> Promise) { - if (!ShortcutManagerCompat.isRequestPinShortcutSupported(fragment.context)) return + if (!ShortcutManagerCompat.isRequestPinShortcutSupported(fragment.context!!)) return val promise = fragment.showProgressDialog("create_shortcut") .and(createPromise()) - val weakThis = WeakReference(fragment) + val weakThis by weak(fragment) promise.successUi { (_, shortcut) -> - val f = weakThis.get() ?: return@successUi - ShortcutManagerCompat.requestPinShortcut(f.context, shortcut, null) + val context = weakThis?.context ?: return@successUi + ShortcutManagerCompat.requestPinShortcut(context, shortcut, null) }.alwaysUi { - val f = weakThis.get() ?: return@alwaysUi + val f = weakThis ?: return@alwaysUi f.dismissProgressDialog("create_shortcut") } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/premium/SyncStatusViewController.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/premium/SyncStatusViewController.kt index ba030be85..42bcb20d6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/premium/SyncStatusViewController.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/premium/SyncStatusViewController.kt @@ -90,16 +90,19 @@ class SyncStatusViewController : PremiumDashboardActivity.ExtraFeatureViewContro class ConnectNetworkStorageSelectionDialogFragment : BaseDialogFragment() { + private val position: Int + get() = arguments!!.getInt(EXTRA_POSITION) + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val providers = DataSyncProvider.Factory.getSupportedProviders(context) + val providers = DataSyncProvider.Factory.getSupportedProviders(context!!) val itemNames = providers.mapToArray(SyncProviderEntry::name) - val builder = AlertDialog.Builder(context) + val builder = AlertDialog.Builder(context!!) builder.setTitle(R.string.title_dialog_sync_connect_to) builder.setItems(itemNames) { _, which -> val activity = activity as PremiumDashboardActivity activity.startActivityForControllerResult(providers[which].authIntent, - arguments.getInt(EXTRA_POSITION), REQUEST_CONNECT_NETWORK_STORAGE) + position, REQUEST_CONNECT_NETWORK_STORAGE) } val dialog = builder.create() dialog.onShow { it.applyTheme() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt index e75941337..540c57e54 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/holder/status/DetailStatusViewHolder.kt @@ -383,8 +383,7 @@ class DetailStatusViewHolder( } } itemView.profileContainer -> { - val activity = fragment.activity - IntentUtils.openUserProfile(activity, status.account_key, status.user_key, + IntentUtils.openUserProfile(adapter.context, status.account_key, status.user_key, status.user_screen_name, status.extras?.user_statusnet_profile_url, preferences[newDocumentApiKey], null) } @@ -418,10 +417,10 @@ class DetailStatusViewHolder( if (layoutPosition < 0) return false val fragment = adapter.fragment val status = adapter.getStatus(layoutPosition) + val activity = fragment.activity!! val preferences = fragment.preferences val twitter = fragment.twitterWrapper val manager = fragment.userColorNameManager - val activity = fragment.activity return MenuUtils.handleStatusClick(activity, fragment, fragment.childFragmentManager, preferences, manager, twitter, status, item) } @@ -435,7 +434,7 @@ class DetailStatusViewHolder( private fun initViews() { itemView.menuBar.setOnMenuItemClickListener(this) val fragment = adapter.fragment - val activity = fragment.activity + val activity = fragment.activity!! val inflater = activity.menuInflater val menu = itemView.menuBar.menu inflater.inflate(R.menu.menu_detail_status, menu) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/viewer/MediaSwipeCloseContainer.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/viewer/MediaSwipeCloseContainer.kt index 4bc0b39c8..9ac0d4892 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/viewer/MediaSwipeCloseContainer.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/viewer/MediaSwipeCloseContainer.kt @@ -19,7 +19,7 @@ import org.mariotaku.ktextension.coerceInOr class MediaSwipeCloseContainer(context: Context, attrs: AttributeSet? = null) : ViewGroup(context, attrs) { private val dragHelper: ViewDragHelper = ViewDragHelper.create(this, 0.5f, object : ViewDragHelper.Callback() { - override fun onViewPositionChanged(changedView: View?, left: Int, top: Int, dx: Int, dy: Int) { + override fun onViewPositionChanged(changedView: View, left: Int, top: Int, dx: Int, dy: Int) { val container = this@MediaSwipeCloseContainer container.childTop = top container.listener?.onSwipeOffsetChanged(top) @@ -40,7 +40,7 @@ class MediaSwipeCloseContainer(context: Context, attrs: AttributeSet? = null) : return top.coerceInOr(-container.height..container.height, 0) } - override fun getViewVerticalDragRange(child: View?): Int { + override fun getViewVerticalDragRange(child: View): Int { val container = this@MediaSwipeCloseContainer return container.height }