diff --git a/app/build.gradle b/app/build.gradle index 8dee7d11..3b2d07c6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "jp.juggler.subwaytooter" minSdkVersion 21 targetSdkVersion 25 - versionCode 35 - versionName "0.3.5" + versionCode 36 + versionName "0.3.6" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -62,4 +62,7 @@ dependencies { compile 'com.github.woxthebox:draglistview:1.4.3' compile 'com.github.omadahealth:swipy:1.2.3@aar' compile 'com.jrummyapps:colorpicker:2.1.6' + + compile 'com.astuetz:pagerslidingtabstrip:1.0.1' + } diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java b/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java index 48c1373b..ec3cf3ec 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ActAppSetting.java @@ -43,6 +43,7 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O Spinner spBackButtonAction; Spinner spUITheme; Spinner spResizeImage; + Spinner spRefreshAfterToot; CheckBox cbNotificationSound; CheckBox cbNotificationVibration; @@ -122,6 +123,20 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O spResizeImage.setAdapter( adapter ); spResizeImage.setOnItemSelectedListener( this ); } + + { + String[] caption_list = new String[]{ + getString( R.string.refresh_scroll_to_toot ), + getString( R.string.refresh_no_scroll ), + getString( R.string.dont_refresh ), + }; + ArrayAdapter< String > adapter = new ArrayAdapter<>( this, android.R.layout.simple_spinner_item, caption_list ); + adapter.setDropDownViewResource( R.layout.lv_spinner_dropdown ); + spRefreshAfterToot = (Spinner) findViewById( R.id.spRefreshAfterToot ); + spRefreshAfterToot.setAdapter( adapter ); + spRefreshAfterToot.setOnItemSelectedListener( this ); + } + } boolean load_busy; @@ -143,7 +158,7 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O spBackButtonAction.setSelection( pref.getInt( Pref.KEY_BACK_BUTTON_ACTION, 0 ) ); spUITheme.setSelection( pref.getInt( Pref.KEY_UI_THEME, 0 ) ); spResizeImage.setSelection( pref.getInt( Pref.KEY_RESIZE_IMAGE, 4 ) ); - + spRefreshAfterToot.setSelection( pref.getInt( Pref.KEY_REFRESH_AFTER_TOOT, 0 ) ); load_busy = false; } @@ -164,7 +179,7 @@ public class ActAppSetting extends AppCompatActivity implements CompoundButton.O .putInt( Pref.KEY_BACK_BUTTON_ACTION, spBackButtonAction.getSelectedItemPosition() ) .putInt( Pref.KEY_UI_THEME, spUITheme.getSelectedItemPosition() ) .putInt( Pref.KEY_RESIZE_IMAGE, spResizeImage.getSelectedItemPosition() ) - + .putInt( Pref.KEY_REFRESH_AFTER_TOOT, spRefreshAfterToot.getSelectedItemPosition() ) .apply(); } diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java index 4c4e9af2..6bbe38ba 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java @@ -27,6 +27,8 @@ import android.view.Menu; import android.view.MenuItem; import android.view.Window; +import com.astuetz.PagerSlidingTabStrip; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -129,10 +131,13 @@ public class ActMain extends AppCompatActivity reloadAccountSetting(); if( ! TextUtils.isEmpty( posted_acct ) ){ - for( Column column : pager_adapter.column_list ){ - SavedAccount a = column.access_info; - if( ! Utils.equalsNullable( a.acct,posted_acct )) continue; - column.startRefreshForPost(posted_status_id); + int refresh_after_toot = pref.getInt( Pref.KEY_REFRESH_AFTER_TOOT,0); + if( refresh_after_toot != Pref.RAT_DONT_REFRESH ){ + for( Column column : pager_adapter.column_list ){ + SavedAccount a = column.access_info; + if( ! Utils.equalsNullable( a.acct,posted_acct )) continue; + column.startRefreshForPost(posted_status_id,refresh_after_toot); + } } posted_acct = null; } @@ -397,7 +402,6 @@ public class ActMain extends AppCompatActivity void initUI(){ setContentView( R.layout.act_main ); llEmpty = findViewById( R.id.llEmpty ); - // // toolbar // Toolbar toolbar = (Toolbar) findViewById( R.id.toolbar ); // setSupportActionBar( toolbar ); @@ -433,6 +437,7 @@ public class ActMain extends AppCompatActivity pager = (ViewPager) findViewById( R.id.viewPager ); pager_adapter = new ColumnPagerAdapter( this ); pager.setAdapter( pager_adapter ); + } public void performAccountAdd(){ diff --git a/app/src/main/java/jp/juggler/subwaytooter/Column.java b/app/src/main/java/jp/juggler/subwaytooter/Column.java index 639ccd6a..cdab258f 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Column.java +++ b/app/src/main/java/jp/juggler/subwaytooter/Column.java @@ -71,6 +71,8 @@ class Column { private static final String PATH_MUTES = "/api/v1/mutes?limit=" + READ_LIMIT; // 1:account_id private static final String PATH_BLOCKS = "/api/v1/blocks?limit=" + READ_LIMIT; // 1:account_id private static final String PATH_FOLLOW_REQUESTS = "/api/v1/follow_requests?limit=" + READ_LIMIT; // 1:account_id + private static final String PATH_BOOSTED_BY = "/api/v1/statuses/%s/reblogged_by?limit=" + READ_LIMIT; // 1:status_id + private static final String PATH_FAVOURITED_BY = "/api/v1/statuses/%s/favourited_by?limit=" + READ_LIMIT; // 1:status_id // 他のリストを返すAPI private static final String PATH_REPORTS = "/api/v1/reports?limit=" + READ_LIMIT; @@ -119,6 +121,8 @@ class Column { static final int TYPE_MUTES = 11; static final int TYPE_BLOCKS = 12; static final int TYPE_FOLLOW_REQUESTS = 13; + static final int TYPE_BOOSTED_BY = 14; + static final int TYPE_FAVOURITED_BY = 15; @NonNull final ActMain activity; @NonNull final SavedAccount access_info; @@ -155,6 +159,8 @@ class Column { switch( type ){ case TYPE_CONVERSATION: + case TYPE_BOOSTED_BY: + case TYPE_FAVOURITED_BY: this.status_id = (Long) getParamAt( params, 0 ); break; @@ -186,6 +192,8 @@ class Column { switch( column_type ){ case TYPE_CONVERSATION: + case TYPE_BOOSTED_BY: + case TYPE_FAVOURITED_BY: item.put( KEY_STATUS_ID, status_id ); break; case TYPE_PROFILE: @@ -226,6 +234,8 @@ class Column { switch( column_type ){ case TYPE_CONVERSATION: + case TYPE_BOOSTED_BY: + case TYPE_FAVOURITED_BY: this.status_id = src.optLong( KEY_STATUS_ID ); break; @@ -263,6 +273,8 @@ class Column { } case TYPE_CONVERSATION: + case TYPE_BOOSTED_BY: + case TYPE_FAVOURITED_BY: try{ long status_id = (Long) getParamAt( params, 0 ); return status_id == this.status_id; @@ -330,6 +342,12 @@ class Column { case TYPE_CONVERSATION: return activity.getString( R.string.conversation_around, status_id ); + case TYPE_BOOSTED_BY: + return activity.getString( R.string.boosted_by ); + + case TYPE_FAVOURITED_BY: + return activity.getString( R.string.favourited_by ); + case TYPE_HASHTAG: return activity.getString( R.string.hashtag_of, hashtag ); @@ -379,6 +397,12 @@ class Column { case TYPE_CONVERSATION: return R.attr.ic_conversation; + case TYPE_BOOSTED_BY: + return R.attr.btn_boost; + + case TYPE_FAVOURITED_BY: + return R.attr.btn_favourite; + case TYPE_HASHTAG: return R.attr.ic_hashtag; @@ -975,6 +999,13 @@ class Column { case TYPE_NOTIFICATIONS: return parseNotifications( client, PATH_NOTIFICATIONS ); + case TYPE_BOOSTED_BY: + return parseAccountList( client, String.format( Locale.JAPAN,PATH_BOOSTED_BY,status_id ) ); + + case TYPE_FAVOURITED_BY: + return parseAccountList( client, String.format( Locale.JAPAN,PATH_FAVOURITED_BY,status_id ) ); + + case TYPE_CONVERSATION: // 指定された発言そのもの @@ -1102,6 +1133,8 @@ class Column { private void updateRelation( TootApiClient client, ArrayList< Object > list_tmp ){ if( list_tmp == null || list_tmp.isEmpty() ) return; + if( access_info.isPseudo() ) return; + HashSet< Long > who_set = new HashSet<>(); HashSet< String > acct_set = new HashSet<>(); { @@ -1212,16 +1245,16 @@ class Column { } - void startRefreshForPost( long status_id ){ + void startRefreshForPost( long status_id, int refresh_after_toot ){ switch(column_type){ case TYPE_HOME: case TYPE_LOCAL: case TYPE_FEDERATE: - startRefresh( true, false, status_id ); + startRefresh( true, false, status_id ,refresh_after_toot); break; case TYPE_PROFILE: if( profile_tab == TAB_STATUS && profile_id == access_info.id ){ - startRefresh( true, false, status_id ); + startRefresh( true, false, status_id ,refresh_after_toot); } break; case TYPE_CONVERSATION: @@ -1231,7 +1264,7 @@ class Column { } } - void startRefresh( boolean bSilent, final boolean bBottom ,final long status_id){ + void startRefresh( final boolean bSilent, final boolean bBottom , final long status_id, final int refresh_after_toot){ if( last_task != null ){ if( ! bSilent ){ @@ -1608,6 +1641,14 @@ class Column { case TYPE_NOTIFICATIONS: return getNotificationList( client, PATH_NOTIFICATIONS ); + case TYPE_BOOSTED_BY: + return getAccountList( client, String.format( Locale.JAPAN,PATH_BOOSTED_BY,status_id ) ); + + case TYPE_FAVOURITED_BY: + return getAccountList( client, String.format( Locale.JAPAN,PATH_FAVOURITED_BY,status_id ) ); + + + case TYPE_PROFILE: if( who_account == null ){ parseAccount1( client.request( @@ -1749,21 +1790,22 @@ class Column { list_data.addAll( list_new ); fireShowContent(); - if( status_index >= 0 ){ + if( status_index >= 0 && refresh_after_toot == Pref.RAT_REFRESH_SCROLL){ if( holder != null ){ //noinspection ConstantConditions sp.pos = status_index; sp.top = 0; holder.setScrollPosition( sp, 0f ); }else{ - scroll_save.pos += status_index; + scroll_save.pos = status_index; scroll_save.top = 0; } }else{ + float delta = bSilent ? 0f : - 20f; if( holder != null ){ //noinspection ConstantConditions sp.pos += added; - holder.setScrollPosition( sp, - 20f ); + holder.setScrollPosition( sp, delta ); }else{ scroll_save.pos += added; } @@ -2037,6 +2079,13 @@ class Column { return getStatusList( client, String.format( Locale.JAPAN, PATH_HASHTAG, Uri.encode( hashtag ) ) ); + case TYPE_BOOSTED_BY: + return getAccountList( client, String.format( Locale.JAPAN,PATH_BOOSTED_BY,status_id ) ); + + case TYPE_FAVOURITED_BY: + return getAccountList( client, String.format( Locale.JAPAN,PATH_FAVOURITED_BY,status_id ) ); + + case TYPE_MUTES: return getAccountList( client, PATH_MUTES ); diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnPagerAdapter.java b/app/src/main/java/jp/juggler/subwaytooter/ColumnPagerAdapter.java index 66169e9b..0d3125ac 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnPagerAdapter.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnPagerAdapter.java @@ -79,7 +79,7 @@ class ColumnPagerAdapter extends PagerAdapter { } @Override public CharSequence getPageTitle( int page_idx ){ - return "page" + page_idx; + return getColumn( page_idx).getColumnName( false ); } @Override public boolean isViewFromObject( View view, Object object ){ diff --git a/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.java b/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.java index 278fea0d..2efc1f2e 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ColumnViewHolder.java @@ -272,7 +272,7 @@ class ColumnViewHolder } @Override public void onRefresh( SwipyRefreshLayoutDirection direction ){ - column.startRefresh( false, direction == SwipyRefreshLayoutDirection.BOTTOM ,-1L); + column.startRefresh( false, direction == SwipyRefreshLayoutDirection.BOTTOM ,-1L,-1); } @Override public void onCheckedChanged( CompoundButton view, boolean isChecked ){ diff --git a/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.java b/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.java index 219e3885..49ce7eec 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.java +++ b/app/src/main/java/jp/juggler/subwaytooter/DlgContextMenu.java @@ -44,7 +44,7 @@ class DlgContextMenu implements View.OnClickListener { , @NonNull SavedAccount access_info , @NonNull TootAccount who , @Nullable TootStatus status - ,int column_type + , int column_type ){ this.activity = activity; this.access_info = access_info; @@ -131,12 +131,12 @@ class DlgContextMenu implements View.OnClickListener { btnBlock.setOnClickListener( this ); // 被フォロー状態 - ImageView ivFollowedBy = (ImageView) viewRoot.findViewById( R.id. ivFollowedBy); - if( !relation.followed_by){ + ImageView ivFollowedBy = (ImageView) viewRoot.findViewById( R.id.ivFollowedBy ); + if( ! relation.followed_by ){ ivFollowedBy.setVisibility( View.GONE ); }else{ ivFollowedBy.setVisibility( View.VISIBLE ); - ivFollowedBy.setImageResource( Styler.getAttributeResourceId( activity,R.attr.ic_followed_by )); + ivFollowedBy.setImageResource( Styler.getAttributeResourceId( activity, R.attr.ic_followed_by ) ); } // follow button @@ -203,14 +203,21 @@ class DlgContextMenu implements View.OnClickListener { v = viewRoot.findViewById( R.id.btnCancel ); v.setOnClickListener( this ); + + v = viewRoot.findViewById( R.id.btnBoostedBy ); + v.setOnClickListener( this ); + + v = viewRoot.findViewById( R.id.btnFavouritedBy ); + v.setOnClickListener( this ); + } void show(){ //noinspection ConstantConditions WindowManager.LayoutParams lp = dialog.getWindow().getAttributes(); - lp.width = (int)(0.5f + 280f * activity.density); + lp.width = (int) ( 0.5f + 280f * activity.density ); lp.height = WindowManager.LayoutParams.WRAP_CONTENT; - dialog.getWindow().setAttributes(lp); + dialog.getWindow().setAttributes( lp ); dialog.show(); } @@ -281,11 +288,23 @@ class DlgContextMenu implements View.OnClickListener { } break; + case R.id.btnBoostedBy: + if( status != null ){ + activity.addColumn( access_info, Column.TYPE_BOOSTED_BY, status.id ); + } + break; + + case R.id.btnFavouritedBy: + if( status != null ){ + activity.addColumn( access_info, Column.TYPE_FAVOURITED_BY, status.id ); + } + break; + case R.id.btnFollow: if( relation.following || relation.requested ){ - activity.callFollow( access_info, who, false, false,activity.unfollow_complete_callback ); + activity.callFollow( access_info, who, false, false, activity.unfollow_complete_callback ); }else{ - activity.callFollow( access_info, who, true, false,activity.follow_complete_callback ); + activity.callFollow( access_info, who, true, false, activity.follow_complete_callback ); } break; @@ -345,7 +364,7 @@ class DlgContextMenu implements View.OnClickListener { final String who_acct = access_info.getFullAcct( who ); AccountPicker.pick( activity, false, false, account_list_non_pseudo, new AccountPicker.AccountPickerCallback() { @Override public void onAccountPicked( SavedAccount ai ){ - activity.callRemoteFollow( ai, who_acct, who.locked, false,activity.follow_complete_callback ); + activity.callRemoteFollow( ai, who_acct, who.locked, false, activity.follow_complete_callback ); } } ); break; @@ -357,15 +376,15 @@ class DlgContextMenu implements View.OnClickListener { case R.id.btnOpenProfileFromAnotherAccount: activity.performOpenUserFromAnotherAccount( who, account_list_non_pseudo_same_instance ); break; - + case R.id.btnNickname: - ActNickname.open( activity,access_info.getFullAcct( who ) ,ActMain.REQUEST_CODE_NICKNAME ); + ActNickname.open( activity, access_info.getFullAcct( who ), ActMain.REQUEST_CODE_NICKNAME ); break; case R.id.btnCancel: dialog.cancel(); break; - + } } diff --git a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java index 6ff10686..0e82e63c 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java +++ b/app/src/main/java/jp/juggler/subwaytooter/ItemViewHolder.java @@ -199,7 +199,7 @@ class ItemViewHolder implements View.OnClickListener, View.OnLongClickListener { showBoost( n.account , n.time_created_at - , R.attr.btn_boost + , R.attr.ic_follow_plus , Utils.formatSpannable1( activity, R.string.display_name_followed_by, n.account.display_name ) ); // diff --git a/app/src/main/java/jp/juggler/subwaytooter/Pref.java b/app/src/main/java/jp/juggler/subwaytooter/Pref.java index 82c86472..9fc71b4d 100644 --- a/app/src/main/java/jp/juggler/subwaytooter/Pref.java +++ b/app/src/main/java/jp/juggler/subwaytooter/Pref.java @@ -13,6 +13,10 @@ class Pref { private static final String KEY_BACK_TO_COLUMN_LIST = "BackToColumnList"; // 使わなくなった + static final int RAT_REFRESH_SCROLL = 0; + static final int RAT_REFRESH__DONT_SCROLL = 1; + static final int RAT_DONT_REFRESH = 2; + static final String KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN = "DontConfirmBeforeCloseColumn"; static final String KEY_BACK_BUTTON_ACTION = "back_button_action"; static final String KEY_PRIOR_LOCAL_URL = "prior_local_url"; @@ -25,5 +29,6 @@ class Pref { static final String KEY_EXIT_APP_WHEN_CLOSE_PROTECTED_COLUMN = "ExitAppWhenCloseProtectedColumn"; static final String KEY_RESIZE_IMAGE = "resize_image"; static final String KEY_SHOW_FOLLOW_BUTTON_IN_BUTTON_BAR = "ShowFollowButtonInButtonBar"; + static final String KEY_REFRESH_AFTER_TOOT = "refresh_after_toot"; } diff --git a/app/src/main/res/layout/act_app_setting.xml b/app/src/main/res/layout/act_app_setting.xml index 6d5db66a..14a1de21 100644 --- a/app/src/main/res/layout/act_app_setting.xml +++ b/app/src/main/res/layout/act_app_setting.xml @@ -208,6 +208,26 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dlg_context_menu.xml b/app/src/main/res/layout/dlg_context_menu.xml index 76169c87..4022e726 100644 --- a/app/src/main/res/layout/dlg_context_menu.xml +++ b/app/src/main/res/layout/dlg_context_menu.xml @@ -74,6 +74,36 @@ android:textAllCaps="false" /> +