2017-04-20 18:23:59 +02:00
|
|
|
package jp.juggler.subwaytooter;
|
|
|
|
|
|
|
|
import android.app.Dialog;
|
|
|
|
import android.app.ProgressDialog;
|
|
|
|
import android.content.DialogInterface;
|
2017-04-23 07:42:09 +02:00
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.SharedPreferences;
|
2017-04-21 14:45:40 +02:00
|
|
|
import android.net.Uri;
|
2017-04-20 18:23:59 +02:00
|
|
|
import android.os.AsyncTask;
|
|
|
|
import android.os.Bundle;
|
2017-04-21 14:45:40 +02:00
|
|
|
import android.support.customtabs.CustomTabsIntent;
|
2017-04-20 18:23:59 +02:00
|
|
|
import android.support.design.widget.FloatingActionButton;
|
2017-04-21 14:45:40 +02:00
|
|
|
import android.support.v4.content.ContextCompat;
|
2017-04-20 18:23:59 +02:00
|
|
|
import android.support.v4.os.AsyncTaskCompat;
|
|
|
|
import android.support.v4.view.ViewPager;
|
2017-04-22 16:45:26 +02:00
|
|
|
import android.support.v7.app.AlertDialog;
|
2017-04-21 14:45:40 +02:00
|
|
|
import android.view.Gravity;
|
2017-04-20 18:23:59 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.support.design.widget.NavigationView;
|
|
|
|
import android.support.v4.view.GravityCompat;
|
|
|
|
import android.support.v4.widget.DrawerLayout;
|
|
|
|
import android.support.v7.app.AppCompatActivity;
|
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
2017-04-21 14:45:40 +02:00
|
|
|
import android.view.Window;
|
|
|
|
|
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.FileNotFoundException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.io.OutputStream;
|
2017-04-23 07:42:09 +02:00
|
|
|
import java.util.ArrayList;
|
2017-04-23 20:05:29 +02:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Comparator;
|
2017-04-22 16:45:26 +02:00
|
|
|
import java.util.HashSet;
|
2017-04-23 20:05:29 +02:00
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
import jp.juggler.subwaytooter.api.TootApiClient;
|
|
|
|
import jp.juggler.subwaytooter.api.TootApiResult;
|
2017-04-21 14:45:40 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootAccount;
|
2017-04-24 13:04:56 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootRelationShip;
|
2017-04-22 16:45:26 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootStatus;
|
2017-04-20 18:23:59 +02:00
|
|
|
import jp.juggler.subwaytooter.dialog.AccountPicker;
|
|
|
|
import jp.juggler.subwaytooter.dialog.LoginForm;
|
2017-04-23 17:16:05 +02:00
|
|
|
import jp.juggler.subwaytooter.dialog.ReportForm;
|
2017-04-20 18:23:59 +02:00
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount;
|
2017-04-23 23:12:11 +02:00
|
|
|
import jp.juggler.subwaytooter.util.ActionsDialog;
|
2017-04-21 14:45:40 +02:00
|
|
|
import jp.juggler.subwaytooter.util.HTMLDecoder;
|
2017-04-23 20:05:29 +02:00
|
|
|
import jp.juggler.subwaytooter.util.LinkClickContext;
|
2017-04-20 18:23:59 +02:00
|
|
|
import jp.juggler.subwaytooter.util.LogCategory;
|
|
|
|
import jp.juggler.subwaytooter.util.Utils;
|
2017-04-22 16:45:26 +02:00
|
|
|
import okhttp3.Request;
|
|
|
|
import okhttp3.RequestBody;
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
public class ActMain extends AppCompatActivity
|
|
|
|
implements NavigationView.OnNavigationItemSelectedListener {
|
|
|
|
public static final LogCategory log = new LogCategory( "ActMain" );
|
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
static boolean update_at_resume = false;
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
// @Override
|
|
|
|
// protected void attachBaseContext(Context newBase) {
|
|
|
|
// super.attachBaseContext( CalligraphyContextWrapper.wrap(newBase));
|
|
|
|
// }
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
SharedPreferences pref;
|
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
@Override
|
|
|
|
protected void onCreate( Bundle savedInstanceState ){
|
|
|
|
super.onCreate( savedInstanceState );
|
2017-04-21 14:45:40 +02:00
|
|
|
requestWindowFeature( Window.FEATURE_NO_TITLE );
|
2017-04-20 18:23:59 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
pref = Pref.pref( this );
|
2017-04-23 07:42:09 +02:00
|
|
|
|
2017-04-21 14:45:40 +02:00
|
|
|
initUI();
|
|
|
|
loadColumnList();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onDestroy(){
|
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onResume(){
|
|
|
|
super.onResume();
|
|
|
|
HTMLDecoder.link_callback = link_click_listener;
|
2017-04-22 16:45:26 +02:00
|
|
|
|
|
|
|
// アカウント設定から戻ってきたら、カラムを消す必要があるかもしれない
|
2017-04-23 15:08:22 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
ArrayList< Integer > new_order = new ArrayList<>();
|
|
|
|
boolean bRemoved = false;
|
|
|
|
for( int i = 0, ie = pager_adapter.getCount() ; i < ie ; ++ i ){
|
|
|
|
Column column = pager_adapter.getColumn( i );
|
|
|
|
SavedAccount sa = SavedAccount.loadAccount( log, column.access_info.db_id );
|
|
|
|
if( sa == null ){
|
|
|
|
bRemoved = true;
|
|
|
|
}else{
|
|
|
|
new_order.add( i );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( bRemoved ){
|
|
|
|
pager_adapter.setOrder( pager, new_order );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-23 21:09:59 +02:00
|
|
|
// 各カラムのアカウント設定を読み直す
|
|
|
|
{
|
|
|
|
ArrayList< SavedAccount > done_list = new ArrayList<>();
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
|
|
|
SavedAccount a = column.access_info;
|
2017-04-23 23:12:11 +02:00
|
|
|
if( a == null || done_list.contains( a ) ) continue;
|
2017-04-23 21:09:59 +02:00
|
|
|
done_list.add( a );
|
|
|
|
a.reloadSetting();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
if( update_at_resume ){
|
2017-04-22 16:45:26 +02:00
|
|
|
update_at_resume = false;
|
|
|
|
// TODO: 各カラムを更新する
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
if( pager_adapter.getCount() == 0 ){
|
2017-04-22 16:45:26 +02:00
|
|
|
llEmpty.setVisibility( View.VISIBLE );
|
|
|
|
}
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPause(){
|
|
|
|
HTMLDecoder.link_callback = null;
|
|
|
|
saveColumnList();
|
|
|
|
super.onPause();
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
static final int REQUEST_CODE_COLUMN_LIST = 1;
|
2017-04-23 07:42:09 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
boolean isOrderChanged( ArrayList< Integer > new_order ){
|
2017-04-23 15:08:22 +02:00
|
|
|
if( new_order.size() != pager_adapter.getCount() ) return true;
|
2017-04-23 17:16:05 +02:00
|
|
|
for( int i = 0, ie = new_order.size() ; i < ie ; ++ i ){
|
|
|
|
if( new_order.get( i ) != i ) return true;
|
2017-04-23 15:08:22 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
@Override
|
|
|
|
protected void onActivityResult( int requestCode, int resultCode, Intent data ){
|
|
|
|
if( resultCode == RESULT_OK && requestCode == REQUEST_CODE_COLUMN_LIST ){
|
|
|
|
if( data != null ){
|
2017-04-23 17:16:05 +02:00
|
|
|
ArrayList< Integer > order = data.getIntegerArrayListExtra( ActColumnList.EXTRA_ORDER );
|
|
|
|
if( order != null && isOrderChanged( order ) ){
|
2017-04-23 07:42:09 +02:00
|
|
|
pager_adapter.setOrder( pager, order );
|
|
|
|
}
|
2017-04-23 15:08:22 +02:00
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
if( pager_adapter.column_list.isEmpty() ){
|
|
|
|
llEmpty.setVisibility( View.VISIBLE );
|
2017-04-23 15:08:22 +02:00
|
|
|
}else{
|
|
|
|
int select = data.getIntExtra( ActColumnList.EXTRA_SELECTION, - 1 );
|
|
|
|
if( select != - 1 ){
|
|
|
|
pager.setCurrentItem( select, true );
|
|
|
|
}
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
super.onActivityResult( requestCode, resultCode, data );
|
|
|
|
}
|
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
@Override
|
|
|
|
public void onBackPressed(){
|
|
|
|
DrawerLayout drawer = (DrawerLayout) findViewById( R.id.drawer_layout );
|
|
|
|
if( drawer.isDrawerOpen( GravityCompat.START ) ){
|
|
|
|
drawer.closeDrawer( GravityCompat.START );
|
2017-04-23 17:16:05 +02:00
|
|
|
}else if( pref.getBoolean( Pref.KEY_BACK_TO_COLUMN_LIST, false ) ){
|
2017-04-23 07:42:09 +02:00
|
|
|
performColumnList();
|
2017-04-22 16:45:26 +02:00
|
|
|
}else if( ! pager_adapter.column_list.isEmpty() ){
|
2017-04-23 17:16:05 +02:00
|
|
|
performColumnClose( false, pager_adapter.getColumn( pager.getCurrentItem() ) );
|
2017-04-20 18:23:59 +02:00
|
|
|
}else{
|
|
|
|
super.onBackPressed();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu( Menu menu ){
|
|
|
|
// Inflate the menu; this adds items to the action bar if it is present.
|
|
|
|
getMenuInflater().inflate( R.menu.act_main, menu );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected( MenuItem item ){
|
|
|
|
// Handle action bar item clicks here. The action bar will
|
|
|
|
// automatically handle clicks on the Home/Up button, so long
|
|
|
|
// as you specify a parent activity in AndroidManifest.xml.
|
|
|
|
int id = item.getItemId();
|
|
|
|
|
|
|
|
//noinspection SimplifiableIfStatement
|
|
|
|
if( id == R.id.action_settings ){
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.onOptionsItemSelected( item );
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("StatementWithEmptyBody")
|
|
|
|
@Override
|
|
|
|
public boolean onNavigationItemSelected( MenuItem item ){
|
|
|
|
// Handle navigation view item clicks here.
|
|
|
|
int id = item.getItemId();
|
|
|
|
|
|
|
|
if( id == R.id.nav_account_add ){
|
|
|
|
performAccountAdd();
|
|
|
|
}else if( id == R.id.nav_add_tl_home ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_HOME );
|
2017-04-20 18:23:59 +02:00
|
|
|
}else if( id == R.id.nav_add_tl_local ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_LOCAL );
|
2017-04-20 18:23:59 +02:00
|
|
|
}else if( id == R.id.nav_add_tl_federate ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_FEDERATE );
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
}else if( id == R.id.nav_add_favourites ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_FAVOURITES );
|
2017-04-20 18:23:59 +02:00
|
|
|
// }else if( id == R.id.nav_add_reports ){
|
2017-04-24 06:01:59 +02:00
|
|
|
// performAddTimeline(Column.TYPE_REPORTS );
|
2017-04-20 18:23:59 +02:00
|
|
|
}else if( id == R.id.nav_add_statuses ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_PROFILE );
|
2017-04-20 18:23:59 +02:00
|
|
|
}else if( id == R.id.nav_add_notifications ){
|
2017-04-24 06:01:59 +02:00
|
|
|
performAddTimeline( Column.TYPE_NOTIFICATIONS );
|
2017-04-20 18:23:59 +02:00
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
}else if( id == R.id.nav_app_setting ){
|
2017-04-23 17:16:05 +02:00
|
|
|
performAppSetting();
|
2017-04-22 16:45:26 +02:00
|
|
|
}else if( id == R.id.nav_account_setting ){
|
|
|
|
performAccountSetting();
|
|
|
|
}else if( id == R.id.nav_column_list ){
|
|
|
|
performColumnList();
|
|
|
|
|
2017-04-24 08:18:54 +02:00
|
|
|
}else if( id == R.id.nav_add_tl_search ){
|
|
|
|
performAddTimeline( Column.TYPE_SEARCH );
|
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
}else if( id == R.id.nav_app_about ){
|
|
|
|
openAppAbout();
|
2017-04-24 08:18:54 +02:00
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
}else if( id == R.id.nav_oss_license ){
|
|
|
|
openOSSLicense( );
|
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
// Handle the camera action
|
|
|
|
// }else if( id == R.id.nav_gallery ){
|
|
|
|
//
|
|
|
|
// }else if( id == R.id.nav_slideshow ){
|
|
|
|
//
|
|
|
|
// }else if( id == R.id.nav_manage ){
|
|
|
|
//
|
|
|
|
// }else if( id == R.id.nav_share ){
|
|
|
|
//
|
|
|
|
// }else if( id == R.id.nav_send ){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawerLayout drawer = (DrawerLayout) findViewById( R.id.drawer_layout );
|
|
|
|
drawer.closeDrawer( GravityCompat.START );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
ViewPager pager;
|
|
|
|
ColumnPagerAdapter pager_adapter;
|
|
|
|
View llEmpty;
|
|
|
|
|
|
|
|
void initUI(){
|
|
|
|
setContentView( R.layout.act_main );
|
|
|
|
llEmpty = findViewById( R.id.llEmpty );
|
2017-04-21 14:45:40 +02:00
|
|
|
|
|
|
|
// // toolbar
|
|
|
|
// Toolbar toolbar = (Toolbar) findViewById( R.id.toolbar );
|
|
|
|
// setSupportActionBar( toolbar );
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
// navigation drawer
|
2017-04-21 14:45:40 +02:00
|
|
|
final DrawerLayout drawer = (DrawerLayout) findViewById( R.id.drawer_layout );
|
|
|
|
// ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
|
|
|
// this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close );
|
|
|
|
// drawer.addDrawerListener( toggle );
|
|
|
|
// toggle.syncState();
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
NavigationView navigationView = (NavigationView) findViewById( R.id.nav_view );
|
|
|
|
navigationView.setNavigationItemSelectedListener( this );
|
|
|
|
|
|
|
|
// floating action button
|
2017-04-21 14:45:40 +02:00
|
|
|
FloatingActionButton fabToot = (FloatingActionButton) findViewById( R.id.fabToot );
|
|
|
|
fabToot.setOnClickListener( new View.OnClickListener() {
|
2017-04-20 18:23:59 +02:00
|
|
|
@Override
|
|
|
|
public void onClick( View view ){
|
2017-04-21 14:45:40 +02:00
|
|
|
performTootButton();
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
// floating action button
|
|
|
|
FloatingActionButton fabMenu = (FloatingActionButton) findViewById( R.id.fabMenu );
|
|
|
|
fabMenu.setOnClickListener( new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick( View view ){
|
2017-04-22 16:45:26 +02:00
|
|
|
if( ! drawer.isDrawerOpen( Gravity.START ) ){
|
|
|
|
drawer.openDrawer( Gravity.START );
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
// ViewPager
|
|
|
|
pager = (ViewPager) findViewById( R.id.viewPager );
|
|
|
|
pager_adapter = new ColumnPagerAdapter( this );
|
|
|
|
pager.setAdapter( pager_adapter );
|
|
|
|
}
|
|
|
|
|
|
|
|
public void performAccountAdd(){
|
2017-04-23 17:16:05 +02:00
|
|
|
LoginForm.showLoginForm( this, null, new LoginForm.LoginFormCallback() {
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
@Override
|
2017-04-21 14:45:40 +02:00
|
|
|
public void startLogin( final Dialog dialog, final String instance, final String user_mail, final String password ){
|
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
final ProgressDialog progress = new ProgressDialog( ActMain.this );
|
2017-04-21 14:45:40 +02:00
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
final AsyncTask< Void, String, TootApiResult > task = new AsyncTask< Void, String, TootApiResult >() {
|
2017-04-21 14:45:40 +02:00
|
|
|
|
|
|
|
long row_id;
|
2017-04-20 18:23:59 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient api_client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
2017-04-22 16:45:26 +02:00
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-04-22 16:45:26 +02:00
|
|
|
public void publishApiProgress( final String s ){
|
2017-04-20 18:23:59 +02:00
|
|
|
Utils.runOnMainThread( new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
|
|
|
progress.setMessage( s );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
api_client.setUserInfo( instance, user_mail, password );
|
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
TootApiResult result = api_client.request( "/api/v1/accounts/verify_credentials" );
|
2017-04-20 18:23:59 +02:00
|
|
|
if( result != null && result.object != null ){
|
2017-04-23 20:05:29 +02:00
|
|
|
// taは使い捨てなので、生成に使うLinkClickContextはダミーで問題ない
|
|
|
|
LinkClickContext lcc = new LinkClickContext() {
|
|
|
|
};
|
2017-04-23 23:12:11 +02:00
|
|
|
TootAccount ta = TootAccount.parse( log, lcc, result.object );
|
2017-04-23 17:16:05 +02:00
|
|
|
String user = ta.username + "@" + instance;
|
|
|
|
this.row_id = SavedAccount.insert( instance, user, result.object, result.token_info );
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
|
|
|
progress.dismiss();
|
2017-04-21 14:45:40 +02:00
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
if( result == null ){
|
|
|
|
// cancelled.
|
|
|
|
}else if( result.object == null ){
|
|
|
|
Utils.showToast( ActMain.this, true, result.error );
|
|
|
|
log.e( result.error );
|
|
|
|
}else{
|
2017-04-21 14:45:40 +02:00
|
|
|
SavedAccount account = SavedAccount.loadAccount( log, row_id );
|
2017-04-20 18:23:59 +02:00
|
|
|
if( account != null ){
|
2017-04-21 14:45:40 +02:00
|
|
|
ActMain.this.onAccountUpdated( account );
|
2017-04-20 18:23:59 +02:00
|
|
|
dialog.dismiss();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
progress.setIndeterminate( true );
|
|
|
|
progress.setCancelable( true );
|
|
|
|
progress.setOnCancelListener( new DialogInterface.OnCancelListener() {
|
|
|
|
@Override
|
|
|
|
public void onCancel( DialogInterface dialog ){
|
|
|
|
task.cancel( true );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
progress.show();
|
|
|
|
AsyncTaskCompat.executeParallel( task );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
public void performColumnClose( boolean bConfirm, final Column column ){
|
|
|
|
if( ! bConfirm && ! pref.getBoolean( Pref.KEY_DONT_CONFIRM_BEFORE_CLOSE_COLUMN, false ) ){
|
2017-04-22 16:45:26 +02:00
|
|
|
new AlertDialog.Builder( this )
|
2017-04-24 08:18:54 +02:00
|
|
|
.setMessage( R.string.confirm_close_column )
|
2017-04-22 16:45:26 +02:00
|
|
|
.setNegativeButton( R.string.cancel, null )
|
|
|
|
.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick( DialogInterface dialog, int which ){
|
2017-04-23 17:16:05 +02:00
|
|
|
performColumnClose( true, column );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
} )
|
|
|
|
.show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
int page_showing = pager.getCurrentItem();
|
|
|
|
int page_delete = pager_adapter.column_list.indexOf( column );
|
2017-04-21 14:45:40 +02:00
|
|
|
pager_adapter.removeColumn( pager, column );
|
2017-04-20 18:23:59 +02:00
|
|
|
if( pager_adapter.getCount() == 0 ){
|
|
|
|
llEmpty.setVisibility( View.VISIBLE );
|
2017-04-22 16:45:26 +02:00
|
|
|
}else if( page_showing > 0 && page_showing == page_delete ){
|
2017-04-23 17:16:05 +02:00
|
|
|
pager.setCurrentItem( page_showing - 1, true );
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
// カラム追加系
|
2017-04-22 16:45:26 +02:00
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
public void addColumn( SavedAccount ai, int type, Object... params ){
|
2017-04-23 07:42:09 +02:00
|
|
|
// 既に同じカラムがあればそこに移動する
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
2017-04-23 20:05:29 +02:00
|
|
|
if( column.isSameSpec( ai, type, params ) ){
|
2017-04-23 17:16:05 +02:00
|
|
|
pager.setCurrentItem( pager_adapter.column_list.indexOf( column ), true );
|
2017-04-23 07:42:09 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
//
|
2017-04-22 16:45:26 +02:00
|
|
|
llEmpty.setVisibility( View.GONE );
|
|
|
|
//
|
2017-04-23 20:05:29 +02:00
|
|
|
Column col = new Column( ActMain.this, ai, type, params );
|
2017-04-23 07:42:09 +02:00
|
|
|
int idx = pager_adapter.addColumn( pager, col );
|
2017-04-23 17:16:05 +02:00
|
|
|
pager.setCurrentItem( idx, true );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
private void onAccountUpdated( SavedAccount data ){
|
|
|
|
Utils.showToast( this, false, R.string.account_confirmed );
|
2017-04-24 06:01:59 +02:00
|
|
|
addColumn( data, Column.TYPE_HOME );
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
void performOpenUser( SavedAccount access_info, TootAccount user ){
|
2017-04-24 06:01:59 +02:00
|
|
|
addColumn( access_info, Column.TYPE_PROFILE, user.id );
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void performConversation( SavedAccount access_info, TootStatus status ){
|
2017-04-24 06:01:59 +02:00
|
|
|
addColumn( access_info, Column.TYPE_CONVERSATION, status.id );
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void performAddTimeline( final int type ){
|
2017-04-20 18:23:59 +02:00
|
|
|
AccountPicker.pick( this, new AccountPicker.AccountPickerCallback() {
|
|
|
|
@Override
|
|
|
|
public void onAccountPicked( SavedAccount ai ){
|
2017-04-24 13:04:56 +02:00
|
|
|
switch( type ){
|
2017-04-24 08:18:54 +02:00
|
|
|
default:
|
|
|
|
addColumn( ai, type, ai.id );
|
|
|
|
break;
|
|
|
|
case Column.TYPE_SEARCH:
|
2017-04-24 13:04:56 +02:00
|
|
|
addColumn( ai, type, "", false );
|
2017-04-24 08:18:54 +02:00
|
|
|
break;
|
|
|
|
}
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
2017-04-21 14:45:40 +02:00
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
public void openHashTag( SavedAccount access_info, String tag ){
|
2017-04-24 06:01:59 +02:00
|
|
|
addColumn( access_info, Column.TYPE_HASHTAG, tag );
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
public interface GetAccountCallback {
|
|
|
|
// return account information
|
|
|
|
// if failed, account is null.
|
|
|
|
void onGetAccount( TootAccount account );
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
void startGetAccount( final SavedAccount access_info, final String host, final String user, final GetAccountCallback callback ){
|
|
|
|
|
|
|
|
final ProgressDialog progress = new ProgressDialog( this );
|
|
|
|
final AsyncTask< Void, Void, TootAccount > task = new AsyncTask< Void, Void, TootAccount >() {
|
|
|
|
@Override
|
|
|
|
protected TootAccount doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( final String s ){
|
|
|
|
Utils.runOnMainThread( new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
|
|
|
progress.setMessage( s );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
client.setAccount( access_info );
|
|
|
|
String path = "/api/v1/accounts/search" + "?q=" + Uri.encode( user );
|
|
|
|
|
|
|
|
TootApiResult result = client.request( path );
|
|
|
|
|
|
|
|
if( result.array != null ){
|
|
|
|
for( int i = 0, ie = result.array.length() ; i < ie ; ++ i ){
|
|
|
|
|
|
|
|
TootAccount item = TootAccount.parse( log, access_info, result.array.optJSONObject( i ) );
|
|
|
|
|
|
|
|
if( ! item.username.equals( user ) ) continue;
|
|
|
|
|
|
|
|
if( ! item.acct.contains( "@" )
|
|
|
|
|| item.acct.equalsIgnoreCase( user + "@" + host ) )
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootAccount result ){
|
|
|
|
super.onPostExecute( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootAccount result ){
|
|
|
|
progress.dismiss();
|
|
|
|
callback.onGetAccount( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
progress.setIndeterminate( true );
|
|
|
|
progress.setCancelable( true );
|
|
|
|
progress.setOnCancelListener( new DialogInterface.OnCancelListener() {
|
|
|
|
@Override
|
|
|
|
public void onCancel( DialogInterface dialog ){
|
|
|
|
task.cancel( true );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
progress.show();
|
|
|
|
AsyncTaskCompat.executeParallel( task );
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
public void openBrowser( SavedAccount account, String url ){
|
|
|
|
openChromeTab( account, url, false );
|
|
|
|
}
|
|
|
|
|
|
|
|
Pattern reHashTag = Pattern.compile( "\\Ahttps://([^/]+)/tags/([^?#]+)\\z" );
|
|
|
|
Pattern reUserPage = Pattern.compile( "\\Ahttps://([^/]+)/@([^?#]+)\\z" );
|
2017-04-23 20:05:29 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
public void openChromeTab( final SavedAccount access_info, final String url, boolean noIntercept ){
|
2017-04-21 14:45:40 +02:00
|
|
|
try{
|
2017-04-23 23:12:11 +02:00
|
|
|
log.d( "openChromeTab url=%s", url );
|
2017-04-23 20:05:29 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
if( ! noIntercept ){
|
2017-04-23 20:05:29 +02:00
|
|
|
// ハッシュタグをアプリ内で開く
|
|
|
|
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 );
|
2017-04-23 23:12:11 +02:00
|
|
|
String tag = Uri.decode( m.group( 2 ) );
|
|
|
|
if( host.equalsIgnoreCase( access_info.host ) ){
|
|
|
|
openHashTag( access_info, tag );
|
|
|
|
return;
|
|
|
|
}else{
|
|
|
|
openHashTagOtherInstance( access_info, url, host, tag );
|
|
|
|
return;
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
|
|
|
|
m = reUserPage.matcher( url );
|
|
|
|
if( m.find() ){
|
|
|
|
// https://mastodon.juggler.jp/@SubwayTooter
|
|
|
|
final String host = m.group( 1 );
|
|
|
|
final String user = Uri.decode( m.group( 2 ) );
|
|
|
|
startGetAccount( access_info, host, user, new GetAccountCallback() {
|
|
|
|
@Override
|
|
|
|
public void onGetAccount( TootAccount who ){
|
|
|
|
if( who != null ){
|
|
|
|
performOpenUser( access_info, who );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
openChromeTab( access_info, url, true );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
return;
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
|
2017-04-21 14:45:40 +02:00
|
|
|
// ビルダーを使って表示方法を指定する
|
|
|
|
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
|
|
|
|
builder.setToolbarColor( ContextCompat.getColor( this, R.color.colorPrimary ) ).setShowTitle( true );
|
|
|
|
|
|
|
|
// CustomTabsでURLをひらくIntentを発行
|
|
|
|
CustomTabsIntent customTabsIntent = builder.build();
|
|
|
|
customTabsIntent.launchUrl( this, Uri.parse( url ) );
|
|
|
|
|
|
|
|
}catch( Throwable ex ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// ex.printStackTrace();
|
2017-04-23 17:16:05 +02:00
|
|
|
log.e( ex, "openChromeTab failed. url=%s", url );
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
// 他インスタンスのハッシュタグの表示
|
2017-04-23 23:12:11 +02:00
|
|
|
private void openHashTagOtherInstance( final SavedAccount access_info, final String url, String host, final String tag ){
|
|
|
|
|
|
|
|
ActionsDialog dialog = new ActionsDialog();
|
2017-04-23 20:05:29 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
ArrayList< SavedAccount > account_list = new ArrayList<>();
|
|
|
|
for( SavedAccount a : SavedAccount.loadAccountList( log ) ){
|
|
|
|
if( a.host.equalsIgnoreCase( host ) ){
|
|
|
|
account_list.add( a );
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
Collections.sort( account_list, new Comparator< SavedAccount >() {
|
2017-04-23 20:05:29 +02:00
|
|
|
@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 ){
|
|
|
|
final SavedAccount _a = a;
|
2017-04-23 23:12:11 +02:00
|
|
|
dialog.addAction(
|
2017-04-24 13:04:56 +02:00
|
|
|
getString( R.string.open_in_account, a.acct )
|
2017-04-23 23:12:11 +02:00
|
|
|
, new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
|
|
|
openHashTag( _a, tag );
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
);
|
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
if( account_list.isEmpty() ){
|
|
|
|
// TODO ログインなしアカウントで開く選択肢
|
|
|
|
}
|
|
|
|
// カラムのアカウントで開く
|
|
|
|
{
|
|
|
|
final SavedAccount _a = access_info;
|
2017-04-23 23:12:11 +02:00
|
|
|
dialog.addAction(
|
2017-04-24 13:04:56 +02:00
|
|
|
getString( R.string.open_in_account, access_info.acct )
|
2017-04-23 23:12:11 +02:00
|
|
|
, new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
|
|
|
openHashTag( _a, tag );
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
|
|
|
|
);
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
// ブラウザで表示する
|
|
|
|
{
|
2017-04-23 23:12:11 +02:00
|
|
|
dialog.addAction(
|
|
|
|
getString( R.string.open_web_on_host, host )
|
|
|
|
, new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
|
|
|
openChromeTab( access_info, url, true );
|
|
|
|
}
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
);
|
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
dialog.show( this, "#" + tag );
|
|
|
|
|
2017-04-23 20:05:29 +02:00
|
|
|
}
|
|
|
|
|
2017-04-21 14:45:40 +02:00
|
|
|
final HTMLDecoder.LinkClickCallback link_click_listener = new HTMLDecoder.LinkClickCallback() {
|
|
|
|
@Override
|
2017-04-23 23:12:11 +02:00
|
|
|
public void onClickLink( LinkClickContext lcc, String url ){
|
|
|
|
openChromeTab( (SavedAccount) lcc, url, false );
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
|
|
|
};
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
private void performTootButton(){
|
2017-04-21 14:45:40 +02:00
|
|
|
Column c = pager_adapter.getColumn( pager.getCurrentItem() );
|
|
|
|
if( c != null && c.access_info != null ){
|
2017-04-23 17:16:05 +02:00
|
|
|
ActPost.open( this, c.access_info.db_id, "" );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
public void performReply( SavedAccount account, TootStatus status ){
|
2017-04-23 17:16:05 +02:00
|
|
|
ActPost.open( this, account.db_id, status );
|
|
|
|
}
|
|
|
|
|
|
|
|
public void performMention( SavedAccount account, TootAccount who ){
|
2017-04-23 20:05:29 +02:00
|
|
|
ActPost.open( this, account.db_id, account.getFullAcct( who ) + " " );
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
2017-04-22 16:45:26 +02:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
private void showColumnMatchAccount( SavedAccount account ){
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
2017-04-24 13:04:56 +02:00
|
|
|
if( account.acct.equals( column.access_info.acct ) ){
|
2017-04-22 16:45:26 +02:00
|
|
|
column.fireVisualCallback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// favourite
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
final HashSet< String > map_busy_fav = new HashSet<>();
|
2017-04-22 16:45:26 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
boolean isBusyFav( SavedAccount account, TootStatus status ){
|
|
|
|
String busy_key = account.host + ":" + status.id;
|
|
|
|
return map_busy_fav.contains( busy_key );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void performFavourite( final SavedAccount account, final TootStatus status ){
|
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
final String busy_key = account.host + ":" + status.id;
|
2017-04-22 16:45:26 +02:00
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
if( map_busy_fav.contains( busy_key ) ){
|
|
|
|
Utils.showToast( this, false, R.string.wait_previous_operation );
|
2017-04-22 16:45:26 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
map_busy_fav.add( busy_key );
|
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
2017-04-23 21:09:59 +02:00
|
|
|
final boolean bSet = ! status.favourited;
|
2017-04-22 16:45:26 +02:00
|
|
|
TootStatus new_status;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( final String s ){
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
client.setAccount( account );
|
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder()
|
|
|
|
.post( RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
2017-04-23 17:16:05 +02:00
|
|
|
, ""
|
|
|
|
) );
|
2017-04-22 16:45:26 +02:00
|
|
|
|
|
|
|
TootApiResult result = client.request(
|
2017-04-23 21:09:59 +02:00
|
|
|
( bSet
|
2017-04-23 17:16:05 +02:00
|
|
|
? "/api/v1/statuses/" + status.id + "/favourite"
|
|
|
|
: "/api/v1/statuses/" + status.id + "/unfavourite"
|
2017-04-22 16:45:26 +02:00
|
|
|
)
|
|
|
|
, request_builder );
|
|
|
|
if( result.object != null ){
|
2017-04-23 23:12:11 +02:00
|
|
|
new_status = TootStatus.parse( log, account, result.object );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
super.onPostExecute( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
2017-04-23 17:16:05 +02:00
|
|
|
map_busy_fav.remove( busy_key );
|
|
|
|
if( new_status != null ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// カウント数は遅延があるみたい
|
2017-04-23 21:09:59 +02:00
|
|
|
if( bSet && new_status.favourites_count <= status.favourites_count ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// 星つけたのにカウントが上がらないのは違和感あるので、表示をいじる
|
2017-04-23 17:16:05 +02:00
|
|
|
new_status.favourites_count = status.favourites_count + 1;
|
2017-04-23 21:09:59 +02:00
|
|
|
}else if( ! bSet && new_status.favourites_count >= status.favourites_count ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// 星外したのにカウントが下がらないのは違和感あるので、表示をいじる
|
2017-04-23 17:16:05 +02:00
|
|
|
new_status.favourites_count = status.favourites_count - 1;
|
2017-04-22 16:45:26 +02:00
|
|
|
if( new_status.favourites_count < 0 ){
|
|
|
|
new_status.favourites_count = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
|
|
|
column.findStatus( account, new_status.id, new Column.StatusEntryCallback() {
|
|
|
|
@Override
|
|
|
|
public void onIterate( TootStatus status ){
|
|
|
|
status.favourited = new_status.favourited;
|
|
|
|
status.favourites_count = new_status.favourites_count;
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
} );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
}else{
|
2017-04-23 17:16:05 +02:00
|
|
|
if( result != null ) Utils.showToast( ActMain.this, true, result.error );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
showColumnMatchAccount( account );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}.execute();
|
2017-04-23 17:16:05 +02:00
|
|
|
showColumnMatchAccount( account );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// boost
|
2017-04-23 17:16:05 +02:00
|
|
|
final HashSet< String > map_busy_boost = new HashSet<>();
|
2017-04-22 16:45:26 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
boolean isBusyBoost( SavedAccount account, TootStatus status ){
|
|
|
|
String busy_key = account.host + ":" + status.id;
|
|
|
|
return map_busy_boost.contains( busy_key );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
public void performBoost( final SavedAccount account, final TootStatus status, boolean bConfirmed ){
|
2017-04-22 16:45:26 +02:00
|
|
|
//
|
|
|
|
final String busy_key = account.host + ":" + status.id;
|
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
if( map_busy_boost.contains( busy_key ) ){
|
2017-04-22 16:45:26 +02:00
|
|
|
Utils.showToast( this, false, R.string.wait_previous_operation );
|
|
|
|
return;
|
2017-04-21 14:45:40 +02:00
|
|
|
}
|
2017-04-22 16:45:26 +02:00
|
|
|
|
|
|
|
if( status.reblogged ){
|
|
|
|
// FAVがついているか、FAV操作中はBoostを外せない
|
|
|
|
if( isBusyFav( account, status ) || status.favourited ){
|
|
|
|
Utils.showToast( this, false, R.string.cant_remove_boost_while_favourited );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}else{
|
2017-04-23 17:16:05 +02:00
|
|
|
if( ! bConfirmed && account.confirm_boost ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// TODO: アカウント設定でスキップさせたい
|
2017-04-23 17:16:05 +02:00
|
|
|
new AlertDialog.Builder( this )
|
|
|
|
.setTitle( R.string.confirm )
|
|
|
|
.setMessage( R.string.confirm_boost )
|
2017-04-22 16:45:26 +02:00
|
|
|
.setPositiveButton( R.string.ok, new DialogInterface.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick( DialogInterface dialog, int which ){
|
2017-04-23 17:16:05 +02:00
|
|
|
performBoost( account, status, true );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
} )
|
2017-04-23 17:16:05 +02:00
|
|
|
.setNegativeButton( R.string.cancel, null )
|
2017-04-22 16:45:26 +02:00
|
|
|
.show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
map_busy_boost.add( busy_key );
|
2017-04-22 16:45:26 +02:00
|
|
|
//
|
2017-04-23 17:16:05 +02:00
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
2017-04-22 16:45:26 +02:00
|
|
|
final boolean new_state = ! status.reblogged;
|
|
|
|
TootStatus new_status;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( final String s ){
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
client.setAccount( account );
|
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder()
|
|
|
|
.post( RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
2017-04-23 17:16:05 +02:00
|
|
|
, ""
|
|
|
|
) );
|
2017-04-22 16:45:26 +02:00
|
|
|
|
|
|
|
TootApiResult result = client.request(
|
2017-04-23 17:16:05 +02:00
|
|
|
"/api/v1/statuses/" + status.id + ( new_state ? "/reblog" : "/unreblog" )
|
2017-04-22 16:45:26 +02:00
|
|
|
, request_builder );
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-22 16:45:26 +02:00
|
|
|
if( result.object != null ){
|
|
|
|
// reblog,unreblog のレスポンスは信用ならんのでステータスを再取得する
|
2017-04-23 17:16:05 +02:00
|
|
|
result = client.request( "/api/v1/statuses/" + status.id );
|
2017-04-22 16:45:26 +02:00
|
|
|
if( result.object != null ){
|
2017-04-23 23:12:11 +02:00
|
|
|
new_status = TootStatus.parse( log, account, result.object );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
super.onPostExecute( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
2017-04-23 17:16:05 +02:00
|
|
|
map_busy_boost.remove( busy_key );
|
|
|
|
if( new_status != null ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// カウント数は遅延があるみたい
|
|
|
|
if( new_status.reblogged && new_status.reblogs_count <= status.reblogs_count ){
|
|
|
|
// 星つけたのにカウントが上がらないのは違和感あるので、表示をいじる
|
2017-04-23 17:16:05 +02:00
|
|
|
new_status.reblogs_count = status.reblogs_count + 1;
|
|
|
|
}else if( ! new_status.reblogged && new_status.reblogs_count >= status.reblogs_count ){
|
2017-04-22 16:45:26 +02:00
|
|
|
// 星外したのにカウントが下がらないのは違和感あるので、表示をいじる
|
2017-04-23 17:16:05 +02:00
|
|
|
new_status.reblogs_count = status.reblogs_count - 1;
|
2017-04-22 16:45:26 +02:00
|
|
|
if( new_status.reblogs_count < 0 ){
|
|
|
|
new_status.reblogs_count = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
|
|
|
column.findStatus( account, new_status.id, new Column.StatusEntryCallback() {
|
|
|
|
@Override
|
|
|
|
public void onIterate( TootStatus status ){
|
|
|
|
status.reblogged = new_status.reblogged;
|
|
|
|
status.reblogs_count = new_status.reblogs_count;
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
} );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
}else{
|
2017-04-23 17:16:05 +02:00
|
|
|
if( result != null ) Utils.showToast( ActMain.this, true, result.error );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
showColumnMatchAccount( account );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}.execute();
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
showColumnMatchAccount( account );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////
|
|
|
|
|
|
|
|
private void performAccountSetting(){
|
|
|
|
AccountPicker.pick( this, new AccountPicker.AccountPickerCallback() {
|
|
|
|
@Override
|
|
|
|
public void onAccountPicked( SavedAccount ai ){
|
2017-04-23 17:16:05 +02:00
|
|
|
ActAccountSetting.open( ActMain.this, ai );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
private void performAppSetting(){
|
2017-04-23 17:16:05 +02:00
|
|
|
ActAppSetting.open( ActMain.this );
|
2017-04-22 16:45:26 +02:00
|
|
|
}
|
|
|
|
|
2017-04-23 07:42:09 +02:00
|
|
|
////////////////////////////////////////////////////////
|
|
|
|
// column list
|
|
|
|
|
|
|
|
JSONArray encodeColumnList(){
|
|
|
|
JSONArray array = new JSONArray();
|
2017-04-23 17:16:05 +02:00
|
|
|
for( int i = 0, ie = pager_adapter.column_list.size() ; i < ie ; ++ i ){
|
|
|
|
Column column = pager_adapter.column_list.get( i );
|
2017-04-23 07:42:09 +02:00
|
|
|
try{
|
|
|
|
JSONObject dst = new JSONObject();
|
2017-04-23 17:16:05 +02:00
|
|
|
column.encodeJSON( dst, i );
|
2017-04-23 07:42:09 +02:00
|
|
|
array.put( dst );
|
|
|
|
}catch( JSONException ex ){
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void performColumnList(){
|
2017-04-23 17:16:05 +02:00
|
|
|
Intent intent = new Intent( this, ActColumnList.class );
|
|
|
|
intent.putExtra( ActColumnList.EXTRA_ORDER, encodeColumnList().toString() );
|
|
|
|
intent.putExtra( ActColumnList.EXTRA_SELECTION, pager.getCurrentItem() );
|
|
|
|
startActivityForResult( intent, REQUEST_CODE_COLUMN_LIST );
|
2017-04-23 07:42:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static final String FILE_COLUMN_LIST = "column_list";
|
|
|
|
|
|
|
|
private void saveColumnList(){
|
|
|
|
JSONArray array = encodeColumnList();
|
|
|
|
try{
|
|
|
|
OutputStream os = openFileOutput( FILE_COLUMN_LIST, MODE_PRIVATE );
|
|
|
|
try{
|
|
|
|
os.write( Utils.encodeUTF8( array.toString() ) );
|
|
|
|
}finally{
|
|
|
|
os.close();
|
|
|
|
}
|
|
|
|
}catch( Throwable ex ){
|
|
|
|
ex.printStackTrace();
|
|
|
|
Utils.showToast( this, ex, "saveColumnList failed." );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void loadColumnList(){
|
|
|
|
try{
|
|
|
|
InputStream is = openFileInput( FILE_COLUMN_LIST );
|
|
|
|
try{
|
|
|
|
ByteArrayOutputStream bao = new ByteArrayOutputStream( is.available() );
|
|
|
|
byte[] tmp = new byte[ 4096 ];
|
|
|
|
for( ; ; ){
|
|
|
|
int r = is.read( tmp, 0, tmp.length );
|
|
|
|
if( r <= 0 ) break;
|
|
|
|
bao.write( tmp, 0, r );
|
|
|
|
}
|
|
|
|
JSONArray array = new JSONArray( Utils.decodeUTF8( bao.toByteArray() ) );
|
|
|
|
for( int i = 0, ie = array.length() ; i < ie ; ++ i ){
|
|
|
|
try{
|
|
|
|
JSONObject src = array.optJSONObject( i );
|
|
|
|
Column col = new Column( ActMain.this, src );
|
|
|
|
pager_adapter.addColumn( pager, col );
|
|
|
|
}catch( Throwable ex ){
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}finally{
|
|
|
|
is.close();
|
|
|
|
}
|
|
|
|
}catch( FileNotFoundException ignored ){
|
|
|
|
}catch( Throwable ex ){
|
|
|
|
ex.printStackTrace();
|
|
|
|
Utils.showToast( this, ex, "loadColumnList failed." );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pager_adapter.column_list.size() > 0 ){
|
|
|
|
llEmpty.setVisibility( View.GONE );
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
////////////////////////////////////////////////////////////////////////////
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
public interface RelationChangedCallback {
|
|
|
|
// void onRelationChanged( TootRelationShip relationship );
|
|
|
|
void onRelationChanged( );
|
|
|
|
}
|
|
|
|
|
|
|
|
private void callFollow( final SavedAccount access_info, final TootAccount who, final boolean bFollow, final RelationChangedCallback callback ){
|
2017-04-23 23:12:11 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( String s ){
|
|
|
|
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
client.setAccount( access_info );
|
2017-04-23 17:16:05 +02:00
|
|
|
|
|
|
|
TootApiResult result;
|
|
|
|
if( bFollow & who.acct.contains( "@" ) ){
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, "uri=" + Uri.encode( who.acct )
|
|
|
|
) );
|
|
|
|
result = client.request( "/api/v1/follows", request_builder );
|
2017-04-24 13:04:56 +02:00
|
|
|
if( result != null ){
|
|
|
|
if( result.object != null ){
|
|
|
|
remote_who = TootAccount.parse( log, access_info, result.object );
|
|
|
|
|
|
|
|
Utils.showToast( ActMain.this, false, bFollow ? R.string.follow_succeeded : R.string.unfollow_succeeded );
|
|
|
|
}else if( bFollow && who.locked && result.response.code() == 422 ){
|
|
|
|
Utils.showToast( ActMain.this, false, R.string.cant_follow_locked_user );
|
|
|
|
}else{
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
}else{
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, "" // 空データ
|
|
|
|
) );
|
|
|
|
result = client.request( "/api/v1/accounts/" + who.id + ( bFollow ? "/follow" : "/unfollow" )
|
|
|
|
, request_builder );
|
2017-04-24 13:04:56 +02:00
|
|
|
if( result != null ){
|
|
|
|
if( result.object != null ){
|
|
|
|
relation = TootRelationShip.parse( log, result.object );
|
|
|
|
|
|
|
|
Utils.showToast( ActMain.this, false, bFollow ? R.string.follow_succeeded : R.string.unfollow_succeeded );
|
|
|
|
}else if( bFollow && who.locked && result.response.code() == 422 ){
|
|
|
|
Utils.showToast( ActMain.this, false, R.string.cant_follow_locked_user );
|
|
|
|
}else{
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
TootRelationShip relation;
|
|
|
|
TootAccount remote_who;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
onPostExecute( null );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
|
|
|
// if( relation != null ){
|
|
|
|
// App1.relationship_map.put( access_info, relation );
|
|
|
|
// if( callback != null ) callback.onRelationChanged( relation );
|
|
|
|
// }else if( remote_who != null ){
|
|
|
|
// App1.relationship_map.addFollowing( access_info, remote_who.id );
|
|
|
|
// if( callback != null )
|
|
|
|
// callback.onRelationChanged( App1.relationship_map.get( access_info, remote_who.id ) );
|
|
|
|
// }
|
|
|
|
|
|
|
|
if( relation != null ){
|
|
|
|
if( callback != null ) callback.onRelationChanged( );
|
|
|
|
}else if( remote_who != null ){
|
|
|
|
if( callback != null )
|
|
|
|
callback.onRelationChanged( );
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
// acct で指定したユーザをリモートフォローする
|
2017-04-24 13:04:56 +02:00
|
|
|
void callRemoteFollow( final SavedAccount access_info, final String acct, final boolean locked, final RelationChangedCallback callback ){
|
2017-04-23 23:12:11 +02:00
|
|
|
|
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( String s ){
|
|
|
|
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
client.setAccount( access_info );
|
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, "uri=" + Uri.encode( acct )
|
|
|
|
) );
|
|
|
|
TootApiResult result = client.request( "/api/v1/follows", request_builder );
|
|
|
|
|
|
|
|
if( result != null ){
|
|
|
|
if( result.object != null ){
|
2017-04-24 13:04:56 +02:00
|
|
|
who = TootAccount.parse( log, access_info, result.object );
|
2017-04-23 23:12:11 +02:00
|
|
|
Utils.showToast( ActMain.this, false, R.string.follow_succeeded );
|
|
|
|
}else if( locked && result.response.code() == 422 ){
|
|
|
|
Utils.showToast( ActMain.this, false, R.string.cant_follow_locked_user );
|
|
|
|
}else{
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
TootAccount who;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
onPostExecute( null );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
|
|
|
if( who != null ){
|
|
|
|
// App1.relationship_map.addFollowing( access_info, who.id );
|
|
|
|
// if( callback != null )
|
|
|
|
// callback.onRelationChanged( App1.relationship_map.get( access_info, who.id ) );
|
|
|
|
|
|
|
|
if( callback != null )
|
|
|
|
callback.onRelationChanged( );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 23:12:11 +02:00
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
// アカウントを選択してからユーザをフォローする
|
2017-04-24 13:04:56 +02:00
|
|
|
void followFromAnotherAccount( final SavedAccount access_info, final TootAccount who, final RelationChangedCallback callback ){
|
2017-04-23 23:12:11 +02:00
|
|
|
AccountPicker.pick( ActMain.this, new AccountPicker.AccountPickerCallback() {
|
|
|
|
@Override
|
|
|
|
public void onAccountPicked( SavedAccount ai ){
|
|
|
|
String acct = who.acct;
|
|
|
|
if( ! acct.contains( "@" ) ){
|
|
|
|
acct = acct + "@" + access_info.host;
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
callRemoteFollow( ai, acct, who.locked, callback );
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
////////////////////////////////////////
|
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
private void callMute( final SavedAccount access_info, final TootAccount who, final boolean bMute, final RelationChangedCallback callback ){
|
2017-04-23 17:16:05 +02:00
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( String s ){
|
|
|
|
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
client.setAccount( access_info );
|
2017-04-23 17:16:05 +02:00
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, "" // 空データ
|
|
|
|
) );
|
|
|
|
TootApiResult result = client.request( "/api/v1/accounts/" + who.id + ( bMute ? "/mute" : "/unmute" )
|
|
|
|
, request_builder );
|
|
|
|
if( result != null ){
|
|
|
|
if( result.object != null ){
|
2017-04-24 13:04:56 +02:00
|
|
|
relation = TootRelationShip.parse( log, result.object );
|
2017-04-23 17:16:05 +02:00
|
|
|
Utils.showToast( ActMain.this, false, bMute ? R.string.mute_succeeded : R.string.unmute_succeeded );
|
2017-04-24 13:04:56 +02:00
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
}else{
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
TootRelationShip relation;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
onPostExecute( null );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
|
|
|
if( relation != null ){
|
|
|
|
// App1.relationship_map.put( access_info, relation );
|
|
|
|
// if( callback != null ) callback.onRelationChanged( relation );
|
|
|
|
|
|
|
|
if( callback != null ) callback.onRelationChanged( );
|
|
|
|
|
|
|
|
if( bMute ){
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
|
|
|
column.removeStatusByAccount( access_info, who.id );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
showColumnMatchAccount( access_info );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
private void callBlock( final SavedAccount access_info, final TootAccount who, final boolean bBlock, final RelationChangedCallback callback ){
|
2017-04-23 17:16:05 +02:00
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( String s ){
|
|
|
|
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
client.setAccount( access_info );
|
2017-04-23 17:16:05 +02:00
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, "" // 空データ
|
|
|
|
) );
|
|
|
|
TootApiResult result = client.request( "/api/v1/accounts/" + who.id + ( bBlock ? "/block" : "/unblock" )
|
|
|
|
, request_builder );
|
|
|
|
if( result != null ){
|
|
|
|
if( result.object != null ){
|
2017-04-24 13:04:56 +02:00
|
|
|
relation = TootRelationShip.parse( log, result.object );
|
2017-04-23 17:16:05 +02:00
|
|
|
Utils.showToast( ActMain.this, false, bBlock ? R.string.block_succeeded : R.string.unblock_succeeded );
|
|
|
|
}else{
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
TootRelationShip relation;
|
|
|
|
TootAccount remote_who;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCancelled( TootApiResult result ){
|
|
|
|
onPostExecute( null );
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute( TootApiResult result ){
|
|
|
|
boolean bOK = false;
|
|
|
|
if( relation != null ){
|
|
|
|
bOK = true;
|
|
|
|
// App1.relationship_map.put( access_info, relation );
|
|
|
|
// if( callback != null ) callback.onRelationChanged( relation );
|
|
|
|
if( callback != null ) callback.onRelationChanged( );
|
|
|
|
}else if( remote_who != null ){
|
|
|
|
bOK = true;
|
|
|
|
// App1.relationship_map.addFollowing( access_info, remote_who.id );
|
|
|
|
// if( callback != null )
|
|
|
|
// callback.onRelationChanged( App1.relationship_map.get( access_info, remote_who.id ) );
|
|
|
|
if( callback != null )
|
|
|
|
callback.onRelationChanged( );
|
|
|
|
}
|
|
|
|
if( bOK ){
|
|
|
|
if( bBlock ){
|
|
|
|
for( Column column : pager_adapter.column_list ){
|
|
|
|
column.removeStatusByAccount( access_info, who.id );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
showColumnMatchAccount( access_info );
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 17:16:05 +02:00
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
public interface ReportCompleteCallback {
|
|
|
|
void onReportComplete( TootApiResult result );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
private void callReport( final SavedAccount account, final TootAccount who, final TootStatus status
|
2017-04-23 17:16:05 +02:00
|
|
|
, final String comment, final ReportCompleteCallback callback
|
|
|
|
){
|
|
|
|
new AsyncTask< Void, Void, TootApiResult >() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected TootApiResult doInBackground( Void... params ){
|
|
|
|
TootApiClient client = new TootApiClient( ActMain.this, new TootApiClient.Callback() {
|
|
|
|
@Override
|
|
|
|
public boolean isApiCancelled(){
|
|
|
|
return isCancelled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void publishApiProgress( String s ){
|
|
|
|
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
client.setAccount( account );
|
|
|
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
|
|
|
sb.append( "account_id=" )
|
|
|
|
.append( Long.toString( status.account.id ) )
|
|
|
|
.append( "&comment=" )
|
|
|
|
.append( Uri.encode( comment ) )
|
|
|
|
;
|
|
|
|
|
|
|
|
if( status != null ){
|
|
|
|
sb.append( "&status_ids[]=" )
|
|
|
|
.append( Long.toString( status.id ) )
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
Request.Builder request_builder = new Request.Builder().post(
|
|
|
|
RequestBody.create(
|
|
|
|
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
|
|
|
, sb.toString()
|
|
|
|
) );
|
|
|
|
TootApiResult result = client.request( "/api/v1/reports", request_builder );
|
|
|
|
if( result != null ){
|
|
|
|
callback.onReportComplete( result );
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
private void openReportForm( final SavedAccount account, final TootAccount who, final TootStatus status ){
|
2017-04-23 17:16:05 +02:00
|
|
|
ReportForm.showReportForm( this, who, status, new ReportForm.ReportFormCallback() {
|
|
|
|
@Override
|
|
|
|
public void startReport( final Dialog dialog, String comment ){
|
2017-04-23 23:12:11 +02:00
|
|
|
callReport( account, who, status, comment, new ReportCompleteCallback() {
|
2017-04-23 17:16:05 +02:00
|
|
|
@Override
|
|
|
|
public void onReportComplete( TootApiResult result ){
|
2017-04-24 08:18:54 +02:00
|
|
|
//noinspection StatementWithEmptyBody
|
2017-04-23 17:16:05 +02:00
|
|
|
if( result == null ){
|
|
|
|
// cancelled
|
|
|
|
}else if( result.object != null ){
|
|
|
|
Utils.showToast( ActMain.this, false, R.string.report_completed );
|
|
|
|
dialog.dismiss();
|
|
|
|
}else{
|
|
|
|
// error
|
|
|
|
Utils.showToast( ActMain.this, false, result.error );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
////////////////////////////////////////////////
|
2017-04-23 17:16:05 +02:00
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
final RelationChangedCallback follow_comolete_callback = new RelationChangedCallback() {
|
|
|
|
// @Override public void onRelationChanged( TootRelationShip relationship ){
|
|
|
|
// Utils.showToast( ActMain.this,false,R.string.follow_succeeded );
|
|
|
|
// }
|
|
|
|
@Override public void onRelationChanged( ){
|
|
|
|
Utils.showToast( ActMain.this,false,R.string.follow_succeeded );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-04-23 17:16:05 +02:00
|
|
|
// ステータスのmoreメニュー
|
2017-04-23 23:12:11 +02:00
|
|
|
public void openStatusMoreMenu( final SavedAccount access_info, final TootStatus status ){
|
2017-04-24 09:03:53 +02:00
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
ActionsDialog dialog = new ActionsDialog();
|
2017-04-24 09:03:53 +02:00
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
final ArrayList< SavedAccount > tmp_list = new ArrayList<>();
|
|
|
|
for( SavedAccount a : SavedAccount.loadAccountList( log ) ){
|
|
|
|
if( a.host.equalsIgnoreCase( access_info.host ) ){
|
2017-04-24 09:03:53 +02:00
|
|
|
tmp_list.add( a );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( ! tmp_list.isEmpty() ){
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.favourite_from_another_account ), new Runnable() {
|
2017-04-24 09:03:53 +02:00
|
|
|
@Override public void run(){
|
|
|
|
AccountPicker.pick( ActMain.this, tmp_list, new AccountPicker.AccountPickerCallback() {
|
|
|
|
@Override public void onAccountPicked( SavedAccount ai ){
|
2017-04-24 13:04:56 +02:00
|
|
|
if( ai != null ) performFavourite( ai, status );
|
2017-04-24 09:03:53 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.boost_from_another_account ), new Runnable() {
|
2017-04-24 09:03:53 +02:00
|
|
|
@Override public void run(){
|
|
|
|
AccountPicker.pick( ActMain.this, tmp_list, new AccountPicker.AccountPickerCallback() {
|
|
|
|
@Override public void onAccountPicked( SavedAccount ai ){
|
2017-04-24 13:04:56 +02:00
|
|
|
if( ai != null ) performBoost( ai, status, false );
|
2017-04-24 09:03:53 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
dialog.addAction( getString( R.string.follow ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callFollow( access_info, status.account, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
2017-04-24 09:03:53 +02:00
|
|
|
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.follow_from_another_account ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
followFromAnotherAccount( access_info, status.account ,follow_comolete_callback);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.unfollow ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callFollow( access_info, status.account, false,null );
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.mute ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callMute( access_info, status.account, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.unmute ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callMute( access_info, status.account, false,null );
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.block ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callBlock( access_info, status.account, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.unblock ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callBlock( access_info, status.account, false ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.report ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
|
|
|
openReportForm( access_info, status.account, status );
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.addAction( getString( R.string.open_web_page ), new Runnable() {
|
2017-04-23 23:12:11 +02:00
|
|
|
@Override public void run(){
|
|
|
|
// 強制的にブラウザで開く
|
|
|
|
openChromeTab( access_info, status.url, true );
|
|
|
|
}
|
|
|
|
} );
|
2017-04-24 13:04:56 +02:00
|
|
|
dialog.show( this, null );
|
2017-04-23 17:16:05 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-04-23 23:12:11 +02:00
|
|
|
public void openAccountMoreMenu( final SavedAccount access_info, final TootAccount who ){
|
|
|
|
ActionsDialog dialog = new ActionsDialog();
|
|
|
|
|
|
|
|
dialog.addAction( getString( R.string.mention ), new Runnable() {
|
|
|
|
@Override public void run(){
|
|
|
|
performMention( access_info, who );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.follow ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callFollow( access_info, who, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.follow_from_another_account ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
followFromAnotherAccount( access_info, who,follow_comolete_callback );
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.unfollow ), new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callFollow( access_info, who, false ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.mute ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callMute( access_info, who, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.unmute ), new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callMute( access_info, who, false,null );
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.block ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callBlock( access_info, who, true ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.unblock ), new Runnable() {
|
|
|
|
@Override public void run(){
|
2017-04-24 13:04:56 +02:00
|
|
|
callBlock( access_info, who, false ,null);
|
2017-04-23 23:12:11 +02:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.addAction( getString( R.string.report ), new Runnable() {
|
|
|
|
@Override public void run(){
|
|
|
|
openReportForm( access_info, who, null );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
dialog.show( this, null );
|
2017-04-23 17:16:05 +02:00
|
|
|
}
|
2017-04-24 13:04:56 +02:00
|
|
|
|
|
|
|
private void openOSSLicense(){
|
|
|
|
startActivity( new Intent(this,ActOSSLicense.class) );
|
|
|
|
}
|
|
|
|
|
|
|
|
private void openAppAbout(){
|
|
|
|
startActivity( new Intent(this,ActAbout.class) );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-20 18:23:59 +02:00
|
|
|
}
|