ステータスのリンクタップでハッシュタグのカラムを表示できるようにした
This commit is contained in:
parent
ad5ce44f9e
commit
67b3df2e5e
|
@ -219,7 +219,7 @@ public class ActAccountSetting extends AppCompatActivity implements View.OnClick
|
|||
|
||||
TootApiResult result = api_client.request( "/api/v1/accounts/verify_credentials" );
|
||||
if( result != null && result.object != null ){
|
||||
TootAccount ta = TootAccount.parse( log, result.object );
|
||||
TootAccount ta = TootAccount.parse( log, account,result.object );
|
||||
|
||||
if( ! ta.username.equals( account.username ) ){
|
||||
return new TootApiResult( getString( R.string.user_name_not_match ) );
|
||||
|
|
|
@ -33,7 +33,11 @@ import java.io.FileNotFoundException;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import jp.juggler.subwaytooter.api.TootApiClient;
|
||||
import jp.juggler.subwaytooter.api.TootApiResult;
|
||||
|
@ -44,6 +48,7 @@ import jp.juggler.subwaytooter.dialog.LoginForm;
|
|||
import jp.juggler.subwaytooter.dialog.ReportForm;
|
||||
import jp.juggler.subwaytooter.table.SavedAccount;
|
||||
import jp.juggler.subwaytooter.util.HTMLDecoder;
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
import jp.juggler.subwaytooter.util.Utils;
|
||||
import okhttp3.Request;
|
||||
|
@ -318,7 +323,10 @@ public class ActMain extends AppCompatActivity
|
|||
|
||||
TootApiResult result = api_client.request( "/api/v1/accounts/verify_credentials" );
|
||||
if( result != null && result.object != null ){
|
||||
TootAccount ta = TootAccount.parse( log, result.object );
|
||||
// taは使い捨てなので、生成に使うLinkClickContextはダミーで問題ない
|
||||
LinkClickContext lcc = new LinkClickContext() {
|
||||
};
|
||||
TootAccount ta = TootAccount.parse( log, lcc,result.object );
|
||||
String user = ta.username + "@" + instance;
|
||||
this.row_id = SavedAccount.insert( instance, user, result.object, result.token_info );
|
||||
}
|
||||
|
@ -386,56 +394,82 @@ public class ActMain extends AppCompatActivity
|
|||
//////////////////////////////////////////////////////////////
|
||||
// カラム追加系
|
||||
|
||||
public void addColumn( SavedAccount ai, int type, long who, long status_id ){
|
||||
public void addColumn( SavedAccount ai, int type, Object... params ){
|
||||
// 既に同じカラムがあればそこに移動する
|
||||
for( Column column : pager_adapter.column_list ){
|
||||
if( ai.user.equals( column.access_info.user )
|
||||
&& column.type == type
|
||||
&& column.who_id == who
|
||||
&& column.status_id == status_id
|
||||
){
|
||||
if( column.isSameSpec( ai, type, params ) ){
|
||||
pager.setCurrentItem( pager_adapter.column_list.indexOf( column ), true );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
llEmpty.setVisibility( View.GONE );
|
||||
//
|
||||
Column col = new Column( ActMain.this, ai, type, who, status_id );
|
||||
Column col = new Column( ActMain.this, ai, type, params );
|
||||
int idx = pager_adapter.addColumn( pager, col );
|
||||
pager.setCurrentItem( idx, true );
|
||||
}
|
||||
|
||||
private void onAccountUpdated( SavedAccount data ){
|
||||
Utils.showToast( this, false, R.string.account_confirmed );
|
||||
addColumn( data, Column.TYPE_TL_HOME, data.id, 0L );
|
||||
addColumn( data, Column.TYPE_TL_HOME );
|
||||
}
|
||||
|
||||
void performOpenUser( SavedAccount access_info, TootAccount user ){
|
||||
addColumn( access_info, Column.TYPE_TL_STATUSES, user.id, 0L );
|
||||
addColumn( access_info, Column.TYPE_TL_STATUSES, user.id );
|
||||
}
|
||||
|
||||
public void performConversation( SavedAccount access_info, TootStatus status ){
|
||||
addColumn( access_info, Column.TYPE_TL_CONVERSATION, access_info.id, status.id );
|
||||
addColumn( access_info, Column.TYPE_TL_CONVERSATION, status.id );
|
||||
}
|
||||
|
||||
private void performAddTimeline( final int type ){
|
||||
AccountPicker.pick( this, new AccountPicker.AccountPickerCallback() {
|
||||
@Override
|
||||
public void onAccountPicked( SavedAccount ai ){
|
||||
addColumn( ai, type, ai.id, 0L );
|
||||
addColumn( ai, type, ai.id );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
public void openBrowser( String url ){
|
||||
openChromeTab( url );
|
||||
public void openHashTag( SavedAccount access_info, String tag ){
|
||||
addColumn( access_info, Column.TYPE_TL_HASHTAG, tag );
|
||||
}
|
||||
|
||||
public void openChromeTab( String url ){
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
public void openBrowser(SavedAccount account, String url ){
|
||||
openChromeTab( account,url,false );
|
||||
}
|
||||
|
||||
Pattern reHashTag = Pattern.compile( "\\Ahttps://([^/]+)/tags/([^?#]+)\\z" );
|
||||
|
||||
|
||||
public void openChromeTab( SavedAccount account, String url ,boolean noIntercept ){
|
||||
try{
|
||||
log.d("openChromeTab url=%s",url);
|
||||
|
||||
if(!noIntercept){
|
||||
// ハッシュタグをアプリ内で開く
|
||||
Matcher m = reHashTag.matcher( url );
|
||||
if( m.find() ){
|
||||
// https://mastodon.juggler.jp/tags/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E3%82%BF%E3%82%B0
|
||||
String host = m.group( 1 );
|
||||
String tag = m.group( 2 );
|
||||
if( tag.length() > 0 ){
|
||||
if( host.equalsIgnoreCase( account.host ) ){
|
||||
openHashTag( account, Uri.decode( tag ) );
|
||||
return;
|
||||
}else{
|
||||
openHashTagOtherInstance( account,url, host,Uri.decode(tag) );
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ビルダーを使って表示方法を指定する
|
||||
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
|
||||
builder.setToolbarColor( ContextCompat.getColor( this, R.color.colorPrimary ) ).setShowTitle( true );
|
||||
|
@ -450,10 +484,90 @@ public class ActMain extends AppCompatActivity
|
|||
}
|
||||
}
|
||||
|
||||
static class Action{
|
||||
String caption;
|
||||
Runnable runnable;
|
||||
}
|
||||
|
||||
// 他インスタンスのハッシュタグの表示
|
||||
private void openHashTagOtherInstance( final SavedAccount access_info,final String url,String host, final String tag ){
|
||||
final ArrayList<Action> action_list = new ArrayList<>();
|
||||
|
||||
ArrayList<SavedAccount> account_list = new ArrayList<>( );
|
||||
for(SavedAccount a : SavedAccount.loadAccountList( log )){
|
||||
if( a.host.equalsIgnoreCase( host )){
|
||||
account_list.add(a);
|
||||
}
|
||||
}
|
||||
Collections.sort( account_list,new Comparator< SavedAccount >() {
|
||||
@Override
|
||||
public int compare( SavedAccount a, SavedAccount b ){
|
||||
return String.CASE_INSENSITIVE_ORDER.compare( a.getFullAcct( a ), b.getFullAcct( b ) );
|
||||
}
|
||||
} );
|
||||
for( SavedAccount a : account_list ){
|
||||
Action action = new Action();
|
||||
action.caption = getString(R.string.open_in_account,a.user);
|
||||
final SavedAccount _a = a;
|
||||
action.runnable = new Runnable() {
|
||||
@Override
|
||||
public void run(){
|
||||
openHashTag( _a,tag );
|
||||
}
|
||||
};
|
||||
action_list.add( action);
|
||||
}
|
||||
if( account_list.isEmpty() ){
|
||||
// TODO ログインなしアカウントで開く選択肢
|
||||
}
|
||||
// カラムのアカウントで開く
|
||||
{
|
||||
Action action = new Action();
|
||||
action.caption = getString(R.string.open_in_account,access_info.user);
|
||||
final SavedAccount _a = access_info;
|
||||
action.runnable = new Runnable() {
|
||||
@Override
|
||||
public void run(){
|
||||
openHashTag( _a,tag );
|
||||
}
|
||||
};
|
||||
action_list.add( action);
|
||||
}
|
||||
// ブラウザで表示する
|
||||
{
|
||||
Action action = new Action();
|
||||
action.caption = getString(R.string.open_web_on_host,host);
|
||||
action.runnable = new Runnable() {
|
||||
@Override
|
||||
public void run(){
|
||||
openChromeTab( access_info,url,true);
|
||||
}
|
||||
};
|
||||
action_list.add( action);
|
||||
}
|
||||
|
||||
String[] caption_list = new String[action_list.size()];
|
||||
for(int i=0,ie=caption_list.length;i<ie;++i){
|
||||
caption_list[i] = action_list.get(i).caption;
|
||||
}
|
||||
new AlertDialog.Builder( this )
|
||||
.setTitle( "#"+tag)
|
||||
.setNegativeButton( R.string.cancel,null )
|
||||
.setItems( caption_list, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dialog, int which ){
|
||||
if( which >= 0 && which < action_list.size()){
|
||||
action_list.get(which).runnable.run();
|
||||
}
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
final HTMLDecoder.LinkClickCallback link_click_listener = new HTMLDecoder.LinkClickCallback() {
|
||||
@Override
|
||||
public void onClickLink( String url ){
|
||||
openChromeTab( url );
|
||||
public void onClickLink( LinkClickContext lcc,String url ){
|
||||
openChromeTab( (SavedAccount)lcc,url ,false );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -469,7 +583,7 @@ public class ActMain extends AppCompatActivity
|
|||
}
|
||||
|
||||
public void performMention( SavedAccount account, TootAccount who ){
|
||||
ActPost.open( this, account.db_id, account.getFullAcct( who ) +" " );
|
||||
ActPost.open( this, account.db_id, account.getFullAcct( who ) + " " );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
@ -534,7 +648,7 @@ public class ActMain extends AppCompatActivity
|
|||
)
|
||||
, request_builder );
|
||||
if( result.object != null ){
|
||||
new_status = TootStatus.parse( log, result.object );
|
||||
new_status = TootStatus.parse( log,account, result.object );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -657,7 +771,7 @@ public class ActMain extends AppCompatActivity
|
|||
// reblog,unreblog のレスポンスは信用ならんのでステータスを再取得する
|
||||
result = client.request( "/api/v1/statuses/" + status.id );
|
||||
if( result.object != null ){
|
||||
new_status = TootStatus.parse( log, result.object );
|
||||
new_status = TootStatus.parse( log, account,result.object );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1239,7 @@ public class ActMain extends AppCompatActivity
|
|||
break;
|
||||
|
||||
case 7:
|
||||
performReport( account, who ,null );
|
||||
performReport( account, who, null );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
sv = intent.getStringExtra( KEY_REPLY_STATUS );
|
||||
if( sv != null ){
|
||||
try{
|
||||
TootStatus repley_status = TootStatus.parse( log, new JSONObject( sv ) );
|
||||
TootStatus repley_status = TootStatus.parse( log, account,new JSONObject( sv ) );
|
||||
|
||||
// CW をリプライ元に合わせる
|
||||
if( ! TextUtils.isEmpty( repley_status.spoiler_text ) ){
|
||||
|
@ -830,7 +830,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
|
||||
TootApiResult result = client.request( "/api/v1/statuses", request_builder );
|
||||
if( result.object != null ){
|
||||
status = TootStatus.parse( log, result.object );
|
||||
status = TootStatus.parse( log, account,result.object );
|
||||
}
|
||||
return result;
|
||||
|
||||
|
@ -879,7 +879,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
llReply.setVisibility( View.GONE );
|
||||
}else{
|
||||
llReply.setVisibility( View.VISIBLE );
|
||||
tvReplyTo.setText( HTMLDecoder.decodeHTML( in_reply_to_text ) );
|
||||
tvReplyTo.setText( HTMLDecoder.decodeHTML( account,in_reply_to_text ) );
|
||||
ivReply.setImageUrl( in_reply_to_image,App1.getImageLoader() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,21 +37,23 @@ public class Column {
|
|||
static final String KEY_TYPE = "type";
|
||||
static final String KEY_WHO_ID = "who_id";
|
||||
static final String KEY_STATUS_ID = "status_id";
|
||||
static final String KEY_HASHTAG = "hashtag";
|
||||
|
||||
static final String KEY_COLUMN_ACCESS = "column_access";
|
||||
static final String KEY_COLUMN_NAME = "column_name";
|
||||
static final String KEY_OLD_INDEX = "old_index";
|
||||
|
||||
final ActMain activity;
|
||||
private final ActMain activity;
|
||||
final SavedAccount access_info;
|
||||
final int type;
|
||||
final long who_id;
|
||||
|
||||
long who_id;
|
||||
long status_id;
|
||||
|
||||
String hashtag;
|
||||
int profile_tab = 0;
|
||||
|
||||
public int scroll_pos;
|
||||
public int scroll_y;
|
||||
int scroll_pos;
|
||||
int scroll_y;
|
||||
|
||||
static final int TYPE_TL_HOME = 1;
|
||||
static final int TYPE_TL_LOCAL = 2;
|
||||
|
@ -61,45 +63,43 @@ public class Column {
|
|||
static final int TYPE_TL_REPORTS = 6;
|
||||
static final int TYPE_TL_NOTIFICATIONS = 7;
|
||||
static final int TYPE_TL_CONVERSATION = 8;
|
||||
static final int TYPE_TL_HASHTAG = 9;
|
||||
|
||||
public Column( ActMain activity, SavedAccount access_info, int type ){
|
||||
this( activity, access_info, type, access_info.id );
|
||||
}
|
||||
|
||||
public Column( ActMain activity, SavedAccount access_info, int type, long who_id, Object... params ){
|
||||
|
||||
Column( ActMain activity, SavedAccount access_info, int type, Object... params ){
|
||||
this.activity = activity;
|
||||
this.access_info = access_info;
|
||||
this.type = type;
|
||||
this.who_id = who_id;
|
||||
if( type == TYPE_TL_CONVERSATION ){
|
||||
if( params==null || params.length < 1 ) throw new IndexOutOfBoundsException( "TYPE_TL_CONVERSATION requires status_id as Long" );
|
||||
if( !( params[0] instanceof Long ) )throw new IllegalArgumentException( "TYPE_TL_CONVERSATION status_id is not Long" );
|
||||
status_id = (Long) params[0];
|
||||
switch(type){
|
||||
case TYPE_TL_CONVERSATION:
|
||||
this.status_id = (Long)getParamAt( params,0 );
|
||||
break;
|
||||
case TYPE_TL_STATUSES:
|
||||
this.who_id = (Long)getParamAt( params,0 );
|
||||
break;
|
||||
case TYPE_TL_HASHTAG:
|
||||
this.hashtag = (String)getParamAt( params,0 );
|
||||
break;
|
||||
}
|
||||
|
||||
startLoading();
|
||||
}
|
||||
|
||||
public Column( ActMain activity, JSONObject src ){
|
||||
this.activity = activity;
|
||||
this.access_info = SavedAccount.loadAccount( log, src.optLong( KEY_ACCOUNT_ROW_ID ) );
|
||||
if( access_info == null ) throw new RuntimeException( "missing account" );
|
||||
this.type = src.optInt( KEY_TYPE );
|
||||
this.who_id = src.optLong( KEY_WHO_ID );
|
||||
this.status_id = src.optLong( KEY_STATUS_ID );
|
||||
startLoading();
|
||||
}
|
||||
|
||||
final AtomicBoolean is_dispose = new AtomicBoolean();
|
||||
|
||||
void dispose(){
|
||||
is_dispose.set( true );
|
||||
}
|
||||
|
||||
public void encodeJSON( JSONObject item, int old_index ) throws JSONException{
|
||||
item.put( KEY_ACCOUNT_ROW_ID, access_info.db_id );
|
||||
item.put( KEY_TYPE, type );
|
||||
item.put( KEY_WHO_ID, who_id );
|
||||
item.put( KEY_STATUS_ID,status_id);
|
||||
|
||||
switch(type){
|
||||
case TYPE_TL_CONVERSATION:
|
||||
item.put( KEY_STATUS_ID,status_id);
|
||||
break;
|
||||
case TYPE_TL_STATUSES:
|
||||
item.put( KEY_WHO_ID, who_id );
|
||||
break;
|
||||
case TYPE_TL_HASHTAG:
|
||||
item.put( KEY_HASHTAG,hashtag );
|
||||
break;
|
||||
}
|
||||
|
||||
// 以下は保存には必要ないが、カラムリスト画面で使う
|
||||
item.put( KEY_COLUMN_ACCESS, access_info.user );
|
||||
|
@ -107,14 +107,44 @@ public class Column {
|
|||
item.put( KEY_OLD_INDEX, old_index );
|
||||
}
|
||||
|
||||
|
||||
Column( ActMain activity, JSONObject src ){
|
||||
this.activity = activity;
|
||||
this.access_info = SavedAccount.loadAccount( log, src.optLong( KEY_ACCOUNT_ROW_ID ) );
|
||||
if( access_info == null ) throw new RuntimeException( "missing account" );
|
||||
this.type = src.optInt( KEY_TYPE );
|
||||
switch(type){
|
||||
case TYPE_TL_CONVERSATION:
|
||||
this.status_id = src.optLong( KEY_STATUS_ID );
|
||||
break;
|
||||
case TYPE_TL_STATUSES:
|
||||
this.who_id = src.optLong( KEY_WHO_ID );
|
||||
break;
|
||||
case TYPE_TL_HASHTAG:
|
||||
this.hashtag = src.optString( KEY_HASHTAG );
|
||||
break;
|
||||
}
|
||||
startLoading();
|
||||
}
|
||||
|
||||
final AtomicBoolean is_dispose = new AtomicBoolean();
|
||||
|
||||
void dispose(){
|
||||
is_dispose.set( true );
|
||||
}
|
||||
|
||||
public String getColumnName(){
|
||||
switch( type ){
|
||||
|
||||
default:
|
||||
return "?";
|
||||
|
||||
case TYPE_TL_HOME:
|
||||
return activity.getString( R.string.home );
|
||||
|
||||
case TYPE_TL_LOCAL:
|
||||
return activity.getString( R.string.local_timeline );
|
||||
|
||||
case TYPE_TL_FEDERATE:
|
||||
return activity.getString( R.string.federate_timeline );
|
||||
|
||||
|
@ -131,12 +161,59 @@ public class Column {
|
|||
|
||||
case TYPE_TL_NOTIFICATIONS:
|
||||
return activity.getString( R.string.notifications );
|
||||
|
||||
case TYPE_TL_CONVERSATION:
|
||||
return activity.getString( R.string.conversation_around,status_id );
|
||||
|
||||
case TYPE_TL_HASHTAG:
|
||||
return activity.getString( R.string.hashtag_of ,hashtag );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Object getParamAt(Object[] params,int idx){
|
||||
if( params == null || idx >= params.length){
|
||||
throw new IndexOutOfBoundsException( "getParamAt idx="+idx );
|
||||
}
|
||||
return params[idx];
|
||||
}
|
||||
|
||||
public boolean isSameSpec( SavedAccount ai, int type, Object[] params ){
|
||||
if( type != this.type || ! Utils.equalsNullable(ai.user,access_info.user ) ) return false;
|
||||
switch( type ){
|
||||
default:
|
||||
return true;
|
||||
|
||||
case TYPE_TL_STATUSES:
|
||||
// プロフィール画面
|
||||
try{
|
||||
long who_id = (Long)getParamAt( params, 0 );
|
||||
return who_id == this.who_id;
|
||||
}catch(Throwable ex){
|
||||
return false;
|
||||
}
|
||||
|
||||
case TYPE_TL_CONVERSATION:
|
||||
// 会話画面
|
||||
try{
|
||||
long status_id = (Long)getParamAt( params, 0 );
|
||||
return status_id == this.status_id;
|
||||
}catch(Throwable ex){
|
||||
return false;
|
||||
}
|
||||
|
||||
case TYPE_TL_HASHTAG:
|
||||
// 会話画面
|
||||
try{
|
||||
long status_id = (Long)getParamAt( params, 0 );
|
||||
return status_id == this.status_id;
|
||||
}catch(Throwable ex){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public interface StatusEntryCallback {
|
||||
void onIterate( TootStatus status );
|
||||
}
|
||||
|
@ -292,7 +369,7 @@ public class Column {
|
|||
TootApiResult parseStatuses( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, true, true );
|
||||
tmp_list_status = TootStatus.parseList( log, result.array );
|
||||
tmp_list_status = TootStatus.parseList( log, access_info,result.array );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -300,7 +377,7 @@ public class Column {
|
|||
TootApiResult parseAccount( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, true, true );
|
||||
who_account = TootAccount.parse( log, result.object );
|
||||
who_account = TootAccount.parse( log, access_info,result.object );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -316,7 +393,7 @@ public class Column {
|
|||
TootApiResult parseNotifications( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, true, true );
|
||||
tmp_list_notification = TootNotification.parseList( log, result.array );
|
||||
tmp_list_notification = TootNotification.parseList( log, access_info,result.array );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -365,6 +442,9 @@ public class Column {
|
|||
|
||||
case TYPE_TL_FAVOURITES:
|
||||
return parseStatuses( client.request( PATH_TL_FAVOURITES ) );
|
||||
|
||||
case TYPE_TL_HASHTAG:
|
||||
return parseStatuses( client.request( "/api/v1/timelines/tag/"+hashtag+"?limit=80" ) );
|
||||
|
||||
case TYPE_TL_REPORTS:
|
||||
return parseReports( client.request( PATH_TL_REPORTS ) );
|
||||
|
@ -375,12 +455,12 @@ public class Column {
|
|||
case TYPE_TL_CONVERSATION:
|
||||
TootApiResult result = client.request( "/api/v1/statuses/"+status_id );
|
||||
if( result== null || result.object == null ) return result;
|
||||
TootStatus target_status = TootStatus.parse( log,result.object );
|
||||
TootStatus target_status = TootStatus.parse( log, access_info,result.object );
|
||||
target_status.conversation_main = true;
|
||||
//
|
||||
result = client.request( "/api/v1/statuses/"+status_id+"/context" );
|
||||
if( result== null || result.object == null ) return result;
|
||||
TootContext context = TootContext.parse( log,result.object );
|
||||
TootContext context = TootContext.parse( log,access_info,result.object );
|
||||
tmp_list_status = new TootStatus.List();
|
||||
if( context.ancestors != null ) tmp_list_status.addAll( context.ancestors);
|
||||
tmp_list_status.add(target_status);
|
||||
|
@ -415,6 +495,7 @@ public class Column {
|
|||
case TYPE_TL_STATUSES:
|
||||
case TYPE_TL_FAVOURITES:
|
||||
case TYPE_TL_CONVERSATION:
|
||||
case TYPE_TL_HASHTAG:
|
||||
initList( status_list, tmp_list_status );
|
||||
break;
|
||||
|
||||
|
@ -526,7 +607,7 @@ public class Column {
|
|||
TootApiResult parseStatuses( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, bBottom, ! bBottom );
|
||||
tmp_list_status = TootStatus.parseList( log, result.array );
|
||||
tmp_list_status = TootStatus.parseList( log, access_info, result.array );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -534,7 +615,7 @@ public class Column {
|
|||
TootApiResult parseAccount( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, bBottom, ! bBottom );
|
||||
who_account = TootAccount.parse( log, result.object );
|
||||
who_account = TootAccount.parse( log, access_info,result.object );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -550,7 +631,7 @@ public class Column {
|
|||
TootApiResult parseNotifications( TootApiResult result ){
|
||||
if( result != null ){
|
||||
saveRange( result, bBottom, ! bBottom );
|
||||
tmp_list_notification = TootNotification.parseList( log, result.array );
|
||||
tmp_list_notification = TootNotification.parseList( log, access_info,result.array );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -600,6 +681,9 @@ public class Column {
|
|||
case TYPE_TL_FAVOURITES:
|
||||
return parseStatuses( client.request( addRange( bBottom, PATH_TL_FAVOURITES ) ) );
|
||||
|
||||
case TYPE_TL_HASHTAG:
|
||||
return parseStatuses( client.request( addRange( bBottom,"/api/v1/timelines/tag/"+hashtag+"?limit=80" ) ) );
|
||||
|
||||
case TYPE_TL_REPORTS:
|
||||
return parseReports( client.request( addRange( bBottom, PATH_TL_REPORTS ) ) );
|
||||
|
||||
|
@ -633,6 +717,7 @@ public class Column {
|
|||
case TYPE_TL_FEDERATE:
|
||||
case TYPE_TL_STATUSES:
|
||||
case TYPE_TL_FAVOURITES:
|
||||
case TYPE_TL_HASHTAG:
|
||||
mergeList( status_list, tmp_list_status, bBottom );
|
||||
break;
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
switch( v.getId() ){
|
||||
case R.id.ivBackground:
|
||||
if( who != null ){
|
||||
activity.openBrowser( who.url );
|
||||
activity.openBrowser( access_info,who.url );
|
||||
}
|
||||
break;
|
||||
case R.id.btnFollowing:
|
||||
|
@ -433,7 +433,7 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
final ImageButton btnMore;
|
||||
|
||||
TootStatus status;
|
||||
SavedAccount account;
|
||||
SavedAccount access_info;
|
||||
TootAccount account_thumbnail;
|
||||
TootAccount account_boost;
|
||||
TootAccount account_follow;
|
||||
|
@ -508,7 +508,7 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
}
|
||||
|
||||
public void bind( ActMain activity, View view, Object item, SavedAccount access_info ){
|
||||
this.account = access_info;
|
||||
this.access_info = access_info;
|
||||
|
||||
llBoosted.setVisibility( View.GONE );
|
||||
llFollow.setVisibility( View.GONE );
|
||||
|
@ -696,11 +696,11 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
public void onClick( View v ){
|
||||
switch( v.getId() ){
|
||||
case R.id.btnHideMedia:
|
||||
MediaShown.save( account.host, status.id, false );
|
||||
MediaShown.save( access_info.host, status.id, false );
|
||||
btnShowMedia.setVisibility( View.VISIBLE );
|
||||
break;
|
||||
case R.id.btnShowMedia:
|
||||
MediaShown.save( account.host, status.id, true );
|
||||
MediaShown.save( access_info.host, status.id, true );
|
||||
btnShowMedia.setVisibility( View.GONE );
|
||||
break;
|
||||
case R.id.ivMedia1:
|
||||
|
@ -717,37 +717,37 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
break;
|
||||
case R.id.btnContentWarning:{
|
||||
boolean new_shown = ( llContents.getVisibility() == View.GONE );
|
||||
ContentWarning.save( account.host, status.id, new_shown );
|
||||
ContentWarning.save( access_info.host, status.id, new_shown );
|
||||
showContent( new_shown );
|
||||
break;
|
||||
}
|
||||
|
||||
case R.id.btnConversation:
|
||||
activity.performConversation( account, status );
|
||||
activity.performConversation( access_info, status );
|
||||
break;
|
||||
case R.id.btnReply:
|
||||
activity.performReply( account, status );
|
||||
activity.performReply( access_info, status );
|
||||
break;
|
||||
case R.id.btnBoost:
|
||||
activity.performBoost( account, status, false );
|
||||
activity.performBoost( access_info, status, false );
|
||||
break;
|
||||
case R.id.btnFavourite:
|
||||
activity.performFavourite( account, status );
|
||||
activity.performFavourite( access_info, status );
|
||||
break;
|
||||
case R.id.btnMore:
|
||||
activity.performStatusMore( account, status );
|
||||
activity.performStatusMore( access_info, status );
|
||||
break;
|
||||
case R.id.ivThumbnail:
|
||||
activity.performOpenUser( account, account_thumbnail );
|
||||
activity.performOpenUser( access_info, account_thumbnail );
|
||||
break;
|
||||
case R.id.llBoosted:
|
||||
activity.performOpenUser( account, account_boost );
|
||||
activity.performOpenUser( access_info, account_boost );
|
||||
break;
|
||||
case R.id.llFollow:
|
||||
activity.performOpenUser( account, account_follow );
|
||||
activity.performOpenUser( access_info, account_follow );
|
||||
break;
|
||||
case R.id.btnFollow:
|
||||
activity.performAccountMore( account,account_follow);
|
||||
activity.performAccountMore( access_info,account_follow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,14 +759,14 @@ public class ColumnViewHolder implements View.OnClickListener, Column.VisualCall
|
|||
if( TextUtils.isEmpty( sv ) ){
|
||||
sv = a.url;
|
||||
}
|
||||
activity.openChromeTab( sv );
|
||||
activity.openChromeTab( access_info,sv ,false);
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void onItemClick(){
|
||||
activity.performConversation( account, status );
|
||||
activity.performConversation( access_info, status );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package jp.juggler.subwaytooter.api.entity;
|
|||
import android.text.Spannable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import jp.juggler.subwaytooter.table.SavedAccount;
|
||||
import jp.juggler.subwaytooter.util.Emojione;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
@ -11,6 +12,7 @@ import org.json.JSONObject;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import jp.juggler.subwaytooter.util.HTMLDecoder;
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
import jp.juggler.subwaytooter.util.Utils;
|
||||
|
||||
|
@ -70,7 +72,7 @@ public class TootAccount {
|
|||
|
||||
public long time_created_at;
|
||||
|
||||
public static TootAccount parse( LogCategory log, JSONObject src, TootAccount dst ){
|
||||
public static TootAccount parse( LogCategory log, LinkClickContext account, JSONObject src, TootAccount dst ){
|
||||
if( src == null ) return null;
|
||||
try{
|
||||
dst.id = src.optLong( "id" );
|
||||
|
@ -89,7 +91,7 @@ public class TootAccount {
|
|||
dst.followers_count = src.optLong( "followers_count" );
|
||||
dst.following_count = src.optLong( "following_count" );
|
||||
dst.statuses_count = src.optLong( "statuses_count" );
|
||||
dst.note = HTMLDecoder.decodeHTML( Utils.optStringX( src, "note" ) );
|
||||
dst.note = HTMLDecoder.decodeHTML( account,Utils.optStringX( src, "note" ) );
|
||||
dst.url = Utils.optStringX( src, "url" );
|
||||
dst.avatar = Utils.optStringX( src, "avatar" ); // "https:\/\/mastodon.juggler.jp\/system\/accounts\/avatars\/000\/000\/148\/original\/0a468974fac5a448.PNG?1492081886",
|
||||
dst.avatar_static = Utils.optStringX( src, "avatar_static" ); // "https:\/\/mastodon.juggler.jp\/system\/accounts\/avatars\/000\/000\/148\/original\/0a468974fac5a448.PNG?1492081886",
|
||||
|
@ -107,17 +109,17 @@ public class TootAccount {
|
|||
}
|
||||
}
|
||||
|
||||
public static TootAccount parse( LogCategory log, JSONObject src ){
|
||||
return parse( log, src, new TootAccount() );
|
||||
public static TootAccount parse( LogCategory log, LinkClickContext account,JSONObject src ){
|
||||
return parse( log, account, src, new TootAccount() );
|
||||
}
|
||||
|
||||
public static List parseList( LogCategory log, JSONArray array ){
|
||||
public static List parseList( LogCategory log, LinkClickContext account,JSONArray array ){
|
||||
List result = new List();
|
||||
if( array != null ){
|
||||
for( int i = array.length() - 1 ; i >= 0 ; -- i ){
|
||||
JSONObject src = array.optJSONObject( i );
|
||||
if( src == null ) continue;
|
||||
TootAccount item = parse( log, src );
|
||||
TootAccount item = parse( log, account,src );
|
||||
if( item != null ) result.add( 0, item );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package jp.juggler.subwaytooter.api.entity;
|
|||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
|
||||
public class TootContext {
|
||||
|
@ -12,12 +13,12 @@ public class TootContext {
|
|||
// descendants The descendants of the status in the conversation, as a list of Statuses
|
||||
public TootStatus.List descendants;
|
||||
|
||||
public static TootContext parse( LogCategory log, JSONObject src ){
|
||||
public static TootContext parse( LogCategory log, LinkClickContext account,JSONObject src ){
|
||||
if( src==null) return null;
|
||||
try{
|
||||
TootContext dst = new TootContext();
|
||||
dst.ancestors = TootStatus.parseList( log,src.optJSONArray( "ancestors" ) );
|
||||
dst.descendants = TootStatus.parseList(log, src.optJSONArray( "descendants" ) );
|
||||
dst.ancestors = TootStatus.parseList( log, account,src.optJSONArray( "ancestors" ) );
|
||||
dst.descendants = TootStatus.parseList(log, account, src.optJSONArray( "descendants" ) );
|
||||
return dst;
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace();
|
||||
|
|
|
@ -5,6 +5,7 @@ import org.json.JSONObject;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
import jp.juggler.subwaytooter.util.Utils;
|
||||
|
||||
|
@ -32,15 +33,15 @@ public class TootNotification extends TootId {
|
|||
|
||||
public long time_created_at;
|
||||
|
||||
public static TootNotification parse( LogCategory log, JSONObject src ){
|
||||
public static TootNotification parse( LogCategory log, LinkClickContext accopunt, JSONObject src ){
|
||||
if( src == null ) return null;
|
||||
try{
|
||||
TootNotification dst = new TootNotification();
|
||||
dst.id = src.optLong( "id" );
|
||||
dst.type = Utils.optStringX( src, "type" );
|
||||
dst.created_at = Utils.optStringX( src, "created_at" );
|
||||
dst.account = TootAccount.parse( log, src.optJSONObject( "account" ) );
|
||||
dst.status = TootStatus.parse( log, src.optJSONObject( "status" ) );
|
||||
dst.account = TootAccount.parse( log, accopunt, src.optJSONObject( "account" ) );
|
||||
dst.status = TootStatus.parse( log, accopunt, src.optJSONObject( "status" ) );
|
||||
|
||||
dst.time_created_at = TootStatus.parseTime( log, dst.created_at );
|
||||
|
||||
|
@ -62,13 +63,13 @@ public class TootNotification extends TootId {
|
|||
}
|
||||
}
|
||||
|
||||
public static List parseList( LogCategory log, JSONArray array ){
|
||||
public static List parseList( LogCategory log, LinkClickContext accopunt,JSONArray array ){
|
||||
List result = new List();
|
||||
if( array != null ){
|
||||
for( int i = array.length() - 1 ; i >= 0 ; -- i ){
|
||||
JSONObject src = array.optJSONObject( i );
|
||||
if( src == null ) continue;
|
||||
TootNotification item = parse( log, src );
|
||||
TootNotification item = parse( log, accopunt,src );
|
||||
if( item != null ) result.add( 0, item );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.json.JSONObject;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
import jp.juggler.subwaytooter.util.Utils;
|
||||
|
||||
|
@ -17,12 +18,12 @@ public class TootResults {
|
|||
// An array of matched hashtags, as strings
|
||||
public ArrayList< String > hashtags;
|
||||
|
||||
public static TootResults parse( LogCategory log, JSONObject src ){
|
||||
public static TootResults parse( LogCategory log, LinkClickContext account,JSONObject src ){
|
||||
if( src == null ) return null;
|
||||
try{
|
||||
TootResults dst = new TootResults();
|
||||
dst.accounts = TootAccount.parseList( log, src.optJSONArray( "accounts" ) );
|
||||
dst.statuses = TootStatus.parseList( log, src.optJSONArray( "statuses" ) );
|
||||
dst.accounts = TootAccount.parseList( log, account, src.optJSONArray( "accounts" ) );
|
||||
dst.statuses = TootStatus.parseList( log, account, src.optJSONArray( "statuses" ) );
|
||||
dst.hashtags = Utils.parseStringArray( log, src.optJSONArray( "hashtags" ) );
|
||||
return dst;
|
||||
}catch( Throwable ex ){
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Locale;
|
|||
import java.util.TimeZone;
|
||||
|
||||
import jp.juggler.subwaytooter.util.HTMLDecoder;
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
import jp.juggler.subwaytooter.util.Utils;
|
||||
|
||||
|
@ -104,7 +105,7 @@ public class TootStatus extends TootId {
|
|||
|
||||
public boolean conversation_main;
|
||||
|
||||
public static TootStatus parse( LogCategory log, JSONObject src ){
|
||||
public static TootStatus parse( LogCategory log, LinkClickContext account, JSONObject src ){
|
||||
|
||||
if( src == null ) return null;
|
||||
|
||||
|
@ -115,10 +116,10 @@ public class TootStatus extends TootId {
|
|||
status.id = src.optLong( "id" );
|
||||
status.uri = Utils.optStringX( src, "uri" );
|
||||
status.url = Utils.optStringX( src, "url" );
|
||||
status.account = TootAccount.parse( log, src.optJSONObject( "account" ) );
|
||||
status.account = TootAccount.parse( log, account,src.optJSONObject( "account" ) );
|
||||
status.in_reply_to_id = Utils.optStringX( src, "in_reply_to_id" ); // null
|
||||
status.in_reply_to_account_id = Utils.optStringX( src, "in_reply_to_account_id" ); // null
|
||||
status.reblog = TootStatus.parse( log, src.optJSONObject( "reblog" ) );
|
||||
status.reblog = TootStatus.parse( log, account,src.optJSONObject( "reblog" ) );
|
||||
status.content = Utils.optStringX( src, "content" );
|
||||
status.created_at = Utils.optStringX( src, "created_at" ); // "2017-04-16T09:37:14.000Z"
|
||||
status.reblogs_count = src.optLong( "reblogs_count" );
|
||||
|
@ -134,9 +135,9 @@ public class TootStatus extends TootId {
|
|||
status.application = Utils.optStringX( src, "application" ); // null
|
||||
|
||||
status.time_created_at = parseTime( log, status.created_at );
|
||||
status.decoded_content = HTMLDecoder.decodeHTML( status.content );
|
||||
status.decoded_tags = HTMLDecoder.decodeTags( status.tags );
|
||||
status.decoded_mentions = HTMLDecoder.decodeMentions( status.mentions );
|
||||
status.decoded_content = HTMLDecoder.decodeHTML( account,status.content );
|
||||
status.decoded_tags = HTMLDecoder.decodeTags( account,status.tags );
|
||||
status.decoded_mentions = HTMLDecoder.decodeMentions(account, status.mentions );
|
||||
|
||||
return status;
|
||||
}catch( Throwable ex ){
|
||||
|
@ -146,13 +147,13 @@ public class TootStatus extends TootId {
|
|||
}
|
||||
}
|
||||
|
||||
public static List parseList( LogCategory log, JSONArray array ){
|
||||
public static List parseList( LogCategory log, LinkClickContext account,JSONArray array ){
|
||||
List result = new List();
|
||||
if( array != null ){
|
||||
for( int i = array.length() - 1 ; i >= 0 ; -- i ){
|
||||
JSONObject src = array.optJSONObject( i );
|
||||
if( src == null ) continue;
|
||||
TootStatus item = parse( log, src );
|
||||
TootStatus item = parse( log,account, src );
|
||||
if( item != null ) result.add( 0, item );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,10 @@ import java.util.ArrayList;
|
|||
|
||||
import jp.juggler.subwaytooter.App1;
|
||||
import jp.juggler.subwaytooter.api.entity.TootAccount;
|
||||
import jp.juggler.subwaytooter.util.LinkClickContext;
|
||||
import jp.juggler.subwaytooter.util.LogCategory;
|
||||
|
||||
public class SavedAccount extends TootAccount{
|
||||
public class SavedAccount extends TootAccount implements LinkClickContext{
|
||||
private static final LogCategory log = new LogCategory( "SavedAccount" );
|
||||
|
||||
private static final String table = "access_info";
|
||||
|
@ -63,7 +64,8 @@ public class SavedAccount extends TootAccount{
|
|||
|
||||
private static SavedAccount parse( Cursor cursor ) throws JSONException{
|
||||
JSONObject src = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_ACCOUNT ) ) );
|
||||
SavedAccount dst = (SavedAccount)parse(log,src,new SavedAccount());
|
||||
SavedAccount dst = new SavedAccount();
|
||||
dst = (SavedAccount)parse(log,dst,src,dst);
|
||||
if( dst != null){
|
||||
dst.db_id = cursor.getLong( cursor.getColumnIndex( COL_ID ) );
|
||||
dst.host = cursor.getString( cursor.getColumnIndex( COL_HOST ) );
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import jp.juggler.subwaytooter.api.entity.TootMention;
|
||||
import jp.juggler.subwaytooter.api.entity.TootTag;
|
||||
import jp.juggler.subwaytooter.table.SavedAccount;
|
||||
|
||||
public class HTMLDecoder {
|
||||
static final LogCategory log = new LogCategory( "HTMLDecoder" );
|
||||
|
@ -81,6 +82,7 @@ public class HTMLDecoder {
|
|||
is_openclose = ! TextUtils.isEmpty( m2.group( 1 ) );
|
||||
}
|
||||
open_type = is_close ? OPEN_TYPE_CLOSE : is_openclose ? OPEN_TYPE_OPENCLOSE : OPEN_TYPE_OPEN;
|
||||
if( tag.equals( "br" )) open_type = OPEN_TYPE_OPENCLOSE;
|
||||
}else{
|
||||
tag = TAG_TEXT;
|
||||
this.open_type = OPEN_TYPE_OPENCLOSE;
|
||||
|
@ -89,7 +91,7 @@ public class HTMLDecoder {
|
|||
}
|
||||
|
||||
public interface LinkClickCallback {
|
||||
void onClickLink( String url );
|
||||
void onClickLink( LinkClickContext account,String url );
|
||||
}
|
||||
|
||||
public static LinkClickCallback link_callback;
|
||||
|
@ -139,7 +141,7 @@ public class HTMLDecoder {
|
|||
|
||||
|
||||
|
||||
public void encodeSpan( SpannableStringBuilder sb ){
|
||||
public void encodeSpan( final LinkClickContext account,SpannableStringBuilder sb ){
|
||||
if( TAG_TEXT.equals( tag ) ){
|
||||
sb.append( Emojione.decodeEmoji( decodeEntity( text ) ) );
|
||||
return;
|
||||
|
@ -149,7 +151,7 @@ public class HTMLDecoder {
|
|||
int start = sb.length();
|
||||
|
||||
for( Node child : child_nodes ){
|
||||
child.encodeSpan( sb );
|
||||
child.encodeSpan( account,sb );
|
||||
}
|
||||
|
||||
if( "a".equals( tag ) ){
|
||||
|
@ -161,7 +163,7 @@ public class HTMLDecoder {
|
|||
@Override
|
||||
public void onClick( View widget ){
|
||||
if( link_callback != null ){
|
||||
link_callback.onClickLink( href );
|
||||
link_callback.onClickLink( account,href );
|
||||
}
|
||||
}
|
||||
}, start, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
|
||||
|
@ -180,7 +182,7 @@ public class HTMLDecoder {
|
|||
|
||||
|
||||
|
||||
public static SpannableStringBuilder decodeHTML( String src ){
|
||||
public static SpannableStringBuilder decodeHTML( LinkClickContext account, String src ){
|
||||
try{
|
||||
TokenParser tracker = new TokenParser( src );
|
||||
Node rootNode = new Node();
|
||||
|
@ -188,13 +190,15 @@ public class HTMLDecoder {
|
|||
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||
|
||||
rootNode.encodeSpan( sb );
|
||||
rootNode.encodeSpan( account, sb );
|
||||
int end = sb.length();
|
||||
while( end > 0 && Character.isWhitespace( sb.charAt( end-1 ) ) ) --end;
|
||||
if( end < sb.length() ){
|
||||
sb.delete( end,sb.length() );
|
||||
}
|
||||
|
||||
// sb.append( "\n" );
|
||||
// sb.append( src );
|
||||
return sb;
|
||||
|
||||
}catch( Throwable ex ){
|
||||
|
@ -203,7 +207,7 @@ public class HTMLDecoder {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static Spannable decodeTags( TootTag.List src_list ){
|
||||
public static Spannable decodeTags( final LinkClickContext account,TootTag.List src_list ){
|
||||
if( src_list == null || src_list.isEmpty()) return null;
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||
for(TootTag item : src_list){
|
||||
|
@ -215,7 +219,7 @@ public class HTMLDecoder {
|
|||
sb.setSpan( new ClickableSpan() {
|
||||
@Override public void onClick( View widget ){
|
||||
if( link_callback != null ){
|
||||
link_callback.onClickLink( item_url );
|
||||
link_callback.onClickLink( account,item_url );
|
||||
}
|
||||
}
|
||||
}, start, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
|
||||
|
@ -223,7 +227,7 @@ public class HTMLDecoder {
|
|||
return sb;
|
||||
}
|
||||
|
||||
public static Spannable decodeMentions( TootMention.List src_list ){
|
||||
public static Spannable decodeMentions( final LinkClickContext account, TootMention.List src_list ){
|
||||
if( src_list == null || src_list.isEmpty()) return null;
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||
for(TootMention item : src_list){
|
||||
|
@ -235,7 +239,7 @@ public class HTMLDecoder {
|
|||
sb.setSpan( new ClickableSpan() {
|
||||
@Override public void onClick( View widget ){
|
||||
if( link_callback != null ){
|
||||
link_callback.onClickLink( item_url );
|
||||
link_callback.onClickLink( account,item_url );
|
||||
}
|
||||
}
|
||||
}, start, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package jp.juggler.subwaytooter.util;
|
||||
|
||||
/**
|
||||
* Created by tateisu on 2017/04/24.
|
||||
*/
|
||||
|
||||
public interface LinkClickContext {
|
||||
}
|
|
@ -175,6 +175,10 @@ public class Utils {
|
|||
return dst_list;
|
||||
}
|
||||
|
||||
public static <T> boolean equalsNullable(T a,T b){
|
||||
return a == null ? b == null : a.equals( b );
|
||||
}
|
||||
|
||||
static final char[] hex = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
|
||||
public static void addHex( StringBuilder sb, byte b ){
|
||||
|
|
|
@ -149,4 +149,9 @@
|
|||
<string name="comment_empty">please comment for any reason to report</string>
|
||||
<string name="report_completed">report completed.</string>
|
||||
<string name="mention">mention</string>
|
||||
<string name="hashtag_of">hashtag :#%1$s</string>
|
||||
<string name="open_in_account">open with %1$s</string>
|
||||
<string name="open_in_browser"/>
|
||||
<string name="open_web_page">open web page</string>
|
||||
<string name="open_web_on_host">open web page on %1$s</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue