diff --git a/.travis.yml b/.travis.yml index e038edd88..d584ce289 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,8 +60,10 @@ install: - cat private/ssh_config >> ~/.ssh/config # Append known_hosts - cat private/ssh_known_hosts >> ~/.ssh/known_hosts - # Checkout Google components + # Clone Google components - ssh-agent bash -c "ssh-add private/ssh_id_rsa; git clone $COMPONENT_GOOGLE_REPO twidere/src/google" > /dev/null 2>&1 + # Force reset to required commit id + - git -C twidere/src/google reset --hard `cat twidere/src/.google.commit-id` > /dev/null 2>&1 # Dropbox accessToken for uploading logs - cat private/dropbox_uploader >> ~/.dropbox_uploader diff --git a/build.gradle b/build.gradle index 54954b4a9..318c6f126 100644 --- a/build.gradle +++ b/build.gradle @@ -38,7 +38,7 @@ subprojects { MariotakuCommons: '0.9.11', RestFu : '0.9.43', ObjectCursor : '0.9.16', - PlayServices : '10.2.0', + PlayServices : '10.2.1', MapsUtils : '0.4.4', Crashlyrics : '2.6.7', FabricPlugin : '1.22.1', diff --git a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/api/TimelineResources.java b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/api/TimelineResources.java index 29f1c9f57..665bbdbd5 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/api/TimelineResources.java +++ b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/api/TimelineResources.java @@ -26,6 +26,7 @@ import org.mariotaku.microblog.library.MicroBlogException; import org.mariotaku.microblog.library.twitter.model.Paging; import org.mariotaku.microblog.library.twitter.model.ResponseList; import org.mariotaku.microblog.library.twitter.model.Status; +import org.mariotaku.microblog.library.twitter.model.TimelineOption; import org.mariotaku.microblog.library.twitter.template.StatusAnnotationTemplate; import org.mariotaku.restfu.annotation.method.GET; import org.mariotaku.restfu.annotation.param.Queries; @@ -47,11 +48,14 @@ public interface TimelineResources { ResponseList getRetweetsOfMe(@Query Paging paging) throws MicroBlogException; @GET("/statuses/user_timeline.json") - ResponseList getUserTimeline(@Query("user_id") String userId, @Query Paging paging) throws MicroBlogException; + ResponseList getUserTimeline(@Query("user_id") String userId, @Query Paging paging, + @Query TimelineOption option) throws MicroBlogException; @GET("/statuses/user_timeline.json") - ResponseList getUserTimeline(@Query Paging paging) throws MicroBlogException; + ResponseList getUserTimeline(@Query Paging paging, @Query TimelineOption option) + throws MicroBlogException; @GET("/statuses/user_timeline.json") - ResponseList getUserTimelineByScreenName(@Query("screen_name") String screenName, @Query Paging paging) throws MicroBlogException; + ResponseList getUserTimelineByScreenName(@Query("screen_name") String screenName, + @Query Paging paging, @Query TimelineOption option) throws MicroBlogException; } diff --git a/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/TimelineOption.java b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/TimelineOption.java new file mode 100644 index 000000000..766b8a3a7 --- /dev/null +++ b/twidere.component.common/src/main/java/org/mariotaku/microblog/library/twitter/model/TimelineOption.java @@ -0,0 +1,38 @@ +/* + * Twidere - Twitter client for Android + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.mariotaku.microblog.library.twitter.model; + +import org.mariotaku.restfu.http.SimpleValueMap; + +/** + * Created by mariotaku on 2017/3/27. + */ + +public class TimelineOption extends SimpleValueMap { + public void setExcludeReplies(boolean excludeReplies) { + put("exclude_replies", excludeReplies); + } + + public void setIncludeRetweets(boolean includeRetweets) { + put("include_rts", includeRetweets); + } +} diff --git a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java index dab88b358..ab9f72b8e 100644 --- a/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java +++ b/twidere.component.common/src/main/java/org/mariotaku/twidere/constant/IntentConstants.java @@ -94,6 +94,7 @@ public interface IntentConstants { String EXTRA_SINCE_SORT_ID = "since_sort_id"; String EXTRA_STATUS_ID = "status_id"; String EXTRA_SCREEN_NAME = "screen_name"; + String EXTRA_EXCLUDE_REPLIES = "exclude_replies"; String EXTRA_SCREEN_NAMES = "screen_names"; String EXTRA_LIST_NAME = "list_name"; String EXTRA_GROUP_NAME = "group_name"; diff --git a/twidere/build.gradle b/twidere/build.gradle index a59b94b5a..99a070853 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -198,7 +198,7 @@ dependencies { task svgToDrawable(type: SvgDrawableTask) { // specify where to pick SVG from - from = files('src/main/svg/drawable') + from = files(android.sourceSets.collect { "src/${it.name}/svg/drawable" }) // specify the android res folder to = file('src/main/res-svg2png') // override files only if necessary @@ -215,7 +215,7 @@ task svgToDrawable(type: SvgDrawableTask) { task svgToMipmap(type: SvgDrawableTask) { // specify where to pick SVG from - from = files('src/main/svg/mipmap') + from = files(android.sourceSets.collect { "src/${it.name}/svg/mipmap" }) // specify the android res folder to = file('src/main/res-svg2png') // override files only if necessary diff --git a/twidere/src/.google.commit-id b/twidere/src/.google.commit-id new file mode 100644 index 000000000..9587f8358 --- /dev/null +++ b/twidere/src/.google.commit-id @@ -0,0 +1 @@ +c0f1eb42515bb3fdf53ff429103f8806bbe97830 diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java index ef1c79806..294e7478b 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/TwitterWrapper.java @@ -95,13 +95,14 @@ public class TwitterWrapper implements Constants { return user; } if (id != null) { - final ResponseList timeline = twitter.getUserTimeline(id, paging); + final ResponseList timeline = twitter.getUserTimeline(id, paging, null); for (final Status status : timeline) { final User user = status.getUser(); if (TextUtils.equals(user.getId(), id)) return user; } } else { - final ResponseList timeline = twitter.getUserTimelineByScreenName(screenName, paging); + final ResponseList timeline = twitter.getUserTimelineByScreenName(screenName, + paging, null); for (final Status status : timeline) { final User user = status.getUser(); if (searchScreenName.equalsIgnoreCase(user.getScreenName())) diff --git a/twidere/src/main/kotlin/org/mariotaku/ktextension/FragmentManagerExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/ktextension/FragmentManagerExtensions.kt new file mode 100644 index 000000000..7327d8c5b --- /dev/null +++ b/twidere/src/main/kotlin/org/mariotaku/ktextension/FragmentManagerExtensions.kt @@ -0,0 +1,29 @@ +/* + * 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.ktextension + +import android.support.v4.app.DialogFragment +import android.support.v4.app.FragmentManager + +fun FragmentManager.dismissDialogFragment(tag: String): Boolean { + val f = findFragmentByTag(tag) as? DialogFragment ?: return false + f.dismiss() + return true +} \ No newline at end of file diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt index bed276b84..d8c3d86db 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt @@ -6,6 +6,7 @@ import android.os.AsyncTask import android.os.Bundle import android.support.v4.app.DialogFragment import android.util.Log +import org.mariotaku.ktextension.dismissDialogFragment import org.mariotaku.twidere.Constants.* import org.mariotaku.twidere.R import org.mariotaku.twidere.constant.IntentConstants @@ -105,11 +106,8 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra } override fun onPostExecute(result: Boolean?) { - activity.executeAfterFragmentResumed { - val activity = it as DataExportActivity - val fm = activity.supportFragmentManager - val f = fm.findFragmentByTag(FRAGMENT_TAG) as? DialogFragment - f?.dismiss() + activity.executeAfterFragmentResumed { activity -> + activity.supportFragmentManager.dismissDialogFragment(FRAGMENT_TAG) } if (result != null && result) { activity.setResult(Activity.RESULT_OK) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataImportActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataImportActivity.kt index 0ac05fdbb..acf4b10c2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataImportActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataImportActivity.kt @@ -5,6 +5,7 @@ import android.os.AsyncTask import android.os.Bundle import android.support.v4.app.DialogFragment import android.util.Log +import org.mariotaku.ktextension.dismissDialogFragment import org.mariotaku.twidere.R import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.fragment.DataExportImportTypeSelectorDialogFragment @@ -107,11 +108,8 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra } override fun onPostExecute(result: Boolean?) { - activity.executeAfterFragmentResumed { - val activity = it as DataImportActivity - val fm = activity.supportFragmentManager - val f = fm.findFragmentByTag(FRAGMENT_TAG) as? DialogFragment - f?.dismiss() + activity.executeAfterFragmentResumed { activity -> + activity.supportFragmentManager.dismissDialogFragment(FRAGMENT_TAG) } if (result != null && result) { activity.setResult(RESULT_OK) @@ -148,11 +146,8 @@ class DataImportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra } override fun onPostExecute(flags: Int?) { - activity.executeAfterFragmentResumed { - val activity = it as DataImportActivity - val fm = activity.supportFragmentManager - val f = fm.findFragmentByTag(FRAGMENT_TAG) as? DialogFragment - f?.dismiss() + activity.executeAfterFragmentResumed { activity -> + activity.supportFragmentManager.dismissDialogFragment(FRAGMENT_TAG) } val df = DataExportImportTypeSelectorDialogFragment() val args = Bundle() 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 9d81b89de..8aad926cf 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/HomeActivity.kt @@ -684,7 +684,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp val accountKey = uri?.getQueryParameter(QUERY_PARAM_ACCOUNT_KEY)?.let(UserKey::valueOf) val adapter = pagerAdapter for (i in 0 until adapter.count) { - val tab = adapter.getTab(i) + val tab = adapter.get(i) if (tabType == Tab.getTypeAlias(tab.type)) { val args = tab.args if (args != null && CustomTabUtils.hasAccountId(this, args, @@ -788,7 +788,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp private fun setupHomeTabs() { pagerAdapter.clear() - pagerAdapter.addTabs(CustomTabUtils.getHomeTabs(this)) + pagerAdapter.addAll(CustomTabUtils.getHomeTabs(this)) val hasNoTab = pagerAdapter.count == 0 emptyTabHint.visibility = if (hasNoTab) View.VISIBLE else View.GONE mainPager.visibility = if (hasNoTab) View.GONE else View.VISIBLE 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 7fe5fb43c..471cd1d84 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/SupportTabsAdapter.kt @@ -38,7 +38,7 @@ import org.mariotaku.twidere.view.iface.PagerIndicator.TabListener import org.mariotaku.twidere.view.iface.PagerIndicator.TabProvider import java.util.* -class SupportTabsAdapter @JvmOverloads constructor( +class SupportTabsAdapter( private val context: Context, fm: FragmentManager, private val indicator: PagerIndicator? = null @@ -47,35 +47,18 @@ class SupportTabsAdapter @JvmOverloads constructor( var hasMultipleColumns: Boolean = false var preferredColumnWidth: Float = 0f - private val tab = ArrayList() + var tabs = ArrayList() + set(value) { + field = tabs + notifyDataSetChanged() + } init { clear() } - fun addTab(cls: Class, args: Bundle? = null, name: String, - icon: DrawableHolder? = null, type: String? = null, position: Int = 0, tag: String? = null) { - addTab(SupportTabSpec(name = name, icon = icon, cls = cls, args = args, - position = position, type = type, tag = tag)) - } - - fun addTab(spec: SupportTabSpec) { - tab.add(spec) - notifyDataSetChanged() - } - - fun addTabs(specs: Collection) { - tab.addAll(specs) - notifyDataSetChanged() - } - - fun clear() { - tab.clear() - notifyDataSetChanged() - } - override fun getCount(): Int { - return tab.size + return this.tabs.size } override fun getItemPosition(obj: Any?): Int { @@ -90,7 +73,7 @@ class SupportTabsAdapter @JvmOverloads constructor( } override fun getPageTitle(position: Int): CharSequence? { - return tab[position].name + return this.tabs[position].name } override fun getPageWidth(position: Int): Float { @@ -109,8 +92,8 @@ class SupportTabsAdapter @JvmOverloads constructor( } override fun getItem(position: Int): Fragment { - val fragment = Fragment.instantiate(context, tab[position].cls.name) - fragment.arguments = getPageArguments(tab[position], position) + val fragment = Fragment.instantiate(context, this.tabs[position].cls.name) + fragment.arguments = getPageArguments(this.tabs[position], position) return fragment } @@ -119,16 +102,9 @@ class SupportTabsAdapter @JvmOverloads constructor( } override fun getPageIcon(position: Int): Drawable { - return getTabIconDrawable(context, tab[position].icon) + return getTabIconDrawable(context, this.tabs[position].icon) } - fun getTab(position: Int): SupportTabSpec { - return tab[position] - } - - val tabs: List - get() = tab - override fun onPageReselected(position: Int) { if (context !is SupportFragmentCallback) return val f = context.currentVisibleFragment @@ -151,8 +127,33 @@ class SupportTabsAdapter @JvmOverloads constructor( return false } - fun setTabLabel(position: Int, label: CharSequence) { - tab.filter { position == it.position }.forEach { it.name = label } + fun add(cls: Class, args: Bundle? = null, name: String, + icon: DrawableHolder? = null, type: String? = null, position: Int = 0, tag: String? = null) { + add(SupportTabSpec(name = name, icon = icon, cls = cls, args = args, + position = position, type = type, tag = tag)) + } + + fun add(spec: SupportTabSpec) { + this.tabs.add(spec) + notifyDataSetChanged() + } + + fun addAll(specs: Collection) { + this.tabs.addAll(specs) + notifyDataSetChanged() + } + + fun get(position: Int): SupportTabSpec { + return this.tabs[position] + } + + fun clear() { + this.tabs.clear() + notifyDataSetChanged() + } + + fun setLabel(position: Int, label: CharSequence) { + this.tabs.filter { position == it.position }.forEach { it.name = label } notifyDataSetChanged() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt index 5c406a209..f6349af35 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/AbsToolbarTabPagesFragment.kt @@ -37,7 +37,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte SupportFragmentCallback, IBaseFragment.SystemWindowsInsetsCallback, ControlBarOffsetListener, HideUiOnScroll, OnPageChangeListener, IToolBarSupportFragment, KeyboardShortcutCallback { - private lateinit var pagerAdapter: SupportTabsAdapter + protected lateinit var pagerAdapter: SupportTabsAdapter override val toolbar: Toolbar get() = toolbarContainer.toolbar @@ -53,6 +53,8 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte addTabs(pagerAdapter) + toolbarTabs.notifyDataSetChanged() + toolbarContainer.setOnSizeChangedListener { _, _, _, _, _ -> val pageLimit = viewPager.offscreenPageLimit val currentItem = viewPager.currentItem @@ -71,7 +73,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte val initialTab = arguments?.getString(EXTRA_INITIAL_TAB) if (initialTab != null) { for (i in 0 until pagerAdapter.count) { - if (initialTab == pagerAdapter.getTab(i).tag) { + if (initialTab == pagerAdapter.get(i).tag) { viewPager.currentItem = i break } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/GroupFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/GroupFragment.kt index 5ac738832..ba793afcd 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/GroupFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/GroupFragment.kt @@ -30,8 +30,8 @@ class GroupFragment : AbsToolbarTabPagesFragment(), LoaderCallbacks { + TAB_TYPE_STATUSES, TAB_TYPE_STATUSES_WITH_REPLIES -> { actionBar.subtitle = resources.getQuantityString(R.plurals.N_statuses, user.statuses_count.toInt(), user.statuses_count) } @@ -1415,16 +1414,24 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, tabArgs.putParcelable(EXTRA_USER_KEY, args.getParcelable(EXTRA_USER_KEY)) tabArgs.putString(EXTRA_SCREEN_NAME, args.getString(EXTRA_SCREEN_NAME)) } - pagerAdapter.addTab(cls = UserTimelineFragment::class.java, args = tabArgs, name = getString(R.string.title_statuses), - icon = DrawableHolder.resource(R.drawable.ic_action_quote), type = TAB_TYPE_STATUSES, position = TAB_POSITION_STATUSES) - pagerAdapter.addTab(cls = UserMediaTimelineFragment::class.java, args = tabArgs, name = getString(R.string.media), - icon = DrawableHolder.resource(R.drawable.ic_action_gallery), type = TAB_TYPE_MEDIA, position = TAB_POSITION_MEDIA) + pagerAdapter.add(cls = UserTimelineFragment::class.java, args = Bundle(tabArgs).apply { + putBoolean(EXTRA_EXCLUDE_REPLIES, true) + }, name = getString(R.string.title_statuses), type = TAB_TYPE_STATUSES, + position = TAB_POSITION_STATUSES) + pagerAdapter.add(cls = UserTimelineFragment::class.java, args = tabArgs, + name = getString(R.string.title_statuses_and_replies), type = TAB_TYPE_STATUSES_WITH_REPLIES, + position = TAB_POSITION_STATUSES) + pagerAdapter.add(cls = UserMediaTimelineFragment::class.java, args = tabArgs, + name = getString(R.string.media), type = TAB_TYPE_MEDIA, + position = TAB_POSITION_MEDIA) if (preferences.getBoolean(KEY_I_WANT_MY_STARS_BACK)) { - pagerAdapter.addTab(cls = UserFavoritesFragment::class.java, args = tabArgs, name = getString(R.string.title_favorites), - icon = DrawableHolder.resource(R.drawable.ic_action_star), type = TAB_TYPE_FAVORITES, position = TAB_POSITION_FAVORITES) + pagerAdapter.add(cls = UserFavoritesFragment::class.java, args = tabArgs, + name = getString(R.string.title_favorites), type = TAB_TYPE_FAVORITES, + position = TAB_POSITION_FAVORITES) } else { - pagerAdapter.addTab(cls = UserFavoritesFragment::class.java, args = tabArgs, name = getString(R.string.title_likes), - icon = DrawableHolder.resource(R.drawable.ic_action_heart), type = TAB_TYPE_FAVORITES, position = TAB_POSITION_FAVORITES) + pagerAdapter.add(cls = UserFavoritesFragment::class.java, args = tabArgs, + name = getString(R.string.title_likes), type = TAB_TYPE_FAVORITES, + position = TAB_POSITION_FAVORITES) } } @@ -1736,6 +1743,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener, private val TAB_POSITION_MEDIA = 1 private val TAB_POSITION_FAVORITES = 2 private val TAB_TYPE_STATUSES = "statuses" + private val TAB_TYPE_STATUSES_WITH_REPLIES = "statuses_with_replies" private val TAB_TYPE_MEDIA = "media" private val TAB_TYPE_FAVORITES = "favorites" } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserListFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserListFragment.kt index 5674c10d8..efec10722 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserListFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserListFragment.kt @@ -153,9 +153,9 @@ class UserListFragment : AbsToolbarTabPagesFragment(), OnClickListener, tabArgs.putString(EXTRA_LIST_ID, args.getString(EXTRA_LIST_ID)) tabArgs.putString(EXTRA_LIST_NAME, args.getString(EXTRA_LIST_NAME)) } - adapter.addTab(cls = UserListTimelineFragment::class.java, args = tabArgs, name = getString(R.string.title_statuses)) - adapter.addTab(cls = UserListMembersFragment::class.java, args = tabArgs, name = getString(R.string.members)) - adapter.addTab(cls = UserListSubscribersFragment::class.java, args = tabArgs, name = getString(R.string.subscribers)) + adapter.add(cls = UserListTimelineFragment::class.java, args = tabArgs, name = getString(R.string.title_statuses)) + adapter.add(cls = UserListMembersFragment::class.java, args = tabArgs, name = getString(R.string.members)) + adapter.add(cls = UserListSubscribersFragment::class.java, args = tabArgs, name = getString(R.string.subscribers)) } override fun onStart() { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserProfileEditorFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserProfileEditorFragment.kt index da4cbacd3..6598e76f6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserProfileEditorFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserProfileEditorFragment.kt @@ -42,7 +42,7 @@ import com.twitter.Validator import kotlinx.android.synthetic.main.fragment_user_profile_editor.* import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.TaskStarter -import org.mariotaku.kpreferences.get +import org.mariotaku.ktextension.dismissDialogFragment import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.ProfileUpdate @@ -51,7 +51,6 @@ import org.mariotaku.twidere.R import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.activity.ColorPickerDialogActivity import org.mariotaku.twidere.activity.ThemedMediaPickerActivity -import org.mariotaku.twidere.constant.profileImageStyleKey import org.mariotaku.twidere.extension.loadProfileBanner import org.mariotaku.twidere.extension.loadProfileImage import org.mariotaku.twidere.extension.model.newMicroBlogInstance @@ -407,9 +406,9 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat return false } - override fun afterExecute(handler: UserProfileEditorFragment?, result: SingleResponse) { - if (handler == null) return - val activity = handler.activity ?: return + override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse) { + if (callback == null) return + val activity = callback.activity ?: return if (result.hasData()) { val account: AccountDetails? = result.extras.getParcelable(EXTRA_ACCOUNT) if (account != null) { @@ -418,20 +417,16 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat TaskStarter.execute(task) } } - handler.executeAfterFragmentResumed { fragment -> - val f = (fragment as UserProfileEditorFragment).fragmentManager.findFragmentByTag(DIALOG_FRAGMENT_TAG) - if (f is DialogFragment) { - f.dismissAllowingStateLoss() - } - f.activity.finish() + callback.executeAfterFragmentResumed { fragment -> + fragment.childFragmentManager.dismissDialogFragment(DIALOG_FRAGMENT_TAG) + fragment.activity.finish() } } override fun beforeExecute() { super.beforeExecute() callback?.executeAfterFragmentResumed { fragment -> - val fm = (fragment as UserProfileEditorFragment).activity.supportFragmentManager - val df = ProgressDialogFragment.show(fm, DIALOG_FRAGMENT_TAG) + val df = ProgressDialogFragment.show(fragment.childFragmentManager, DIALOG_FRAGMENT_TAG) df.isCancelable = false } } @@ -451,8 +446,8 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat return TwitterWrapper.deleteProfileBannerImage(activity, accountKey) } - override fun afterExecute(handler: UserProfileEditorFragment?, result: SingleResponse) { - super.afterExecute(handler, result) + override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse) { + super.afterExecute(callback, result) if (result.data != null) { getUserInfo() Toast.makeText(activity, R.string.message_toast_profile_banner_image_updated, Toast.LENGTH_SHORT).show() @@ -473,8 +468,8 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat private inner class UpdateProfileBannerImageTaskInternal(context: Context, accountKey: UserKey, imageUri: Uri, deleteImage: Boolean) : UpdateProfileBannerImageTask(context, accountKey, imageUri, deleteImage) { - override fun afterExecute(handler: UserProfileEditorFragment?, result: SingleResponse?) { - super.afterExecute(handler, result) + override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse?) { + super.afterExecute(callback, result) setUpdateState(false) getUserInfo() } @@ -495,8 +490,8 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat ) : UpdateProfileBackgroundImageTask(context, accountKey, imageUri, tile, deleteImage) { - override fun afterExecute(handler: UserProfileEditorFragment?, result: SingleResponse) { - super.afterExecute(handler, result) + override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse) { + super.afterExecute(callback, result) setUpdateState(false) getUserInfo() } @@ -515,8 +510,8 @@ class UserProfileEditorFragment : BaseFragment(), OnSizeChangedListener, TextWat deleteImage: Boolean ) : UpdateProfileImageTask(context, accountKey, imageUri, deleteImage) { - override fun afterExecute(handler: UserProfileEditorFragment?, result: SingleResponse) { - super.afterExecute(handler, result) + override fun afterExecute(callback: UserProfileEditorFragment?, result: SingleResponse) { + super.afterExecute(callback, result) if (result.data != null) { displayUser(result.data) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserTimelineFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserTimelineFragment.kt index d6a8e9b4a..7e8970097 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserTimelineFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/UserTimelineFragment.kt @@ -48,6 +48,7 @@ class UserTimelineFragment : ParcelableStatusesFragment() { val accountKey = Utils.getAccountKey(context, args)!! val userKey = args.getParcelable(EXTRA_USER_KEY) val screenName = args.getString(EXTRA_SCREEN_NAME) + val excludeReplies = args.getBoolean(EXTRA_EXCLUDE_REPLIES) val result = ArrayList() result.add(AUTHORITY_USER_TIMELINE) result.add("account=$accountKey") @@ -58,6 +59,9 @@ class UserTimelineFragment : ParcelableStatusesFragment() { } else { return null } + if (excludeReplies) { + result.add("exclude_replies") + } return result.toTypedArray() } @@ -91,9 +95,10 @@ class UserTimelineFragment : ParcelableStatusesFragment() { val screenName = args.getString(EXTRA_SCREEN_NAME) val tabPosition = args.getInt(EXTRA_TAB_POSITION, -1) val loadingMore = args.getBoolean(EXTRA_LOADING_MORE, false) + val excludeReplies = args.getBoolean(EXTRA_EXCLUDE_REPLIES, false) val pinnedIds = if (adapter.hasPinnedStatuses) null else pinnedStatusIds return UserTimelineLoader(context, accountKey, userKey, screenName, sinceId, maxId, data, - savedStatusesFileArgs, tabPosition, fromUser, loadingMore, pinnedIds) + savedStatusesFileArgs, tabPosition, fromUser, loadingMore, pinnedIds, excludeReplies) } override fun onStatusesLoaded(loader: Loader?>, data: List?) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersImportFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersImportFragment.kt index 672742f9b..2a094c42d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersImportFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/BaseFiltersImportFragment.kt @@ -203,9 +203,7 @@ abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment - val fm = fragment.fragmentManager - val df = fm.findFragmentByTag("import_progress") as? DialogFragment - df?.dismiss() + fragment.childFragmentManager.dismissDialogFragment("import_progress") } weakThis.get()?.adapter?.notifyDataSetChanged() } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersFragment.kt index 2be1f9578..9beeaaaa3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersFragment.kt @@ -32,11 +32,11 @@ class FiltersFragment : AbsToolbarTabPagesFragment() { } override fun addTabs(adapter: SupportTabsAdapter) { - adapter.addTab(cls = FilteredUsersFragment::class.java, name = getString(R.string.filter_type_users), tag = "users") - adapter.addTab(cls = FilteredKeywordsFragment::class.java, name = getString(R.string.filter_type_keywords), tag = "keywords") - adapter.addTab(cls = FilteredSourcesFragment::class.java, name = getString(R.string.filter_type_sources), tag = "sources") - adapter.addTab(cls = FilteredLinksFragment::class.java, name = getString(R.string.filter_type_links), tag = "links") - adapter.addTab(cls = FilterSettingsFragment::class.java, name = getString(R.string.settings), tag = "settings") + adapter.add(cls = FilteredUsersFragment::class.java, name = getString(R.string.filter_type_users), tag = "users") + adapter.add(cls = FilteredKeywordsFragment::class.java, name = getString(R.string.filter_type_keywords), tag = "keywords") + adapter.add(cls = FilteredSourcesFragment::class.java, name = getString(R.string.filter_type_sources), tag = "sources") + adapter.add(cls = FilteredLinksFragment::class.java, name = getString(R.string.filter_type_links), tag = "links") + adapter.add(cls = FilterSettingsFragment::class.java, name = getString(R.string.settings), tag = "settings") } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt index 251270df5..c8c2c5574 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt @@ -8,7 +8,6 @@ import android.content.DialogInterface import android.content.Intent import android.database.Cursor import android.os.Bundle -import android.support.v4.app.DialogFragment import android.support.v4.app.LoaderManager import android.support.v4.content.CursorLoader import android.support.v4.content.Loader @@ -138,8 +137,7 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac val fragmentRef = WeakReference(fragment) task.callback = { fragmentRef.get()?.executeAfterFragmentResumed { fragment -> - val df = fragment.childFragmentManager.findFragmentByTag(FRAGMENT_TAG_RREFRESH_FILTERS) as? DialogFragment - df?.dismiss() + fragment.fragmentManager.dismissDialogFragment(FRAGMENT_TAG_RREFRESH_FILTERS) } } TaskStarter.execute(task) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt index 9fe0de2e6..1d569baa9 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt @@ -32,6 +32,7 @@ import android.support.v4.app.DialogFragment import android.support.v4.app.FragmentActivity import android.support.v4.app.LoaderManager import android.support.v4.content.AsyncTaskLoader +import android.support.v4.content.FixedAsyncTaskLoader import android.support.v4.content.Loader import android.support.v7.app.AlertDialog import android.support.v7.app.AppCompatActivity @@ -473,7 +474,8 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment, internal class ConversationInfoLoader( context: Context, val accountKey: UserKey, - val conversationId: String) : AsyncTaskLoader(context) { + val conversationId: String + ) : FixedAsyncTaskLoader(context) { override fun loadInBackground(): ParcelableMessageConversation? { val where = Expression.and(Expression.equalsArgs(Conversations.ACCOUNT_KEY), diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/UserTimelineLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/UserTimelineLoader.kt index 2c7cc095f..d2508f9bf 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/UserTimelineLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/UserTimelineLoader.kt @@ -28,6 +28,7 @@ import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.ResponseList import org.mariotaku.microblog.library.twitter.model.Status +import org.mariotaku.microblog.library.twitter.model.TimelineOption import org.mariotaku.twidere.R import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableStatus @@ -48,7 +49,8 @@ class UserTimelineLoader( tabPosition: Int, fromUser: Boolean, loadingMore: Boolean, - val pinnedStatusIds: Array? + val pinnedStatusIds: Array?, + val excludeReplies: Boolean = false ) : MicroBlogAPIStatusesLoader(context, accountId, sinceId, maxId, -1, data, savedStatusesArgs, tabPosition, fromUser, loadingMore) { @@ -77,10 +79,12 @@ class UserTimelineLoader( null } } + val option = TimelineOption() + option.setExcludeReplies(excludeReplies) if (userId != null) { - return microBlog.getUserTimeline(userId.id, paging) + return microBlog.getUserTimeline(userId.id, paging, option) } else if (screenName != null) { - return microBlog.getUserTimelineByScreenName(screenName, paging) + return microBlog.getUserTimelineByScreenName(screenName, paging, option) } else { throw MicroBlogException("Invalid user") } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBackgroundImageTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBackgroundImageTask.kt index 7b75dbc9b..058b9c9a6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBackgroundImageTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBackgroundImageTask.kt @@ -27,8 +27,8 @@ open class UpdateProfileBackgroundImageTask( private val deleteImage: Boolean ) : BaseAbstractTask, ResultHandler>(context) { - override fun afterExecute(handler: ResultHandler?, result: SingleResponse) { - super.afterExecute(handler, result) + override fun afterExecute(callback: ResultHandler?, result: SingleResponse) { + super.afterExecute(callback, result) if (result.hasData()) { Utils.showOkMessage(context, R.string.message_toast_profile_banner_image_updated, false) bus.post(ProfileUpdatedEvent(result.data!!)) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.kt index 1afb8e8c0..3072fced6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileBannerImageTask.kt @@ -28,8 +28,8 @@ open class UpdateProfileBannerImageTask( private val profileImageSize = context.getString(R.string.profile_image_size) - override fun afterExecute(handler: ResultHandler?, result: SingleResponse?) { - super.afterExecute(handler, result) + override fun afterExecute(callback: ResultHandler?, result: SingleResponse?) { + super.afterExecute(callback, result) if (result!!.hasData()) { Utils.showOkMessage(context, R.string.message_toast_profile_banner_image_updated, false) bus.post(ProfileUpdatedEvent(result.data!!)) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileImageTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileImageTask.kt index 8f44fea74..ed0fb1e69 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileImageTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateProfileImageTask.kt @@ -52,8 +52,8 @@ open class UpdateProfileImageTask( } - override fun afterExecute(handler: ResultHandler?, result: SingleResponse) { - super.afterExecute(handler, result) + override fun afterExecute(callback: ResultHandler?, result: SingleResponse) { + super.afterExecute(callback, result) if (result.hasData()) { Utils.showOkMessage(context, R.string.profile_image_updated, false) bus.post(ProfileUpdatedEvent(result.data!!)) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt index ae9601d4f..162eb199e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt @@ -70,7 +70,7 @@ class GetTrendsTask( } } - override fun afterExecute(handler: Any?, result: Unit) { + override fun afterExecute(callback: Any?, result: Unit) { bus.post(TrendsRefreshedEvent()) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt index 4f92763ea..7d6931589 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt @@ -85,7 +85,7 @@ class UpdateStatusTask( stateCallback.beforeExecute() } - override fun afterExecute(handler: Any?, result: UpdateStatusResult) { + override fun afterExecute(callback: Any?, result: UpdateStatusResult) { stateCallback.afterExecute(result) logUpdateStatus(params.first, result) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt index b4eb0f30b..f5e7d7f4b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/view/controller/twitter/card/CardPollViewController.kt @@ -147,9 +147,9 @@ class CardPollViewController : ContainerView.ViewController() { cardData.putString("selected_choice", (i + 1).toString()) val task = object : AbstractTask() { - override fun afterExecute(handler: CardPollViewController?, result: ParcelableCardEntity?) { + override fun afterExecute(callback: CardPollViewController?, result: ParcelableCardEntity?) { result ?: return - handler?.displayAndReloadPoll(result, status) + callback?.displayAndReloadPoll(result, status) } override fun doLongOperation(cardDataMap: CardDataMap): ParcelableCardEntity? { diff --git a/twidere/src/main/res/values/strings.xml b/twidere/src/main/res/values/strings.xml index 911331e7e..c4a41c4d3 100644 --- a/twidere/src/main/res/values/strings.xml +++ b/twidere/src/main/res/values/strings.xml @@ -71,6 +71,7 @@ Like liking + Manage in Buffer Mark as read modifying lists Mute @@ -1155,12 +1156,14 @@ Open source license Twidere ∞ Quick action + Scheduled tweets Search Select users Set nickname Sign in to Buffer Tweet Tweets + Tweets & replies Tweets scheduling Streaming Name @@ -1263,5 +1266,5 @@ User\'s tweets Vibration - Scheduled tweets + Disconnect from Buffer