diff --git a/app/src/main/java/io/lbry/browser/MainActivity.java b/app/src/main/java/io/lbry/browser/MainActivity.java index 522e1cdf..fcd34261 100644 --- a/app/src/main/java/io/lbry/browser/MainActivity.java +++ b/app/src/main/java/io/lbry/browser/MainActivity.java @@ -336,6 +336,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener // preference keys public static final String PREFERENCE_KEY_BACKGROUND_PLAYBACK = "io.lbry.browser.preference.userinterface.BackgroundPlayback"; + public static final String PREFERENCE_KEY_MEDIA_AUTOPLAY = "io.lbry.browser.preference.userinterface.MediaAutoplay"; public static final String PREFERENCE_KEY_DARK_MODE = "io.lbry.browser.preference.userinterface.DarkMode"; public static final String PREFERENCE_KEY_SHOW_MATURE_CONTENT = "io.lbry.browser.preference.userinterface.ShowMatureContent"; public static final String PREFERENCE_KEY_SHOW_URL_SUGGESTIONS = "io.lbry.browser.preference.userinterface.UrlSuggestions"; @@ -680,6 +681,11 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener return sp.getBoolean(PREFERENCE_KEY_BACKGROUND_PLAYBACK, true); } + public boolean isMediaAutoplayEnabled() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); + return sp.getBoolean(PREFERENCE_KEY_MEDIA_AUTOPLAY, true); + } + public boolean initialSubscriptionMergeDone() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); return sp.getBoolean(PREFERENCE_KEY_INTERNAL_INITIAL_SUBSCRIPTION_MERGE_DONE, false); diff --git a/app/src/main/java/io/lbry/browser/tasks/CommentCreateTask.java b/app/src/main/java/io/lbry/browser/tasks/CommentCreateTask.java index 5cdce1d9..54f810e6 100644 --- a/app/src/main/java/io/lbry/browser/tasks/CommentCreateTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/CommentCreateTask.java @@ -7,18 +7,29 @@ import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; -import java.util.Objects; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.TimeUnit; import io.lbry.browser.exceptions.ApiCallException; import io.lbry.browser.model.Comment; -import io.lbry.browser.utils.Comments; import io.lbry.browser.utils.Helper; +import io.lbry.browser.utils.Lbry; +import io.lbry.browser.utils.Lbryio; +import okhttp3.OkHttpClient; +import okhttp3.Request; import okhttp3.Response; public class CommentCreateTask extends AsyncTask { - private final Comment comment; - private final View progressView; - private final CommentCreateWithTipHandler handler; + private static final String STATUS_ENDPOINT = "https://comments.lbry.com"; + + private Comment comment; + private View progressView; + private CommentCreateWithTipHandler handler; private Exception error; public CommentCreateTask(Comment comment, View progressView, CommentCreateWithTipHandler handler) { @@ -35,31 +46,29 @@ public class CommentCreateTask extends AsyncTask { Comment createdComment = null; try { // check comments status endpoint - Comments.checkCommentsEndpointStatus(); + Request request = new Request.Builder().url(STATUS_ENDPOINT).build(); + OkHttpClient client = new OkHttpClient.Builder(). + writeTimeout(30, TimeUnit.SECONDS). + readTimeout(30, TimeUnit.SECONDS). + build(); + Response response = client.newCall(request).execute(); + JSONObject status = new JSONObject(response.body().string()); + String statusText = Helper.getJSONString("text", null, status); + boolean isRunning = Helper.getJSONBoolean("is_running", false, status); + if (!"ok".equalsIgnoreCase(statusText) || !isRunning) { + throw new ApiCallException("The comment server is not available at this time. Please try again later."); + } - JSONObject comment_body = new JSONObject(); - comment_body.put("comment", comment.getText()); - comment_body.put("claim_id", comment.getClaimId()); + Map options = new HashMap<>(); + options.put("comment", comment.getText()); + options.put("claim_id", comment.getClaimId()); + options.put("channel_id", comment.getChannelId()); + options.put("channel_name", comment.getChannelName()); if (!Helper.isNullOrEmpty(comment.getParentId())) { - comment_body.put("parent_id", comment.getParentId()); + options.put("parent_id", comment.getParentId()); } - comment_body.put("channel_id", comment.getChannelId()); - comment_body.put("channel_name", comment.getChannelName()); - - JSONObject jsonChannelSign = Comments.channelSign(comment_body, comment.getChannelId(), comment.getChannelName()); - - if (jsonChannelSign.has("signature") && jsonChannelSign.has("signing_ts")) { - comment_body.put("signature", jsonChannelSign.getString("signature")); - comment_body.put("signing_ts", jsonChannelSign.getString("signing_ts")); - } - - Response resp = Comments.performRequest(comment_body, "comment.Create"); - String responseString = Objects.requireNonNull(resp.body()).string(); - resp.close(); - JSONObject jsonResponse = new JSONObject(responseString); - - if (jsonResponse.has("result")) - createdComment = Comment.fromJSONObject(jsonResponse.getJSONObject("result")); + JSONObject jsonObject = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_COMMENT_CREATE, options); + createdComment = Comment.fromJSONObject(jsonObject); } catch (ApiCallException | ClassCastException | IOException | JSONException ex) { error = ex; } diff --git a/app/src/main/java/io/lbry/browser/tasks/CommentListTask.java b/app/src/main/java/io/lbry/browser/tasks/CommentListTask.java index 36cf3131..2833e003 100644 --- a/app/src/main/java/io/lbry/browser/tasks/CommentListTask.java +++ b/app/src/main/java/io/lbry/browser/tasks/CommentListTask.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.Map; import io.lbry.browser.model.Comment; -import io.lbry.browser.utils.Comments; import io.lbry.browser.utils.Helper; import io.lbry.browser.utils.Lbry; @@ -22,8 +21,8 @@ public class CommentListTask extends AsyncTask> { private final int page; private final int pageSize; private final String claim; - private final ProgressBar progressBar; - private final CommentListHandler handler; + private ProgressBar progressBar; + private CommentListHandler handler; private Exception error; public CommentListTask(int page, int pageSize, String claim, ProgressBar progressBar, CommentListHandler handler) { @@ -53,7 +52,7 @@ public class CommentListTask extends AsyncTask> { options.put("skip_validation", true); options.put("visible", true); - JSONObject result = (JSONObject) Lbry.parseResponse(Comments.performRequest(Lbry.buildJsonParams(options), "comment.List")); + JSONObject result = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_COMMENT_LIST, options); JSONArray items = result.getJSONArray("items"); List children = new ArrayList<>(); diff --git a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java index e04e5068..b2248c62 100644 --- a/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java +++ b/app/src/main/java/io/lbry/browser/ui/findcontent/FileViewFragment.java @@ -12,7 +12,6 @@ import android.graphics.Color; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; import android.text.Editable; import android.text.TextWatcher; import android.text.format.DateUtils; @@ -98,6 +97,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -284,14 +284,13 @@ public class FileViewFragment extends BaseFragment implements fileViewPlayerListener = new Player.EventListener() { @Override - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { + public void onPlaybackStateChanged(@Player.State int playbackState) { if (playbackState == Player.STATE_READY) { elapsedDuration = MainActivity.appPlayer.getCurrentPosition(); totalDuration = MainActivity.appPlayer.getDuration() < 0 ? 0 : MainActivity.appPlayer.getDuration(); if (!playbackStarted) { logPlay(currentUrl, startTimeMillis); playbackStarted = true; - isPlaying = true; long lastPosition = loadLastPlaybackPosition(); if (lastPosition > -1) { @@ -303,7 +302,7 @@ public class FileViewFragment extends BaseFragment implements hideBuffering(); if (loadingNewClaim) { - MainActivity.appPlayer.setPlayWhenReady(true); + MainActivity.appPlayer.setPlayWhenReady(Objects.requireNonNull((MainActivity) (getActivity())).isMediaAutoplayEnabled()); loadingNewClaim = false; } } else if (playbackState == Player.STATE_BUFFERING) { @@ -340,6 +339,11 @@ public class FileViewFragment extends BaseFragment implements hideBuffering(); } } + + @Override + public void onIsPlayingChanged(boolean isPlayng) { + isPlaying = isPlayng; + } }; return root; @@ -1762,7 +1766,7 @@ public class FileViewFragment extends BaseFragment implements ((MainActivity) context).setNowPlayingClaim(claim, currentUrl); } - MainActivity.appPlayer.setPlayWhenReady(true); + MainActivity.appPlayer.setPlayWhenReady(Objects.requireNonNull((MainActivity) (getActivity())).isMediaAutoplayEnabled()); String userAgent = Util.getUserAgent(context, getString(R.string.app_name)); String mediaSourceUrl = getStreamingUrl(); MediaSource mediaSource = new ProgressiveMediaSource.Factory( @@ -1770,7 +1774,8 @@ public class FileViewFragment extends BaseFragment implements new DefaultExtractorsFactory() ).setLoadErrorHandlingPolicy(new StreamLoadErrorPolicy()).createMediaSource(Uri.parse(mediaSourceUrl)); - MainActivity.appPlayer.prepare(mediaSource, true, true); + MainActivity.appPlayer.setMediaSource(mediaSource, true); + MainActivity.appPlayer.prepare(); } } } diff --git a/app/src/main/java/io/lbry/browser/utils/Comments.java b/app/src/main/java/io/lbry/browser/utils/Comments.java deleted file mode 100644 index 47d86fc6..00000000 --- a/app/src/main/java/io/lbry/browser/utils/Comments.java +++ /dev/null @@ -1,99 +0,0 @@ -package io.lbry.browser.utils; - -import android.os.Build; - -import org.apache.commons.codec.binary.Hex; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -import io.lbry.browser.exceptions.ApiCallException; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; - -public class Comments { - private static final String STATUS_ENDPOINT = "https://comments.lbry.com"; - public static final String COMMENT_SERVER_ENDPOINT = "https://comments.lbry.com/api/v2"; - - public static JSONObject channelSign(JSONObject commentBody, String channelId, String channelName) throws ApiCallException, JSONException { - byte[] commentBodyBytes = commentBody.getString("comment").getBytes(StandardCharsets.UTF_8); - String encodedCommentBody; - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) - encodedCommentBody = Hex.encodeHexString(commentBodyBytes, false); - else - encodedCommentBody = new String(Hex.encodeHex(commentBodyBytes)); - - Map signingParams = new HashMap<>(3); - signingParams.put("hexdata", encodedCommentBody); - signingParams.put("channel_id", channelId); - signingParams.put("channel_name", channelName); - - return (JSONObject) Lbry.genericApiCall("channel_sign", signingParams); - } - - /** - * Performs request to default Comment Server - * @param params JSON containing parameters to send to the server - * @param method One of the available methods for comments - * @return Response from the server - * @throws IOException throwable from OkHttpClient execute() - */ - public static Response performRequest(JSONObject params, String method) throws IOException { - return performRequest(COMMENT_SERVER_ENDPOINT, params, method); - } - - /** - * Performs the request to Comment Server - * @param commentServer Url where to direct the request - * @param params JSON containing parameters to send to the server - * @param method One of the available methods for comments - * @return Response from the server - * @throws IOException throwable from OkHttpClient execute() - */ - public static Response performRequest(String commentServer, JSONObject params, String method) throws IOException { - final MediaType JSON = MediaType.get("application/json; charset=utf-8"); - - Map requestParams = new HashMap<>(4); - requestParams.put("jsonrpc", "2.0"); - requestParams.put("id", TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())); - requestParams.put("method", method); - requestParams.put("params", params); - - RequestBody requestBody = RequestBody.create(Lbry.buildJsonParams(requestParams).toString(), JSON); - - Request commentCreateRequest = new Request.Builder() - .url(commentServer.concat("?m=").concat(method)) - .post(requestBody) - .build(); - - OkHttpClient client = new OkHttpClient.Builder().writeTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .build(); - - return client.newCall(commentCreateRequest).execute(); - } - - public static void checkCommentsEndpointStatus() throws IOException, JSONException, ApiCallException { - Request request = new Request.Builder().url(STATUS_ENDPOINT).build(); - OkHttpClient client = new OkHttpClient.Builder().writeTimeout(30, TimeUnit.SECONDS) - .readTimeout(30, TimeUnit.SECONDS) - .build(); - Response response = client.newCall(request).execute(); - JSONObject status = new JSONObject(Objects.requireNonNull(response.body()).string()); - String statusText = Helper.getJSONString("text", null, status); - boolean isRunning = Helper.getJSONBoolean("is_running", false, status); - if (!"ok".equalsIgnoreCase(statusText) || !isRunning) { - throw new ApiCallException("The comment server is not available at this time. Please try again later."); - } - } -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7463513e..5c4da9f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -247,6 +247,7 @@ Content & User interface Other Enable background playback + Autoplay media files Enable dark theme Show mature content Show URL suggestions diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index 6348a2d9..9f588829 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -10,6 +10,11 @@ app:defaultValue="true" app:title="@string/enable_background_playback" app:iconSpaceReserved="false" /> +