From 8cc08ba7872a8c6091c04455f7a89cdef332cf53 Mon Sep 17 00:00:00 2001 From: stom79 Date: Wed, 17 Oct 2018 14:34:29 +0200 Subject: [PATCH] Improve peertube - 2 --- .../mastodon/activities/PeertubeActivity.java | 132 +++++++----------- .../fr/gouv/etalab/mastodon/client/API.java | 58 +++++--- .../mastodon/client/Entities/Peertube.java | 19 +++ .../mastodon/drawers/PeertubeAdapter.java | 63 ++++----- .../gouv/etalab/mastodon/helper/Helper.java | 17 +++ app/src/main/res/layout/drawer_peertube.xml | 85 +++++++++++ app/src/main/res/values/strings.xml | 3 +- 7 files changed, 241 insertions(+), 136 deletions(-) create mode 100644 app/src/main/res/layout/drawer_peertube.xml diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/PeertubeActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/PeertubeActivity.java index 2cf4615b7..fee9f201a 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/PeertubeActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/PeertubeActivity.java @@ -15,20 +15,22 @@ package fr.gouv.etalab.mastodon.activities; -import android.annotation.SuppressLint; -import android.app.Dialog; +import android.Manifest; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.media.MediaPlayer; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; -import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.util.Log; +import android.text.Html; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -38,14 +40,7 @@ import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import android.widget.VideoView; - -import java.io.BufferedInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; import java.lang.ref.WeakReference; -import java.net.URL; -import java.net.URLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.List; @@ -68,7 +63,8 @@ import fr.gouv.etalab.mastodon.helper.FullScreenMediaController; import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface; -import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; +import static fr.gouv.etalab.mastodon.helper.Helper.EXTERNAL_STORAGE_REQUEST_CODE; +import static fr.gouv.etalab.mastodon.helper.Helper.manageDownloads; /** @@ -259,7 +255,45 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube peertube_download.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - new DownloadFileFromURL().execute(peertube.getStreamURL()); + if(Build.VERSION.SDK_INT >= 23 ){ + if (ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(PeertubeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, EXTERNAL_STORAGE_REQUEST_CODE); + } else { + manageDownloads(PeertubeActivity.this, peertube.getStreamURL()); + } + }else{ + manageDownloads(PeertubeActivity.this, peertube.getStreamURL()); + } + } + }); + + peertube_share.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent sendIntent = new Intent(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.shared_via)); + String url; + + url = "https://" +peertube.getInstance() + "/videos/watch/"+ peertube.getUuid(); + boolean share_details = sharedpreferences.getBoolean(Helper.SET_SHARE_DETAILS, true); + String extra_text; + if( share_details) { + extra_text = "@" +peertube.getAccount().getAcct(); + extra_text += "\r\n\r\n" + peertube.getName(); + extra_text += "\n\n" + Helper.shortnameToUnicode(":link:", true) + " " + url + "\r\n-\n"; + final String contentToot; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + contentToot = Html.fromHtml(peertube.getDescription(), Html.FROM_HTML_MODE_LEGACY).toString(); + else + //noinspection deprecation + contentToot = Html.fromHtml(peertube.getDescription()).toString(); + extra_text += contentToot; + }else { + extra_text = url; + } + sendIntent.putExtra(Intent.EXTRA_TEXT, extra_text); + sendIntent.setType("text/plain"); + startActivity(Intent.createChooser(sendIntent, getString(R.string.share_with))); } }); } @@ -274,9 +308,6 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube return; } List statuses = apiResponse.getStatuses(); - Log.v(Helper.TAG,"statuses " + statuses); - if( statuses != null) - Log.v(Helper.TAG,"size " + statuses.size()); if( statuses == null || statuses.size() == 0){ RelativeLayout no_action = findViewById(R.id.no_action); no_action.setVisibility(View.VISIBLE); @@ -297,73 +328,4 @@ public class PeertubeActivity extends BaseActivity implements OnRetrievePeertube } } - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case progress_bar_type: // we set this to 0 - pDialog = new ProgressDialog(PeertubeActivity.this); - pDialog.setMessage(getString(R.string.download_wait)); - pDialog.setIndeterminate(false); - pDialog.setMax(100); - pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - pDialog.setCancelable(true); - pDialog.show(); - return pDialog; - default: - return null; - } - } - - - /** - * https://stackoverflow.com/a/15758953 - */ - @SuppressLint("StaticFieldLeak") - class DownloadFileFromURL extends AsyncTask { - - @Override - protected void onPreExecute() { - super.onPreExecute(); - showDialog(progress_bar_type); - } - @Override - protected String doInBackground(String... f_url) { - int count; - try { - URL url = new URL(f_url[0]); - URLConnection conection = url.openConnection(); - conection.connect(); - int lenghtOfFile = conection.getContentLength(); - InputStream input = new BufferedInputStream(url.openStream(), - 8192); - OutputStream output = new FileOutputStream(Environment - .getExternalStorageDirectory().toString() - + "/2011.kml"); - byte data[] = new byte[1024]; - long total = 0; - while ((count = input.read(data)) != -1) { - total += count; - publishProgress("" + (int) ((total * 100) / lenghtOfFile)); - output.write(data, 0, count); - } - output.flush(); - output.close(); - input.close(); - - } catch (Exception e) { - } - - return null; - } - protected void onProgressUpdate(String... progress) { - pDialog.setProgress(Integer.parseInt(progress[0])); - } - - @Override - protected void onPostExecute(String file_url) { - dismissDialog(progress_bar_type); - } - - } } 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 1cb2164e6..bd1cb3bb7 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 @@ -16,7 +16,6 @@ package fr.gouv.etalab.mastodon.client; import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; import org.json.JSONArray; import org.json.JSONException; @@ -31,9 +30,11 @@ import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; @@ -621,7 +622,7 @@ public class API { HttpsConnection httpsConnection = new HttpsConnection(context); String response = httpsConnection.get("https://"+instance+"/api/v1/videos", 60, params, null); JSONArray jsonArray = new JSONObject(response).getJSONArray("data"); - peertubes = parsePeertube(jsonArray); + peertubes = parsePeertube(instance, jsonArray); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException e) { @@ -649,7 +650,7 @@ public class API { HttpsConnection httpsConnection = new HttpsConnection(context); String response = httpsConnection.get(String.format("https://"+instance+"/api/v1/videos/%s", videoId), 60, null, null); JSONObject jsonObject = new JSONObject(response); - peertube = parseSinglePeertube(context, jsonObject); + peertube = parseSinglePeertube(context, instance, jsonObject); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException e) { @@ -1546,6 +1547,9 @@ public class API { */ public Results search(String query) { + //A fix for peertube and account + if( query.startsWith("http") && query.split("@").length > 2) + query = "@"+query.split("@")[1] +"@"+ query.split("@")[2]; HashMap params = new HashMap<>(); params.put("q", query); try { @@ -2335,14 +2339,14 @@ public class API { * @param jsonArray JSONArray * @return List */ - private List parsePeertube(JSONArray jsonArray){ + private List parsePeertube(String instance, JSONArray jsonArray){ List peertubes = new ArrayList<>(); try { int i = 0; while (i < jsonArray.length() ){ JSONObject resobj = jsonArray.getJSONObject(i); - Peertube peertube = parsePeertube(context, resobj); + Peertube peertube = parsePeertube(context, instance, resobj); i++; peertubes.add(peertube); } @@ -2358,7 +2362,7 @@ public class API { * @param resobj JSONObject * @return Peertube */ - private static Peertube parsePeertube(Context context, JSONObject resobj){ + private static Peertube parsePeertube(Context context, String instance, JSONObject resobj){ Peertube peertube = new Peertube(); try { peertube.setId(resobj.get("id").toString()); @@ -2368,6 +2372,17 @@ public class API { peertube.setEmbedPath(resobj.get("embedPath").toString()); peertube.setPreviewPath(resobj.get("previewPath").toString()); peertube.setThumbnailPath(resobj.get("thumbnailPath").toString()); + peertube.setAccount(parseAccountResponsePeertube(context, instance, resobj.getJSONObject("account"))); + peertube.setInstance(instance); + peertube.setView(Integer.parseInt(resobj.get("views").toString())); + peertube.setLike(Integer.parseInt(resobj.get("likes").toString())); + peertube.setDislike(Integer.parseInt(resobj.get("dislikes").toString())); + peertube.setDuration(Integer.parseInt(resobj.get("duration").toString())); + try { + peertube.setCreated_at(Helper.mstStringToDate(context, resobj.get("createdAt").toString())); + } catch (ParseException e) { + e.printStackTrace(); + } } catch (JSONException e) { e.printStackTrace(); } @@ -2380,13 +2395,13 @@ public class API { * @param resobj JSONObject * @return Peertube */ - private static Peertube parseSinglePeertube(Context context, JSONObject resobj){ + private static Peertube parseSinglePeertube(Context context, String instance, JSONObject resobj){ Peertube peertube = new Peertube(); try { - Log.v(Helper.TAG,"resobj= " + resobj); peertube.setId(resobj.get("id").toString()); peertube.setUuid(resobj.get("uuid").toString()); peertube.setName(resobj.get("name").toString()); + peertube.setInstance(instance); peertube.setDescription(resobj.get("description").toString()); peertube.setEmbedPath(resobj.get("embedPath").toString()); peertube.setPreviewPath(resobj.get("previewPath").toString()); @@ -2395,6 +2410,7 @@ public class API { peertube.setLike(Integer.parseInt(resobj.get("likes").toString())); peertube.setDislike(Integer.parseInt(resobj.get("dislikes").toString())); peertube.setDuration(Integer.parseInt(resobj.get("duration").toString())); + peertube.setAccount(parseAccountResponsePeertube(context, instance, resobj.getJSONObject("account"))); try { peertube.setCreated_at(Helper.mstStringToDate(context, resobj.get("createdAt").toString())); } catch (ParseException e) { @@ -2419,7 +2435,6 @@ public class API { * @return Peertube */ private static List parseSinglePeertubeComments(Context context, String instance, JSONObject resobj){ - Peertube peertube = new Peertube(); List statuses = new ArrayList<>(); try { JSONArray jsonArray = resobj.getJSONArray("data"); @@ -2796,22 +2811,33 @@ public class API { * @param resobj JSONObject * @return Account */ - @SuppressWarnings("InfiniteRecursion") private static Account parseAccountResponsePeertube(Context context, String instance, JSONObject resobj){ - Account account = new Account(); try { account.setId(resobj.get("id").toString()); account.setUsername(resobj.get("name").toString()); account.setAcct(resobj.get("name").toString() + "@"+ resobj.get("host").toString()); account.setDisplay_name(resobj.get("displayName").toString()); - account.setCreated_at(Helper.mstStringToDate(context, resobj.get("createdAt").toString())); - account.setFollowers_count(Integer.valueOf(resobj.get("followersCount").toString())); - account.setFollowing_count(Integer.valueOf(resobj.get("followingCount").toString())); + if( resobj.has("createdAt") ) + account.setCreated_at(Helper.mstStringToDate(context, resobj.get("createdAt").toString())); + else + account.setCreated_at(new Date()); + + if( resobj.has("followersCount") ) + account.setFollowers_count(Integer.valueOf(resobj.get("followersCount").toString())); + else + account.setFollowers_count(0); + if( resobj.has("followingCount")) + account.setFollowing_count(Integer.valueOf(resobj.get("followingCount").toString())); + else + account.setFollowing_count(0); account.setStatuses_count(0); - account.setNote(resobj.get("description").toString()); + if( resobj.has("description") ) + account.setNote(resobj.get("description").toString()); + else + account.setNote(""); account.setUrl(resobj.get("url").toString()); - if( resobj.get("avatar").toString() != null && !resobj.get("avatar").toString().equals("null")){ + if( resobj.has("avatar") && !resobj.get("avatar").toString().equals("null")){ account.setAvatar("https://" + instance + resobj.getJSONObject("avatar").get("path")); }else account.setAvatar(null); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Peertube.java b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Peertube.java index 5dbf9ed6b..c6de12507 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Peertube.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/client/Entities/Peertube.java @@ -35,6 +35,9 @@ public class Peertube { private int dislike; private Date created_at; private int duration; + private String instance; + private Account account; + public String getId() { return id; @@ -139,4 +142,20 @@ public class Peertube { public void setDuration(int duration) { this.duration = duration; } + + public String getInstance() { + return instance; + } + + public void setInstance(String instance) { + this.instance = instance; + } + + public Account getAccount() { + return account; + } + + public void setAccount(Account account) { + this.account = account; + } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PeertubeAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PeertubeAdapter.java index 93eb6d16c..69b05ba56 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PeertubeAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PeertubeAdapter.java @@ -17,11 +17,8 @@ package fr.gouv.etalab.mastodon.drawers; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -38,14 +35,14 @@ import java.util.regex.Pattern; import fr.gouv.etalab.mastodon.R; import fr.gouv.etalab.mastodon.activities.PeertubeActivity; -import fr.gouv.etalab.mastodon.activities.WebviewActivity; import fr.gouv.etalab.mastodon.asynctasks.ManageListsAsyncTask; import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.client.Entities.Account; import fr.gouv.etalab.mastodon.client.Entities.Peertube; +import fr.gouv.etalab.mastodon.helper.CrossActions; import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnListActionInterface; -import static fr.gouv.etalab.mastodon.helper.Helper.changeDrawableColor; /** @@ -71,7 +68,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new PeertubeAdapter.ViewHolder(layoutInflater.inflate(R.layout.drawer_how_to_videos, parent, false)); + return new PeertubeAdapter.ViewHolder(layoutInflater.inflate(R.layout.drawer_peertube, parent, false)); } @Override @@ -81,30 +78,24 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio final PeertubeAdapter.ViewHolder holder = (PeertubeAdapter.ViewHolder) viewHolder; final Peertube peertube = peertubes.get(position); + Account account = peertube.getAccount(); - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + holder.peertube_account_name.setText(account.getAcct()); + holder.peertube_title.setText(peertube.getName()); + holder.peertube_duration.setText(context.getString(R.string.duration_video, Helper.secondsToString(peertube.getDuration()))); + holder.peertube_date.setText(String.format(" - %s", Helper.dateDiff(context, peertube.getCreated_at()))); + holder.peertube_views.setText(context.getString(R.string.number_view_video, Helper.withSuffix(peertube.getView()))); - if( theme == Helper.THEME_LIGHT){ - holder.how_to_container.setBackgroundResource(R.color.mastodonC3__); - changeDrawableColor(context, R.drawable.ic_keyboard_arrow_right,R.color.black); - }else if(theme == Helper.THEME_DARK){ - holder.how_to_container.setBackgroundResource(R.color.mastodonC1_); - changeDrawableColor(context, R.drawable.ic_keyboard_arrow_right,R.color.dark_text); - }else if(theme == Helper.THEME_BLACK) { - holder.how_to_container.setBackgroundResource(R.color.black_2); - changeDrawableColor(context, R.drawable.ic_keyboard_arrow_right,R.color.dark_text); - } - Drawable next = ContextCompat.getDrawable(context, R.drawable.ic_keyboard_arrow_right); - holder.how_to_description.setText(peertube.getDescription()); - holder.how_to_title.setText(peertube.getName()); - assert next != null; - final float scale = context.getResources().getDisplayMetrics().density; - next.setBounds(0,0,(int) (30 * scale + 0.5f),(int) (30 * scale + 0.5f)); - holder.how_to_description.setCompoundDrawables(null, null, next, null); - Glide.with(holder.how_to_image.getContext()) - .load("https://" + instance + peertube.getThumbnailPath()) - .into(holder.how_to_image); + holder.peertube_profile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CrossActions.doCrossProfile(context, account); + } + }); + Glide.with(holder.peertube_video_image.getContext()) + .load("https://" + peertube.getInstance() + peertube.getThumbnailPath()) + .into(holder.peertube_video_image); + Helper.loadGiF(context, account.getAvatar(), holder.peertube_profile); holder.how_to_container.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -144,15 +135,19 @@ public class PeertubeAdapter extends RecyclerView.Adapter implements OnListActio class ViewHolder extends RecyclerView.ViewHolder{ LinearLayout how_to_container; - ImageView how_to_image; - TextView how_to_description; - TextView how_to_title; + ImageView peertube_profile, peertube_video_image; + TextView peertube_account_name, peertube_views, peertube_duration; + TextView peertube_title, peertube_date; public ViewHolder(@NonNull View itemView) { super(itemView); - how_to_description = itemView.findViewById(R.id.how_to_description); - how_to_title = itemView.findViewById(R.id.how_to_title); - how_to_image = itemView.findViewById(R.id.how_to_image); + peertube_account_name = itemView.findViewById(R.id.peertube_account_name); + peertube_title = itemView.findViewById(R.id.peertube_title); + peertube_video_image = itemView.findViewById(R.id.peertube_video_image); + peertube_profile = itemView.findViewById(R.id.peertube_profile); how_to_container = itemView.findViewById(R.id.how_to_container); + peertube_date = itemView.findViewById(R.id.peertube_date); + peertube_views = itemView.findViewById(R.id.peertube_views); + peertube_duration = itemView.findViewById(R.id.peertube_duration); } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index 55adbce4d..1964fd885 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -2056,6 +2056,23 @@ public class Helper { return output; } + public static String secondsToString(int pTime) { + + int hour = pTime/3660; + int min = pTime/60; + int sec = pTime-(min*60); + String strHour="0", strMin="0", strSec="0"; + + if( hour > 0 ) + strHour = String.format(Locale.getDefault(), "%02d", hour); + if( min > 0 ) + strMin = String.format(Locale.getDefault(), "%02d", min); + strSec = String.format(Locale.getDefault(), "%02d", sec); + if( hour > 0 ) + return String.format(Locale.getDefault(),"%s:%s:%s",strHour, strMin,strSec); + else + return String.format(Locale.getDefault(), "%s:%s",strMin,strSec); + } public static void loadGiF(final Context context, String url, final ImageView imageView){ SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); diff --git a/app/src/main/res/layout/drawer_peertube.xml b/app/src/main/res/layout/drawer_peertube.xml new file mode 100644 index 000000000..2c3c586cd --- /dev/null +++ b/app/src/main/res/layout/drawer_peertube.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9892cdb73..f610a47c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -636,8 +636,9 @@ Peertube instance Display private messages timeline Keep background process when app is closed - Downloading file. Please wait... Be the first to leave a comment on this video with the top right button! + %s views + Duration: %s Never