improved UI on tablet

This commit is contained in:
Mariotaku Lee 2017-01-18 01:59:44 +08:00
parent 7bd9c1e86f
commit ff21ccc962
50 changed files with 450 additions and 287 deletions

View File

@ -91,7 +91,6 @@ dependencies {
kapt 'com.hannesdorfmann.parcelableplease:processor:1.0.2' kapt 'com.hannesdorfmann.parcelableplease:processor:1.0.2'
kapt 'com.google.dagger:dagger-compiler:2.8' kapt 'com.google.dagger:dagger-compiler:2.8'
kapt 'com.github.mariotaku.ObjectCursor:processor:0.9.12' kapt 'com.github.mariotaku.ObjectCursor:processor:0.9.12'
kapt 'nz.bradcampbell:paperparcel-compiler:2.0.0-beta2'
compile project(':twidere.component.common') compile project(':twidere.component.common')
compile project(':twidere.component.nyan') compile project(':twidere.component.nyan')
@ -179,7 +178,6 @@ dependencies {
compile 'nl.komponents.kovenant:kovenant-android:3.3.0' compile 'nl.komponents.kovenant:kovenant-android:3.3.0'
compile 'nl.komponents.kovenant:kovenant-functional:3.3.0' compile 'nl.komponents.kovenant:kovenant-functional:3.3.0'
compile 'nl.komponents.kovenant:kovenant-combine:3.3.0' compile 'nl.komponents.kovenant:kovenant-combine:3.3.0'
compile 'nz.bradcampbell:paperparcel:2.0.0-beta2'
} }
task svgToDrawable(type: SvgDrawableTask) { task svgToDrawable(type: SvgDrawableTask) {

View File

@ -15,6 +15,7 @@ import nl.komponents.kovenant.ui.successUi
import org.mariotaku.twidere.Constants import org.mariotaku.twidere.Constants
import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity
import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment
import org.mariotaku.twidere.model.premium.PurchaseResult
import org.mariotaku.twidere.util.premium.GooglePlayExtraFeaturesService import org.mariotaku.twidere.util.premium.GooglePlayExtraFeaturesService
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@ -82,7 +83,10 @@ class GooglePlayInAppPurchaseActivity : AbsExtraFeaturePurchaseActivity(),
} }
private fun handlePurchased(sku: SkuDetails, transaction: TransactionDetails) { private fun handlePurchased(sku: SkuDetails, transaction: TransactionDetails) {
val result = PurchaseResult(requestingFeature, sku.priceValue, sku.currency) val result = PurchaseResult()
result.feature = requestingFeature
result.price = sku.priceValue
result.currency = sku.currency
finishWithResult(result) finishWithResult(result)
} }

View File

@ -297,7 +297,7 @@
<activity <activity
android:name=".activity.LinkHandlerActivity" android:name=".activity.LinkHandlerActivity"
android:parentActivityName=".activity.HomeActivity" android:parentActivityName=".activity.HomeActivity"
android:theme="@style/Theme.Twidere" android:theme="@style/Theme.Twidere.Content"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"

View File

@ -17,7 +17,6 @@
package org.mariotaku.twidere.adapter.decorator; package org.mariotaku.twidere.adapter.decorator;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -26,6 +25,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.State; import android.support.v7.widget.RecyclerView.State;
import android.support.v7.widget.TintTypedArray;
import android.view.View; import android.view.View;
public class DividerItemDecoration extends RecyclerView.ItemDecoration { public class DividerItemDecoration extends RecyclerView.ItemDecoration {
@ -46,7 +46,7 @@ public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private int mDecorationStart = -1, mDecorationEnd = -1, mDecorationEndOffset; private int mDecorationStart = -1, mDecorationEnd = -1, mDecorationEndOffset;
public DividerItemDecoration(Context context, int orientation) { public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS); final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, null, ATTRS);
mDivider = a.getDrawable(0); mDivider = a.getDrawable(0);
a.recycle(); a.recycle();
setOrientation(orientation); setOrientation(orientation);

View File

@ -0,0 +1,63 @@
package org.mariotaku.twidere.model.premium;
import android.os.Parcel;
import android.os.Parcelable;
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
/**
* Created by mariotaku on 2017/1/17.
*/
@ParcelablePlease
public class PurchaseResult implements Parcelable {
String feature;
double price;
String currency;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
public String getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
PurchaseResultParcelablePlease.writeToParcel(this, dest, flags);
}
public static final Creator<PurchaseResult> CREATOR = new Creator<PurchaseResult>() {
public PurchaseResult createFromParcel(Parcel source) {
PurchaseResult target = new PurchaseResult();
PurchaseResultParcelablePlease.readFromParcel(target, source);
return target;
}
public PurchaseResult[] newArray(int size) {
return new PurchaseResult[size];
}
};
}

View File

