1
0
mirror of https://github.com/TwidereProject/Twidere-Android synced 2025-02-14 18:50:39 +01:00

started to implement import blocks/mutes

This commit is contained in:
Mariotaku Lee 2016-12-26 22:11:20 +08:00
parent a0ea72e3c0
commit 57cc550795
39 changed files with 570 additions and 194 deletions

View File

@ -120,6 +120,8 @@ public interface TwidereConstants extends SharedPreferenceConstants, IntentConst
String AUTHORITY_ACCOUNTS = "accounts"; String AUTHORITY_ACCOUNTS = "accounts";
String AUTHORITY_DRAFTS = "drafts"; String AUTHORITY_DRAFTS = "drafts";
String AUTHORITY_FILTERS = "filters"; String AUTHORITY_FILTERS = "filters";
String AUTHORITY_FILTERS_IMPORT_BLOCKS = "filters/import/blocks";
String AUTHORITY_FILTERS_IMPORT_MUTES = "filters/import/mutes";
String AUTHORITY_PROFILE_EDITOR = "profile_editor"; String AUTHORITY_PROFILE_EDITOR = "profile_editor";
String QUERY_PARAM_ACCOUNT_KEY = "account_key"; String QUERY_PARAM_ACCOUNT_KEY = "account_key";

View File

