diff --git a/.idea/dictionaries/tateisu.xml b/.idea/dictionaries/tateisu.xml
index b6dd600b..86b253ea 100644
--- a/.idea/dictionaries/tateisu.xml
+++ b/.idea/dictionaries/tateisu.xml
@@ -8,6 +8,7 @@
favourited
hashtag
hashtags
+ idempotency
noto
nsfw
reblog
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
index 9bc03365..1a953e37 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActMain.java
@@ -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 ) );
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/ActPost.java b/app/src/main/java/jp/juggler/subwaytooter/ActPost.java
index 640627d4..ea7cf484 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/ActPost.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/ActPost.java
@@ -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 );
diff --git a/app/src/main/java/jp/juggler/subwaytooter/App1.java b/app/src/main/java/jp/juggler/subwaytooter/App1.java
index b494ec62..8b0ba4ff 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/App1.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/App1.java
@@ -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 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() );
diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java
index 6f2cf59b..b8792792 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/api/TootApiClient.java
@@ -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 ) );
}
diff --git a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootAttachment.java b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootAttachment.java
index 248ffcd7..ab21ee8d 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootAttachment.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/api/entity/TootAttachment.java
@@ -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
+// }
+// ],
\ No newline at end of file
diff --git a/app/src/main/java/jp/juggler/subwaytooter/util/Utils.java b/app/src/main/java/jp/juggler/subwaytooter/util/Utils.java
index ae31e9f6..3c713fc4 100644
--- a/app/src/main/java/jp/juggler/subwaytooter/util/Utils.java
+++ b/app/src/main/java/jp/juggler/subwaytooter/util/Utils.java
@@ -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 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 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;
}