diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3c7f270ea..57facc615 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -141,7 +141,6 @@ /> 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); + RecyclerView lv_comments = findViewById(R.id.peertube_comments); + lv_comments.setVisibility(View.GONE); + }else { + SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + boolean isOnWifi = Helper.isOnWIFI(PeertubeActivity.this); + int behaviorWithAttachments = sharedpreferences.getInt(Helper.SET_ATTACHMENT_ACTION, Helper.ATTACHMENT_ALWAYS); + int positionSpinnerTrans = sharedpreferences.getInt(Helper.SET_TRANSLATOR, Helper.TRANS_YANDEX); + String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); + StatusListAdapter statusListAdapter = new StatusListAdapter(PeertubeActivity.this, RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE, userId, isOnWifi, behaviorWithAttachments, positionSpinnerTrans, statuses); + RecyclerView lv_comments = findViewById(R.id.peertube_comments); + LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this); + lv_comments.setLayoutManager(mLayoutManager); + lv_comments.setNestedScrollingEnabled(false); + lv_comments.setAdapter(statusListAdapter); + + } + } + + @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/asynctasks/RetrievePeertubeSingleCommentsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrievePeertubeSingleCommentsAsyncTask.java new file mode 100644 index 000000000..7f95dab70 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrievePeertubeSingleCommentsAsyncTask.java @@ -0,0 +1,64 @@ +/* Copyright 2018 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.lang.ref.WeakReference; + +import fr.gouv.etalab.mastodon.client.API; +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.interfaces.OnRetrievePeertubeInterface; + + +/** + * Created by Thomas on 16/10/2018. + * Retrieves peertube single + */ + +public class RetrievePeertubeSingleCommentsAsyncTask extends AsyncTask { + + + + private APIResponse apiResponse; + private String videoId; + private OnRetrievePeertubeInterface listener; + private WeakReference contextReference; + private String instanceName; + + + + public RetrievePeertubeSingleCommentsAsyncTask(Context context, String instanceName, String videoId, OnRetrievePeertubeInterface onRetrievePeertubeInterface){ + this.contextReference = new WeakReference<>(context); + this.videoId = videoId; + this.listener = onRetrievePeertubeInterface; + this.instanceName = instanceName; + } + + + + @Override + protected Void doInBackground(Void... params) { + API api = new API(this.contextReference.get()); + apiResponse = api.getSinglePeertubeComments(this.instanceName, videoId); + return null; + } + + @Override + protected void onPostExecute(Void result) { + listener.onRetrievePeertubeComments(apiResponse); + } +} 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 50089b710..1cb2164e6 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 @@ -649,7 +649,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(jsonObject); + peertube = parseSinglePeertube(context, jsonObject); } catch (HttpsConnection.HttpsConnectionException e) { setError(e.getStatusCode(), e); } catch (NoSuchAlgorithmException e) { @@ -667,6 +667,31 @@ public class API { return apiResponse; } + /** + * Retrieves Peertube videos from an instance *synchronously* + * @return APIResponse + */ + public APIResponse getSinglePeertubeComments(String instance, String videoId) { + statuses = new ArrayList<>(); + try { + HttpsConnection httpsConnection = new HttpsConnection(context); + String response = httpsConnection.get(String.format("https://"+instance+"/api/v1/videos/%s/comment-threads", videoId), 60, null, null); + JSONObject jsonObject = new JSONObject(response); + statuses = parseSinglePeertubeComments(context, instance, jsonObject); + } catch (HttpsConnection.HttpsConnectionException e) { + setError(e.getStatusCode(), e); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } catch (JSONException e) { + e.printStackTrace(); + } + apiResponse.setStatuses(statuses); + return apiResponse; + } /** * Retrieves home timeline for the account *synchronously* @@ -2355,9 +2380,10 @@ public class API { * @param resobj JSONObject * @return Peertube */ - private static Peertube parseSinglePeertube(JSONObject resobj){ + private static Peertube parseSinglePeertube(Context context, 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()); @@ -2365,6 +2391,15 @@ public class API { peertube.setEmbedPath(resobj.get("embedPath").toString()); peertube.setPreviewPath(resobj.get("previewPath").toString()); peertube.setThumbnailPath(resobj.get("thumbnailPath").toString()); + 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(); + } JSONArray files = resobj.getJSONArray("files"); for(int j = 0 ; j < files.length() ; j++){ @@ -2378,6 +2413,44 @@ public class API { return peertube; } + /** + * Parse json response for peertube comments + * @param resobj JSONObject + * @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"); + int i = 0; + while (i < jsonArray.length() ){ + Status status = new Status(); + JSONObject comment = jsonArray.getJSONObject(i); + status.setId(comment.get("id").toString()); + status.setUri(comment.get("url").toString()); + status.setUrl(comment.get("url").toString()); + status.setSensitive(false); + status.setSpoiler_text(""); + status.setContent(comment.get("text").toString()); + status.setIn_reply_to_id(comment.get("inReplyToCommentId").toString()); + status.setAccount(parseAccountResponsePeertube(context, instance, comment.getJSONObject("account"))); + status.setCreated_at(Helper.mstStringToDate(context, comment.get("createdAt").toString())); + status.setMentions(new ArrayList<>()); + status.setEmojis(new ArrayList<>()); + status.setMedia_attachments(new ArrayList<>()); + status.setVisibility("public"); + i++; + statuses.add(status); + } + } catch (JSONException e) { + e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } + return statuses; + } + /** * Parse json response for unique how to * @param resobj JSONObject @@ -2718,6 +2791,37 @@ public class API { } + /** + * Parse json response an unique peertube account + * @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())); + account.setStatuses_count(0); + account.setNote(resobj.get("description").toString()); + account.setUrl(resobj.get("url").toString()); + if( resobj.get("avatar").toString() != null && !resobj.get("avatar").toString().equals("null")){ + account.setAvatar("https://" + instance + resobj.getJSONObject("avatar").get("path")); + }else + account.setAvatar(null); + account.setAvatar_static(resobj.get("avatar").toString()); + } catch (JSONException ignored) {} catch (ParseException e) { + e.printStackTrace(); + } + return account; + } + /** * Parse json response an unique account * @param resobj JSONObject 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 71d00eb6c..5dbf9ed6b 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 @@ -14,6 +14,8 @@ * see . */ package fr.gouv.etalab.mastodon.client.Entities; +import java.util.Date; + /** * Created by Thomas on 29/09/2018. * Manage how to videos @@ -28,6 +30,11 @@ public class Peertube { private String previewPath; private String embedPath; private String streamURL; + private int view; + private int like; + private int dislike; + private Date created_at; + private int duration; public String getId() { return id; @@ -92,4 +99,44 @@ public class Peertube { public void setStreamURL(String streamURL) { this.streamURL = streamURL; } + + public int getView() { + return view; + } + + public void setView(int view) { + this.view = view; + } + + public int getLike() { + return like; + } + + public void setLike(int like) { + this.like = like; + } + + public int getDislike() { + return dislike; + } + + public void setDislike(int dislike) { + this.dislike = dislike; + } + + public Date getCreated_at() { + return created_at; + } + + public void setCreated_at(Date created_at) { + this.created_at = created_at; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = 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 f8d00ca2b..55adbce4d 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 @@ -2066,6 +2066,13 @@ public class Helper { return; } } + if( url == null) { + Glide.with(imageView.getContext()) + .load(R.drawable.missing) + .apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10))) + .into(imageView); + return; + } if( !disableGif) Glide.with(imageView.getContext()) .load(url) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrievePeertubeInterface.java b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrievePeertubeInterface.java index 506c52f34..8c64cf4e0 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrievePeertubeInterface.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/interfaces/OnRetrievePeertubeInterface.java @@ -22,4 +22,5 @@ import fr.gouv.etalab.mastodon.client.APIResponse; */ public interface OnRetrievePeertubeInterface { void onRetrievePeertube(APIResponse apiResponse); + void onRetrievePeertubeComments(APIResponse apiResponse); } diff --git a/app/src/main/res/drawable-anydpi/ic_cloud_download_peertube.xml b/app/src/main/res/drawable-anydpi/ic_cloud_download_peertube.xml new file mode 100644 index 000000000..d11e9d8d2 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_cloud_download_peertube.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_share_peertube.xml b/app/src/main/res/drawable-anydpi/ic_share_peertube.xml new file mode 100644 index 000000000..5f7aed400 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_share_peertube.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_thumb_down_peertube.xml b/app/src/main/res/drawable-anydpi/ic_thumb_down_peertube.xml new file mode 100644 index 000000000..6cb0649c9 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_thumb_down_peertube.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_thumb_up_peertube.xml b/app/src/main/res/drawable-anydpi/ic_thumb_up_peertube.xml new file mode 100644 index 000000000..fb115d5d2 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_thumb_up_peertube.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable-anydpi/ic_visibility_peertube.xml b/app/src/main/res/drawable-anydpi/ic_visibility_peertube.xml new file mode 100644 index 000000000..42ed85bee --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_visibility_peertube.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/missing.png b/app/src/main/res/drawable/missing.png new file mode 100644 index 000000000..34c8e45e6 Binary files /dev/null and b/app/src/main/res/drawable/missing.png differ diff --git a/app/src/main/res/layout/activity_peertube.xml b/app/src/main/res/layout/activity_peertube.xml index 5ab77f279..c3d8402bb 100644 --- a/app/src/main/res/layout/activity_peertube.xml +++ b/app/src/main/res/layout/activity_peertube.xml @@ -24,26 +24,165 @@ android:layout_height="match_parent" tools:context=".activities.PeertubeActivity"> - - - - - + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 334fa7819..9892cdb73 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -636,6 +636,8 @@ 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! Never