Add pinned status tab (#994)

* Add pinned status tab

* Make TabLayout scrollable.
This commit is contained in:
kyori19 2019-01-21 16:37:25 +09:00 committed by Konrad Pozniak
parent fe535c2e0c
commit 96162ab544
8 changed files with 45 additions and 37 deletions

View file

@ -16,27 +16,27 @@
package com.keylesspalace.tusky package com.keylesspalace.tusky
import android.animation.ArgbEvaluator import android.animation.ArgbEvaluator
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager import android.preference.PreferenceManager
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.Px
import androidx.emoji.text.EmojiCompat
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.annotation.Px
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
import androidx.emoji.text.EmojiCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.CollapsingToolbarLayout import com.google.android.material.appbar.CollapsingToolbarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
@ -251,7 +251,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasSupportF
// Setup the tabs and timeline pager. // Setup the tabs and timeline pager.
val adapter = AccountPagerAdapter(supportFragmentManager, accountId) val adapter = AccountPagerAdapter(supportFragmentManager, accountId)
val pageTitles = arrayOf(getString(R.string.title_statuses), getString(R.string.title_statuses_with_replies), getString(R.string.title_media)) val pageTitles = arrayOf(getString(R.string.title_statuses), getString(R.string.title_statuses_with_replies), getString(R.string.title_statuses_pinned), getString(R.string.title_media))
adapter.setPageTitles(pageTitles) adapter.setPageTitles(pageTitles)
accountFragmentViewPager.pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin) accountFragmentViewPager.pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
val pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable, val pageMarginDrawable = ThemeUtils.getDrawable(this, R.attr.tab_page_margin_drawable,

View file

@ -18,19 +18,13 @@ package com.keylesspalace.tusky;
import android.content.Intent; import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.ActionBar;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.Toolbar;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import com.google.android.material.snackbar.Snackbar;
import com.keylesspalace.tusky.adapter.ReportAdapter; import com.keylesspalace.tusky.adapter.ReportAdapter;
import com.keylesspalace.tusky.di.Injectable; import com.keylesspalace.tusky.di.Injectable;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
@ -44,6 +38,12 @@ import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
@ -189,7 +189,7 @@ public class ReportActivity extends BaseActivity implements Injectable {
onFetchStatusesFailure((Exception) t); onFetchStatusesFailure((Exception) t);
} }
}; };
mastodonApi.accountStatuses(accountId, null, null, null, null, null) mastodonApi.accountStatuses(accountId, null, null, null, null, null, null)
.enqueue(callback); .enqueue(callback);
} }

View file

@ -17,14 +17,14 @@ package com.keylesspalace.tusky.fragment
import android.graphics.Color import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
@ -157,10 +157,10 @@ class AccountMediaFragment : BaseFragment(), Injectable {
if (fetchingStatus != FetchingStatus.NOT_FETCHING) return@setOnRefreshListener if (fetchingStatus != FetchingStatus.NOT_FETCHING) return@setOnRefreshListener
currentCall = if (statuses.isEmpty()) { currentCall = if (statuses.isEmpty()) {
fetchingStatus = FetchingStatus.INITIAL_FETCHING fetchingStatus = FetchingStatus.INITIAL_FETCHING
api.accountStatuses(accountId, null, null, null, null, true) api.accountStatuses(accountId, null, null, null, null, true, null)
} else { } else {
fetchingStatus = FetchingStatus.REFRESHING fetchingStatus = FetchingStatus.REFRESHING
api.accountStatuses(accountId, null, statuses[0].id, null, null, true) api.accountStatuses(accountId, null, statuses[0].id, null, null, true, null)
} }
currentCall?.enqueue(callback) currentCall?.enqueue(callback)
@ -180,7 +180,7 @@ class AccountMediaFragment : BaseFragment(), Injectable {
statuses.lastOrNull()?.let { last -> statuses.lastOrNull()?.let { last ->
Log.d(TAG, "Requesting statuses with max_id: ${last.id}, (bottom)") Log.d(TAG, "Requesting statuses with max_id: ${last.id}, (bottom)")
fetchingStatus = FetchingStatus.FETCHING_BOTTOM fetchingStatus = FetchingStatus.FETCHING_BOTTOM
currentCall = api.accountStatuses(accountId, last.id, null, null, null, true) currentCall = api.accountStatuses(accountId, last.id, null, null, null, true, null)
currentCall?.enqueue(bottomCallback) currentCall?.enqueue(bottomCallback)
} }
} }
@ -196,7 +196,7 @@ class AccountMediaFragment : BaseFragment(), Injectable {
val accountId = arguments?.getString(ACCOUNT_ID_ARG) val accountId = arguments?.getString(ACCOUNT_ID_ARG)
if (fetchingStatus == FetchingStatus.NOT_FETCHING && statuses.isEmpty()) { if (fetchingStatus == FetchingStatus.NOT_FETCHING && statuses.isEmpty()) {
fetchingStatus = FetchingStatus.INITIAL_FETCHING fetchingStatus = FetchingStatus.INITIAL_FETCHING
currentCall = api.accountStatuses(accountId, null, null, null, null, true) currentCall = api.accountStatuses(accountId, null, null, null, null, true, null)
currentCall?.enqueue(callback) currentCall?.enqueue(callback)
} }
} }

View file

