アカウントだけを指定した通報は動作していませんでした。メニューから削除されます。投稿時にIdempotency-Key ヘッダを付与。
This commit is contained in:
parent
c668bb5d7d
commit
dad9a200a4
|
@ -8,6 +8,7 @@
|
|||
<w>favourited</w>
|
||||
<w>hashtag</w>
|
||||
<w>hashtags</w>
|
||||
<w>idempotency</w>
|
||||
<w>noto</w>
|
||||
<w>nsfw</w>
|
||||
<w>reblog</w>
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.os.AsyncTask;
|
|||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.customtabs.CustomTabsIntent;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.os.AsyncTaskCompat;
|
||||
|
@ -141,6 +142,7 @@ public class ActMain extends AppCompatActivity
|
|||
}
|
||||
|
||||
ColumnViewHolder.ListItemPopup list_item_popup;
|
||||
|
||||
void closeListItemPopup(){
|
||||
if( list_item_popup != null ){
|
||||
list_item_popup.dismiss();
|
||||
|
@ -328,7 +330,7 @@ public class ActMain extends AppCompatActivity
|
|||
|
||||
}else if( id == R.id.nav_add_blocks ){
|
||||
performAddTimeline( Column.TYPE_BLOCKS );
|
||||
|
||||
|
||||
}else if( id == R.id.nav_follow_requests ){
|
||||
performAddTimeline( Column.TYPE_FOLLOW_REQUESTS );
|
||||
|
||||
|
@ -1660,7 +1662,7 @@ public class ActMain extends AppCompatActivity
|
|||
) );
|
||||
|
||||
return client.request(
|
||||
"/api/v1/follow_requests/" + who.id+ ( bAllow ? "/authorize" : "/reject" )
|
||||
"/api/v1/follow_requests/" + who.id + ( bAllow ? "/authorize" : "/reject" )
|
||||
, request_builder );
|
||||
}
|
||||
|
||||
|
@ -1680,7 +1682,7 @@ public class ActMain extends AppCompatActivity
|
|||
column.removeFollowRequest( access_info, who.id );
|
||||
}
|
||||
|
||||
Utils.showToast( ActMain.this, false,( bAllow ? R.string.follow_request_authorized : R.string.follow_request_rejected),who.display_name );
|
||||
Utils.showToast( ActMain.this, false, ( bAllow ? R.string.follow_request_authorized : R.string.follow_request_rejected ), who.display_name );
|
||||
}else{
|
||||
Utils.showToast( ActMain.this, false, result.error );
|
||||
}
|
||||
|
@ -1739,7 +1741,9 @@ public class ActMain extends AppCompatActivity
|
|||
}
|
||||
|
||||
private void callReport(
|
||||
@NonNull final SavedAccount account
|
||||
@NonNull final SavedAccount access_info
|
||||
|
||||
, @NonNull final TootAccount who
|
||||
, @NonNull final TootStatus status
|
||||
, @NonNull final String comment
|
||||
, final ReportCompleteCallback callback
|
||||
|
@ -1756,16 +1760,20 @@ public class ActMain extends AppCompatActivity
|
|||
}
|
||||
} );
|
||||
|
||||
client.setAccount( account );
|
||||
client.setAccount( access_info );
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append( "account_id=" )
|
||||
.append( Long.toString( who.id ) )
|
||||
.append( "&comment=" )
|
||||
.append( Uri.encode( comment ) );
|
||||
|
||||
String sb = "account_id=" + Long.toString( status.account.id )
|
||||
+ "&comment=" + Uri.encode( comment )
|
||||
+ "&status_ids[]=" + Long.toString( status.id );
|
||||
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
|
||||
, sb.toString()
|
||||
) );
|
||||
|
||||
return client.request( "/api/v1/reports", request_builder );
|
||||
|
@ -1789,13 +1797,13 @@ public class ActMain extends AppCompatActivity
|
|||
}.execute();
|
||||
}
|
||||
|
||||
private void openReportForm( final SavedAccount account, final TootAccount who, final TootStatus status ){
|
||||
private void openReportForm( @NonNull final SavedAccount account, @NonNull final TootAccount who, @NonNull final TootStatus status ){
|
||||
ReportForm.showReportForm( this, who, status, new ReportForm.ReportFormCallback() {
|
||||
|
||||
@Override public void startReport( final Dialog dialog, String comment ){
|
||||
|
||||
// レポートの送信を開始する
|
||||
callReport( account, status, comment, new ReportCompleteCallback() {
|
||||
callReport( account, who, status, comment, new ReportCompleteCallback() {
|
||||
@Override public void onReportComplete( TootApiResult result ){
|
||||
|
||||
// 成功したらダイアログを閉じる
|
||||
|
@ -1957,17 +1965,19 @@ public class ActMain extends AppCompatActivity
|
|||
callBlock( access_info, status.account, false, null );
|
||||
}
|
||||
} );
|
||||
dialog.addAction( getString( R.string.report ), new Runnable() {
|
||||
@Override public void run(){
|
||||
openReportForm( access_info, status.account, status );
|
||||
}
|
||||
} );
|
||||
|
||||
if( access_info.isMe( status.account ) ){
|
||||
dialog.addAction( getString( R.string.delete ), new Runnable() {
|
||||
@Override public void run(){
|
||||
deleteStatus( access_info, status.id );
|
||||
}
|
||||
} );
|
||||
}else{
|
||||
dialog.addAction( getString( R.string.report ), new Runnable() {
|
||||
@Override public void run(){
|
||||
openReportForm( access_info, status.account, status );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if( column_type == Column.TYPE_CONVERSATION && status.application != null ){
|
||||
|
@ -1991,12 +2001,12 @@ public class ActMain extends AppCompatActivity
|
|||
if( column_type == Column.TYPE_FOLLOW_REQUESTS ){
|
||||
dialog.addAction( getString( R.string.follow_request_ok ), new Runnable() {
|
||||
@Override public void run(){
|
||||
callFollowRequestAuthorize( access_info, who ,true);
|
||||
callFollowRequestAuthorize( access_info, who, true );
|
||||
}
|
||||
} );
|
||||
dialog.addAction( getString( R.string.follow_request_ng ), new Runnable() {
|
||||
@Override public void run(){
|
||||
callFollowRequestAuthorize( access_info, who ,false);
|
||||
callFollowRequestAuthorize( access_info, who, false );
|
||||
}
|
||||
} );
|
||||
|
||||
|
@ -2044,15 +2054,14 @@ public class ActMain extends AppCompatActivity
|
|||
callBlock( access_info, who, false, null );
|
||||
}
|
||||
} );
|
||||
dialog.addAction( getString( R.string.report ), new Runnable() {
|
||||
@Override public void run(){
|
||||
openReportForm( access_info, who, null );
|
||||
}
|
||||
} );
|
||||
// dialog.addAction( getString( R.string.report ), new Runnable() {
|
||||
// @Override public void run(){
|
||||
// openReportForm( access_info, who, null );
|
||||
// }
|
||||
// } );
|
||||
dialog.show( this, null );
|
||||
}
|
||||
|
||||
|
||||
private void openOSSLicense(){
|
||||
startActivity( new Intent( this, ActOSSLicense.class ) );
|
||||
}
|
||||
|
|
|
@ -940,19 +940,14 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
|
||||
TootStatus status;
|
||||
|
||||
@Override
|
||||
protected TootApiResult doInBackground( Void... params ){
|
||||
@Override protected TootApiResult doInBackground( Void... params ){
|
||||
TootApiClient client = new TootApiClient( ActPost.this, new TootApiClient.Callback() {
|
||||
@Override
|
||||
public boolean isApiCancelled(){
|
||||
@Override public boolean isApiCancelled(){
|
||||
return isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishApiProgress( final String s ){
|
||||
@Override public void publishApiProgress( final String s ){
|
||||
Utils.runOnMainThread( new Runnable() {
|
||||
@Override
|
||||
public void run(){
|
||||
@Override public void run(){
|
||||
progress.setMessage( s );
|
||||
}
|
||||
} );
|
||||
|
@ -960,12 +955,16 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
} );
|
||||
|
||||
client.setAccount( target_account );
|
||||
String post_content = sb.toString();
|
||||
String digest = Utils.digestSHA256( post_content + target_account.acct );
|
||||
|
||||
Request.Builder request_builder = new Request.Builder()
|
||||
.post( RequestBody.create(
|
||||
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
|
||||
, sb.toString()
|
||||
) );
|
||||
, post_content
|
||||
) )
|
||||
.header( "Idempotency-Key" ,digest)
|
||||
;
|
||||
|
||||
TootApiResult result = client.request( "/api/v1/statuses", request_builder );
|
||||
if( result.object != null ){
|
||||
|
@ -986,7 +985,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
|
|||
|
||||
if( status != null ){
|
||||
ActMain.update_at_resume = true;
|
||||
ActPost.this.finish();
|
||||
//DEBUG ActPost.this.finish();
|
||||
}else{
|
||||
if( result != null ){
|
||||
Utils.showToast( ActPost.this, true, result.error );
|
||||
|
|
|
@ -17,6 +17,9 @@ import com.android.volley.RequestQueue;
|
|||
import com.android.volley.toolbox.ImageLoader;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import jp.juggler.subwaytooter.table.AcctSet;
|
||||
import jp.juggler.subwaytooter.table.MutedApp;
|
||||
import jp.juggler.subwaytooter.table.ClientInfo;
|
||||
|
@ -26,7 +29,11 @@ import jp.juggler.subwaytooter.table.MediaShown;
|
|||
import jp.juggler.subwaytooter.table.NotificationTracking;
|
||||
import jp.juggler.subwaytooter.table.SavedAccount;
|
||||
import jp.juggler.subwaytooter.table.UserRelation;
|
||||
import okhttp3.CipherSuite;
|
||||
import okhttp3.ConnectionSpec;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.TlsVersion;
|
||||
import okhttp3.internal.Util;
|
||||
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
|
||||
import uk.co.chrisjenx.calligraphy.TypefaceUtils;
|
||||
|
||||
|
@ -153,7 +160,8 @@ public class App1 extends Application {
|
|||
|
||||
}
|
||||
|
||||
public static final OkHttpClient ok_http_client = new OkHttpClient();
|
||||
public static OkHttpClient ok_http_client ;
|
||||
|
||||
|
||||
public static Typeface typeface_emoji ;
|
||||
|
||||
|
@ -179,6 +187,28 @@ public class App1 extends Application {
|
|||
typeface_emoji = TypefaceUtils.load(getAssets(), "emojione_android.ttf");
|
||||
}
|
||||
|
||||
if( ok_http_client == null ){
|
||||
// ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
|
||||
// .tlsVersions( TlsVersion.TLS_1_2)
|
||||
// .cipherSuites(
|
||||
// CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
// CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
// CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
|
||||
// .build();
|
||||
//
|
||||
// ArrayList<ConnectionSpec> spec_list = new ArrayList<>( );
|
||||
// spec_list.add(ConnectionSpec.MODERN_TLS );
|
||||
// // spec_list.add(ConnectionSpec.COMPATIBLE_TLS );
|
||||
// spec_list.add(ConnectionSpec.CLEARTEXT );
|
||||
// ok_http_client = new OkHttpClient.Builder()
|
||||
// .connectionSpecs( spec_list )
|
||||
// .build();
|
||||
|
||||
ok_http_client = new OkHttpClient();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( db_open_helper == null ){
|
||||
db_open_helper = new DBOpenHelper( getApplicationContext() );
|
||||
|
||||
|
|
|
@ -111,6 +111,7 @@ public class TootApiClient {
|
|||
try{
|
||||
response = call.execute();
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace( );
|
||||
return new TootApiResult(
|
||||
Utils.formatError( ex, context.getResources(), R.string.network_error )
|
||||
);
|
||||
|
@ -183,6 +184,7 @@ public class TootApiClient {
|
|||
try{
|
||||
response = call.execute();
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace( );
|
||||
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
|
||||
}
|
||||
if( callback.isApiCancelled() ) return null;
|
||||
|
@ -266,6 +268,7 @@ public class TootApiClient {
|
|||
try{
|
||||
response = call.execute();
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace( );
|
||||
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
|
||||
}
|
||||
if( callback.isApiCancelled() ) return null;
|
||||
|
@ -306,6 +309,7 @@ public class TootApiClient {
|
|||
try{
|
||||
response = call.execute();
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace( );
|
||||
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -74,3 +74,47 @@ public class TootAttachment {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// v1.3 から 添付ファイルの画像のピクセルサイズが取得できるようになった
|
||||
// https://github.com/tootsuite/mastodon/issues/1985
|
||||
// "media_attachments" : [
|
||||
// {
|
||||
// "id" : 4,
|
||||
// "type" : "image",
|
||||
// "remote_url" : "",
|
||||
// "meta" : {
|
||||
// "original" : {
|
||||
// "width" : 600,
|
||||
// "size" : "600x400",
|
||||
// "height" : 400,
|
||||
// "aspect" : 1.5
|
||||
// },
|
||||
// "small" : {
|
||||
// "aspect" : 1.49812734082397,
|
||||
// "height" : 267,
|
||||
// "size" : "400x267",
|
||||
// "width" : 400
|
||||
// }
|
||||
// },
|
||||
// "url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/004/original/3416fc5188c656da.jpg?1493138517",
|
||||
// "preview_url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/004/small/3416fc5188c656da.jpg?1493138517",
|
||||
// "text_url" : "http://127.0.0.1:3000/media/4hfW3Kt4U9UxDvV_xug"
|
||||
// },
|
||||
// {
|
||||
// "text_url" : "http://127.0.0.1:3000/media/0vTH_B1kjvIvlUBhGBw",
|
||||
// "preview_url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/003/small/23519a5e64064e32.png?1493138030",
|
||||
// "meta" : {
|
||||
// "fps" : 15,
|
||||
// "duration" : 5.06,
|
||||
// "width" : 320,
|
||||
// "size" : "320x180",
|
||||
// "height" : 180,
|
||||
// "length" : "0:00:05.06",
|
||||
// "aspect" : 1.77777777777778
|
||||
// },
|
||||
// "url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/003/original/23519a5e64064e32.mp4?1493138030",
|
||||
// "remote_url" : "",
|
||||
// "type" : "gifv",
|
||||
// "id" : 3
|
||||
// }
|
||||
// ],
|
|
@ -134,7 +134,7 @@ public class Utils {
|
|||
try{
|
||||
return str.getBytes( "UTF-8" );
|
||||
}catch( Throwable ex ){
|
||||
return new byte[0]; // 入力がnullの場合のみ発生
|
||||
return new byte[ 0 ]; // 入力がnullの場合のみ発生
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,39 +156,38 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static String optStringX( JSONObject src, String key){
|
||||
return src.isNull( key ) ? null : src.optString( key );
|
||||
public static String optStringX( JSONObject src, String key ){
|
||||
return src.isNull( key ) ? null : src.optString( key );
|
||||
}
|
||||
|
||||
public static String optStringX( JSONArray src, int key){
|
||||
return src.isNull( key ) ? null : src.optString( key );
|
||||
|
||||
public static String optStringX( JSONArray src, int key ){
|
||||
return src.isNull( key ) ? null : src.optString( key );
|
||||
}
|
||||
|
||||
public static ArrayList< String > parseStringArray( LogCategory log, JSONArray array ){
|
||||
ArrayList< String > dst_list = new ArrayList<>( );
|
||||
ArrayList< String > dst_list = new ArrayList<>();
|
||||
if( array != null ){
|
||||
for(int i=0,ie=array.length();i<ie;++i){
|
||||
String sv = Utils.optStringX(array,i);
|
||||
for( int i = 0, ie = array.length() ; i < ie ; ++ i ){
|
||||
String sv = Utils.optStringX( array, i );
|
||||
dst_list.add( sv );
|
||||
}
|
||||
}
|
||||
return dst_list;
|
||||
}
|
||||
|
||||
public static <T> boolean equalsNullable(T a,T b){
|
||||
public static < T > boolean equalsNullable( T a, T b ){
|
||||
return a == null ? b == null : a.equals( b );
|
||||
}
|
||||
|
||||
public static CharSequence dumpCodePoints(String str){
|
||||
public static CharSequence dumpCodePoints( String str ){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i=0,ie=str.length(),cp;i<ie;i+=Character.charCount(cp)){
|
||||
for( int i = 0, ie = str.length(), cp ; i < ie ; i += Character.charCount( cp ) ){
|
||||
cp = str.codePointAt( i );
|
||||
sb.append( String.format( "0x%x,", cp ) );
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
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 ){
|
||||
|
@ -304,6 +303,18 @@ public class Utils {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static String digestSHA256( String src ){
|
||||
if( src == null ) return null;
|
||||
try{
|
||||
MessageDigest md = MessageDigest.getInstance( "SHA-256" );
|
||||
md.reset();
|
||||
return encodeHex( md.digest( src.getBytes( "UTF-8" ) ) );
|
||||
}catch( Throwable ex ){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
static HashMap< Character, String > taisaku_map = new HashMap<>();
|
||||
|
@ -555,11 +566,11 @@ public class Utils {
|
|||
String s = context.getString( string_id );
|
||||
int end = s.length();
|
||||
int pos = s.indexOf( "%1$s" );
|
||||
if( pos == -1 ) return s;
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder( );
|
||||
if( pos > 0 ) sb.append(s.substring( 0,pos ));
|
||||
sb.append( display_name);
|
||||
if( pos +4 < end ) sb.append(s.substring( pos+4,end ));
|
||||
if( pos == - 1 ) return s;
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||
if( pos > 0 ) sb.append( s.substring( 0, pos ) );
|
||||
sb.append( display_name );
|
||||
if( pos + 4 < end ) sb.append( s.substring( pos + 4, end ) );
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
@ -814,14 +825,13 @@ public class Utils {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Activity getActivityFromView( View view) {
|
||||
public static Activity getActivityFromView( View view ){
|
||||
Context context = view.getContext();
|
||||
while (context instanceof ContextWrapper ) {
|
||||
if (context instanceof Activity) {
|
||||
return (Activity)context;
|
||||
while( context instanceof ContextWrapper ){
|
||||
if( context instanceof Activity ){
|
||||
return (Activity) context;
|
||||
}
|
||||
context = ((ContextWrapper)context).getBaseContext();
|
||||
context = ( (ContextWrapper) context ).getBaseContext();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue