package jp.juggler.subwaytooter; import android.content.Context; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.EditText; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.android.volley.toolbox.NetworkImageView; import com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayout; import com.omadahealth.github.swipyrefreshlayout.library.SwipyRefreshLayoutDirection; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.regex.Matcher; import java.util.regex.Pattern; import jp.juggler.subwaytooter.api.entity.TootAccount; import jp.juggler.subwaytooter.api.entity.TootAttachment; import jp.juggler.subwaytooter.api.entity.TootGap; import jp.juggler.subwaytooter.api.entity.TootNotification; import jp.juggler.subwaytooter.api.entity.TootStatus; import jp.juggler.subwaytooter.table.ContentWarning; import jp.juggler.subwaytooter.table.MediaShown; import jp.juggler.subwaytooter.table.SavedAccount; import jp.juggler.subwaytooter.util.Emojione; import jp.juggler.subwaytooter.util.LogCategory; import jp.juggler.subwaytooter.util.Utils; class ColumnViewHolder implements View.OnClickListener, Column.VisualCallback, SwipyRefreshLayout.OnRefreshListener, CompoundButton.OnCheckedChangeListener { private static final LogCategory log = new LogCategory( "ColumnViewHolder" ); public final ActMain activity; final AtomicBoolean is_destroyed = new AtomicBoolean( false ); private final Column column; ColumnViewHolder( ActMain activity, Column column ){ this.activity = activity; this.column = column; } private boolean isPageDestroyed(){ return is_destroyed.get() || activity.isFinishing(); } void onPageDestroy( View root ){ saveScrollPosition(); log.d( "onPageDestroy:%s", column.getColumnName( true ) ); column.removeVisualListener( this ); } private TextView tvLoading; private ListView listView; private TextView tvColumnContext; private TextView tvColumnName; private StatusListAdapter status_adapter; private HeaderViewHolder vh_header; private SwipyRefreshLayout swipyRefreshLayout; private View btnSearch; private EditText etSearch; private CheckBox cbResolve; private View llColumnSetting; private EditText etRegexFilter; private TextView tvRegexFilterError; void onPageCreate( View root, int page_idx, int page_count ){ log.d( "onPageCreate:%s", column.getColumnName( true ) ); ( (TextView) root.findViewById( R.id.tvColumnIndex ) ) .setText( activity.getString( R.string.column_index, page_idx + 1, page_count ) ); tvColumnName = (TextView) root.findViewById( R.id.tvColumnName ); tvColumnContext = (TextView) root.findViewById( R.id.tvColumnContext ); root.findViewById( R.id.btnColumnClose ).setOnClickListener( this ); root.findViewById( R.id.btnColumnReload ).setOnClickListener( this ); root.findViewById( R.id.llColumnHeader ).setOnClickListener( this ); tvLoading = (TextView) root.findViewById( R.id.tvLoading ); listView = (ListView) root.findViewById( R.id.listView ); status_adapter = new StatusListAdapter(); listView.setAdapter( status_adapter ); this.swipyRefreshLayout = (SwipyRefreshLayout) root.findViewById( R.id.swipyRefreshLayout ); swipyRefreshLayout.setOnRefreshListener( this ); swipyRefreshLayout.setDistanceToTriggerSync( (int) ( 0.5f + 20f * activity.density ) ); View llSearch = root.findViewById( R.id.llSearch ); btnSearch = root.findViewById( R.id.btnSearch ); etSearch = (EditText) root.findViewById( R.id.etSearch ); cbResolve = (CheckBox) root.findViewById( R.id.cbResolve ); listView.setFastScrollEnabled( ! Pref.pref( activity ).getBoolean( Pref.KEY_DISABLE_FAST_SCROLLER, false ) ); boolean bAllowFilter; switch( column.type ){ default: bAllowFilter = true; break; case Column.TYPE_SEARCH: case Column.TYPE_CONVERSATION: case Column.TYPE_REPORTS: case Column.TYPE_BLOCKS: case Column.TYPE_MUTES: case Column.TYPE_NOTIFICATIONS: bAllowFilter = false; break; } boolean bAllowFilterBoost; switch( column.type ){ default: bAllowFilterBoost = false; break; case Column.TYPE_HOME: case Column.TYPE_PROFILE: bAllowFilterBoost = true; break; } View btnColumnSetting = root.findViewById( R.id.btnColumnSetting ); llColumnSetting = root.findViewById( R.id.llColumnSetting ); btnColumnSetting.setVisibility( View.VISIBLE ); btnColumnSetting.setOnClickListener( this ); llColumnSetting.setVisibility( View.GONE ); CheckBox cb; cb = (CheckBox) root.findViewById( R.id.cbDontCloseColumn ); cb.setChecked( column.dont_close ); cb.setOnCheckedChangeListener( this ); cb = (CheckBox) root.findViewById( R.id.cbWithAttachment ); cb.setChecked( column.with_attachment ); cb.setOnCheckedChangeListener( this ); cb.setEnabled( bAllowFilter ); cb.setVisibility( bAllowFilter ? View.VISIBLE : View.GONE ); cb = (CheckBox) root.findViewById( R.id.cbDontShowBoost ); cb.setChecked( column.dont_show_boost ); cb.setOnCheckedChangeListener( this ); cb.setEnabled( bAllowFilter ); cb.setVisibility( bAllowFilterBoost ? View.VISIBLE : View.GONE ); cb = (CheckBox) root.findViewById( R.id.cbDontShowReply ); cb.setChecked( column.dont_show_reply ); cb.setOnCheckedChangeListener( this ); cb.setEnabled( bAllowFilter ); cb.setVisibility( bAllowFilterBoost ? View.VISIBLE : View.GONE ); etRegexFilter = (EditText) root.findViewById( R.id.etRegexFilter ); if( ! bAllowFilter ){ etRegexFilter.setVisibility( View.GONE ); root.findViewById( R.id.llRegexFilter ).setVisibility( View.GONE ); }else{ etRegexFilter.setText( column.regex_text ); // tvRegexFilterErrorの表示を更新 tvRegexFilterError = (TextView) root.findViewById( R.id.tvRegexFilterError ); isRegexValid(); // 入力の追跡 etRegexFilter.addTextChangedListener( new TextWatcher() { @Override public void beforeTextChanged( CharSequence s, int start, int count, int after ){ } @Override public void onTextChanged( CharSequence s, int start, int before, int count ){ } @Override public void afterTextChanged( Editable s ){ activity.handler.removeCallbacks( proc_start_filter ); if( isRegexValid() ){ activity.handler.postDelayed( proc_start_filter, 1500L ); } } } ); } Button button = (Button) root.findViewById( R.id.btnDeleteNotification ); if( column.type != Column.TYPE_NOTIFICATIONS ){ button.setVisibility( View.GONE ); }else{ button.setVisibility( View.VISIBLE ); button.setOnClickListener( this ); } if( column.type != Column.TYPE_SEARCH ){ llSearch.setVisibility( View.GONE ); }else{ etSearch.setText( column.search_query ); cbResolve.setChecked( column.search_resolve ); btnSearch.setOnClickListener( this ); etSearch.setOnEditorActionListener( new TextView.OnEditorActionListener() { @Override public boolean onEditorAction( TextView v, int actionId, KeyEvent event ){ if( actionId == EditorInfo.IME_ACTION_SEARCH ){ btnSearch.performClick(); return true; } return false; } } ); } if( column.type == Column.TYPE_PROFILE ){ vh_header = new HeaderViewHolder( activity, listView ); listView.addHeaderView( vh_header.viewRoot ); } switch( column.type ){ case Column.TYPE_CONVERSATION: case Column.TYPE_SEARCH: swipyRefreshLayout.setEnabled( false ); } // column.addVisualListener( this ); onVisualColumn(); } private final Runnable proc_start_filter = new Runnable() { @Override public void run(){ if( isPageDestroyed() ) return; if( isRegexValid() ){ column.regex_text = etRegexFilter.getText().toString(); activity.saveColumnList(); column.startLoading(); } } }; private boolean isRegexValid(){ String s = etRegexFilter.getText().toString(); if( s.length() == 0 ){ tvRegexFilterError.setText( "" ); return true; } try{ @SuppressWarnings("unused") Matcher m = Pattern.compile( s ).matcher( "" ); tvRegexFilterError.setText( "" ); return true; }catch( Throwable ex ){ String message = ex.getMessage(); if( TextUtils.isEmpty( message ) ) message = Utils.formatError( ex, activity.getResources(), R.string.regex_error ); tvRegexFilterError.setText( message ); return false; } } @Override public void onCheckedChanged( CompoundButton view, boolean isChecked ){ switch( view.getId() ){ case R.id.cbDontCloseColumn: column.dont_close = isChecked; activity.saveColumnList(); break; case R.id.cbWithAttachment: column.with_attachment = isChecked; activity.saveColumnList(); column.startLoading(); break; case R.id.cbDontShowBoost: column.dont_show_boost = isChecked; activity.saveColumnList(); column.startLoading(); break; case R.id.cbDontShowReply: column.dont_show_reply = isChecked; activity.saveColumnList(); column.startLoading(); break; } } @Override public void onClick( View v ){ switch( v.getId() ){ case R.id.btnColumnClose: activity.performColumnClose( false, column ); break; case R.id.btnColumnReload: if( column.type == Column.TYPE_SEARCH ){ hideKeyboard( etSearch ); etSearch.setText( column.search_query ); cbResolve.setChecked( column.search_resolve ); } column.startLoading(); break; case R.id.btnSearch: hideKeyboard( etSearch ); column.search_query = etSearch.getText().toString().trim(); column.search_resolve = cbResolve.isChecked(); column.startLoading(); break; case R.id.llColumnHeader: if( status_adapter.getCount() > 0 ) listView.setSelectionFromTop( 0, 0 ); break; case R.id.btnColumnSetting: llColumnSetting.setVisibility( llColumnSetting.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE ); break; case R.id.btnDeleteNotification: activity.deleteNotification( false, column.access_info ); break; } } private void hideKeyboard( View v ){ InputMethodManager imm = (InputMethodManager) activity.getSystemService( Context.INPUT_METHOD_SERVICE ); imm.hideSoftInputFromWindow( v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS ); } private void showError( String message ){ tvLoading.setVisibility( View.VISIBLE ); tvLoading.setText( message ); swipyRefreshLayout.setVisibility( View.GONE ); // ロード完了後に先頭から表示させる if( status_adapter.getCount() > 0 ){ listView.setSelectionFromTop( 0, 0 ); } } // final RelationshipMap.UpdateCallback callback_relation = new RelationshipMap.UpdateCallback() { // @Override public void onRelationShipUpdate(){ // onVisualColumn(); // } // }; @Override public void onVisualColumn(){ // App1.relationship_map.checkUpdate( activity, column.access_info,callback_relation ); tvColumnContext.setText( column.access_info.getFullAcct( column.access_info ) ); tvColumnName.setText( column.getColumnName( false ) ); if( column.is_dispose.get() ){ showError( "column was disposed." ); return; } if( vh_header != null ){ vh_header.bind( activity, column.access_info, column.who_account ); } if( column.bInitialLoading ){ String message = column.task_progress; if( message == null ) message = "loading?"; showError( message ); return; } if( ! TextUtils.isEmpty( column.mInitialLoadingError ) ){ showError( column.mInitialLoadingError ); return; } if( ! column.bRefreshLoading ){ swipyRefreshLayout.setRefreshing( false ); if( column.mRefreshLoadingError != null ){ Utils.showToast( activity, true, column.mRefreshLoadingError ); column.mRefreshLoadingError = null; } } if( column.list_data.isEmpty() && vh_header == null ){ showError( activity.getString( R.string.list_empty ) ); }else{ tvLoading.setVisibility( View.GONE ); swipyRefreshLayout.setVisibility( View.VISIBLE ); status_adapter.set( column.list_data ); if( column.scroll_hack > 0 ){ listView.setSelectionFromTop( column.scroll_hack - 1, - (int) ( 0.5f + 80f * activity.density ) ); column.scroll_hack = 0; } } proc_restore_scroll.run(); } @Override public void onRefresh( SwipyRefreshLayoutDirection direction ){ String error = column.startRefresh( direction == SwipyRefreshLayoutDirection.BOTTOM ); if( ! TextUtils.isEmpty( error ) ){ swipyRefreshLayout.setRefreshing( false ); Utils.showToast( activity, true, error ); } } private final Runnable proc_restore_scroll = new Runnable() { @Override public void run(){ if( column.scroll_pos == 0 && column.scroll_y == 0 ){ return; } if( listView.getVisibility() != View.VISIBLE ){ column.scroll_pos = 0; column.scroll_y = 0; return; } if( column.scroll_pos > status_adapter.getCount() ){ column.scroll_pos = 0; column.scroll_y = 0; return; } listView.setSelectionFromTop( column.scroll_pos, column.scroll_y ); column.scroll_pos = 0; column.scroll_y = 0; } }; void saveScrollPosition(){ column.scroll_pos = 0; column.scroll_y = 0; if( listView.getVisibility() == View.VISIBLE ){ if( listView.getChildCount() > 0 ){ int pos = listView.getFirstVisiblePosition(); int y = listView.getChildAt( 0 ).getTop(); column.scroll_pos = pos; column.scroll_y = y; } } } /////////////////////////////////////////////////////////////////// private class HeaderViewHolder implements View.OnClickListener { final View viewRoot; final NetworkImageView ivBackground; final TextView tvCreated; final NetworkImageView ivAvatar; final TextView tvDisplayName; final TextView tvAcct; final Button btnFollowing; final Button btnFollowers; final Button btnStatusCount; final View btnMore; final TextView tvNote; TootAccount who; SavedAccount access_info; HeaderViewHolder( final ActMain activity, ListView parent ){ viewRoot = activity.getLayoutInflater().inflate( R.layout.lv_list_header, parent, false ); this.ivBackground = (NetworkImageView) viewRoot.findViewById( R.id.ivBackground ); this.tvCreated = (TextView) viewRoot.findViewById( R.id.tvCreated ); this.ivAvatar = (NetworkImageView) viewRoot.findViewById( R.id.ivAvatar ); this.tvDisplayName = (TextView) viewRoot.findViewById( R.id.tvDisplayName ); this.tvAcct = (TextView) viewRoot.findViewById( R.id.tvAcct ); this.btnFollowing = (Button) viewRoot.findViewById( R.id.btnFollowing ); this.btnFollowers = (Button) viewRoot.findViewById( R.id.btnFollowers ); this.btnStatusCount = (Button) viewRoot.findViewById( R.id.btnStatusCount ); this.tvNote = (TextView) viewRoot.findViewById( R.id.tvNote ); this.btnMore = viewRoot.findViewById( R.id.btnMore ); ivBackground.setOnClickListener( this ); btnFollowing.setOnClickListener( this ); btnFollowers.setOnClickListener( this ); btnStatusCount.setOnClickListener( this ); btnMore.setOnClickListener( this ); tvNote.setMovementMethod( LinkMovementMethod.getInstance() ); } void bind( ActMain activity, SavedAccount access_info, TootAccount who ){ this.who = who; this.access_info = access_info; if( who == null ){ tvCreated.setText( "" ); ivBackground.setImageDrawable( null ); ivAvatar.setImageDrawable( null ); tvDisplayName.setText( "" ); tvAcct.setText( "" ); tvNote.setText( "" ); btnStatusCount.setText( activity.getString( R.string.statuses ) + "\n" + "?" ); btnFollowing.setText( activity.getString( R.string.following ) + "\n" + "?" ); btnFollowers.setText( activity.getString( R.string.followers ) + "\n" + "?" ); }else{ tvCreated.setText( TootStatus.formatTime( who.time_created_at ) ); ivBackground.setImageUrl( who.header_static, App1.getImageLoader() ); ivAvatar.setImageUrl( who.avatar_static, App1.getImageLoader() ); tvDisplayName.setText( who.display_name ); String s = access_info.getFullAcct( who ); if( who.locked ){ s += " " + Emojione.map_name2unicode.get( "lock" ); } tvAcct.setText( Emojione.decodeEmoji( s ) ); tvNote.setText( who.note ); btnStatusCount.setText( activity.getString( R.string.statuses ) + "\n" + who.statuses_count ); btnFollowing.setText( activity.getString( R.string.following ) + "\n" + who.following_count ); btnFollowers.setText( activity.getString( R.string.followers ) + "\n" + who.followers_count ); } } @Override public void onClick( View v ){ switch( v.getId() ){ case R.id.ivBackground: if( who != null ){ // 強制的にブラウザで開く activity.openChromeTab( access_info, who.url, true ); } break; case R.id.btnFollowing: column.profile_tab = Column.TAB_FOLLOWING; column.startLoading(); break; case R.id.btnFollowers: column.profile_tab = Column.TAB_FOLLOWERS; column.startLoading(); break; case R.id.btnStatusCount: column.profile_tab = Column.TAB_STATUS; column.startLoading(); break; case R.id.btnMore: activity.openAccountMoreMenu( access_info, who ); break; } } } private class StatusListAdapter extends BaseAdapter { final ArrayList< Object > status_list = new ArrayList<>(); < T > void set( List< T > src ){ this.status_list.clear(); this.status_list.addAll( src ); notifyDataSetChanged(); } @Override public int getCount(){ return status_list.size(); } @Override public Object getItem( int position ){ if( position >= 0 && position < status_list.size() ) return status_list.get( position ); return null; } @Override public long getItemId( int position ){ return 0; } @Override public View getView( int position, View view, ViewGroup parent ){ Object o = ( position >= 0 && position < status_list.size() ? status_list.get( position ) : null ); StatusViewHolder holder; if( view == null ){ view = activity.getLayoutInflater().inflate( R.layout.lv_status, parent, false ); holder = new StatusViewHolder( view ); view.setTag( holder ); }else{ holder = (StatusViewHolder) view.getTag(); } holder.bind( activity, o, column.access_info ); return view; } } private class StatusViewHolder implements View.OnClickListener { final View llBoosted; final ImageView ivBoosted; final TextView tvBoosted; final TextView tvBoostedAcct; final TextView tvBoostedTime; final View llFollow; final NetworkImageView ivFollow; final TextView tvFollowerName; final TextView tvFollowerAcct; final ImageButton btnFollow; final View llStatus; final NetworkImageView ivThumbnail; final TextView tvName; final TextView tvTime; final TextView tvAcct; final View llContentWarning; final TextView tvContentWarning; final Button btnContentWarning; final View llContents; final TextView tvMentions; final TextView tvContent; final View flMedia; final View btnHideMedia; final View btnShowMedia; final NetworkImageView ivMedia1; final NetworkImageView ivMedia2; final NetworkImageView ivMedia3; final NetworkImageView ivMedia4; final ImageButton btnReply; final Button btnBoost; final Button btnFavourite; final ImageButton btnMore; TootStatus status; SavedAccount access_info; TootAccount account_thumbnail; TootAccount account_boost; TootAccount account_follow; View btnConversation; String search_tag; View llSearchTag; Button btnSearchTag; TootGap gap; StatusViewHolder( View view ){ this.llBoosted = view.findViewById( R.id.llBoosted ); this.ivBoosted = (ImageView) view.findViewById( R.id.ivBoosted ); this.tvBoosted = (TextView) view.findViewById( R.id.tvBoosted ); this.tvBoostedTime = (TextView) view.findViewById( R.id.tvBoostedTime ); this.tvBoostedAcct = (TextView) view.findViewById( R.id.tvBoostedAcct ); this.llFollow = view.findViewById( R.id.llFollow ); this.ivFollow = (NetworkImageView) view.findViewById( R.id.ivFollow ); this.tvFollowerName = (TextView) view.findViewById( R.id.tvFollowerName ); this.tvFollowerAcct = (TextView) view.findViewById( R.id.tvFollowerAcct ); this.btnFollow = (ImageButton) view.findViewById( R.id.btnFollow ); this.llStatus = view.findViewById( R.id.llStatus ); this.ivThumbnail = (NetworkImageView) view.findViewById( R.id.ivThumbnail ); this.tvName = (TextView) view.findViewById( R.id.tvName ); this.tvTime = (TextView) view.findViewById( R.id.tvTime ); this.tvAcct = (TextView) view.findViewById( R.id.tvAcct ); this.llContentWarning = view.findViewById( R.id.llContentWarning ); this.tvContentWarning = (TextView) view.findViewById( R.id.tvContentWarning ); this.btnContentWarning = (Button) view.findViewById( R.id.btnContentWarning ); this.llContents = view.findViewById( R.id.llContents ); this.tvContent = (TextView) view.findViewById( R.id.tvContent ); this.tvMentions = (TextView) view.findViewById( R.id.tvMentions ); this.btnConversation = view.findViewById( R.id.btnConversation ); this.btnReply = (ImageButton) view.findViewById( R.id.btnReply ); this.btnBoost = (Button) view.findViewById( R.id.btnBoost ); this.btnFavourite = (Button) view.findViewById( R.id.btnFavourite ); this.btnMore = (ImageButton) view.findViewById( R.id.btnMore ); this.flMedia = view.findViewById( R.id.flMedia ); this.btnHideMedia = view.findViewById( R.id.btnHideMedia ); this.btnShowMedia = view.findViewById( R.id.btnShowMedia ); this.ivMedia1 = (NetworkImageView) view.findViewById( R.id.ivMedia1 ); this.ivMedia2 = (NetworkImageView) view.findViewById( R.id.ivMedia2 ); this.ivMedia3 = (NetworkImageView) view.findViewById( R.id.ivMedia3 ); this.ivMedia4 = (NetworkImageView) view.findViewById( R.id.ivMedia4 ); this.llSearchTag = view.findViewById( R.id.llSearchTag ); this.btnSearchTag = (Button) view.findViewById( R.id.btnSearchTag ); btnSearchTag.setOnClickListener( this ); btnContentWarning.setOnClickListener( this ); btnHideMedia.setOnClickListener( this ); btnShowMedia.setOnClickListener( this ); ivMedia1.setOnClickListener( this ); ivMedia2.setOnClickListener( this ); ivMedia3.setOnClickListener( this ); ivMedia4.setOnClickListener( this ); btnFollow.setOnClickListener( this ); btnConversation.setOnClickListener( this ); btnReply.setOnClickListener( this ); btnBoost.setOnClickListener( this ); btnFavourite.setOnClickListener( this ); btnMore.setOnClickListener( this ); ivThumbnail.setOnClickListener( this ); // ここを個別タップにすると邪魔すぎる tvName.setOnClickListener( this ); llBoosted.setOnClickListener( this ); llFollow.setOnClickListener( this ); btnFollow.setOnClickListener( this ); tvContent.setMovementMethod( LinkMovementMethod.getInstance() ); tvMentions.setMovementMethod( LinkMovementMethod.getInstance() ); } void bind( ActMain activity, Object item, SavedAccount access_info ){ this.access_info = access_info; llBoosted.setVisibility( View.GONE ); llFollow.setVisibility( View.GONE ); llStatus.setVisibility( View.GONE ); llSearchTag.setVisibility( View.GONE ); if( item == null ) return; if( item instanceof String ){ showSearchTag( (String) item ); }else if( item instanceof TootAccount ){ showFollow( (TootAccount) item ); }else if( item instanceof TootNotification ){ TootNotification n = (TootNotification) item; if( TootNotification.TYPE_FAVOURITE.equals( n.type ) ){ showBoost( n.account , n.time_created_at , R.attr.btn_favourite , Utils.formatSpannable1( activity, R.string.display_name_favourited_by, n.account.display_name ) ); if( n.status != null ) showStatus( activity, n.status, access_info ); }else if( TootNotification.TYPE_REBLOG.equals( n.type ) ){ showBoost( n.account , n.time_created_at , R.attr.btn_boost , Utils.formatSpannable1( activity, R.string.display_name_boosted_by, n.account.display_name ) ); if( n.status != null ) showStatus( activity, n.status, access_info ); }else if( TootNotification.TYPE_FOLLOW.equals( n.type ) ){ showBoost( n.account , n.time_created_at , R.attr.btn_boost , Utils.formatSpannable1( activity, R.string.display_name_followed_by, n.account.display_name ) ); // showFollow( n.account ); }else if( TootNotification.TYPE_MENTION.equals( n.type ) ){ showBoost( n.account , n.time_created_at , R.attr.btn_reply , Utils.formatSpannable1( activity, R.string.display_name_replied_by, n.account.display_name ) ); if( n.status != null ) showStatus( activity, n.status, access_info ); } }else if( item instanceof TootStatus ){ TootStatus status = (TootStatus) item; if( status.reblog != null ){ showBoost( status.account , status.time_created_at , R.attr.btn_boost , Utils.formatSpannable1( activity, R.string.display_name_boosted_by, status.account.display_name ) ); showStatus( activity, status.reblog, access_info ); }else{ showStatus( activity, status, access_info ); } }else if( item instanceof TootGap ){ showGap( (TootGap) item ); } } private void showSearchTag( String tag ){ this.gap = null; search_tag = tag; llSearchTag.setVisibility( View.VISIBLE ); btnSearchTag.setText( "#" + tag ); } private void showGap( TootGap gap ){ this.gap = gap; search_tag = null; llSearchTag.setVisibility( View.VISIBLE ); btnSearchTag.setText( activity.getString( R.string.read_gap ) ); } void showBoost( TootAccount who, long time, int icon_attr_id, CharSequence text ){ account_boost = who; llBoosted.setVisibility( View.VISIBLE ); ivBoosted.setImageResource( Styler.getAttributeResourceId( activity, icon_attr_id ) ); tvBoostedTime.setText( TootStatus.formatTime( time ) ); tvBoostedAcct.setText( access_info.getFullAcct( who ) ); tvBoosted.setText( text ); } private void showFollow( TootAccount who ){ account_follow = who; llFollow.setVisibility( View.VISIBLE ); ivFollow.setImageUrl( who.avatar_static, App1.getImageLoader() ); tvFollowerName.setText( who.display_name ); tvFollowerAcct.setText( access_info.getFullAcct( who ) ); btnFollow.setImageResource( Styler.getAttributeResourceId( activity, R.attr.ic_account_add ) ); } private void showStatus( ActMain activity, TootStatus status, SavedAccount account ){ this.status = status; account_thumbnail = status.account; llStatus.setVisibility( View.VISIBLE ); tvAcct.setText( account.getFullAcct( status.account ) ); tvTime.setText( TootStatus.formatTime( status.time_created_at ) ); tvName.setText( status.account.display_name ); ivThumbnail.setImageUrl( status.account.avatar_static, App1.getImageLoader() ); tvContent.setText( status.decoded_content ); // if( status.decoded_tags == null ){ // tvTags.setVisibility( View.GONE ); // }else{ // tvTags.setVisibility( View.VISIBLE ); // tvTags.setText( status.decoded_tags ); // } if( status.decoded_mentions == null ){ tvMentions.setVisibility( View.GONE ); }else{ tvMentions.setVisibility( View.VISIBLE ); tvMentions.setText( status.decoded_mentions ); } // Content warning if( TextUtils.isEmpty( status.spoiler_text ) ){ llContentWarning.setVisibility( View.GONE ); llContents.setVisibility( View.VISIBLE ); }else{ llContentWarning.setVisibility( View.VISIBLE ); tvContentWarning.setText( status.decoded_spoiler_text ); boolean cw_shown = ContentWarning.isShown( account.host, status.id, false ); showContent( cw_shown ); } if( status.media_attachments == null || status.media_attachments.isEmpty() ){ flMedia.setVisibility( View.GONE ); }else{ flMedia.setVisibility( View.VISIBLE ); setMedia( ivMedia1, status, 0 ); setMedia( ivMedia2, status, 1 ); setMedia( ivMedia3, status, 2 ); setMedia( ivMedia4, status, 3 ); // hide sensitive media boolean is_shown = MediaShown.isShown( account.host, status.id, account.dont_hide_nsfw || ! status.sensitive ); btnShowMedia.setVisibility( ! is_shown ? View.VISIBLE : View.GONE ); } int color_normal = Styler.getAttributeColor( activity, R.attr.colorImageButton ); int color_accent = Styler.getAttributeColor( activity, R.attr.colorImageButtonAccent ); if( TootStatus.VISIBILITY_DIRECT.equals( status.visibility ) ){ setButton( btnBoost, false, color_accent, R.attr.ic_mail, "" ); }else if( TootStatus.VISIBILITY_PRIVATE.equals( status.visibility ) ){ setButton( btnBoost, false, color_accent, R.attr.ic_lock, "" ); }else if( activity.isBusyBoost( account, status ) ){ setButton( btnBoost, false, color_normal, R.attr.btn_refresh, "?" ); }else{ int color = ( status.reblogged ? color_accent : color_normal ); setButton( btnBoost, true, color, R.attr.btn_boost, Long.toString( status.reblogs_count ) ); } if( activity.isBusyFav( account, status ) ){ setButton( btnFavourite, false, color_normal, R.attr.btn_refresh, "?" ); }else{ int color = ( status.favourited ? color_accent : color_normal ); setButton( btnFavourite, true, color, R.attr.btn_favourite, Long.toString( status.favourites_count ) ); } } private void setButton( Button b, boolean enabled, int color, int icon_attr, String text ){ Drawable d = Styler.getAttributeDrawable( activity, icon_attr ).mutate(); d.setColorFilter( color, PorterDuff.Mode.SRC_ATOP ); b.setCompoundDrawablesRelativeWithIntrinsicBounds( d, null, null, null ); b.setText( text ); b.setTextColor( color ); b.setEnabled( enabled ); } private void showContent( boolean shown ){ btnContentWarning.setText( shown ? R.string.hide : R.string.show ); llContents.setVisibility( shown ? View.VISIBLE : View.GONE ); } private void setMedia( NetworkImageView iv, TootStatus status, int idx ){ if( idx >= status.media_attachments.size() ){ iv.setVisibility( View.GONE ); }else{ iv.setVisibility( View.VISIBLE ); TootAttachment ta = status.media_attachments.get( idx ); String url = ta.preview_url; if( TextUtils.isEmpty( url ) ) url = ta.remote_url; iv.setImageUrl( url, App1.getImageLoader() ); } } @Override public void onClick( View v ){ switch( v.getId() ){ case R.id.btnHideMedia: MediaShown.save( access_info.host, status.id, false ); btnShowMedia.setVisibility( View.VISIBLE ); break; case R.id.btnShowMedia: MediaShown.save( access_info.host, status.id, true ); btnShowMedia.setVisibility( View.GONE ); break; case R.id.ivMedia1: clickMedia( 0 ); break; case R.id.ivMedia2: clickMedia( 1 ); break; case R.id.ivMedia3: clickMedia( 2 ); break; case R.id.ivMedia4: clickMedia( 3 ); break; case R.id.btnContentWarning:{ boolean new_shown = ( llContents.getVisibility() == View.GONE ); ContentWarning.save( access_info.host, status.id, new_shown ); showContent( new_shown ); break; } case R.id.btnConversation: activity.performConversation( access_info, status ); break; case R.id.btnReply: activity.performReply( access_info, status ); break; case R.id.btnBoost: activity.performBoost( access_info, status, false ); break; case R.id.btnFavourite: activity.performFavourite( access_info, status ); break; case R.id.btnMore: activity.openStatusMoreMenu( access_info, status ); break; case R.id.ivThumbnail: activity.performOpenUser( access_info, account_thumbnail ); break; case R.id.llBoosted: activity.performOpenUser( access_info, account_boost ); break; case R.id.llFollow: activity.performOpenUser( access_info, account_follow ); break; case R.id.btnFollow: activity.openAccountMoreMenu( access_info, account_follow ); break; case R.id.btnSearchTag: if( search_tag != null ){ activity.openHashTag( access_info, search_tag ); }else if( gap != null ){ String error = column.startGap( gap ); if( ! TextUtils.isEmpty( error ) ){ Utils.showToast( activity, true, error ); }else{ swipyRefreshLayout.setRefreshing( true ); } } break; } } private void clickMedia( int i ){ try{ TootAttachment a = status.media_attachments.get( i ); String sv; if( Pref.pref( activity ).getBoolean( Pref.KEY_PRIOR_LOCAL_URL, false ) ){ sv = a.url; if( TextUtils.isEmpty( sv ) ){ sv = a.remote_url; } }else{ sv = a.remote_url; if( TextUtils.isEmpty( sv ) ){ sv = a.url; } } activity.openChromeTab( access_info, sv, false ); }catch( Throwable ex ){ ex.printStackTrace(); } } } }