@ -132,6 +132,8 @@ public abstract class TabConfiguration {
private final String key; private final String key;
private StringHolder title; private StringHolder title;
@Nullable @Nullable
private StringHolder summary;
@Nullable
private StringHolder headerTitle; private StringHolder headerTitle;
private int position; private int position;
private boolean mutable; private boolean mutable;
@ -155,16 +157,35 @@ public abstract class TabConfiguration {
this.title = title; this.title = title;
} }
@Nullable
public StringHolder getSummary() {
return summary;
}
public void setSummary(@Nullable StringHolder summary) {
this.summary = summary;
}
public ExtraConfiguration title(StringHolder title) { public ExtraConfiguration title(StringHolder title) {
setTitle(title); setTitle(title);
return this; return this;
} }
public ExtraConfiguration summary(StringHolder summary) {
setSummary(summary);
return this;
}
public ExtraConfiguration title(@StringRes int titleRes) { public ExtraConfiguration title(@StringRes int titleRes) {
setTitle(StringHolder.resource(titleRes)); setTitle(StringHolder.resource(titleRes));
return this; return this;
} }
public ExtraConfiguration summary(@StringRes int summaryRes) {
setSummary(StringHolder.resource(summaryRes));
return this;
}
@Nullable @Nullable
public StringHolder getHeaderTitle() { public StringHolder getHeaderTitle() {
return headerTitle; return headerTitle;

View File

@ -119,14 +119,19 @@ public class InteractionsTabConfiguration extends TabConfiguration {
final View view = getView(); final View view = getView();
final CheckBox checkBox = (CheckBox) view.findViewById(android.R.id.checkbox); final CheckBox checkBox = (CheckBox) view.findViewById(android.R.id.checkbox);
final TextView titleView = (TextView) view.findViewById(android.R.id.title); final TextView titleView = (TextView) view.findViewById(android.R.id.title);
final TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
view.setEnabled(hasOfficial); view.setEnabled(hasOfficial);
titleView.setEnabled(hasOfficial); titleView.setEnabled(hasOfficial);
summaryView.setEnabled(hasOfficial);
checkBox.setEnabled(hasOfficial); checkBox.setEnabled(hasOfficial);
if (hasOfficial) { if (hasOfficial) {
checkBox.setChecked(valueBackup); checkBox.setChecked(valueBackup);
summaryView.setVisibility(View.GONE);
} else { } else {
valueBackup = checkBox.isChecked(); valueBackup = checkBox.isChecked();
checkBox.setChecked(true); checkBox.setChecked(true);
summaryView.setText(R.string.summary_interactions_not_available);
summaryView.setVisibility(View.VISIBLE);
} }
} }

View File

@ -1,91 +0,0 @@
/*
* 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/>.
*/
package org.mariotaku.twidere.preference;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.support.annotation.NonNull;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.adapter.DummyItemAdapter;
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable;
import org.mariotaku.twidere.view.holder.StatusViewHolder;
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder;
import static org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME;
public class CardPreviewPreference extends Preference implements OnSharedPreferenceChangeListener {
private StatusViewHolder mHolder;
private DummyItemAdapter mAdapter;
public CardPreviewPreference(final Context context) {
this(context, null);
}
public CardPreviewPreference(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public CardPreviewPreference(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
final SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE);
setLayoutResource(R.layout.layout_preferences_card_preview_compact);
preferences.registerOnSharedPreferenceChangeListener(this);
mAdapter = new DummyItemAdapter(context);
}
@Override
public void onSharedPreferenceChanged(final SharedPreferences preferences, final String key) {
mAdapter.updateOptions();
mHolder = null;
notifyChanged();
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
if (mHolder == null) {
mHolder = new StatusViewHolder(mAdapter, holder.itemView);
}
mHolder.setupViewOptions();
mHolder.displaySampleStatus();
mHolder.setStatusClickListener(new IStatusViewHolder.SimpleStatusClickListener() {
@Override
public void onItemActionClick(@NonNull RecyclerView.ViewHolder holder, int id, int position) {
if (id == R.id.favorite) {
((StatusViewHolder) holder).playLikeAnimation(new LikeAnimationDrawable.OnLikedListener() {
@Override
public boolean onLiked() {
return false;
}
});
}
}
});
super.onBindViewHolder(holder);
}
}

View File

@ -0,0 +1,76 @@
/*
* 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/>.
*/
package org.mariotaku.twidere.preference
import android.content.Context
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.support.v7.preference.Preference
import android.support.v7.preference.PreferenceViewHolder
import android.support.v7.widget.RecyclerView
import android.util.AttributeSet
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
import org.mariotaku.twidere.adapter.DummyItemAdapter
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
import org.mariotaku.twidere.view.holder.StatusViewHolder
import org.mariotaku.twidere.view.holder.iface.IStatusViewHolder
class CardPreviewPreference(
context: Context,
attrs: AttributeSet? = null
) : Preference(context, attrs), OnSharedPreferenceChangeListener {
private var holder: StatusViewHolder? = null
private val adapter: DummyItemAdapter = DummyItemAdapter(context)
init {
val preferences = context.getSharedPreferences(SHARED_PREFERENCES_NAME,
Context.MODE_PRIVATE)
layoutResource = R.layout.layout_preferences_card_preview_compact
preferences.registerOnSharedPreferenceChangeListener(this)
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
adapter.updateOptions()
holder = null
notifyChanged()
}
override fun onBindViewHolder(holder: PreferenceViewHolder) {
if (this.holder == null) {
this.holder = StatusViewHolder(adapter, holder.itemView).apply {
setStatusClickListener(object : IStatusViewHolder.StatusClickListener {
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
if (id == R.id.favorite) {
(holder as StatusViewHolder).playLikeAnimation(LikeAnimationDrawable.OnLikedListener { false })
}
}
})
}
}
this.holder?.let {
it.setupViewOptions()
it.displaySampleStatus()
}
super.onBindViewHolder(holder)
}
}

View File

