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_DRAFTS = "drafts";
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 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.twidere.model.util.UserKeyConverter;
import org.mariotaku.twidere.model.util.UserKeyCursorFieldConverter;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
import java.util.List;
@ -69,17 +70,25 @@ public class FiltersData {
}
@JsonObject
@CursorObject(valuesCreator = true)
@CursorObject(valuesCreator = true, tableInfo = true)
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)
UserKey userKey;
@CursorField(Filters.Users.NAME)
@CursorField(value = Filters.Users.NAME, type = CursorField.TEXT)
@JsonField(name = "name")
String name;
@CursorField(Filters.Users.SCREEN_NAME)
@CursorField(value = Filters.Users.SCREEN_NAME, type = CursorField.TEXT)
@JsonField(name = "screen_name")
String screenName;
/**
* Used for filter list subscription
*/
@CursorField(value = Filters.Users.SOURCE, type = "INTEGER DEFAULT -1")
@JsonField(name = "source")
long source;
public UserKey getUserKey() {
return userKey;
@ -105,6 +114,14 @@ public class FiltersData {
this.userKey = userKey;
}
public long getSource() {
return source;
}
public void setSource(long source) {
this.source = source;
}
@Override
public String toString() {
return "UserItem{" +
@ -116,11 +133,19 @@ public class FiltersData {
}
@JsonObject
@CursorObject(valuesCreator = true)
@CursorObject(valuesCreator = true, tableInfo = true)
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")
String value;
/**
* Used for filter list subscription
*/
@CursorField(value = Filters.Users.SOURCE, type = "INTEGER DEFAULT -1")
@JsonField(name = "source")
long source;
public String getValue() {
return value;
@ -130,6 +155,14 @@ public class FiltersData {
this.value = value;
}
public long getSource() {
return source;
}
public void setSource(long source) {
this.source = source;
}
@Override
public String toString() {
return "BaseItem{" +

View File

@ -24,6 +24,8 @@ import android.net.Uri;
import android.provider.BaseColumns;
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.ParcelableDirectMessageTableInfo;
import org.mariotaku.twidere.model.ParcelableStatusTableInfo;
@ -565,15 +567,17 @@ public interface TwidereDataStore {
String VALUE = "value";
String SOURCE = "source";
String ENABLE_IN_HOME_TIMELINE = "enable_in_home_timeline";
String ENABLE_IN_MENTIONS = "enable_in_mentions";
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 {
@ -609,11 +613,11 @@ public interface TwidereDataStore {
String USER_KEY = "user_id";
String NAME = "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,
TYPE_TEXT_NOT_NULL};
String[] TYPES = FiltersData$UserItemTableInfo.TYPES;
}
}

View File

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

View File

@ -34,7 +34,7 @@ import static org.mariotaku.twidere.annotation.PreferenceType.STRING;
public interface Constants extends TwidereConstants {
String DATABASES_NAME = "twidere.sqlite";
int DATABASES_VERSION = 155;
int DATABASES_VERSION = 156;
int MENU_GROUP_STATUS_EXTENSION = 10;
int MENU_GROUP_COMPOSE_EXTENSION = 11;
@ -75,8 +75,10 @@ public interface Constants extends TwidereConstants {
int LINK_ID_SCHEDULED_STATUSES = 61;
int LINK_ID_ACCOUNTS = 101;
int LINK_ID_DRAFTS = 102;
int LINK_ID_FILTERS = 103;
int LINK_ID_PROFILE_EDITOR = 104;
int LINK_ID_FILTERS = 110;
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_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.ConversationEntries;
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.view.CardMediaContainer.PreviewStyle;
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_DRAFTS, null, LINK_ID_DRAFTS);
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);
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;
}
@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
public static int getProfileImageStyle(String 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.fragment.*
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.SystemWindowsInsetsCallback
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.util.*
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
class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IControlBarActivity, SupportFragmentCallback {
@ -386,6 +389,12 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
LINK_ID_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 -> {
title = getString(R.string.app_name)
}
@ -721,6 +730,12 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
}
fragment = SearchFragment()
}
LINK_ID_FILTERS_IMPORT_BLOCKS -> {
fragment = FiltersImportBlocksFragment()
}
LINK_ID_FILTERS_IMPORT_MUTES -> {
fragment = FiltersImportMutesFragment()
}
else -> {
return null
}

View File

@ -44,7 +44,7 @@ class DummyItemAdapter @JvmOverloads constructor(
override var sensitiveContentEnabled: Boolean = false
override var mediaPreviewEnabled: 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 statusClickListener: IStatusViewHolder.StatusClickListener? = 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.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

View File

@ -28,7 +28,8 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosi
/**
* 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
override var loadMoreSupportedPosition: Long = 0

View File

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

View File

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

View File

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

View File

@ -6,19 +6,19 @@ import android.text.TextUtils
import org.mariotaku.kpreferences.*
import org.mariotaku.ktextension.toLong
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.TwidereConstants.*
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_REMEMBER_POSITION
import org.mariotaku.twidere.extension.getNonEmptyString
import org.mariotaku.twidere.model.CustomAPIConfig
import org.mariotaku.twidere.model.account.cred.Credentials
import org.mariotaku.twidere.view.ProfileImageView
/**
* Created by mariotaku on 16/8/25.
*/
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 nameFirstKey = KBooleanKey(KEY_NAME_FIRST, 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 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) {
override fun read(preferences: SharedPreferences): Long {
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.
* 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,
recyclerView: RecyclerView,

View File

@ -46,10 +46,6 @@ abstract class CursorSupportUsersListFragment : ParcelableUsersFragment() {
super.onActivityCreated(savedInstanceState)
}
override fun onDestroyView() {
super.onDestroyView()
}
override fun onLoaderReset(loader: Loader<List<ParcelableUser>?>) {
super.onLoaderReset(loader)
}
@ -70,15 +66,15 @@ abstract class CursorSupportUsersListFragment : ParcelableUsersFragment() {
val loaderArgs = Bundle(arguments)
loaderArgs.putBoolean(EXTRA_FROM_USER, true)
loaderArgs.putLong(EXTRA_NEXT_CURSOR, nextCursor)
loaderArgs.putLong(EXTRA_PAGE, nextPage.toLong())
loaderArgs.putInt(EXTRA_PAGE, nextPage)
loaderManager.restartLoader(0, loaderArgs, this)
}
override fun onSaveInstanceState(outState: Bundle?) {
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState!!.putLong(EXTRA_NEXT_CURSOR, nextCursor)
outState.putLong(EXTRA_NEXT_CURSOR, nextCursor)
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* 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.content.ContentValues
@ -51,6 +51,8 @@ import org.mariotaku.twidere.TwidereConstants.EXTRA_URI
import org.mariotaku.twidere.activity.iface.IControlBarActivity
import org.mariotaku.twidere.adapter.ComposeAutoCompleteAdapter
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.util.ParseUtils
import org.mariotaku.twidere.util.Utils
@ -263,7 +265,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment<SimpleCursorAdap
private class FilterListAdapter(
context: Context
) : SimpleCursorAdapter(context, R.layout.simple_list_item_activated_1, null,
BaseFiltersFragment.FilterListAdapter.from, BaseFiltersFragment.FilterListAdapter.to, 0) {
from, to, 0) {
companion object {
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
import android.net.Uri
import org.mariotaku.twidere.fragment.BaseFiltersFragment
import org.mariotaku.twidere.provider.TwidereDataStore
class FilteredKeywordsFragment : BaseFiltersFragment() {

View File

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

View File

@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.MenuItem
import org.mariotaku.twidere.R
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
class FilteredSourcesFragment : BaseFiltersFragment() {

View File

@ -16,12 +16,11 @@ import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.ktextension.setItemAvailability
import org.mariotaku.sqliteqb.library.Expression
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.LinkHandlerActivity
import org.mariotaku.twidere.activity.UserListSelectorActivity
import org.mariotaku.twidere.constant.IntentConstants.*
import org.mariotaku.twidere.constant.nameFirstKey
import org.mariotaku.twidere.fragment.BaseFiltersFragment
import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment
import org.mariotaku.twidere.model.ParcelableUser
import org.mariotaku.twidere.model.UserKey
@ -66,10 +65,18 @@ class FilteredUsersFragment : BaseFiltersFragment() {
resolver.insert(TwidereDataStore.Filters.Users.CONTENT_URI, values)
}
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 -> {
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 -> {
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.adapter.SupportTabsAdapter
import org.mariotaku.twidere.fragment.*
import org.mariotaku.twidere.fragment.BaseFiltersFragment.*
import org.mariotaku.twidere.fragment.filter.BaseFiltersFragment.*
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() {
setUserClickListener(adapter.userClickListener)
setActionClickListeners(adapter.requestClickListener, adapter.followClickListener)
setActionClickListeners(adapter.requestClickListener, adapter.friendshipClickListener)
}
private fun setActionClickListeners(requestClickListener: RequestClickListener?,
@ -274,11 +274,11 @@ class UserViewHolder(
setTextSize(adapter.textSize)
}
}
private fun RelativeLayout.LayoutParams.clearVerticalRules() {
intArrayOf(RelativeLayout.ABOVE, RelativeLayout.BELOW, RelativeLayout.ALIGN_BASELINE,
RelativeLayout.ALIGN_TOP, RelativeLayout.ALIGN_BOTTOM).forEach { verb ->
removeRule(verb)
private fun RelativeLayout.LayoutParams.clearVerticalRules() {
intArrayOf(RelativeLayout.ABOVE, RelativeLayout.BELOW, RelativeLayout.ALIGN_BASELINE,
RelativeLayout.ALIGN_TOP, RelativeLayout.ALIGN_BOTTOM).forEach { 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">
<org.mariotaku.twidere.view.ProfileImageView
android:id="@android:id/icon"
android:id="@+id/profileImage"
style="?profileImageStyle"
android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small"
android:layout_weight="0"
android:contentDescription="@string/icon"
android:scaleType="centerCrop"
tools:src="@drawable/ic_profile_image_twidere"/>
@ -40,6 +41,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingEnd="0dp"
@ -48,21 +50,33 @@
android:paddingStart="@dimen/element_spacing_small">
<TextView
android:id="@android:id/text1"
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:textColorPrimary"
tools:text="User name"/>
<TextView
android:id="@android:id/text2"
android:id="@+id/screenName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="\@screenname"/>
</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>

View File

@ -17,26 +17,32 @@
~ 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"
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:listPreferredItemHeight"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_normal">
android:padding="@dimen/element_spacing_normal"
tools:layout_gravity="center">
<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" />
tools:src="@drawable/ic_profile_image_twidere"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingEnd="0dp"
@ -48,17 +54,30 @@
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
tools:text="text1"
android:maxLines="1"/>
android:textColor="?android:textColorPrimary"
android:textStyle="bold"
tools:text="Title"/>
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="text2"
android:maxLines="1"/>
android:textColor="?android:textColorSecondary"
tools:text="summary"/>
</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

@ -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
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:gravity="center_vertical"
android:minHeight="?android:listPreferredItemHeightSmall"
android:orientation="horizontal"
android:padding="@dimen/element_spacing_small">
android:padding="@dimen/element_spacing_small"
tools:layout_gravity="center">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/icon_size_list_item_small"
android:layout_height="@dimen/icon_size_list_item_small"
android:layout_weight="0"
android:contentDescription="@string/icon"
android:scaleType="fitCenter"/>
android:scaleType="fitCenter"
tools:src="@drawable/ic_profile_image_twidere"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingEnd="0dp"
@ -48,15 +53,26 @@
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:maxLines="1"/>
tools:text="Title"/>
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="1"/>
tools:text="Summary"/>
</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

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

View File

@ -830,6 +830,7 @@
<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_muted_users">Import from muted users</string>
<string name="title_select_users">Select users</string>
<string name="action_purchase">Purchase</string>
<!-- Action title used for restore purchase -->
<string name="action_restore_purchase">Restore</string>