diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java index 942e6bd63..b4b025725 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/ShowConversationActivity.java @@ -30,6 +30,7 @@ import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.MotionEvent; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index f4bdfc008..4e3fe0a08 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -49,7 +49,6 @@ import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; @@ -68,6 +67,7 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.TimePicker; import android.widget.Toast; @@ -105,7 +105,7 @@ import fr.gouv.etalab.mastodon.asynctasks.RetrieveAccountsForReplyAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAccountsAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.RetrieveSearchAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateDescriptionAttachmentAsyncTask; -import fr.gouv.etalab.mastodon.asynctasks.UploadActionAsyncTask; +import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Attachment; @@ -146,7 +146,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc private String visibility; private final int PICK_IMAGE = 56556; - private ProgressBar loading_picture; private ImageButton toot_picture; private ImageLoader imageLoader; private DisplayImageOptions options; @@ -235,7 +234,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc toot_space_left = findViewById(R.id.toot_space_left); toot_visibility = findViewById(R.id.toot_visibility); toot_picture = findViewById(R.id.toot_picture); - loading_picture = findViewById(R.id.loading_picture); toot_picture_container = findViewById(R.id.toot_picture_container); toot_content = findViewById(R.id.toot_content); int newInputType = toot_content.getInputType() & (toot_content.getInputType() ^ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); @@ -243,8 +241,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc toot_cw_content = findViewById(R.id.toot_cw_content); picture_scrollview = findViewById(R.id.picture_scrollview); toot_sensitive = findViewById(R.id.toot_sensitive); - - drawer_layout = findViewById(R.id.drawer_layout); drawer_layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override @@ -323,10 +319,9 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc byte[] bitmapdata = bos.toByteArray(); ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata); toot_picture_container.setVisibility(View.VISIBLE); - loading_picture.setVisibility(View.VISIBLE); picture_scrollview.setVisibility(View.VISIBLE); toot_picture.setEnabled(false); - new UploadActionAsyncTask(getApplicationContext(), bs, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new API(getApplicationContext()).uploadMedia(bs, TootActivity.this); } toot_content.setText(String.format("\n\nvia @%s\n\n%s\n\n", tootMention, urlMention)); toot_space_left.setText(String.valueOf(toot_content.length())); @@ -393,9 +388,8 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc picture_scrollview.setVisibility(View.VISIBLE); InputStream bis = new ByteArrayInputStream(binaryData); toot_picture_container.setVisibility(View.VISIBLE); - loading_picture.setVisibility(View.VISIBLE); toot_picture.setEnabled(false); - new UploadActionAsyncTask(getApplicationContext(),bis,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new API(getApplicationContext()).uploadMedia(bis, TootActivity.this); f.write(binaryData); f.close(); } catch (IOException e) { @@ -680,15 +674,13 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc try { InputStream inputStream = getContentResolver().openInputStream(fileUri); toot_picture_container.setVisibility(View.VISIBLE); - loading_picture.setVisibility(View.VISIBLE); picture_scrollview.setVisibility(View.VISIBLE); toot_picture.setEnabled(false); - new UploadActionAsyncTask(getApplicationContext(), inputStream, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new API(getApplicationContext()).uploadMedia(inputStream, TootActivity.this); count++; } catch (FileNotFoundException e) { Toast.makeText(getApplicationContext(), R.string.toot_select_image_error, Toast.LENGTH_LONG).show(); - loading_picture.setVisibility(View.GONE); toot_picture.setEnabled(true); e.printStackTrace(); } @@ -712,12 +704,10 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc //noinspection ConstantConditions InputStream inputStream = getContentResolver().openInputStream(data.getData()); toot_picture_container.setVisibility(View.VISIBLE); - loading_picture.setVisibility(View.VISIBLE); toot_picture.setEnabled(false); - new UploadActionAsyncTask(getApplicationContext(),inputStream,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new API(getApplicationContext()).uploadMedia(inputStream, TootActivity.this); } catch (FileNotFoundException e) { Toast.makeText(getApplicationContext(),R.string.toot_select_image_error,Toast.LENGTH_LONG).show(); - loading_picture.setVisibility(View.GONE); toot_picture.setEnabled(true); e.printStackTrace(); } @@ -978,7 +968,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc @Override public void onRetrieveAttachment(final Attachment attachment, Error error) { - loading_picture.setVisibility(View.GONE); if( error != null){ final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); boolean show_error_messages = sharedpreferences.getBoolean(Helper.SET_SHOW_ERROR_MESSAGES, true); @@ -1087,6 +1076,21 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } } + @Override + public void onUpdateProgress(int progress) { + ProgressBar progressBar = findViewById(R.id.upload_progress); + TextView toolbar_text = findViewById(R.id.toolbar_text); + RelativeLayout progress_bar_container = findViewById(R.id.progress_bar_container); + if( progress <= 100) { + progressBar.setScaleY(3f); + progress_bar_container.setVisibility(View.VISIBLE); + progressBar.setProgress(progress); + toolbar_text.setText(String.format("%s%%", progress)); + }else{ + progress_bar_container.setVisibility(View.GONE); + } + } + /** * Removes a media @@ -1378,7 +1382,6 @@ public class TootActivity extends AppCompatActivity implements OnRetrieveSearcAc } toRemove.clear(); } - loading_picture.setVisibility(View.GONE); if( attachments != null && attachments.size() > 0){ toot_picture_container.setVisibility(View.VISIBLE); picture_scrollview.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UploadActionAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UploadActionAsyncTask.java deleted file mode 100644 index 8521fc293..000000000 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/UploadActionAsyncTask.java +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2017 Thomas Schneider - * - * This file is a part of Mastalab - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Mastalab; if not, - * see . */ -package fr.gouv.etalab.mastodon.asynctasks; - -import android.content.Context; -import android.os.AsyncTask; - -import java.io.InputStream; -import java.lang.ref.WeakReference; - -import fr.gouv.etalab.mastodon.client.API; -import fr.gouv.etalab.mastodon.client.Entities.Attachment; -import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface; - - -/** - * Created by Thomas on 01/05/2017. - * Proceeds to file upload - */ - -public class UploadActionAsyncTask extends AsyncTask { - - private OnRetrieveAttachmentInterface listener; - private Attachment attachment; - private InputStream inputStream; - private API api; - private WeakReference contextReference; - - public UploadActionAsyncTask(Context context, InputStream inputStream, OnRetrieveAttachmentInterface onRetrieveAttachmentInterface){ - this.contextReference = new WeakReference<>(context); - this.listener = onRetrieveAttachmentInterface; - this.inputStream = inputStream; - } - - @Override - protected Void doInBackground(Void... params) { - api = new API(this.contextReference.get()); - attachment = api.uploadMedia(inputStream); - return null; - } - - @Override - protected void onPostExecute(Void result) { - listener.onRetrieveAttachment(attachment, api.getError()); - } - -} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java index bfa5e375f..2960a4c7d 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/API.java @@ -17,9 +17,9 @@ package fr.gouv.etalab.mastodon.client; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; import android.widget.Toast; +import com.loopj.android.http.AsyncHttpClient; import com.loopj.android.http.AsyncHttpResponseHandler; import com.loopj.android.http.JsonHttpResponseHandler; import com.loopj.android.http.RequestParams; @@ -29,7 +29,12 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.lang.*; import java.security.KeyManagementException; import java.security.KeyStoreException; @@ -44,6 +49,7 @@ import cz.msebera.android.httpclient.Header; import fr.gouv.etalab.mastodon.client.Entities.*; import fr.gouv.etalab.mastodon.client.Entities.Error; import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveAttachmentInterface; import mastodon.etalab.gouv.fr.mastodon.R; import static fr.gouv.etalab.mastodon.helper.Helper.USER_AGENT; @@ -60,6 +66,7 @@ public class API { private SyncHttpClient client = new SyncHttpClient(); + private AsyncHttpClient asyncClient = new AsyncHttpClient(); private Account account; private Context context; @@ -1267,34 +1274,79 @@ public class API { * @param inputStream InputStream * @return Attachment */ - public Attachment uploadMedia(InputStream inputStream){ + public Attachment uploadMedia(InputStream inputStream, final OnRetrieveAttachmentInterface listener){ + File file = null; + try { + file = new File(context.getCacheDir(), "cacheFileAppeal.srl"); + OutputStream output = new FileOutputStream(file); + try { + byte[] buffer = new byte[4 * 1024]; // or other buffer size + int read; - RequestParams params = new RequestParams(); - params.put("file", inputStream); - - post("/media", 240000, params, new JsonHttpResponseHandler() { - - @Override - public void onSuccess(int statusCode, Header[] headers, JSONObject response) { - attachment = parseAttachmentResponse(response); - } - @Override - public void onSuccess(int statusCode, Header[] headers, JSONArray response) { - try { - attachment = parseAttachmentResponse(response.getJSONObject(0)); - } catch (JSONException e) { - e.printStackTrace(); + while ((read = inputStream.read(buffer)) != -1) { + output.write(buffer, 0, read); } + output.flush(); + } finally { + output.close(); } - @Override - public void onFailure(int statusCode, Header[] headers, Throwable error, JSONObject response){ - setError(statusCode, error); - } - @Override - public void onFailure(int statusCode, Header[] headers, String message, Throwable error){ - setError(statusCode, error); - } - }); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + RequestParams params = new RequestParams(); + try { + params.put("file", file); + postAsync("/media", 240000, params, new JsonHttpResponseHandler() { + + @Override + public void onStart(){ + listener.onUpdateProgress(0); + } + @Override + public void onProgress(long bytesWritten, long totalSize){ + int progress = (int)((bytesWritten*100/totalSize)); + listener.onUpdateProgress(progress); + } + + @Override + public void onSuccess(int statusCode, Header[] headers, JSONObject response) { + attachment = parseAttachmentResponse(response); + listener.onUpdateProgress(101); + listener.onRetrieveAttachment(attachment, null); + } + + @Override + public void onSuccess(int statusCode, Header[] headers, JSONArray response) { + try { + attachment = parseAttachmentResponse(response.getJSONObject(0)); + listener.onUpdateProgress(101); + listener.onRetrieveAttachment(attachment, null); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void onFailure(int statusCode, Header[] headers, Throwable error, JSONObject response) { + listener.onUpdateProgress(101); + APIError = new Error(); + APIError.setError(statusCode + " - " + error.getMessage()); + listener.onRetrieveAttachment(null, APIError); + } + + @Override + public void onFailure(int statusCode, Header[] headers, String message, Throwable error) { + listener.onUpdateProgress(101); + APIError = new Error(); + APIError.setError(statusCode + " - " + error.getMessage()); + listener.onRetrieveAttachment(null, APIError); + } + }); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } return attachment; } @@ -1887,6 +1939,23 @@ public class API { } } + + private void postAsync(String action, int timeout, RequestParams params, AsyncHttpResponseHandler responseHandler) { + try { + asyncClient.setConnectTimeout(timeout); + asyncClient.setUserAgent(USER_AGENT); + asyncClient.addHeader("Authorization", "Bearer "+prefKeyOauthTokenT); + MastalabSSLSocketFactory mastalabSSLSocketFactory = new MastalabSSLSocketFactory(MastalabSSLSocketFactory.getKeystore()); + mastalabSSLSocketFactory.setHostnameVerifier(MastalabSSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + asyncClient.setSSLSocketFactory(mastalabSSLSocketFactory); + asyncClient.post(getAbsoluteUrl(action), params, responseHandler); + } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | UnrecoverableKeyException e) { + Toast.makeText(context, R.string.toast_error,Toast.LENGTH_LONG).show(); + e.printStackTrace(); + } + } + + public Error getError(){ return APIError; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveAttachmentInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveAttachmentInterface.java index 9c93e297d..ebd100f2c 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveAttachmentInterface.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrieveAttachmentInterface.java @@ -23,4 +23,5 @@ import fr.gouv.etalab.mastodon.client.Entities.Error; */ public interface OnRetrieveAttachmentInterface { void onRetrieveAttachment(Attachment attachment, Error error); + void onUpdateProgress(int progress); } diff --git a/app/src/main/res/layout/activity_toot.xml b/app/src/main/res/layout/activity_toot.xml index 926d64811..82520bf16 100644 --- a/app/src/main/res/layout/activity_toot.xml +++ b/app/src/main/res/layout/activity_toot.xml @@ -53,6 +53,30 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> + + + + + -