@ -169,7 +169,12 @@ public class ThemeUtils implements Constants {
} }
public static Drawable getSelectableItemBackgroundDrawable(final Context context) { public static Drawable getSelectableItemBackgroundDrawable(final Context context) {
final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.selectableItemBackground}); return getDrawableFromThemeAttribute(context, android.R.attr.selectableItemBackground);
}
public static Drawable getDrawableFromThemeAttribute(final Context context, int attr) {
final TypedArray a = context.obtainStyledAttributes(new int[]{attr});
try { try {
return a.getDrawable(0); return a.getDrawable(0);
} finally { } finally {

View File

@ -23,15 +23,12 @@ import android.content.Context;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v7.widget.AppCompatTextView; import android.support.v7.widget.AppCompatTextView;
import android.text.format.DateUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import org.mariotaku.twidere.Constants; import org.mariotaku.twidere.Constants;
import org.mariotaku.twidere.R;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import static android.text.format.DateUtils.getRelativeTimeSpanString;
import static org.mariotaku.twidere.util.Utils.formatSameDayTime; import static org.mariotaku.twidere.util.Utils.formatSameDayTime;
public class ShortTimeView extends AppCompatTextView implements Constants { public class ShortTimeView extends AppCompatTextView implements Constants {
@ -83,10 +80,10 @@ public class ShortTimeView extends AppCompatTextView implements Constants {
} else { } else {
final long current = System.currentTimeMillis(); final long current = System.currentTimeMillis();
if (Math.abs(current - mTime) > 60 * 1000) { if (Math.abs(current - mTime) > 60 * 1000) {
setText(getRelativeTimeSpanString(mTime, System.currentTimeMillis(), // setText(getRelativeTimeSpanString(mTime, System.currentTimeMillis(),
DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_ALL)); // DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_ALL));
} else { } else {
setText(R.string.just_now); // setText(R.string.just_now);
} }
} }
} }

View File

@ -94,7 +94,8 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb
import org.mariotaku.twidere.view.HomeDrawerLayout import org.mariotaku.twidere.view.HomeDrawerLayout
import org.mariotaku.twidere.view.TabPagerIndicator import org.mariotaku.twidere.view.TabPagerIndicator
class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, SupportFragmentCallback, OnLongClickListener, DrawerLayout.DrawerListener { class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, SupportFragmentCallback,
OnLongClickListener, DrawerLayout.DrawerListener {
private val accountUpdatedListener = AccountUpdatedListener(this) private val accountUpdatedListener = AccountUpdatedListener(this)
@ -338,7 +339,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
drawerToggle = ActionBarDrawerToggle(this, homeMenu, R.string.open_accounts_dashboard, drawerToggle = ActionBarDrawerToggle(this, homeMenu, R.string.open_accounts_dashboard,
R.string.close_accounts_dashboard) R.string.close_accounts_dashboard)
homeContent.setOnFitSystemWindowsListener(this) homeContent.setOnFitSystemWindowsListener(this)
pagerAdapter = SupportTabsAdapter(this, supportFragmentManager, mainTabs, tabColumns) pagerAdapter = SupportTabsAdapter(this, supportFragmentManager, mainTabs)
mainPager.adapter = pagerAdapter mainPager.adapter = pagerAdapter
mainTabs.setViewPager(mainPager) mainTabs.setViewPager(mainPager)
mainTabs.setOnPageChangeListener(this) mainTabs.setOnPageChangeListener(this)
@ -533,7 +534,6 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
} }
override fun onDestroy() { override fun onDestroy() {
stopService(Intent(this, StreamingService::class.java)) stopService(Intent(this, StreamingService::class.java))
// Delete unused items in databases. // Delete unused items in databases.
@ -795,12 +795,14 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
val hasNoTab = pagerAdapter.count == 0 val hasNoTab = pagerAdapter.count == 0
emptyTabHint.visibility = if (hasNoTab) View.VISIBLE else View.GONE emptyTabHint.visibility = if (hasNoTab) View.VISIBLE else View.GONE
mainPager.visibility = if (hasNoTab) View.GONE else View.VISIBLE mainPager.visibility = if (hasNoTab) View.GONE else View.VISIBLE
if (pagerAdapter.getPageWidth(0) < 1) { if (resources.getBoolean(R.bool.home_tab_has_multiple_columns)) {
mainPager.pageMargin = resources.getDimensionPixelOffset(R.dimen.home_page_margin) mainPager.pageMargin = resources.getDimensionPixelOffset(R.dimen.home_page_margin)
mainPager.setPageMarginDrawable(R.color.home_page_margin_color) mainPager.setPageMarginDrawable(ThemeUtils.getDrawableFromThemeAttribute(this, R.attr.dividerVertical))
pagerAdapter.pageWidth = resources.getDimension(R.dimen.preferred_tab_column_width) / resources.displayMetrics.widthPixels
} else { } else {
mainPager.pageMargin = 0 mainPager.pageMargin = 0
mainPager.setPageMarginDrawable(null) mainPager.setPageMarginDrawable(null)
pagerAdapter.pageWidth = 1f
} }
} }

View File

@ -34,6 +34,7 @@ import android.text.TextUtils
import android.view.KeyEvent import android.view.KeyEvent
import android.view.MenuItem import android.view.MenuItem
import android.view.Window import android.view.Window
import kotlinx.android.synthetic.main.activity_link_handler.*
import org.mariotaku.kpreferences.get import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.convert import org.mariotaku.ktextension.convert
import org.mariotaku.ktextension.set import org.mariotaku.ktextension.set
@ -65,7 +66,8 @@ import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallb
import org.mariotaku.twidere.util.Utils.LINK_ID_FILTERS_IMPORT_BLOCKS 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 {
private lateinit var multiSelectHandler: MultiSelectEventHandler private lateinit var multiSelectHandler: MultiSelectEventHandler
private lateinit var controlBarShowHideHelper: ControlBarShowHideHelper private lateinit var controlBarShowHideHelper: ControlBarShowHideHelper
@ -74,17 +76,15 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
private var subtitle: CharSequence? = null private var subtitle: CharSequence? = null
private var hideOffsetNotSupported: Boolean = false private var hideOffsetNotSupported: Boolean = false
override val currentVisibleFragment: Fragment? override val currentVisibleFragment: Fragment?
get() { get() = supportFragmentManager.findFragmentByTag("content_fragment")
return supportFragmentManager.findFragmentById(android.R.id.content)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
multiSelectHandler = MultiSelectEventHandler(this) multiSelectHandler = MultiSelectEventHandler(this)
controlBarShowHideHelper = ControlBarShowHideHelper(this) controlBarShowHideHelper = ControlBarShowHideHelper(this)
multiSelectHandler.dispatchOnCreate() multiSelectHandler.dispatchOnCreate()
val uri = intent.data val uri = intent.data
val linkId = matchLinkId(uri) val linkId = matchLinkId(uri)
intent.setExtrasClassLoader(classLoader) intent.setExtrasClassLoader(classLoader)
@ -107,17 +107,26 @@ class LinkHandlerActivity : BaseActivity(), SystemWindowsInsetsCallback, IContro
return return
} }
val contentFragmentId: Int
if (fragment is IToolBarSupportFragment) { if (fragment is IToolBarSupportFragment) {
if (!fragment.setupWindow(this)) { if (!fragment.setupWindow(this)) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE) supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_MODE_OVERLAY) supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_MODE_OVERLAY)
} }
contentFragmentId = android.R.id.content
} else {
setContentView(R.layout.activity_link_handler)
toolbar?.let { toolbar ->
setSupportActionBar(toolbar)
}
contentFragmentId = R.id.contentFragment
} }
setupActionBarOption() setupActionBarOption()
Utils.logOpenNotificationFromUri(this, uri) Utils.logOpenNotificationFromUri(this, uri)
val ft = supportFragmentManager.beginTransaction() val ft = supportFragmentManager.beginTransaction()
ft.replace(android.R.id.content, fragment) ft.replace(contentFragmentId, fragment, "content_fragment")
ft.commit() ft.commit()
setTitle(linkId, uri) setTitle(linkId, uri)
finishOnly = java.lang.Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY)) finishOnly = java.lang.Boolean.parseBoolean(uri.getQueryParameter(QUERY_PARAM_FINISH_ONLY))

View File