@ -7,6 +7,7 @@ import org.mariotaku.library.objectcursor.annotation.CursorField;
import org.mariotaku.library.objectcursor.annotation.CursorObject; import org.mariotaku.library.objectcursor.annotation.CursorObject;
import org.mariotaku.twidere.model.util.UserKeyConverter; import org.mariotaku.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter; import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters; import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import java.util.List; import java.util.List;
@ -69,17 +70,25 @@ public class FiltersData {
} }
@JsonObject @JsonObject
@CursorObject(valuesCreator = true) @CursorObject(valuesCreator = true, tableInfo = true)
public static class UserItem { public static class UserItem {
@CursorField(value = Filters.Users.USER_KEY, converter = UserKeyCursorFieldConverter.class) @CursorField(value = Filters.Users._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY)
long _id;
@CursorField(value = Filters.Users.USER_KEY, converter = UserKeyCursorFieldConverter.class, type = "TEXT NOT NULL UNIQUE")
@JsonField(name = "user_key", typeConverter = UserKeyConverter.class) @JsonField(name = "user_key", typeConverter = UserKeyConverter.class)
UserKey userKey; UserKey userKey;
@CursorField(Filters.Users.NAME) @CursorField(value = Filters.Users.NAME, type = CursorField.TEXT)
@JsonField(name = "name") @JsonField(name = "name")
String name; String name;
@CursorField(Filters.Users.SCREEN_NAME) @CursorField(value = Filters.Users.SCREEN_NAME, type = CursorField.TEXT)
@JsonField(name = "screen_name") @JsonField(name = "screen_name")
String screenName; String screenName;
/**
* Used for filter list subscription
*/
@CursorField(value = Filters.Users.SOURCE, type = "INTEGER DEFAULT -1")
@JsonField(name = "source")
long source;
public UserKey getUserKey() { public UserKey getUserKey() {
return userKey; return userKey;
@ -105,6 +114,14 @@ public class FiltersData {
this.userKey = userKey; this.userKey = userKey;
} }
public long getSource() {
return source;
}
public void setSource(long source) {
this.source = source;
}
@Override @Override
public String toString() { public String toString() {
return "UserItem{" + return "UserItem{" +
@ -116,11 +133,19 @@ public class FiltersData {
} }
@JsonObject @JsonObject
@CursorObject(valuesCreator = true) @CursorObject(valuesCreator = true, tableInfo = true)
public static class BaseItem { public static class BaseItem {
@CursorField(Filters.VALUE) @CursorField(value = Filters._ID, type = TwidereDataStore.TYPE_PRIMARY_KEY)
long _id;
@CursorField(value = Filters.VALUE, type = "TEXT NOT NULL UNIQUE")
@JsonField(name = "value") @JsonField(name = "value")
String value; String value;
/**
* Used for filter list subscription
*/
@CursorField(value = Filters.Users.SOURCE, type = "INTEGER DEFAULT -1")
@JsonField(name = "source")
long source;
public String getValue() { public String getValue() {
return value; return value;
@ -130,6 +155,14 @@ public class FiltersData {
this.value = value; this.value = value;
} }
public long getSource() {
return source;
}
public void setSource(long source) {
this.source = source;
}
@Override @Override
public String toString() { public String toString() {
return "BaseItem{" + return "BaseItem{" +

View File

@ -24,6 +24,8 @@ import android.net.Uri;
import android.provider.BaseColumns; import android.provider.BaseColumns;
import org.mariotaku.twidere.model.DraftTableInfo; import org.mariotaku.twidere.model.DraftTableInfo;
import org.mariotaku.twidere.model.FiltersData$BaseItemTableInfo;
import org.mariotaku.twidere.model.FiltersData$UserItemTableInfo;
import org.mariotaku.twidere.model.ParcelableActivityTableInfo; import org.mariotaku.twidere.model.ParcelableActivityTableInfo;
import org.mariotaku.twidere.model.ParcelableDirectMessageTableInfo; import org.mariotaku.twidere.model.ParcelableDirectMessageTableInfo;
import org.mariotaku.twidere.model.ParcelableStatusTableInfo; import org.mariotaku.twidere.model.ParcelableStatusTableInfo;
@ -565,15 +567,17 @@ public interface TwidereDataStore {
String VALUE = "value"; String VALUE = "value";
String SOURCE = "source";
String ENABLE_IN_HOME_TIMELINE = "enable_in_home_timeline"; String ENABLE_IN_HOME_TIMELINE = "enable_in_home_timeline";
String ENABLE_IN_MENTIONS = "enable_in_mentions"; String ENABLE_IN_MENTIONS = "enable_in_mentions";
String ENABLE_FOR_RETWEETS = "enable_for_retweets"; String ENABLE_FOR_RETWEETS = "enable_for_retweets";
String[] COLUMNS = {_ID, VALUE}; String[] COLUMNS = FiltersData$BaseItemTableInfo.COLUMNS;
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL_UNIQUE}; String[] TYPES = FiltersData$BaseItemTableInfo.TYPES;
interface Keywords extends Filters { interface Keywords extends Filters {
@ -609,11 +613,11 @@ public interface TwidereDataStore {
String USER_KEY = "user_id"; String USER_KEY = "user_id";
String NAME = "name"; String NAME = "name";
String SCREEN_NAME = "screen_name"; String SCREEN_NAME = "screen_name";
String SOURCE = "source";
String[] COLUMNS = {_ID, USER_KEY, NAME, SCREEN_NAME}; String[] COLUMNS = FiltersData$UserItemTableInfo.COLUMNS;
String[] TYPES = {TYPE_PRIMARY_KEY, TYPE_TEXT_NOT_NULL, TYPE_TEXT_NOT_NULL, String[] TYPES = FiltersData$UserItemTableInfo.TYPES;
TYPE_TEXT_NOT_NULL};
} }
} }

View File

@ -7,7 +7,6 @@ import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails import com.anjlab.android.iab.v3.TransactionDetails
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.TwidereConstants.EXTRA_DATA import org.mariotaku.twidere.TwidereConstants.EXTRA_DATA
import org.mariotaku.twidere.model.premium.GooglePurchaseResult
/** /**
* Created by mariotaku on 2016/12/25. * Created by mariotaku on 2016/12/25.
@ -53,11 +52,9 @@ class GooglePlayInAppPurchaseActivity : Activity(), BillingProcessor.IBillingHan
override fun onProductPurchased(productId: String?, details: TransactionDetails?) { override fun onProductPurchased(productId: String?, details: TransactionDetails?) {
billingProcessor.getPurchaseTransactionDetails(productId) billingProcessor.getPurchaseTransactionDetails(productId)
val data = Intent() val data = Intent()
val purchaseResult = GooglePurchaseResult()
details?.purchaseInfo?.purchaseData?.let { purchaseData -> details?.purchaseInfo?.purchaseData?.let { purchaseData ->
data.putExtra(EXTRA_DATA, purchaseData)
} }
data.putExtra(EXTRA_DATA, purchaseResult)
setResult(RESULT_OK, data) setResult(RESULT_OK, data)
finish() finish()
} }

View File

@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING;
public interface Constants extends TwidereConstants { public interface Constants extends TwidereConstants {
String DATABASES_NAME = "twidere.sqlite"; String DATABASES_NAME = "twidere.sqlite";
int DATABASES_VERSION = 155; int DATABASES_VERSION = 156;
int MENU_GROUP_STATUS_EXTENSION = 10; int MENU_GROUP_STATUS_EXTENSION = 10;
int MENU_GROUP_COMPOSE_EXTENSION = 11; int MENU_GROUP_COMPOSE_EXTENSION = 11;
@ -75,8 +75,10 @@ public interface Constants extends TwidereConstants {
int LINK_ID_SCHEDULED_STATUSES = 61; int LINK_ID_SCHEDULED_STATUSES = 61;
int LINK_ID_ACCOUNTS = 101; int LINK_ID_ACCOUNTS = 101;
int LINK_ID_DRAFTS = 102; int LINK_ID_DRAFTS = 102;
int LINK_ID_FILTERS = 103; int LINK_ID_FILTERS = 110;
int LINK_ID_PROFILE_EDITOR = 104; int LINK_ID_FILTERS_IMPORT_BLOCKS = 111;
int LINK_ID_FILTERS_IMPORT_MUTES = 112;
int LINK_ID_PROFILE_EDITOR = 121;
String TWIDERE_PREVIEW_NICKNAME = "Twidere"; String TWIDERE_PREVIEW_NICKNAME = "Twidere";
String TWIDERE_PREVIEW_NAME = "Twidere Project"; String TWIDERE_PREVIEW_NAME = "Twidere Project";

View File

@ -124,7 +124,6 @@ import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages; import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries; import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages.ConversationEntries;
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses; import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
import org.mariotaku.twidere.util.ErrorInfoStore.DisplayErrorInfo;
import org.mariotaku.twidere.util.TwidereLinkify.HighlightStyle; import org.mariotaku.twidere.util.TwidereLinkify.HighlightStyle;
import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle; import org.mariotaku.twidere.view.CardMediaContainer.PreviewStyle;
import org.mariotaku.twidere.view.ShapedImageView; import org.mariotaku.twidere.view.ShapedImageView;
@ -197,6 +196,8 @@ public final class Utils implements Constants {
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_ACCOUNTS, null, LINK_ID_ACCOUNTS); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_ACCOUNTS, null, LINK_ID_ACCOUNTS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_DRAFTS, null, LINK_ID_DRAFTS); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_DRAFTS, null, LINK_ID_DRAFTS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_FILTERS, null, LINK_ID_FILTERS); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_FILTERS, null, LINK_ID_FILTERS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_FILTERS_IMPORT_BLOCKS, null, LINK_ID_FILTERS_IMPORT_BLOCKS);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_FILTERS_IMPORT_MUTES, null, LINK_ID_FILTERS_IMPORT_MUTES);
LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_PROFILE_EDITOR, null, LINK_ID_PROFILE_EDITOR); LINK_HANDLER_URI_MATCHER.addURI(AUTHORITY_PROFILE_EDITOR, null, LINK_ID_PROFILE_EDITOR);
HOME_TABS_URI_MATCHER.addURI(CustomTabType.HOME_TIMELINE, null, TAB_CODE_HOME_TIMELINE); HOME_TABS_URI_MATCHER.addURI(CustomTabType.HOME_TIMELINE, null, TAB_CODE_HOME_TIMELINE);
@ -732,19 +733,6 @@ public final class Utils implements Constants {
return url; return url;
} }
@ShapeStyle
public static int getProfileImageStyle(Context context) {
final SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
final String style = prefs.getString(KEY_PROFILE_IMAGE_STYLE, null);
return getProfileImageStyle(style);
}
@ShapeStyle
public static int getProfileImageStyle(@NonNull SharedPreferences prefs) {
final String style = prefs.getString(KEY_PROFILE_IMAGE_STYLE, null);
return getProfileImageStyle(style);
}
@ShapeStyle @ShapeStyle
public static int getProfileImageStyle(String style) { public static int getProfileImageStyle(String style) {
if (VALUE_PROFILE_IMAGE_STYLE_SQUARE.equalsIgnoreCase(style)) { if (VALUE_PROFILE_IMAGE_STYLE_SQUARE.equalsIgnoreCase(style)) {

View File

@ -48,6 +48,8 @@ import org.mariotaku.twidere.constant.KeyboardShortcutConstants
import org.mariotaku.twidere.constant.SharedPreferenceConstants import org.mariotaku.twidere.constant.SharedPreferenceConstants
import org.mariotaku.twidere.fragment.* import org.mariotaku.twidere.fragment.*
import org.mariotaku.twidere.fragment.filter.FiltersFragment import org.mariotaku.twidere.fragment.filter.FiltersFragment
import org.mariotaku.twidere.fragment.filter.FiltersImportBlocksFragment
import org.mariotaku.twidere.fragment.filter.FiltersImportMutesFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment import org.mariotaku.twidere.fragment.iface.IBaseFragment
import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback import org.mariotaku.twidere.fragment.iface.IBaseFragment.SystemWindowsInsetsCallback
import org.mariotaku.twidere.fragment.iface.IToolBarSupportFragment import org.mariotaku.twidere.fragment.iface.IToolBarSupportFragment
@ -56,6 +58,7 @@ import org.mariotaku.twidere.graphic.EmptyDrawable
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.* import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
import org.mariotaku.twidere.util.Utils.LINK_ID_FILTERS_IMPORT_BLOCKS
import org.mariotaku.twidere.util.Utils.matchLinkId import org.mariotaku.twidere.util.Utils.matchLinkId
class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IControlBarActivity, SupportFragmentCallback { class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IControlBarActivity, SupportFragmentCallback {
@ -386,6 +389,12 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
LINK_ID_PUBLIC_TIMELINE -> { LINK_ID_PUBLIC_TIMELINE -> {
title = getString(R.string.public_timeline) title = getString(R.string.public_timeline)
} }
LINK_ID_FILTERS_IMPORT_BLOCKS -> {
title = getString(R.string.title_select_users)
}
LINK_ID_FILTERS_IMPORT_MUTES -> {
title = getString(R.string.title_select_users)
}
else -> { else -> {
title = getString(R.string.app_name) title = getString(R.string.app_name)
} }
@ -721,6 +730,12 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
} }
fragment = SearchFragment() fragment = SearchFragment()
} }
LINK_ID_FILTERS_IMPORT_BLOCKS -> {
fragment = FiltersImportBlocksFragment()
}
LINK_ID_FILTERS_IMPORT_MUTES -> {
fragment = FiltersImportMutesFragment()
}
else -> { else -> {
return null return null
} }

View File

@ -44,7 +44,7 @@ class DummyItemAdapter @JvmOverloads constructor(
override var sensitiveContentEnabled: Boolean = false override var sensitiveContentEnabled: Boolean = false
override var mediaPreviewEnabled: Boolean = false override var mediaPreviewEnabled: Boolean = false
override var isShowAbsoluteTime: Boolean = false override var isShowAbsoluteTime: Boolean = false
override var followClickListener: IUsersAdapter.FriendshipClickListener? = null override var friendshipClickListener: IUsersAdapter.FriendshipClickListener? = null
override var requestClickListener: IUsersAdapter.RequestClickListener? = null override var requestClickListener: IUsersAdapter.RequestClickListener? = null
override var statusClickListener: IStatusViewHolder.StatusClickListener? = null override var statusClickListener: IStatusViewHolder.StatusClickListener? = null
override var userClickListener: IUsersAdapter.UserClickListener? = null override var userClickListener: IUsersAdapter.UserClickListener? = null

View File

@ -29,7 +29,7 @@ import org.mariotaku.twidere.loader.ExtensionsListLoader.ExtensionInfo
import org.mariotaku.twidere.util.PermissionsManager import org.mariotaku.twidere.util.PermissionsManager
import org.mariotaku.twidere.view.holder.CheckableTwoLineWithIconViewHolder import org.mariotaku.twidere.view.holder.CheckableTwoLineWithIconViewHolder
class ExtensionsAdapter(context: Context) : ArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line_checked) { class ExtensionsAdapter(context: Context) : ArrayAdapter<ExtensionInfo>(context, R.layout.list_item_two_line) {
private val mPermissionsManager: PermissionsManager private val mPermissionsManager: PermissionsManager

View File

@ -28,7 +28,8 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
/** /**
* Created by mariotaku on 15/4/16. * Created by mariotaku on 15/4/16.
*/ */
abstract class LoadMoreSupportAdapter<VH : ViewHolder>(context: Context) : BaseRecyclerViewAdapter<VH>(context), ILoadMoreSupportAdapter { abstract class LoadMoreSupportAdapter<VH : ViewHolder>(context: Context) :
BaseRecyclerViewAdapter<VH>(context), ILoadMoreSupportAdapter {
@IndicatorPosition @IndicatorPosition
override var loadMoreSupportedPosition: Long = 0 override var loadMoreSupportedPosition: Long = 0

View File

@ -24,14 +24,14 @@ import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.IGroupsAdapter import org.mariotaku.twidere.adapter.iface.IGroupsAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.Companion.ITEM_VIEW_TYPE_LOAD_INDICATOR import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.Companion.ITEM_VIEW_TYPE_LOAD_INDICATOR
import org.mariotaku.twidere.constant.SharedPreferenceConstants import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.model.ParcelableGroup import org.mariotaku.twidere.model.ParcelableGroup
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.view.holder.GroupViewHolder import org.mariotaku.twidere.view.holder.GroupViewHolder
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
@ -53,11 +53,11 @@ class ParcelableGroupsAdapter(context: Context) : LoadMoreSupportAdapter<Recycle
init { init {
mEventListener = EventListener(this) mEventListener = EventListener(this)
inflater = LayoutInflater.from(context) inflater = LayoutInflater.from(context)
textSize = preferences.getInt(SharedPreferenceConstants.KEY_TEXT_SIZE, context.resources.getInteger(R.integer.default_text_size)).toFloat() textSize = preferences[textSizeKey].toFloat()
profileImageStyle = Utils.getProfileImageStyle(preferences.getString(SharedPreferenceConstants.KEY_PROFILE_IMAGE_STYLE, null)) profileImageStyle = preferences[profileImageStyleKey]
profileImageEnabled = preferences.getBoolean(SharedPreferenceConstants.KEY_DISPLAY_PROFILE_IMAGE, true) profileImageEnabled = preferences[displayProfileImageKey]
nameFirst = preferences.getBoolean(SharedPreferenceConstants.KEY_NAME_FIRST, true) nameFirst = preferences[nameFirstKey]
isShowAbsoluteTime = preferences.getBoolean(SharedPreferenceConstants.KEY_SHOW_ABSOLUTE_TIME, false) isShowAbsoluteTime = preferences[showAbsoluteTimeKey]
} }
fun getData(): List<ParcelableGroup>? { fun getData(): List<ParcelableGroup>? {

View File

@ -23,15 +23,18 @@ import android.content.Context
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.Companion.ITEM_VIEW_TYPE_LOAD_INDICATOR import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.Companion.ITEM_VIEW_TYPE_LOAD_INDICATOR
import org.mariotaku.twidere.adapter.iface.IUsersAdapter import org.mariotaku.twidere.adapter.iface.IUsersAdapter
import org.mariotaku.twidere.constant.SharedPreferenceConstants import org.mariotaku.twidere.constant.displayProfileImageKey
import org.mariotaku.twidere.constant.profileImageStyleKey
import org.mariotaku.twidere.constant.showAbsoluteTimeKey
import org.mariotaku.twidere.constant.textSizeKey
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
import org.mariotaku.twidere.view.holder.UserViewHolder import org.mariotaku.twidere.view.holder.UserViewHolder
@ -46,15 +49,15 @@ class ParcelableUsersAdapter(context: Context) : LoadMoreSupportAdapter<Recycler
override val isShowAbsoluteTime: Boolean override val isShowAbsoluteTime: Boolean
override var userClickListener: IUsersAdapter.UserClickListener? = null override var userClickListener: IUsersAdapter.UserClickListener? = null
override var requestClickListener: IUsersAdapter.RequestClickListener? = null override var requestClickListener: IUsersAdapter.RequestClickListener? = null
override var followClickListener: IUsersAdapter.FriendshipClickListener? = null override var friendshipClickListener: IUsersAdapter.FriendshipClickListener? = null
override var simpleLayout: Boolean = false override var simpleLayout: Boolean = false
init { init {
inflater = LayoutInflater.from(context) inflater = LayoutInflater.from(context)
textSize = preferences.getInt(SharedPreferenceConstants.KEY_TEXT_SIZE, context.resources.getInteger(R.integer.default_text_size)).toFloat() textSize = preferences[textSizeKey].toFloat()
profileImageStyle = Utils.getProfileImageStyle(preferences.getString(SharedPreferenceConstants.KEY_PROFILE_IMAGE_STYLE, null)) profileImageStyle = preferences[profileImageStyleKey]
profileImageEnabled = preferences.getBoolean(SharedPreferenceConstants.KEY_DISPLAY_PROFILE_IMAGE) profileImageEnabled = preferences[displayProfileImageKey]
isShowAbsoluteTime = preferences.getBoolean(SharedPreferenceConstants.KEY_SHOW_ABSOLUTE_TIME) isShowAbsoluteTime = preferences[showAbsoluteTimeKey]
} }
fun getData(): List<ParcelableUser>? { fun getData(): List<ParcelableUser>? {

View File

@ -33,7 +33,7 @@ interface IUsersAdapter<in Data> : IContentCardAdapter {
val requestClickListener: RequestClickListener? val requestClickListener: RequestClickListener?
val followClickListener: FriendshipClickListener? val friendshipClickListener: FriendshipClickListener?
val showAccountsColor: Boolean val showAccountsColor: Boolean

View File

@ -6,19 +6,19 @@ import android.text.TextUtils
import org.mariotaku.kpreferences.* import org.mariotaku.kpreferences.*
import org.mariotaku.ktextension.toLong import org.mariotaku.ktextension.toLong
import org.mariotaku.twidere.BuildConfig import org.mariotaku.twidere.BuildConfig
import org.mariotaku.twidere.Constants.KEY_DISPLAY_PROFILE_IMAGE
import org.mariotaku.twidere.Constants.KEY_NO_CLOSE_AFTER_TWEET_SENT import org.mariotaku.twidere.Constants.KEY_NO_CLOSE_AFTER_TWEET_SENT
import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_REMEMBER_POSITION
import org.mariotaku.twidere.extension.getNonEmptyString import org.mariotaku.twidere.extension.getNonEmptyString
import org.mariotaku.twidere.model.CustomAPIConfig import org.mariotaku.twidere.model.CustomAPIConfig
import org.mariotaku.twidere.model.account.cred.Credentials import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.view.ProfileImageView
/** /**
* Created by mariotaku on 16/8/25. * Created by mariotaku on 16/8/25.
*/ */
val mediaPreviewStyleKey = KStringKey(KEY_MEDIA_PREVIEW_STYLE, VALUE_MEDIA_PREVIEW_STYLE_CROP) val mediaPreviewStyleKey = KStringKey(KEY_MEDIA_PREVIEW_STYLE, VALUE_MEDIA_PREVIEW_STYLE_CROP)
val profileImageStyleKey = KStringKey(KEY_PROFILE_IMAGE_STYLE, VALUE_PROFILE_IMAGE_STYLE_ROUND)
val textSizeKey = KIntKey(KEY_TEXT_SIZE, 15) val textSizeKey = KIntKey(KEY_TEXT_SIZE, 15)
val nameFirstKey = KBooleanKey(KEY_NAME_FIRST, true) val nameFirstKey = KBooleanKey(KEY_NAME_FIRST, true)
val displayProfileImageKey = KBooleanKey(KEY_DISPLAY_PROFILE_IMAGE, true) val displayProfileImageKey = KBooleanKey(KEY_DISPLAY_PROFILE_IMAGE, true)
@ -53,6 +53,19 @@ val themeKey = KStringKey(KEY_THEME, VALUE_THEME_NAME_LIGHT)
val themeColorKey = KIntKey(KEY_THEME_COLOR, 0) val themeColorKey = KIntKey(KEY_THEME_COLOR, 0)
val filterUnavailableQuoteStatusesKey = KBooleanKey("filter_unavailable_quote_statuses", false) val filterUnavailableQuoteStatusesKey = KBooleanKey("filter_unavailable_quote_statuses", false)
object profileImageStyleKey : KSimpleKey<Int>(KEY_PROFILE_IMAGE_STYLE, ProfileImageView.SHAPE_CIRCLE) {
override fun read(preferences: SharedPreferences): Int {
if (preferences.getString(key, null) == VALUE_PROFILE_IMAGE_STYLE_SQUARE) return ProfileImageView.SHAPE_RECTANGLE
return ProfileImageView.SHAPE_CIRCLE
}
override fun write(editor: SharedPreferences.Editor, value: Int): Boolean {
editor.putString(key, if (value == ProfileImageView.SHAPE_CIRCLE) VALUE_PROFILE_IMAGE_STYLE_ROUND else VALUE_PROFILE_IMAGE_STYLE_SQUARE)
return true
}
}
object refreshIntervalKey : KSimpleKey<Long>(KEY_REFRESH_INTERVAL, 15) { object refreshIntervalKey : KSimpleKey<Long>(KEY_REFRESH_INTERVAL, 15) {
override fun read(preferences: SharedPreferences): Long { override fun read(preferences: SharedPreferences): Long {
return preferences.getString(key, null).toLong(def) return preferences.getString(key, null).toLong(def)

View File

@ -33,7 +33,8 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
* Comment, blah, blah, blah. * Comment, blah, blah, blah.
* Created by mariotaku on 15/4/16. * Created by mariotaku on 15/4/16.
*/ */
abstract class AbsContentListRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>> : AbsContentRecyclerViewFragment<A, LinearLayoutManager>() { abstract class AbsContentListRecyclerViewFragment<A : LoadMoreSupportAdapter<RecyclerView.ViewHolder>>
: AbsContentRecyclerViewFragment<A, LinearLayoutManager>() {
override fun createItemDecoration(context: Context, override fun createItemDecoration(context: Context,
recyclerView: RecyclerView, recyclerView: RecyclerView,

View File

@ -46,10 +46,6 @@ abstract class CursorSupportUsersListFragment : ParcelableUsersFragment() {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
} }
override fun onDestroyView() {
super.onDestroyView()
}
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) { override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
super.onLoaderReset(loader) super.onLoaderReset(loader)
} }
@ -70,15 +66,15 @@ abstract class CursorSupportUsersListFragment : ParcelableUsersFragment() {
val loaderArgs = Bundle(arguments) val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true) loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor) loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor)
loaderArgs.putLong(EXTRA_PAGE, nextPage.toLong()) loaderArgs.putInt(EXTRA_PAGE, nextPage)
loaderManager.restartLoader(0, loaderArgs, this) loaderManager.restartLoader(0, loaderArgs, this)
} }
override fun onSaveInstanceState(outState: Bundle?) { override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
outState!!.putLong(EXTRA_NEXT_CURSOR, nextCursor) outState.putLong(EXTRA_NEXT_CURSOR, nextCursor)
outState.putLong(EXTRA_PREV_CURSOR, prevCursor) outState.putLong(EXTRA_PREV_CURSOR, prevCursor)
outState.putLong(EXTRA_NEXT_PAGE, nextPage.toLong()) outState.putInt(EXTRA_NEXT_PAGE, nextPage)
} }
abstract override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): CursorSupportUsersLoader abstract override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean): CursorSupportUsersLoader

View File

@ -29,7 +29,7 @@ import org.mariotaku.twidere.model.message.FriendshipTaskEvent
class MutesUsersListFragment : CursorSupportUsersListFragment() { class MutesUsersListFragment : CursorSupportUsersListFragment() {
public override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context,
args: Bundle, args: Bundle,
fromUser: Boolean): CursorSupportUsersLoader { fromUser: Boolean): CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)

View File

@ -95,7 +95,7 @@ abstract class ParcelableUsersFragment : AbsContentListRecyclerViewFragment<Parc
override fun onCreateAdapter(context: Context): ParcelableUsersAdapter { override fun onCreateAdapter(context: Context): ParcelableUsersAdapter {
val adapter = ParcelableUsersAdapter(context) val adapter = ParcelableUsersAdapter(context)
adapter.simpleLayout = simpleLayout adapter.simpleLayout = simpleLayout
adapter.followClickListener = this adapter.friendshipClickListener = this
return adapter return adapter
} }

View File

@ -66,8 +66,8 @@ class SearchUsersFragment : ParcelableUsersFragment() {
loaderManager.restartLoader<List<ParcelableUser>>(0, loaderArgs, this) loaderManager.restartLoader<List<ParcelableUser>>(0, loaderArgs, this)
} }
override fun onSaveInstanceState(outState: Bundle?) { override fun onSaveInstanceState(outState: Bundle) {
outState!!.putInt(EXTRA_PAGE, page) outState.putInt(EXTRA_PAGE, page)
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
} }

View File

@ -29,7 +29,7 @@ import org.mariotaku.twidere.model.message.FriendshipTaskEvent
class UserBlocksListFragment : CursorSupportUsersListFragment() { class UserBlocksListFragment : CursorSupportUsersListFragment() {
public override fun onCreateUsersLoader(context: Context, override fun onCreateUsersLoader(context: Context,
args: Bundle, args: Bundle,
fromUser: Boolean): CursorSupportUsersLoader { fromUser: Boolean): CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY) val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)

View File

@ -61,9 +61,9 @@ class UserListMembersFragment : CursorSupportUsersListFragment() {
registerForContextMenu(recyclerView) registerForContextMenu(recyclerView)
} }
override fun onSaveInstanceState(outState: Bundle?) { override fun onSaveInstanceState(outState: Bundle) {
outState!!.putParcelable(EXTRA_USER_LIST, userList)
super.onSaveInstanceState(outState) super.onSaveInstanceState(outState)
outState.putParcelable(EXTRA_USER_LIST, userList)
} }
override fun onStart() { override fun onStart() {

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.mariotaku.twidere.fragment package org.mariotaku.twidere.fragment.filter
import android.app.Dialog import android.app.Dialog
import android.content.ContentValues import android.content.ContentValues
@ -51,6 +51,8 @@ import org.mariotaku.twidere.TwidereConstants.EXTRA_URI
import org.mariotaku.twidere.activity.iface.IControlBarActivity import org.mariotaku.twidere.activity.iface.IControlBarActivity
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter
import org.mariotaku.twidere.fragment.AbsContentListViewFragment
import org.mariotaku.twidere.fragment.BaseDialogFragment
import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Filters
import org.mariotaku.twidere.util.ParseUtils import org.mariotaku.twidere.util.ParseUtils
import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.Utils
@ -263,7 +265,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
private class FilterListAdapter( private class FilterListAdapter(
context: Context context: Context
) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null, ) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null,
BaseFiltersFragment.FilterListAdapter.from, BaseFiltersFragment.FilterListAdapter.to, 0) { from, to, 0) {
companion object { companion object {
private val from = arrayOf(Filters.VALUE) private val from = arrayOf(Filters.VALUE)

View File

@ -0,0 +1,244 @@
package org.mariotaku.twidere.fragment.filter
import android.content.Context
import android.os.Bundle
import android.support.v4.app.LoaderManager
import android.support.v4.content.Loader
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.LoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.IContentCardAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition
import org.mariotaku.twidere.constant.*
import org.mariotaku.twidere.fragment.AbsContentListRecyclerViewFragment
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.loader.iface.IExtendedLoader
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.view.holder.LoadIndicatorViewHolder
import org.mariotaku.twidere.view.holder.SimpleUserViewHolder
/**
* Created by mariotaku on 2016/12/26.
*/
abstract class BaseFiltersImportFragment : AbsContentListRecyclerViewFragment<BaseFiltersImportFragment.SelectableUsersAdapter>(),
LoaderManager.LoaderCallbacks<List<ParcelableUser>?> {
protected var nextCursor: Long = -1
private set
protected var prevCursor: Long = -1
private set
protected var nextPage = 1
private set
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true)
loaderManager.initLoader(0, loaderArgs, this)
}
override fun onCreateLoader(id: Int, args: Bundle): Loader<List<ParcelableUser>?> {
val fromUser = args.getBoolean(IntentConstants.EXTRA_FROM_USER)
args.remove(IntentConstants.EXTRA_FROM_USER)
return onCreateUsersLoader(context, args, fromUser)
}
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
adapter.data = null
}
override fun onLoadFinished(loader: Loader<List<ParcelableUser>?>, data: List<ParcelableUser>?) {
adapter.data = data
if (loader !is IExtendedLoader || loader.fromUser) {
adapter.loadMoreSupportedPosition = if (hasMoreData(data)) ILoadMoreSupportAdapter.END else ILoadMoreSupportAdapter.NONE
refreshEnabled = true
}
if (loader is IExtendedLoader) {
loader.fromUser = false
}
showContent()
refreshEnabled = true
refreshing = false
setLoadMoreIndicatorPosition(ILoadMoreSupportAdapter.NONE)
val cursorLoader = loader as CursorSupportUsersLoader
nextCursor = cursorLoader.nextCursor
prevCursor = cursorLoader.prevCursor
nextPage = cursorLoader.nextPage
}
override fun onLoadMoreContents(@IndicatorPosition position: Long) {
// Only supports load from end, skip START flag
if (position and ILoadMoreSupportAdapter.START !== 0L) return
super.onLoadMoreContents(position)
if (position == 0L) return
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(IntentConstants.EXTRA_FROM_USER, true)
loaderArgs.putLong(IntentConstants.EXTRA_NEXT_CURSOR, nextCursor)
loaderArgs.putInt(IntentConstants.EXTRA_PAGE, nextPage)
loaderManager.restartLoader(0, loaderArgs, this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_filters_import, container, false)
}
override fun onCreateAdapter(context: Context): SelectableUsersAdapter {
return SelectableUsersAdapter(context)
}
protected abstract fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
Loader<List<ParcelableUser>?>
protected open fun hasMoreData(data: List<ParcelableUser>?): Boolean {
return data == null || !data.isEmpty()
}
class SelectableUsersAdapter(context: Context) : LoadMoreSupportAdapter<RecyclerView.ViewHolder>(context), IContentCardAdapter {
override val isShowAbsoluteTime: Boolean
override val profileImageEnabled: Boolean
override val profileImageStyle: Int
override val textSize: Float
val ITEM_VIEW_TYPE_USER = 2
private val inflater: LayoutInflater
var data: List<ParcelableUser>? = null
set(value) {
field = value
notifyDataSetChanged()
}
init {
inflater = LayoutInflater.from(context)
isShowAbsoluteTime = preferences[showAbsoluteTimeKey]
profileImageEnabled = preferences[displayProfileImageKey]
profileImageStyle = preferences[profileImageStyleKey]
textSize = preferences[textSizeKey].toFloat()
}
private fun bindUser(holder: SelectableUserViewHolder, position: Int) {
holder.displayUser(getUser(position)!!)
}
override fun getItemCount(): Int {
val position = loadMoreIndicatorPosition
var count = userCount
if (position and ILoadMoreSupportAdapter.START !== 0L) {
count++
}
if (position and ILoadMoreSupportAdapter.END !== 0L) {
count++
}
return count
}
fun getUser(position: Int): ParcelableUser? {
val dataPosition = position - userStartIndex
if (dataPosition < 0 || dataPosition >= userCount) return null
return data!![dataPosition]
}
val userStartIndex: Int
get() {
val position = loadMoreIndicatorPosition
var start = 0
if (position and ILoadMoreSupportAdapter.START !== 0L) {
start += 1
}
return start
}
fun getUserId(position: Int): String? {
if (position == userCount) return null
return data!![position].key.id
}
val userCount: Int
get() {
if (data == null) return 0
return data!!.size
}
fun removeUserAt(position: Int): Boolean {
val data = this.data as? MutableList ?: return false
val dataPosition = position - userStartIndex
if (dataPosition < 0 || dataPosition >= userCount) return false
data.removeAt(dataPosition)
notifyItemRemoved(position)
return true
}
fun setUserAt(position: Int, user: ParcelableUser): Boolean {
val data = this.data as? MutableList ?: return false
val dataPosition = position - userStartIndex
if (dataPosition < 0 || dataPosition >= userCount) return false
data[dataPosition] = user
notifyItemChanged(position)
return true
}
fun findPosition(accountKey: UserKey, userKey: UserKey): Int {
if (data == null) return RecyclerView.NO_POSITION
for (i in userStartIndex until userStartIndex + userCount) {
val user = data!![i]
if (accountKey == user.account_key && userKey == user.key) {
return i
}
}
return RecyclerView.NO_POSITION
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
ITEM_VIEW_TYPE_USER -> {
val view = inflater.inflate(R.layout.list_item_simple_user, parent, false)
val holder = SelectableUserViewHolder(view, this)
return holder
}
ILoadMoreSupportAdapter.ITEM_VIEW_TYPE_LOAD_INDICATOR -> {
val view = inflater.inflate(R.layout.card_item_load_indicator, parent, false)
return LoadIndicatorViewHolder(view)
}
}
throw IllegalStateException("Unknown view type " + viewType)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder.itemViewType) {
ITEM_VIEW_TYPE_USER -> {
bindUser(holder as SelectableUserViewHolder, position)
}
}
}
override fun getItemViewType(position: Int): Int {
if (loadMoreIndicatorPosition and ILoadMoreSupportAdapter.START !== 0L && position == 0) {
return ILoadMoreSupportAdapter.ITEM_VIEW_TYPE_LOAD_INDICATOR
}
if (position == userCount) {
return ILoadMoreSupportAdapter.ITEM_VIEW_TYPE_LOAD_INDICATOR
}
return ITEM_VIEW_TYPE_USER
}
}
class SelectableUserViewHolder(
itemView: View,
adapter: IContentCardAdapter
) : SimpleUserViewHolder(itemView, adapter) {
override fun displayUser(user: ParcelableUser) {
super.displayUser(user)
}
}
}

View File

@ -1,7 +1,6 @@
package org.mariotaku.twidere.fragment.filter package org.mariotaku.twidere.fragment.filter
import android.net.Uri import android.net.Uri
import org.mariotaku.twidere.fragment.BaseFiltersFragment
import org.mariotaku.twidere.provider.TwidereDataStore import org.mariotaku.twidere.provider.TwidereDataStore
class FilteredKeywordsFragment : BaseFiltersFragment() { class FilteredKeywordsFragment : BaseFiltersFragment() {

View File

@ -1,7 +1,7 @@
package org.mariotaku.twidere.fragment.filter package org.mariotaku.twidere.fragment.filter
import android.net.Uri import android.net.Uri
import org.mariotaku.twidere.fragment.BaseFiltersFragment import org.mariotaku.twidere.fragment.filter.BaseFiltersFragment
import org.mariotaku.twidere.provider.TwidereDataStore import org.mariotaku.twidere.provider.TwidereDataStore
class FilteredLinksFragment : BaseFiltersFragment() { class FilteredLinksFragment : BaseFiltersFragment() {

View File

@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.MenuItem import android.view.MenuItem
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_URI import org.mariotaku.twidere.constant.IntentConstants.EXTRA_URI
import org.mariotaku.twidere.fragment.BaseFiltersFragment import org.mariotaku.twidere.fragment.filter.BaseFiltersFragment
import org.mariotaku.twidere.provider.TwidereDataStore import org.mariotaku.twidere.provider.TwidereDataStore
class FilteredSourcesFragment : BaseFiltersFragment() { class FilteredSourcesFragment : BaseFiltersFragment() {

View File

@ -16,12 +16,11 @@ import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.Expression
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.REQUEST_SELECT_USER import org.mariotaku.twidere.TwidereConstants.*
import org.mariotaku.twidere.activity.AccountSelectorActivity import org.mariotaku.twidere.activity.AccountSelectorActivity
import org.mariotaku.twidere.activity.LinkHandlerActivity
import org.mariotaku.twidere.activity.UserListSelectorActivity import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.nameFirstKey import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.fragment.BaseFiltersFragment
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
@ -66,10 +65,18 @@ class FilteredUsersFragment : BaseFiltersFragment() {
resolver.insert(TwidereDataStore.Filters.Users.CONTENT_URI, values) resolver.insert(TwidereDataStore.Filters.Users.CONTENT_URI, values)
} }
REQUEST_IMPORT_BLOCKS_SELECT_ACCOUNT -> { REQUEST_IMPORT_BLOCKS_SELECT_ACCOUNT -> {
if (resultCode != FragmentActivity.RESULT_OK) return
val intent = Intent(context, LinkHandlerActivity::class.java)
intent.data = Uri.Builder().scheme(SCHEME_TWIDERE).authority(AUTHORITY_FILTERS_IMPORT_BLOCKS).build()
intent.putExtra(EXTRA_ACCOUNT_KEY, data!!.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY))
startActivity(intent)
} }
REQUEST_IMPORT_MUTES_SELECT_ACCOUNT -> { REQUEST_IMPORT_MUTES_SELECT_ACCOUNT -> {
if (resultCode != FragmentActivity.RESULT_OK) return
val intent = Intent(context, LinkHandlerActivity::class.java)
intent.data = Uri.Builder().scheme(SCHEME_TWIDERE).authority(AUTHORITY_FILTERS_IMPORT_MUTES).build()
intent.putExtra(EXTRA_ACCOUNT_KEY, data!!.getParcelableExtra<UserKey>(EXTRA_ACCOUNT_KEY))
startActivity(intent)
} }
REQUEST_ADD_USER_SELECT_ACCOUNT -> { REQUEST_ADD_USER_SELECT_ACCOUNT -> {
if (resultCode != FragmentActivity.RESULT_OK) return if (resultCode != FragmentActivity.RESULT_OK) return

View File

@ -23,7 +23,7 @@ import android.os.Bundle
import org.mariotaku.twidere.R import org.mariotaku.twidere.R
import org.mariotaku.twidere.adapter.SupportTabsAdapter import org.mariotaku.twidere.adapter.SupportTabsAdapter
import org.mariotaku.twidere.fragment.* import org.mariotaku.twidere.fragment.*
import org.mariotaku.twidere.fragment.BaseFiltersFragment.* import org.mariotaku.twidere.fragment.filter.BaseFiltersFragment.*
class FiltersFragment : AbsToolbarTabPagesFragment() { class FiltersFragment : AbsToolbarTabPagesFragment() {

View File

@ -0,0 +1,24 @@
package org.mariotaku.twidere.fragment.filter
import android.content.Context
import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.loader.UserBlocksLoader
import org.mariotaku.twidere.model.UserKey
/**
* Created by mariotaku on 2016/12/26.
*/
class FiltersImportBlocksFragment : BaseFiltersImportFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey>(IntentConstants.EXTRA_ACCOUNT_KEY)
val loader = UserBlocksLoader(context, accountKey, adapter.data, fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
}
}

View File

@ -0,0 +1,22 @@
package org.mariotaku.twidere.fragment.filter
import android.content.Context
import android.os.Bundle
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT_KEY
import org.mariotaku.twidere.loader.CursorSupportUsersLoader
import org.mariotaku.twidere.loader.MutesUsersLoader
import org.mariotaku.twidere.model.UserKey
/**
* Created by mariotaku on 2016/12/26.
*/
class FiltersImportMutesFragment : BaseFiltersImportFragment() {
override fun onCreateUsersLoader(context: Context, args: Bundle, fromUser: Boolean):
CursorSupportUsersLoader {
val accountKey = args.getParcelable<UserKey>(EXTRA_ACCOUNT_KEY)
val loader = MutesUsersLoader(context, accountKey, adapter.data, fromUser)
loader.cursor = nextCursor
loader.page = nextPage
return loader
}
}

View File

@ -0,0 +1,37 @@
package org.mariotaku.twidere.view.holder
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.CheckBox
import android.widget.TextView
import kotlinx.android.synthetic.main.list_item_simple_user.view.*
import org.mariotaku.twidere.adapter.iface.IContentCardAdapter
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.view.ProfileImageView
/**
* Created by mariotaku on 2016/12/1.
*/
open class SimpleUserViewHolder(itemView: View, val adapter: IContentCardAdapter) : RecyclerView.ViewHolder(itemView) {
val nameView: TextView
val secondaryNameView: TextView
val profileImageView: ProfileImageView
val checkBox: CheckBox
init {
nameView = itemView.name
secondaryNameView = itemView.screenName
profileImageView = itemView.profileImage
checkBox = itemView.checkBox
profileImageView.style = adapter.profileImageStyle
}
open fun displayUser(user: ParcelableUser) {
nameView.text = user.name
secondaryNameView.text = "@${user.screen_name}"
adapter.mediaLoader.displayProfileImage(profileImageView, user)
}
}

View File

@ -230,7 +230,7 @@ class UserViewHolder(
fun setOnClickListeners() { fun setOnClickListeners() {
setUserClickListener(adapter.userClickListener) setUserClickListener(adapter.userClickListener)
setActionClickListeners(adapter.requestClickListener, adapter.followClickListener) setActionClickListeners(adapter.requestClickListener, adapter.friendshipClickListener)
} }
private fun setActionClickListeners(requestClickListener: RequestClickListener?, private fun setActionClickListeners(requestClickListener: RequestClickListener?,
@ -274,11 +274,11 @@ class UserViewHolder(
setTextSize(adapter.textSize) setTextSize(adapter.textSize)
} }
}
private fun RelativeLayout.LayoutParams.clearVerticalRules() { private fun RelativeLayout.LayoutParams.clearVerticalRules() {
intArrayOf(RelativeLayout.ABOVE, RelativeLayout.BELOW, RelativeLayout.ALIGN_BASELINE, intArrayOf(RelativeLayout.ABOVE, RelativeLayout.BELOW, RelativeLayout.ALIGN_BASELINE,
RelativeLayout.ALIGN_TOP, RelativeLayout.ALIGN_BOTTOM).forEach { verb -> RelativeLayout.ALIGN_TOP, RelativeLayout.ALIGN_BOTTOM).forEach { verb ->
removeRule(verb) removeRule(verb)
} }
} }
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="@layout/fragment_content_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

View File

@ -29,10 +29,11 @@
android:padding="@dimen/element_spacing_normal"> android:padding="@dimen/element_spacing_normal">
<org.mariotaku.twidere.view.ProfileImageView <org.mariotaku.twidere.view.ProfileImageView
android:id="@android:id/icon" android:id="@+id/profileImage"
style="?profileImageStyle" style="?profileImageStyle"
android:layout_width="@dimen/icon_size_list_item_small" android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small" android:layout_height="@dimen/icon_size_list_item_small"
android:layout_weight="0"
android:contentDescription="@string/icon" android:contentDescription="@string/icon"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:src="@drawable/ic_profile_image_twidere"/> tools:src="@drawable/ic_profile_image_twidere"/>
@ -40,6 +41,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical" android:orientation="vertical"
android:paddingEnd="0dp" android:paddingEnd="0dp"
@ -48,21 +50,33 @@
android:paddingStart="@dimen/element_spacing_small"> android:paddingStart="@dimen/element_spacing_small">
<TextView <TextView
android:id="@android:id/text1" android:id="@+id/name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
tools:text="User name"/> tools:text="User name"/>
<TextView <TextView
android:id="@android:id/text2" android:id="@+id/screenName"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="\@screenname"/> tools:text="\@screenname"/>
</LinearLayout> </LinearLayout>
<org.mariotaku.twidere.view.ActivatedCheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>

View File

@ -17,26 +17,32 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeight" android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal"> android:padding="@dimen/element_spacing_normal"
tools:layout_gravity="center">
<ImageView <ImageView
android:id="@android:id/icon" android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item" android:layout_width="@dimen/icon_size_list_item"
android:layout_height="@dimen/icon_size_list_item" android:layout_height="@dimen/icon_size_list_item"
android:layout_weight="0"
android:contentDescription="@string/icon" android:contentDescription="@string/icon"
android:scaleType="fitCenter" android:scaleType="fitCenter"
tools:src="@android:drawable/sym_def_app_icon" /> tools:src="@drawable/ic_profile_image_twidere"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical" android:orientation="vertical"
android:paddingEnd="0dp" android:paddingEnd="0dp"
@ -48,17 +54,30 @@
android:id="@android:id/text1" android:id="@android:id/text1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="text1" android:textColor="?android:textColorPrimary"
android:maxLines="1"/> android:textStyle="bold"
tools:text="Title"/>
<TextView <TextView
android:id="@android:id/text2" android:id="@android:id/text2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="text2" android:textColor="?android:textColorSecondary"
android:maxLines="1"/> tools:text="summary"/>
</LinearLayout> </LinearLayout>
<org.mariotaku.twidere.view.ActivatedCheckBox
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item"
android:layout_height="@dimen/icon_size_list_item"
android:layout_weight="0"
android:contentDescription="@string/icon"
android:scaleType="fitCenter"
tools:src="@android:drawable/sym_def_app_icon" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingEnd="0dp"
android:paddingLeft="@dimen/element_spacing_normal"
android:paddingRight="0dp"
android:paddingStart="@dimen/element_spacing_normal">
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
tools:text="text1"
android:maxLines="1"/>
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="text2"
android:maxLines="1"/>
</LinearLayout>
<org.mariotaku.twidere.view.ActivatedCheckBox
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>

View File

@ -20,23 +20,28 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeightSmall" android:minHeight="?android:listPreferredItemHeightSmall"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="@dimen/element_spacing_small"> android:padding="@dimen/element_spacing_small"
tools:layout_gravity="center">
<ImageView <ImageView
android:id="@android:id/icon" android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item_small" android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small" android:layout_height="@dimen/icon_size_list_item_small"
android:layout_weight="0"
android:contentDescription="@string/icon" android:contentDescription="@string/icon"
android:scaleType="fitCenter"/> android:scaleType="fitCenter"
tools:src="@drawable/ic_profile_image_twidere"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="vertical" android:orientation="vertical"
android:paddingEnd="0dp" android:paddingEnd="0dp"
@ -48,15 +53,26 @@
android:id="@android:id/text1" android:id="@android:id/text1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:maxLines="1"/> tools:text="Title"/>
<TextView <TextView
android:id="@android:id/text2" android:id="@android:id/text2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="1"/> tools:text="Summary"/>
</LinearLayout> </LinearLayout>
<org.mariotaku.twidere.view.ActivatedCheckBox
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>

View File

@ -62,20 +62,20 @@
android:id="@+id/name" android:id="@+id/name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold" android:textStyle="bold"
tools:text="List" tools:text="List"/>
android:maxLines="1"/>
<org.mariotaku.twidere.view.TimelineContentTextView <org.mariotaku.twidere.view.TimelineContentTextView
android:id="@+id/createdBy" android:id="@+id/createdBy"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary"
tools:text="Created by user" tools:text="Created by user"/>
android:maxLines="1"/>
</LinearLayout> </LinearLayout>
<TextView <TextView
@ -87,7 +87,8 @@
android:layout_below="@+id/nameContainer" android:layout_below="@+id/nameContainer"
android:paddingTop="@dimen/element_spacing_small" android:paddingTop="@dimen/element_spacing_small"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/> android:textColor="?android:attr/textColorSecondary"
tools:text="@string/sample_status_text"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -106,8 +107,9 @@
android:drawableLeft="@drawable/ic_indicator_following" android:drawableLeft="@drawable/ic_indicator_following"
android:drawablePadding="4dp" android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_indicator_following" android:drawableStart="@drawable/ic_indicator_following"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="1"/> tools:text="255"/>
<TextView <TextView
android:id="@+id/subscribersCount" android:id="@+id/subscribersCount"
@ -117,8 +119,9 @@
android:drawableLeft="@drawable/ic_indicator_followers" android:drawableLeft="@drawable/ic_indicator_followers"
android:drawablePadding="4dp" android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_indicator_followers" android:drawableStart="@drawable/ic_indicator_followers"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="1"/> tools:text="255"/>
</LinearLayout> </LinearLayout>
</org.mariotaku.twidere.view.ColorLabelRelativeLayout> </org.mariotaku.twidere.view.ColorLabelRelativeLayout>

View File

@ -830,6 +830,7 @@
<string name="preference_filter_unavailable_quote_statuses">Filter unavailable quotes</string> <string name="preference_filter_unavailable_quote_statuses">Filter unavailable quotes</string>
<string name="action_filter_import_from_blocked_users">Import from blocked users</string> <string name="action_filter_import_from_blocked_users">Import from blocked users</string>
<string name="action_filter_import_from_muted_users">Import from muted users</string> <string name="action_filter_import_from_muted_users">Import from muted users</string>
<string name="title_select_users">Select users</string>
<string name="action_purchase">Purchase</string> <string name="action_purchase">Purchase</string>
<!-- Action title used for restore purchase --> <!-- Action title used for restore purchase -->
<string name="action_restore_purchase">Restore</string> <string name="action_restore_purchase">Restore</string>