@ -110,6 +110,7 @@ public class TimelineFragment extends SFragment implements
PUBLIC_FEDERATED, PUBLIC_FEDERATED,
TAG, TAG,
USER, USER,
USER_PINNED,
USER_WITH_REPLIES, USER_WITH_REPLIES,
FAVOURITES, FAVOURITES,
LIST LIST
@ -201,6 +202,7 @@ public class TimelineFragment extends SFragment implements
kind = Kind.valueOf(arguments.getString(KIND_ARG)); kind = Kind.valueOf(arguments.getString(KIND_ARG));
if (kind == Kind.TAG if (kind == Kind.TAG
|| kind == Kind.USER || kind == Kind.USER
|| kind == Kind.USER_PINNED
|| kind == Kind.USER_WITH_REPLIES || kind == Kind.USER_WITH_REPLIES
|| kind == Kind.LIST) { || kind == Kind.LIST) {
hashtagOrId = arguments.getString(HASHTAG_OR_ID_ARG); hashtagOrId = arguments.getString(HASHTAG_OR_ID_ARG);
@ -847,9 +849,11 @@ public class TimelineFragment extends SFragment implements
case TAG: case TAG:
return api.hashtagTimeline(tagOrId, null, fromId, uptoId, LOAD_AT_ONCE); return api.hashtagTimeline(tagOrId, null, fromId, uptoId, LOAD_AT_ONCE);
case USER: case USER:
return api.accountStatuses(tagOrId, fromId, uptoId, LOAD_AT_ONCE, true, null); return api.accountStatuses(tagOrId, fromId, uptoId, LOAD_AT_ONCE, true, null, null);
case USER_PINNED:
return api.accountStatuses(tagOrId, fromId, uptoId, LOAD_AT_ONCE, null, null, true);
case USER_WITH_REPLIES: case USER_WITH_REPLIES:
return api.accountStatuses(tagOrId, fromId, uptoId, LOAD_AT_ONCE, null, null); return api.accountStatuses(tagOrId, fromId, uptoId, LOAD_AT_ONCE, null, null, null);
case FAVOURITES: case FAVOURITES:
return api.favourites(fromId, uptoId, LOAD_AT_ONCE); return api.favourites(fromId, uptoId, LOAD_AT_ONCE);
case LIST: case LIST:

View file

@ -15,8 +15,6 @@
package com.keylesspalace.tusky.network; package com.keylesspalace.tusky.network;
import androidx.annotation.Nullable;
import com.keylesspalace.tusky.entity.AccessToken; import com.keylesspalace.tusky.entity.AccessToken;
import com.keylesspalace.tusky.entity.Account; import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.entity.AppCredentials; import com.keylesspalace.tusky.entity.AppCredentials;
@ -33,6 +31,7 @@ import com.keylesspalace.tusky.entity.StatusContext;
import java.util.List; import java.util.List;
import androidx.annotation.Nullable;
import io.reactivex.Single; import io.reactivex.Single;
import okhttp3.MultipartBody; import okhttp3.MultipartBody;
import okhttp3.RequestBody; import okhttp3.RequestBody;
@ -219,7 +218,8 @@ public interface MastodonApi {
@Query("since_id") String sinceId, @Query("since_id") String sinceId,
@Query("limit") Integer limit, @Query("limit") Integer limit,
@Nullable @Query("exclude_replies") Boolean excludeReplies, @Nullable @Query("exclude_replies") Boolean excludeReplies,
@Nullable @Query("only_media") Boolean onlyMedia); @Nullable @Query("only_media") Boolean onlyMedia,
@Nullable @Query("pinned") Boolean pinned);
@GET("api/v1/accounts/{id}/followers") @GET("api/v1/accounts/{id}/followers")
Call<List<Account>> accountFollowers( Call<List<Account>> accountFollowers(

View file

@ -15,13 +15,13 @@
package com.keylesspalace.tusky.pager; package com.keylesspalace.tusky.pager;
import com.keylesspalace.tusky.fragment.AccountMediaFragment;
import com.keylesspalace.tusky.fragment.TimelineFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentPagerAdapter;
import com.keylesspalace.tusky.fragment.AccountMediaFragment;
import com.keylesspalace.tusky.fragment.TimelineFragment;
public class AccountPagerAdapter extends FragmentPagerAdapter { public class AccountPagerAdapter extends FragmentPagerAdapter {
private String accountId; private String accountId;
private String[] pageTitles; private String[] pageTitles;
@ -45,6 +45,9 @@ public class AccountPagerAdapter extends FragmentPagerAdapter {
return TimelineFragment.newInstance(TimelineFragment.Kind.USER_WITH_REPLIES, accountId); return TimelineFragment.newInstance(TimelineFragment.Kind.USER_WITH_REPLIES, accountId);
} }
case 2: { case 2: {
return TimelineFragment.newInstance(TimelineFragment.Kind.USER_PINNED, accountId);
}
case 3: {
return AccountMediaFragment.newInstance(accountId); return AccountMediaFragment.newInstance(accountId);
} }
default: { default: {
@ -55,7 +58,7 @@ public class AccountPagerAdapter extends FragmentPagerAdapter {
@Override @Override
public int getCount() { public int getCount() {
return 3; return 4;
} }
@Override @Override

View file

@ -281,7 +281,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:colorBackground" android:background="?android:colorBackground"
app:tabGravity="center" app:tabGravity="center"
app:tabMode="fixed" app:tabMode="scrollable"
app:tabTextAppearance="@style/TuskyTabAppearance" /> app:tabTextAppearance="@style/TuskyTabAppearance" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View file

@ -30,6 +30,7 @@
<string name="title_tag">#%s</string> <string name="title_tag">#%s</string>
<string name="title_statuses">Posts</string> <string name="title_statuses">Posts</string>
<string name="title_statuses_with_replies">With replies</string> <string name="title_statuses_with_replies">With replies</string>
<string name="title_statuses_pinned">Pinned</string>
<string name="title_follows">Follows</string> <string name="title_follows">Follows</string>
<string name="title_followers">Followers</string> <string name="title_followers">Followers</string>
<string name="title_favourites">Favourites</string> <string name="title_favourites">Favourites</string>