@ -2,11 +2,9 @@ package org.mariotaku.twidere.activity.premium
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Parcel
import android.os.Parcelable
import org.mariotaku.twidere.activity.BaseActivity import org.mariotaku.twidere.activity.BaseActivity
import org.mariotaku.twidere.constant.IntentConstants import org.mariotaku.twidere.constant.IntentConstants
import paperparcel.PaperParcel import org.mariotaku.twidere.model.premium.PurchaseResult
/** /**
* Created by mariotaku on 2017/1/8. * Created by mariotaku on 2017/1/8.
@ -25,19 +23,6 @@ abstract class AbsExtraFeaturePurchaseActivity : BaseActivity() {
finish() finish()
} }
@PaperParcel
data class PurchaseResult(val feature: String, val price: Double, val currency: String) : Parcelable {
companion object {
@JvmField val CREATOR = PaperParcelAbsExtraFeaturePurchaseActivity_PurchaseResult.CREATOR
}
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) {
PaperParcelAbsExtraFeaturePurchaseActivity_PurchaseResult.writeToParcel(this, dest, flags)
}
}
companion object { companion object {
const val RESULT_SERVICE_UNAVAILABLE = 1 const val RESULT_SERVICE_UNAVAILABLE = 1

View File

@ -361,6 +361,8 @@ class ParcelableActivitiesAdapter(
fun onStatusClick(holder: IStatusViewHolder, position: Int) fun onStatusClick(holder: IStatusViewHolder, position: Int)
fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int)
} }
internal class StubViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { internal class StubViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@ -417,29 +419,28 @@ class ParcelableActivitiesAdapter(
override fun onStatusClick(holder: IStatusViewHolder, position: Int) { override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return val adapter = adapterRef.get() ?: return
if (adapter.activityAdapterListener != null) { adapter.activityAdapterListener?.onStatusClick(holder, position)
adapter.activityAdapterListener!!.onStatusClick(holder, position) }
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return
adapter.activityAdapterListener?.onQuotedStatusClick(holder, position)
} }
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) { override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
val adapter = adapterRef.get() ?: return val adapter = adapterRef.get() ?: return
if (adapter.activityAdapterListener != null) { adapter.activityAdapterListener?.onMediaClick(holder, view, media, statusPosition)
adapter.activityAdapterListener!!.onMediaClick(holder, view, media, statusPosition)
}
} }
override fun onActivityClick(holder: ActivityTitleSummaryViewHolder, position: Int) { override fun onActivityClick(holder: ActivityTitleSummaryViewHolder, position: Int) {
val adapter = adapterRef.get() ?: return val adapter = adapterRef.get() ?: return
if (adapter.activityAdapterListener == null) return adapter.activityAdapterListener?.onActivityClick(holder, position)
adapter.activityAdapterListener!!.onActivityClick(holder, position)
} }
override fun onItemMenuClick(holder: RecyclerView.ViewHolder, menuView: View, position: Int) { override fun onItemMenuClick(holder: RecyclerView.ViewHolder, menuView: View, position: Int) {
val adapter = adapterRef.get() ?: return val adapter = adapterRef.get() ?: return
if (adapter.activityAdapterListener != null) { adapter.activityAdapterListener?.onStatusMenuClick(holder as StatusViewHolder, menuView, position)
adapter.activityAdapterListener!!.onStatusMenuClick(holder as StatusViewHolder, menuView, position)
}
} }
} }

View File

@ -41,8 +41,7 @@ import java.util.*
class SupportTabsAdapter @JvmOverloads constructor( class SupportTabsAdapter @JvmOverloads constructor(
private val context: Context, private val context: Context,
fm: FragmentManager, fm: FragmentManager,
private val indicator: PagerIndicator? = null, private val indicator: PagerIndicator? = null
private val columns: Int = 1
) : SupportFixedFragmentStatePagerAdapter(fm), TabProvider, TabListener { ) : SupportFixedFragmentStatePagerAdapter(fm), TabProvider, TabListener {
private val tab = ArrayList<SupportTabSpec>() private val tab = ArrayList<SupportTabSpec>()
@ -92,7 +91,7 @@ class SupportTabsAdapter @JvmOverloads constructor(
} }
override fun getPageWidth(position: Int): Float { override fun getPageWidth(position: Int): Float {
return 1.0f / columns return pageWidth
} }
override fun getItem(position: Int): Fragment { override fun getItem(position: Int): Fragment {
@ -153,4 +152,6 @@ class SupportTabsAdapter @JvmOverloads constructor(
private val EXTRA_ADAPTER_POSITION = "adapter_position" private val EXTRA_ADAPTER_POSITION = "adapter_position"
} }
var pageWidth: Float = 1f
} }

View File

@ -26,7 +26,7 @@ import android.view.View
* Created by mariotaku on 14/12/3. * Created by mariotaku on 14/12/3.
*/ */
interface ContentCardClickListener { interface ContentCardClickListener {
fun onItemActionClick(holder: ViewHolder, id: Int, position: Int) fun onItemActionClick(holder: ViewHolder, id: Int, position: Int) {}
fun onItemMenuClick(holder: ViewHolder, menuView: View, position: Int) fun onItemMenuClick(holder: ViewHolder, menuView: View, position: Int) {}
} }

View File

@ -37,13 +37,12 @@ interface IGapSupportedAdapter {
interface GapClickListener { interface GapClickListener {
fun onGapClick(holder: GapViewHolder, position: Int) fun onGapClick(holder: GapViewHolder, position: Int) {}
} }
companion object { companion object {
const val ITEM_VIEW_TYPE_GAP = 1
val ITEM_VIEW_TYPE_GAP = 1
} }

View File

@ -6,4 +6,5 @@ import org.mariotaku.twidere.model.ParcelableStatus
* Created by mariotaku on 2017/1/7. * Created by mariotaku on 2017/1/7.
*/ */
val ParcelableStatus.media_type: Int val ParcelableStatus.media_type: Int
get() = media?.firstOrNull()?.type ?: 0 get() = media?.firstOrNull()?.type ?: 0

View File

@ -358,6 +358,11 @@ abstract class AbsActivitiesFragment protected constructor() :
IntentUtils.openStatus(context, status, null) IntentUtils.openStatus(context, status, null)
} }
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val status = getActivityStatus(position) ?: return
IntentUtils.openStatus(context, status.account_key, status.quoted_id)
}
private fun getActivityStatus(position: Int): ParcelableStatus? { private fun getActivityStatus(position: Int): ParcelableStatus? {
return adapter.getActivity(position)?.getActivityStatus() return adapter.getActivity(position)?.getActivityStatus()
} }

View File

