diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7ac0cf49..28eca8a7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -56,13 +56,6 @@
-
-
-
-
-
-
-
{
- private static final String TAG = "LbryBufferEvent";
- private static final String ENDPOINT = "https://collector-service.api.lbry.tv/api/v1/events/video";
-
- private String streamUrl;
- private String userIdHash;
- private long streamDuration;
- private long streamPosition;
- private long bufferDuration;
-
- public BufferEventTask(String streamUrl, long streamDuration, long streamPosition, long bufferDuration, String userIdHash) {
- this.streamUrl = streamUrl;
- this.bufferDuration = bufferDuration;
- this.streamDuration = streamDuration;
- this.streamPosition = streamPosition;
- this.userIdHash = userIdHash;
- }
-
- protected Void doInBackground(Void... params) {
- JSONObject requestBody = new JSONObject();
- JSONObject data = new JSONObject();
- try {
- data.put("url", streamUrl);
- data.put("position", streamPosition);
- data.put("stream_duration", streamDuration);
- //data.put("duration", bufferDuration);
-
- requestBody.put("device", "android");
- requestBody.put("type", "buffering");
- requestBody.put("client", userIdHash);
- requestBody.put("data", data);
-
- RequestBody body = RequestBody.create(requestBody.toString(), Helper.JSON_MEDIA_TYPE);
- Request request = new Request.Builder().url(ENDPOINT).post(body).build();
- OkHttpClient client = new OkHttpClient.Builder().
- writeTimeout(60, TimeUnit.SECONDS).
- readTimeout(60, TimeUnit.SECONDS).
- build();
-
- Response response = client.newCall(request).execute();
- String responseString = response.body().string();
- Log.d(TAG, String.format("buffer event sent: %s", responseString));
- } catch (Exception ex) {
- // we don't want to fail if a buffer event fails to register
- Log.d(TAG, String.format("buffer event log failed: %s", ex.getMessage()), ex);
- }
-
- return null;
- }
-}
diff --git a/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java b/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java
index c82d728a..ff48f5d8 100644
--- a/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java
+++ b/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java
@@ -60,12 +60,12 @@ public class MergeSubscriptionsTask extends AsyncTask remoteUnsubs = new ArrayList<>();
+ List finalRemoteSubs = new ArrayList<>();
+ if (remoteSubs.size() > 0) {
+ for (int i = 0; i < remoteSubs.size(); i++) {
+ Subscription sub = remoteSubs.get(i);
+ if (!combined.contains(sub)) {
Map options = new HashMap<>();
- String channelClaimId = uri.getChannelClaimId();
- String channelName = Helper.normalizeChannelName(local.getChannelName());
- if (!Helper.isNullOrEmpty(channelClaimId) && !Helper.isNullOrEmpty(channelName)) {
- options.put("claim_id", channelClaimId);
- options.put("channel_name", channelName);
- Lbryio.parseResponse(Lbryio.call("subscription", "new", options, context));
+ LbryUri uri = LbryUri.tryParse(sub.getUrl());
+ if (uri != null) {
+ options.put("claim_id", uri.getChannelClaimId());
+ Lbryio.parseResponse(Lbryio.call("subscription", "delete", options, context));
+ remoteUnsubs.add(sub);
+ } else {
+ finalRemoteSubs.add(sub);
}
- } catch (LbryUriException | LbryioRequestException | LbryioResponseException ex) {
- // pass
- Log.e(TAG, String.format("subscription/new failed: %s", ex.getMessage()), ex);
}
}
}
@@ -115,8 +114,8 @@ public class MergeSubscriptionsTask extends AsyncTask 0) {
- // we only want to log a buffer event after the media has already started playing
- String mediaSourceUrl = getStreamingUrl();
- long duration = MainActivity.appPlayer.getDuration();
- long position = MainActivity.appPlayer.getCurrentPosition();
- // TODO: Determine a hash for the userId
- String userIdHash = Helper.SHA256(Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0");
- if (mediaSourceUrl.startsWith(CDN_PREFIX)) {
- BufferEventTask bufferEvent = new BufferEventTask(claim.getPermanentUrl(), duration, position, 1, userIdHash);
- bufferEvent.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
- } else {
- // sdk stream buffer events should be handled differently
- Bundle bundle = new Bundle();
- bundle.putString("url", claim.getPermanentUrl());
- bundle.putLong("stream_duration", duration);
- bundle.putLong("stream_position", position);
- bundle.putString("user_id_hash", userIdHash);
- LbryAnalytics.logEvent(LbryAnalytics.EVENT_BUFFER, bundle);
- }
- }
-
showBuffering();
} else {
hideBuffering();
@@ -749,44 +724,6 @@ public class FileViewFragment extends BaseFragment implements
}
}
- private View.OnClickListener followUnfollowListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (claim != null && claim.getSigningChannel() != null) {
- Claim publisher = claim.getSigningChannel();
- boolean isFollowing = Lbryio.isFollowing(publisher);
- Subscription subscription = Subscription.fromClaim(publisher);
- view.setEnabled(false);
- Context context = getContext();
- new ChannelSubscribeTask(context, publisher.getClaimId(), subscription, isFollowing, new ChannelSubscribeTask.ChannelSubscribeHandler() {
- @Override
- public void onSuccess() {
- if (isFollowing) {
- Lbryio.removeSubscription(subscription);
- Lbryio.removeCachedResolvedSubscription(publisher);
- } else {
- Lbryio.addSubscription(subscription);
- Lbryio.addCachedResolvedSubscription(publisher);
- }
- view.setEnabled(true);
- checkIsFollowing();
- FollowingFragment.resetClaimSearchContent = true;
-
- // Save shared user state
- if (context != null) {
- context.sendBroadcast(new Intent(MainActivity.ACTION_SAVE_SHARED_USER_STATE));
- }
- }
-
- @Override
- public void onError(Exception exception) {
- view.setEnabled(true);
- }
- }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
- };
-
private void resolveUrl(String url) {
resolving = true;
Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE);
@@ -1123,10 +1060,44 @@ public class FileViewFragment extends BaseFragment implements
}
});
- View buttonFollow = root.findViewById(R.id.file_view_icon_follow);
- View buttonUnfollow = root.findViewById(R.id.file_view_icon_unfollow);
- buttonFollow.setOnClickListener(followUnfollowListener);
- buttonUnfollow.setOnClickListener(followUnfollowListener);
+ View buttonFollowUnfollow = root.findViewById(R.id.file_view_icon_follow_unfollow);
+ buttonFollowUnfollow.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (claim != null && claim.getSigningChannel() != null) {
+ Claim publisher = claim.getSigningChannel();
+ boolean isFollowing = Lbryio.isFollowing(publisher);
+ Subscription subscription = Subscription.fromClaim(publisher);
+ buttonFollowUnfollow.setEnabled(false);
+ Context context = getContext();
+ new ChannelSubscribeTask(context, publisher.getClaimId(), subscription, isFollowing, new ChannelSubscribeTask.ChannelSubscribeHandler() {
+ @Override
+ public void onSuccess() {
+ if (isFollowing) {
+ Lbryio.removeSubscription(subscription);
+ Lbryio.removeCachedResolvedSubscription(publisher);
+ } else {
+ Lbryio.addSubscription(subscription);
+ Lbryio.addCachedResolvedSubscription(publisher);
+ }
+ buttonFollowUnfollow.setEnabled(true);
+ checkIsFollowing();
+ FollowingFragment.resetClaimSearchContent = true;
+
+ // Save shared user state
+ if (context != null) {
+ context.sendBroadcast(new Intent(MainActivity.ACTION_SAVE_SHARED_USER_STATE));
+ }
+ }
+
+ @Override
+ public void onError(Exception exception) {
+ buttonFollowUnfollow.setEnabled(true);
+ }
+ }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+ }
+ });
commentChannelSpinnerAdapter = new InlineChannelSpinnerAdapter(getContext(), R.layout.spinner_item_channel, new ArrayList<>());
commentChannelSpinnerAdapter.addPlaceholder(false);
@@ -1447,17 +1418,7 @@ public class FileViewFragment extends BaseFragment implements
}
}
- boolean isAnonymous = claim.getSigningChannel() == null;
- View iconFollow = root.findViewById(R.id.file_view_icon_follow);
- View iconUnfollow = root.findViewById(R.id.file_view_icon_unfollow);
- if (isAnonymous) {
- if (iconFollow.getVisibility() == View.VISIBLE) {
- iconFollow.setVisibility(View.INVISIBLE);
- }
- if (iconUnfollow.getVisibility() == View.VISIBLE) {
- iconUnfollow.setVisibility(View.INVISIBLE);
- }
- }
+ root.findViewById(R.id.file_view_icon_follow_unfollow).setVisibility(claim.getSigningChannel() != null ? View.VISIBLE : View.GONE);
MaterialButton mainActionButton = root.findViewById(R.id.file_view_main_action_button);
if (claim.isPlayable()) {
@@ -2447,10 +2408,11 @@ public class FileViewFragment extends BaseFragment implements
Context context = getContext();
View root = getView();
if (context != null && root != null) {
- OutlineIconView iconFollow = root.findViewById(R.id.file_view_icon_follow);
- SolidIconView iconUnfollow = root.findViewById(R.id.file_view_icon_unfollow);
- Helper.setViewVisibility(iconFollow, !isFollowing ? View.VISIBLE: View.INVISIBLE);
- Helper.setViewVisibility(iconUnfollow, isFollowing ? View.VISIBLE : View.INVISIBLE);
+ SolidIconView iconFollowUnfollow = root.findViewById(R.id.file_view_icon_follow_unfollow);
+ if (iconFollowUnfollow != null) {
+ iconFollowUnfollow.setText(isFollowing ? R.string.fa_heart_broken : R.string.fa_heart);
+ iconFollowUnfollow.setTextColor(ContextCompat.getColor(context, isFollowing ? R.color.foreground : R.color.red));
+ }
}
}
}
diff --git a/app/src/main/java/io/lbry/browser/utils/Helper.java b/app/src/main/java/io/lbry/browser/utils/Helper.java
index eac70533..a2883ca2 100644
--- a/app/src/main/java/io/lbry/browser/utils/Helper.java
+++ b/app/src/main/java/io/lbry/browser/utils/Helper.java
@@ -30,8 +30,6 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.google.android.gms.common.util.Hex;
-
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@@ -39,9 +37,6 @@ import org.json.JSONObject;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -771,14 +766,4 @@ public final class Helper {
}
return id.toString();
}
-
- public static String SHA256(String value) {
- try {
- MessageDigest digest = MessageDigest.getInstance("SHA-256");
- byte[] hash = digest.digest(value.getBytes("UTF-8"));
- return Hex.bytesToStringLowercase(hash);
- } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
- return null;
- }
- }
}
diff --git a/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java b/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java
index d5eadd7c..17b66b69 100644
--- a/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java
+++ b/app/src/main/java/io/lbry/browser/utils/LbryAnalytics.java
@@ -11,7 +11,6 @@ public class LbryAnalytics {
public static final String EVENT_APP_ERROR = "app_error";
public static final String EVENT_APP_LAUNCH = "app_launch";
public static final String EVENT_COMMENT_CREATE = "comment_create";
- public static final String EVENT_BUFFER = "buffer";
public static final String EVENT_EMAIL_ADDED = "email_added";
public static final String EVENT_EMAIL_VERIFIED = "email_verified";
public static final String EVENT_FIRST_RUN_COMPLETED = "first_run_completed";
diff --git a/app/src/main/java/io/lbry/browser/utils/LbryUri.java b/app/src/main/java/io/lbry/browser/utils/LbryUri.java
index 94458cfa..9e0790a7 100644
--- a/app/src/main/java/io/lbry/browser/utils/LbryUri.java
+++ b/app/src/main/java/io/lbry/browser/utils/LbryUri.java
@@ -17,8 +17,7 @@ public class LbryUri {
public static final int CHANNEL_NAME_MIN_LENGTH = 1;
public static final int CLAIM_ID_MAX_LENGTH = 40;
- private static final String REGEX_PART_PROTOCOL = "^((?:lbry://|https://)?)";
- private static final String REGEX_PART_HOST = "((?:open.lbry.com/)?)";
+ private static final String REGEX_PART_PROTOCOL = "^((?:lbry://)?)";
private static final String REGEX_PART_STREAM_OR_CHANNEL_NAME = "([^:$#/]*)";
private static final String REGEX_PART_MODIFIER_SEPARATOR = "([:$#]?)([^/]*)";
private static final String QUERY_STRING_BREAKER = "^([\\S]+)([?][\\S]*)";
@@ -59,9 +58,8 @@ public class LbryUri {
return parse(url, false);
}
public static LbryUri parse(String url, boolean requireProto) throws LbryUriException {
- Pattern componentsPattern = Pattern.compile(String.format("%s%s%s%s(/?)%s%s",
+ Pattern componentsPattern = Pattern.compile(String.format("%s%s%s(/?)%s%s",
REGEX_PART_PROTOCOL,
- REGEX_PART_HOST,
REGEX_PART_STREAM_OR_CHANNEL_NAME,
REGEX_PART_MODIFIER_SEPARATOR,
REGEX_PART_STREAM_OR_CHANNEL_NAME,
@@ -95,48 +93,37 @@ public class LbryUri {
}
// components[0] = proto
- // components[1] = host
- // components[2] = streamNameOrChannelName
- // components[3] = primaryModSeparator
- // components[4] = primaryModValue
- // components[5] = pathSep
- // components[6] = possibleStreamName
- // components[7] = secondaryModSeparator
- // components[8] = secondaryModValue
+ // components[1] = streamNameOrChannelName
+ // components[2] = primaryModSeparator
+ // components[3] = primaryModValue
+ // components[4] = pathSep
+ // components[5] = possibleStreamName
+ // components[6] = secondaryModSeparator
+ // components[7] = secondaryModValue
if (requireProto && Helper.isNullOrEmpty(components.get(0))) {
throw new LbryUriException("LBRY URLs must include a protocol prefix (lbry://).");
}
- if (Helper.isNullOrEmpty(components.get(2))) {
+ if (Helper.isNullOrEmpty(components.get(1))) {
throw new LbryUriException("URL does not include name.");
}
- for (String component : components.subList(2, components.size())) {
+ for (String component : components.subList(1, components.size())) {
if (component.indexOf(' ') > -1) {
throw new LbryUriException("URL cannot include a space.");
}
}
- String streamOrChannelName = components.get(2);
- String primaryModSeparator = components.get(3);
- String primaryModValue = components.get(4);
- String possibleStreamName = components.get(6);
- String secondaryModSeparator = components.get(7);
- String secondaryModValue = components.get(8);
+ String streamOrChannelName = components.get(1);
+ String primaryModSeparator = components.get(2);
+ String primaryModValue = components.get(3);
+ String possibleStreamName = components.get(5);
+ String secondaryModSeparator = components.get(6);
+ String secondaryModValue = components.get(7);
boolean includesChannel = streamOrChannelName.startsWith("@");
boolean isChannel = includesChannel && Helper.isNullOrEmpty(possibleStreamName);
String channelName = includesChannel && streamOrChannelName.length() > 1 ? streamOrChannelName.substring(1) : null;
-
- // It would have thrown already on the RegEx parser if protocol value was incorrect
- // open.lbry.com uses ':' as ModSeparators while lbry:// expects '#'
- if (components.get(1).equals("open.lbry.com/")) {
- if (primaryModSeparator.equals(":"))
- primaryModSeparator = "#";
- if (secondaryModSeparator.equals(":"))
- secondaryModSeparator = "#";
- }
-
if (includesChannel) {
if (Helper.isNullOrEmpty(channelName)) {
throw new LbryUriException("No channel name after @.");
@@ -160,7 +147,7 @@ public class LbryUri {
LbryUri uri = new LbryUri();
uri.setChannel(isChannel);
- uri.setPath(Helper.join(components.subList(2, components.size()), ""));
+ uri.setPath(Helper.join(components.subList(1, components.size()), ""));
uri.setStreamName(streamName);
uri.setStreamClaimId(streamClaimId);
uri.setChannelName(channelName);
diff --git a/app/src/main/res/layout/fragment_channel.xml b/app/src/main/res/layout/fragment_channel.xml
index 7602a54a..af46977f 100644
--- a/app/src/main/res/layout/fragment_channel.xml
+++ b/app/src/main/res/layout/fragment_channel.xml
@@ -210,22 +210,14 @@
android:clickable="true"
android:layout_width="36dp"
android:layout_height="36dp">
-
-
diff --git a/app/src/main/res/layout/fragment_file_view.xml b/app/src/main/res/layout/fragment_file_view.xml
index 1ff24b8e..ebac1449 100644
--- a/app/src/main/res/layout/fragment_file_view.xml
+++ b/app/src/main/res/layout/fragment_file_view.xml
@@ -484,7 +484,7 @@
android:paddingTop="12dp"
android:paddingLeft="16dp"
android:paddingBottom="12dp"
- android:layout_toLeftOf="@id/file_view_icon_follow">
+ android:layout_toLeftOf="@id/file_view_icon_follow_unfollow">
-
-
-