@ -399,7 +399,13 @@ abstract class AbsStatusesFragment protected constructor() :
} }
override fun onStatusClick(holder: IStatusViewHolder, position: Int) { override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
IntentUtils.openStatus(activity, adapter.getStatus(position)!!, null) val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(activity, status, null)
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(activity, status.account_key, status.quoted_id)
} }
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean { override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {

View File

@ -45,7 +45,7 @@ abstract class AbsToolbarTabPagesFragment : BaseFragment(), RefreshScrollTopInte
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
val activity = activity val activity = activity
pagerAdapter = SupportTabsAdapter(activity, childFragmentManager, null, 1) pagerAdapter = SupportTabsAdapter(activity, childFragmentManager, null)
viewPager.adapter = pagerAdapter viewPager.adapter = pagerAdapter
viewPager.offscreenPageLimit = 2 viewPager.offscreenPageLimit = 2
viewPager.addOnPageChangeListener(this) viewPager.addOnPageChangeListener(this)

View File

@ -46,12 +46,17 @@ class ItemsListFragment : AbsContentListRecyclerViewFragment<VariousItemsAdapter
override fun onCreateAdapter(context: Context): VariousItemsAdapter { override fun onCreateAdapter(context: Context): VariousItemsAdapter {
val adapter = VariousItemsAdapter(context) val adapter = VariousItemsAdapter(context)
val dummyItemAdapter = adapter.dummyAdapter val dummyItemAdapter = adapter.dummyAdapter
dummyItemAdapter.statusClickListener = object : IStatusViewHolder.SimpleStatusClickListener() { dummyItemAdapter.statusClickListener = object : IStatusViewHolder.StatusClickListener {
override fun onStatusClick(holder: IStatusViewHolder, position: Int) { override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
val status = dummyItemAdapter.getStatus(position) ?: return val status = dummyItemAdapter.getStatus(position) ?: return
IntentUtils.openStatus(getContext(), status, null) IntentUtils.openStatus(getContext(), status, null)
} }
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val status = dummyItemAdapter.getStatus(position) ?: return
IntentUtils.openStatus(getContext(), status.account_key, status.quoted_id)
}
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) { override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
val status = dummyItemAdapter.getStatus(position) ?: return val status = dummyItemAdapter.getStatus(position) ?: return
AbsStatusesFragment.handleStatusActionClick(context, fragmentManager, AbsStatusesFragment.handleStatusActionClick(context, fragmentManager,

View File

@ -303,7 +303,6 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
} }
override fun onItemActionClick(holder: ViewHolder, id: Int, position: Int) { override fun onItemActionClick(holder: ViewHolder, id: Int, position: Int) {
val status = adapter.getStatus(position) val status = adapter.getStatus(position)
AbsStatusesFragment.handleStatusActionClick(context, fragmentManager, twitterWrapper, AbsStatusesFragment.handleStatusActionClick(context, fragmentManager, twitterWrapper,
@ -311,7 +310,13 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
} }
override fun onStatusClick(holder: IStatusViewHolder, position: Int) { override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
IntentUtils.openStatus(activity, adapter.getStatus(position)!!, null) val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(activity, status.account_key, status.quoted_id)
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(activity, status.account_key, status.quoted_id)
} }
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean { override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
@ -2056,29 +2061,33 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
} }
class StatusActivitySummaryLoader(context: Context, private val mAccountKey: UserKey, private val mStatusId: String) : AsyncTaskLoader<StatusActivity>(context) { class StatusActivitySummaryLoader(
context: Context,
private val accountKey: UserKey,
private val statusId: String
) : AsyncTaskLoader<StatusActivity>(context) {
override fun loadInBackground(): StatusActivity? { override fun loadInBackground(): StatusActivity? {
val context = context val context = context
val details = AccountUtils.getAccountDetails(AccountManager.get(context), mAccountKey, true) ?: return null val details = AccountUtils.getAccountDetails(AccountManager.get(context), accountKey, true) ?: return null
if (AccountType.TWITTER != details.type) { if (AccountType.TWITTER != details.type) {
return null return null
} }
val twitter = MicroBlogAPIFactory.getInstance(context, mAccountKey) ?: return null val twitter = MicroBlogAPIFactory.getInstance(context, accountKey) ?: return null
val paging = Paging() val paging = Paging()
paging.setCount(10) paging.setCount(10)
val activitySummary = StatusActivity(mStatusId, emptyList()) val activitySummary = StatusActivity(statusId, emptyList())
val retweeters = ArrayList<ParcelableUser>() val retweeters = ArrayList<ParcelableUser>()
try { try {
for (status in twitter.getRetweets(mStatusId, paging)) { for (status in twitter.getRetweets(statusId, paging)) {
val user = ParcelableUserUtils.fromUser(status.user, mAccountKey) val user = ParcelableUserUtils.fromUser(status.user, accountKey)
if (!DataStoreUtils.isFilteringUser(context, user.key.toString())) { if (!DataStoreUtils.isFilteringUser(context, user.key.toString())) {
retweeters.add(user) retweeters.add(user)
} }
} }
activitySummary.retweeters = retweeters activitySummary.retweeters = retweeters
val countValues = ContentValues() val countValues = ContentValues()
val status = twitter.showStatus(mStatusId) val status = twitter.showStatus(statusId)
activitySummary.favoriteCount = status.favoriteCount activitySummary.favoriteCount = status.favoriteCount
activitySummary.retweetCount = status.retweetCount activitySummary.retweetCount = status.retweetCount
activitySummary.replyCount = status.replyCount activitySummary.replyCount = status.replyCount
@ -2093,7 +2102,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
Expression.or( Expression.or(
Expression.equalsArgs(Statuses.STATUS_ID), Expression.equalsArgs(Statuses.STATUS_ID),
Expression.equalsArgs(Statuses.RETWEET_ID))) Expression.equalsArgs(Statuses.RETWEET_ID)))
val statusWhereArgs = arrayOf(mAccountKey.toString(), mStatusId, mStatusId) val statusWhereArgs = arrayOf(accountKey.toString(), statusId, statusId)
cr.update(Statuses.CONTENT_URI, countValues, statusWhere.sql, statusWhereArgs) cr.update(Statuses.CONTENT_URI, countValues, statusWhere.sql, statusWhereArgs)
val activityWhere = Expression.and( val activityWhere = Expression.and(
Expression.equalsArgs(Activities.ACCOUNT_KEY), Expression.equalsArgs(Activities.ACCOUNT_KEY),
@ -2102,7 +2111,7 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
Expression.equalsArgs(Activities.STATUS_RETWEET_ID))) Expression.equalsArgs(Activities.STATUS_RETWEET_ID)))
val pStatus = ParcelableStatusUtils.fromStatus(status, val pStatus = ParcelableStatusUtils.fromStatus(status,
mAccountKey, false) accountKey, false)
cr.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(pStatus)) cr.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(pStatus))
val activityCursor = cr.query(Activities.AboutMe.CONTENT_URI, val activityCursor = cr.query(Activities.AboutMe.CONTENT_URI,
@ -2145,7 +2154,6 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
var retweetCount: Long = 0 var retweetCount: Long = 0
) { ) {
fun isStatus(status: ParcelableStatus): Boolean { fun isStatus(status: ParcelableStatus): Boolean {
return TextUtils.equals(statusId, if (status.is_retweet) status.retweet_id else status.id) return TextUtils.equals(statusId, if (status.is_retweet) status.retweet_id else status.id)
} }
@ -2153,13 +2161,18 @@ class StatusFragment : BaseFragment(), LoaderCallbacks<SingleResponse<Parcelable
data class ReadPosition(var statusId: Long, var offsetTop: Int) data class ReadPosition(var statusId: Long, var offsetTop: Int)
private class StatusDividerItemDecoration(context: Context, private val statusAdapter: StatusAdapter, orientation: Int) : DividerItemDecoration(context, orientation) { private class StatusDividerItemDecoration(
context: Context,
private val statusAdapter: StatusAdapter,
orientation: Int
) : DividerItemDecoration(context, orientation) {
override fun isDividerEnabled(childPos: Int): Boolean { override fun isDividerEnabled(childPos: Int): Boolean {
if (childPos >= statusAdapter.itemCount || childPos < 0) return false if (childPos >= statusAdapter.itemCount || childPos < 0) return false
val itemType = statusAdapter.getItemType(childPos) val itemType = statusAdapter.getItemType(childPos)
when (itemType) { when (itemType) {
StatusAdapter.ITEM_IDX_REPLY_LOAD_MORE, StatusAdapter.ITEM_IDX_REPLY_ERROR, StatusAdapter.ITEM_IDX_SPACE -> return false StatusAdapter.ITEM_IDX_REPLY_LOAD_MORE, StatusAdapter.ITEM_IDX_REPLY_ERROR,
StatusAdapter.ITEM_IDX_SPACE -> return false
} }
return true return true
} }

View File

@ -315,7 +315,7 @@ class UserFragment : BaseFragment(), OnClickListener, OnLinkClickListener,
followContainer.follow.compoundDrawablePadding = Math.round(followContainer.follow.textSize * 0.25f) followContainer.follow.compoundDrawablePadding = Math.round(followContainer.follow.textSize * 0.25f)
followingYouIndicator.visibility = if (userRelationship.followed_by) View.VISIBLE else View.GONE followingYouIndicator.visibility = if (userRelationship.followed_by) View.VISIBLE else View.GONE
val resolver = context.contentResolver val resolver = context.applicationContext.contentResolver
task { task {
resolver.insert(CachedUsers.CONTENT_URI, ParcelableUserValuesCreator.create(user)) resolver.insert(CachedUsers.CONTENT_URI, ParcelableUserValuesCreator.create(user))
resolver.insert(CachedRelationships.CONTENT_URI, ParcelableRelationshipValuesCreator.create(userRelationship)) resolver.insert(CachedRelationships.CONTENT_URI, ParcelableRelationshipValuesCreator.create(userRelationship))

View File

@ -137,7 +137,13 @@ class UserMediaTimelineFragment : AbsContentRecyclerViewFragment<StaggeredGridPa
} }
override fun onStatusClick(holder: IStatusViewHolder, position: Int) { override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
IntentUtils.openStatus(context, adapter.getStatus(position)!!, null) val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(context, status, null)
}
override fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {
val status = adapter.getStatus(position) ?: return
IntentUtils.openStatus(context, status.account_key, status.quoted_id)
} }
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean { override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {

View File

@ -1,7 +1,8 @@
package org.mariotaku.twidere.model.analyzer package org.mariotaku.twidere.model.analyzer
import android.content.Intent import android.content.Intent
import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity import org.mariotaku.twidere.activity.premium.AbsExtraFeaturePurchaseActivity.Companion.EXTRA_PURCHASE_RESULT
import org.mariotaku.twidere.model.premium.PurchaseResult
import org.mariotaku.twidere.util.Analyzer import org.mariotaku.twidere.util.Analyzer
/** /**
@ -18,8 +19,7 @@ data class PurchaseFinished(val productName: String) : Analyzer.Event {
const val NAME_EXTRA_FEATURES = "Enhanced Features" const val NAME_EXTRA_FEATURES = "Enhanced Features"
fun create(data: Intent): PurchaseFinished { fun create(data: Intent): PurchaseFinished {
val purchaseResult: AbsExtraFeaturePurchaseActivity.PurchaseResult val purchaseResult: PurchaseResult = data.getParcelableExtra(EXTRA_PURCHASE_RESULT)
= data.getParcelableExtra(AbsExtraFeaturePurchaseActivity.EXTRA_PURCHASE_RESULT)
val result = PurchaseFinished(purchaseResult.feature) val result = PurchaseFinished(purchaseResult.feature)
result.price = purchaseResult.price result.price = purchaseResult.price
result.currency = purchaseResult.currency result.currency = purchaseResult.currency

View File

@ -15,7 +15,11 @@ import org.mariotaku.twidere.model.tab.TabConfiguration
/** /**
* Created by mariotaku on 2016/12/5. * Created by mariotaku on 2016/12/5.
*/ */
open class BooleanExtraConfiguration(key: String, val defaultValue: BooleanHolder) : TabConfiguration.ExtraConfiguration(key) { open class BooleanExtraConfiguration(
key: String,
val defaultValue: BooleanHolder
) : TabConfiguration.ExtraConfiguration(key) {
open var value: Boolean open var value: Boolean
get() = checkBox.isChecked get() = checkBox.isChecked
set(value) { set(value) {
@ -33,8 +37,17 @@ open class BooleanExtraConfiguration(key: String, val defaultValue: BooleanHolde
override fun onViewCreated(context: Context, view: View, fragment: CustomTabsFragment.TabEditorDialogFragment) { override fun onViewCreated(context: Context, view: View, fragment: CustomTabsFragment.TabEditorDialogFragment) {
super.onViewCreated(context, view, fragment) super.onViewCreated(context, view, fragment)
val titleView = view.findViewById(android.R.id.title) as TextView val titleView = view.findViewById(android.R.id.title) as TextView
val summaryView = view.findViewById(android.R.id.summary) as TextView
titleView.text = title.createString(context) titleView.text = title.createString(context)
val summary = this.summary
if (summary != null) {
summaryView.visibility = View.VISIBLE
summaryView.text = summary.createString(context)
} else {
summaryView.visibility = View.GONE
}
checkBox = view.findViewById(android.R.id.checkbox) as CheckBox checkBox = view.findViewById(android.R.id.checkbox) as CheckBox
checkBox.visibility = View.VISIBLE checkBox.visibility = View.VISIBLE
checkBox.isChecked = defaultValue.createBoolean(context) checkBox.isChecked = defaultValue.createBoolean(context)

View File

@ -444,6 +444,8 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
favoriteButton.setOnClickListener(eventListener) favoriteButton.setOnClickListener(eventListener)
mediaLabel.setOnClickListener(eventListener) mediaLabel.setOnClickListener(eventListener)
quotedView.setOnClickListener(eventListener)
} }
@ -577,6 +579,9 @@ class StatusViewHolder(private val adapter: IStatusesAdapter<*>, itemView: View)
holder.itemContent -> { holder.itemContent -> {
listener.onStatusClick(holder, position) listener.onStatusClick(holder, position)
} }
holder.quotedView -> {
listener.onQuotedStatusClick(holder, position)
}
holder.itemMenu -> { holder.itemMenu -> {
listener.onItemMenuClick(holder, v, position) listener.onItemMenuClick(holder, v, position)
} }

View File

@ -19,10 +19,8 @@
package org.mariotaku.twidere.view.holder.iface package org.mariotaku.twidere.view.holder.iface
import android.support.v7.widget.RecyclerView
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import org.mariotaku.twidere.adapter.iface.ContentCardClickListener import org.mariotaku.twidere.adapter.iface.ContentCardClickListener
import org.mariotaku.twidere.adapter.iface.IGapSupportedAdapter import org.mariotaku.twidere.adapter.iface.IGapSupportedAdapter
import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable import org.mariotaku.twidere.graphic.like.LikeAnimationDrawable
@ -30,7 +28,6 @@ import org.mariotaku.twidere.model.ParcelableMedia
import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus
import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.UserKey
import org.mariotaku.twidere.view.CardMediaContainer import org.mariotaku.twidere.view.CardMediaContainer
import org.mariotaku.twidere.view.holder.GapViewHolder
/** /**
* Created by mariotaku on 15/10/26. * Created by mariotaku on 15/10/26.
@ -55,42 +52,15 @@ interface IStatusViewHolder : CardMediaContainer.OnMediaClickListener {
interface StatusClickListener : ContentCardClickListener, IGapSupportedAdapter.GapClickListener { interface StatusClickListener : ContentCardClickListener, IGapSupportedAdapter.GapClickListener {
fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {}
fun onStatusClick(holder: IStatusViewHolder, position: Int) fun onStatusClick(holder: IStatusViewHolder, position: Int) {}
fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean fun onQuotedStatusClick(holder: IStatusViewHolder, position: Int) {}
fun onUserProfileClick(holder: IStatusViewHolder, position: Int) fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean = false
fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {}
} }
abstract class SimpleStatusClickListener : StatusClickListener {
override fun onMediaClick(holder: IStatusViewHolder, view: View, media: ParcelableMedia, statusPosition: Int) {
}
override fun onStatusClick(holder: IStatusViewHolder, position: Int) {
}
override fun onStatusLongClick(holder: IStatusViewHolder, position: Int): Boolean {
return false
}
override fun onGapClick(holder: GapViewHolder, position: Int) {
}
override fun onUserProfileClick(holder: IStatusViewHolder, position: Int) {
}
override fun onItemActionClick(holder: RecyclerView.ViewHolder, id: Int, position: Int) {
}
override fun onItemMenuClick(holder: RecyclerView.ViewHolder, menuView: View, position: Int) {
}
}
} }

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentTop="true"
android:background="?colorToolbar"
android:elevation="@dimen/toolbar_elevation"
android:tag="ate_ignore"
app:popupTheme="?actionBarPopupTheme"
tools:elevation="0dp"/>
<FrameLayout
android:id="@+id/contentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"/>
<View
android:id="@+id/windowOverlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toolbar"
android:background="?android:windowContentOverlay"/>
</RelativeLayout>

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">
<FrameLayout
android:id="@+id/contentFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

View File

@ -30,17 +30,35 @@
android:orientation="horizontal" android:orientation="horizontal"
tools:ignore="Overdraw"> tools:ignore="Overdraw">
<TextView <LinearLayout
android:id="@android:id/title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:maxLines="1" android:minHeight="48dp"
android:textAppearance="?android:attr/textAppearanceMedium" android:orientation="vertical">
android:textColor="?android:textColorPrimary"/>
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:textColorPrimary"
tools:text="Title"/>
<TextView
android:id="@android:id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="This is summary text"/>
</LinearLayout>
<CheckBox <CheckBox
android:id="@android:id/checkbox" android:id="@android:id/checkbox"
@ -53,6 +71,7 @@
android:layout_weight="0" android:layout_weight="0"
android:clickable="false" android:clickable="false"
android:focusable="false" android:focusable="false"
android:visibility="gone"/> android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout> </LinearLayout>

View File

@ -223,6 +223,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/mediaPreview" android:layout_below="@+id/mediaPreview"
android:layout_marginTop="@dimen/element_spacing_small" android:layout_marginTop="@dimen/element_spacing_small"
android:background="?selectableItemBackground"
android:clickable="true"
android:paddingBottom="@dimen/element_spacing_small" android:paddingBottom="@dimen/element_spacing_small"
android:paddingEnd="@dimen/element_spacing_small" android:paddingEnd="@dimen/element_spacing_small"
android:paddingLeft="@dimen/element_spacing_normal" android:paddingLeft="@dimen/element_spacing_normal"

View File

@ -2,6 +2,5 @@
<resources> <resources>
<bool name="default_display_tab_label">true</bool> <bool name="default_display_tab_label">true</bool>
<bool name="home_display_icon">true</bool>
</resources> </resources>

View File

@ -5,7 +5,7 @@
<style name="Theme.Twidere.Dialog.DayNight" parent="Theme.Twidere.Light.Dialog"/> <style name="Theme.Twidere.Dialog.DayNight" parent="Theme.Twidere.Light.Dialog"/>
<style name="Theme.Twidere.DialogWhenLarge.NoActionBar.DayNight" parent="Theme.Twidere.Light.DialogWhenLarge.NoActionBar"/> <style name="Theme.Twidere.Content.DayNight" parent="Theme.Twidere.Light.Content"/>
<style name="Theme.Twidere.NoActionBar.DayNight" parent="Theme.Twidere.Light.NoActionBar"/> <style name="Theme.Twidere.NoActionBar.DayNight" parent="Theme.Twidere.Light.NoActionBar"/>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="settings_panel_margin_start_details">@dimen/settings_panel_width_entries</dimen>
</resources>

View File

@ -19,8 +19,8 @@
<resources> <resources>
<style name="Widget.Base.TextView.Light" parent="android:Widget.Material.TextView" /> <style name="Widget.Base.TextView.Light" parent="android:Widget.Material.TextView"/>
<style name="Widget.Base.TextView.Dark" parent="android:Widget.Material.Light.TextView" /> <style name="Widget.Base.TextView.Dark" parent="android:Widget.Material.Light.TextView"/>
</resources> </resources>

View File

@ -2,6 +2,8 @@
<resources> <resources>
<bool name="default_display_tab_label">true</bool> <bool name="default_display_tab_label">true</bool>
<bool name="home_display_icon">true</bool>
<!-- Config for home screen -->
<bool name="home_tab_has_multiple_columns">true</bool>
</resources> </resources>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.Twidere.Dark.Content" parent="Theme.Twidere.Dark.Dialog">
<item name="windowNoTitle">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:listDivider" tools:ignore="PrivateResource">
@drawable/abc_list_divider_mtrl_alpha
</item>
<item name="dividerVertical">?android:listDivider</item>
<item name="dividerHorizontal">?android:listDivider</item>
</style>
<style name="Theme.Twidere.Light.Content" parent="Theme.Twidere.Light.Dialog">
<item name="windowNoTitle">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:listDivider" tools:ignore="PrivateResource">
@drawable/abc_list_divider_mtrl_alpha
</item>
<item name="dividerVertical">?android:listDivider</item>
<item name="dividerHorizontal">?android:listDivider</item>
</style>
</resources>

View File

@ -22,4 +22,5 @@
(such as screen margins) for screens with more than 820dp of available width. This (such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen> <dimen name="activity_horizontal_margin">64dp</dimen>
<dimen name="settings_panel_margin_start_details">@dimen/settings_panel_width_entries</dimen>
</resources> </resources>

View File

@ -3,7 +3,9 @@
<bool name="default_display_tab_label">false</bool> <bool name="default_display_tab_label">false</bool>
<bool name="support_new_document_intent">false</bool> <bool name="support_new_document_intent">false</bool>
<bool name="home_display_icon">false</bool>
<bool name="has_font_family">false</bool> <bool name="has_font_family">false</bool>
<!-- Config for home screen -->
<bool name="home_tab_has_multiple_columns">false</bool>
</resources> </resources>

View File

@ -10,6 +10,8 @@
<dimen name="button_size_content_card">42dp</dimen> <dimen name="button_size_content_card">42dp</dimen>
<dimen name="button_size_content_card_action">36dp</dimen> <dimen name="button_size_content_card_action">36dp</dimen>
<!-- Element spacings (padding, margin) -->
<dimen name="element_spacing_xsmall">2dp</dimen> <dimen name="element_spacing_xsmall">2dp</dimen>
<dimen name="element_spacing_small">4dp</dimen> <dimen name="element_spacing_small">4dp</dimen>
<dimen name="element_spacing_msmall">6dp</dimen> <dimen name="element_spacing_msmall">6dp</dimen>
@ -24,6 +26,10 @@
<dimen name="element_spacing_minus_mlarge">-12dp</dimen> <dimen name="element_spacing_minus_mlarge">-12dp</dimen>
<dimen name="element_spacing_minus_large">-16dp</dimen> <dimen name="element_spacing_minus_large">-16dp</dimen>
<dimen name="element_spacing_minus_xlarge">-24dp</dimen> <dimen name="element_spacing_minus_xlarge">-24dp</dimen>
<!-- Preferred size -->
<dimen name="preferred_tab_column_width">420dp</dimen>
<dimen name="icon_size_list_item">56dp</dimen> <dimen name="icon_size_list_item">56dp</dimen>
<dimen name="icon_size_list_item_small">42dp</dimen> <dimen name="icon_size_list_item_small">42dp</dimen>
<dimen name="icon_size_card_list_item">48dp</dimen> <dimen name="icon_size_card_list_item">48dp</dimen>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- The platform's desired fixed width for a dialog along the major axis
(the screen is in landscape). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_width_major">100%</item>
<!-- The platform's desired fixed width for a dialog along the minor axis
(the screen is in portrait). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_width_minor">100%</item>
<!-- The platform's desired fixed height for a dialog along the major axis
(the screen is in portrait). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_height_major">80%</item>
<!-- The platform's desired fixed height for a dialog along the minor axis
(the screen is in landscape). This may be either a fraction or a dimension.-->
<item type="dimen" name="dialog_fixed_height_minor">100%</item>
</resources>

View File

@ -903,4 +903,5 @@
<string name="title_filters_subscription_invalid">Invalid subscription</string> <string name="title_filters_subscription_invalid">Invalid subscription</string>
<string name="title_filters_subscription_url">URL</string> <string name="title_filters_subscription_url">URL</string>
<string name="label_filters_subscription">Subscription</string> <string name="label_filters_subscription">Subscription</string>
<string name="summary_interactions_not_available">Only available with official keys</string>
</resources> </resources>

View File

@ -11,10 +11,9 @@
<item name="lightThemeResource">@style/Theme.Twidere.Light.Dialog</item> <item name="lightThemeResource">@style/Theme.Twidere.Light.Dialog</item>
</style> </style>
<style name="Theme.Twidere.DialogWhenLarge.NoActionBar" parent="Theme.Twidere.DialogWhenLarge.NoActionBar.DayNight"> <style name="Theme.Twidere.Content" parent="Theme.Twidere.Content.DayNight">
<item name="darkThemeResource">@style/Theme.Twidere.Dark.DialogWhenLarge.NoActionBar</item> <item name="darkThemeResource">@style/Theme.Twidere.Dark.Content</item>
<item name="lightThemeResource">@style/Theme.Twidere.Light.DialogWhenLarge.NoActionBar <item name="lightThemeResource">@style/Theme.Twidere.Light.Content</item>
</item>
</style> </style>
<style name="Theme.Twidere.NoActionBar" parent="Theme.Twidere.NoActionBar.DayNight"> <style name="Theme.Twidere.NoActionBar" parent="Theme.Twidere.NoActionBar.DayNight">

View File

@ -18,6 +18,7 @@
--> -->
<resources> <resources>
<style name="Animation.Base.Dialog" parent="android:Animation.Dialog"/>
<style name="Theme.AppCompat.TranslucentDecor"/> <style name="Theme.AppCompat.TranslucentDecor"/>

View File

@ -44,33 +44,7 @@
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style> </style>
<style name="Theme.Twidere.Dark.DialogWhenLarge.NoActionBar" parent="Theme.AppCompat.DialogWhenLarge"> <style name="Theme.Twidere.Dark.Content" parent="Theme.Twidere.Dark"/>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">false</item>
<!-- Widget styles -->
<item name="android:listSeparatorTextViewStyle">@style/Widget.Dark.TextView.ListSeparator
</item>
<!-- Card UI styles -->
<item name="cardActionButtonStyle">@style/Widget.CardActionButton</item>
<item name="profileImageStyle">@style/Widget.ProfileImage</item>
<item name="profileImageStyleLarge">@style/Widget.ProfileImage.Large</item>
<item name="cardItemBackgroundColor">@color/background_color_card_item_dark</item>
<!-- Twidere specific styles -->
<item name="menuIconColor">@color/action_icon_light</item>
<item name="messageBubbleColor">@color/message_bubble_color_dark</item>
<item name="quoteIndicatorBackgroundColor">@color/quote_indicator_background_dark</item>
<item name="colorToolbar">@color/background_color_action_bar_dark</item>
<item name="isToolbarColored">false</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="Theme.Twidere.Dark.Dialog" parent="Theme.AppCompat.Dialog"> <style name="Theme.Twidere.Dark.Dialog" parent="Theme.AppCompat.Dialog">

View File

@ -48,34 +48,7 @@
<item name="actionBarTheme">@style/Theme.Twidere.Dark.ActionBar</item> <item name="actionBarTheme">@style/Theme.Twidere.Dark.ActionBar</item>
</style> </style>
<style name="Theme.Twidere.Light.DialogWhenLarge.NoActionBar" parent="Theme.AppCompat.Light.DialogWhenLarge"> <style name="Theme.Twidere.Light.Content" parent="Theme.Twidere.Light"/>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="windowActionModeOverlay">false</item>
<!-- Widget styles -->
<item name="android:listSeparatorTextViewStyle">@style/Widget.Light.TextView.ListSeparator
</item>
<!-- Card UI styles -->
<item name="cardActionButtonStyle">@style/Widget.Light.CardActionButton</item>
<item name="profileImageStyle">@style/Widget.Light.ProfileImage</item>
<item name="profileImageStyleLarge">@style/Widget.Light.ProfileImage.Large</item>
<item name="cardItemBackgroundColor">@color/background_color_card_item_light</item>
<!-- Twidere specific styles -->
<item name="menuIconColor">@color/action_icon_dark</item>
<item name="messageBubbleColor">@color/message_bubble_color_light</item>
<item name="quoteIndicatorBackgroundColor">@color/quote_indicator_background_light</item>
<item name="colorToolbar">?colorPrimary</item>
<item name="isToolbarColored">true</item>
<item name="actionBarTheme">@null</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="Theme.Twidere.Light.Dialog" parent="Theme.AppCompat.Light.Dialog"> <style name="Theme.Twidere.Light.Dialog" parent="Theme.AppCompat.Light.Dialog">

View File

@ -5,7 +5,7 @@
<style name="Theme.Twidere.Dialog.DayNight" parent="Theme.Twidere.Dark.Dialog"/> <style name="Theme.Twidere.Dialog.DayNight" parent="Theme.Twidere.Dark.Dialog"/>
<style name="Theme.Twidere.DialogWhenLarge.NoActionBar.DayNight" parent="Theme.Twidere.Dark.DialogWhenLarge.NoActionBar"/> <style name="Theme.Twidere.Content.DayNight" parent="Theme.Twidere.Dark.Content"/>
<style name="Theme.Twidere.NoActionBar.DayNight" parent="Theme.Twidere.Dark.NoActionBar"/> <style name="Theme.Twidere.NoActionBar.DayNight" parent="Theme.Twidere.Dark.NoActionBar"/>