Add background playback setting. Fix crash bugs.

This commit is contained in:
Akinwale Ariwodola 2020-06-05 08:25:08 +01:00
parent 084407e129
commit 8bcee90d68
16 changed files with 199 additions and 138 deletions

View file

@ -265,6 +265,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
public static final String ACTION_SAVE_SHARED_USER_STATE = "io.lbry.browser.Broadcast.SaveSharedUserState"; public static final String ACTION_SAVE_SHARED_USER_STATE = "io.lbry.browser.Broadcast.SaveSharedUserState";
// preference keys // preference keys
public static final String PREFERENCE_KEY_BACKGROUND_PLAYBACK = "io.lbry.browser.preference.userinterface.BackgroundPlayback";
public static final String PREFERENCE_KEY_DARK_MODE = "io.lbry.browser.preference.userinterface.DarkMode"; 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_MATURE_CONTENT = "io.lbry.browser.preference.userinterface.ShowMatureContent";
public static final String PREFERENCE_KEY_SHOW_URL_SUGGESTIONS = "io.lbry.browser.preference.userinterface.UrlSuggestions"; public static final String PREFERENCE_KEY_SHOW_URL_SUGGESTIONS = "io.lbry.browser.preference.userinterface.UrlSuggestions";

View file

@ -569,7 +569,11 @@ public class ChannelCommentsFragment extends Fragment implements SdkStatusListen
@Override @Override
public void onError(Exception error) { public void onError(Exception error) {
showError(error.getMessage()); try {
showError(error != null ? error.getMessage() : getString(R.string.comment_error));
} catch (IllegalStateException ex) {
// pass
}
afterPostComment(); afterPostComment();
} }
}); });

View file

@ -259,22 +259,25 @@ public class ChannelContentFragment extends Fragment implements DownloadActionLi
@Override @Override
public void onSuccess(List<Claim> claims, boolean hasReachedEnd) { public void onSuccess(List<Claim> claims, boolean hasReachedEnd) {
if (contentListAdapter == null) { if (contentListAdapter == null) {
contentListAdapter = new ClaimListAdapter(claims, getContext()); Context context = getContext();
contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() { if (context != null) {
@Override contentListAdapter = new ClaimListAdapter(claims, context);
public void onClaimClicked(Claim claim) { contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
Context context = getContext(); @Override
if (context instanceof MainActivity) { public void onClaimClicked(Claim claim) {
MainActivity activity = (MainActivity) context; Context context = getContext();
if (claim.getName().startsWith("@")) { if (context instanceof MainActivity) {
// channel claim MainActivity activity = (MainActivity) context;
activity.openChannelClaim(claim); if (claim.getName().startsWith("@")) {
} else { // channel claim
activity.openFileClaim(claim); activity.openChannelClaim(claim);
} else {
activity.openFileClaim(claim);
}
} }
} }
} });
}); }
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }

View file

@ -180,10 +180,13 @@ public class ChannelFragment extends BaseFragment implements FetchChannelsListen
@Override @Override
public void onTipSent(BigDecimal amount) { public void onTipSent(BigDecimal amount) {
double sentAmount = amount.doubleValue(); double sentAmount = amount.doubleValue();
String message = getResources().getQuantityString( View view = getView();
R.plurals.you_sent_a_tip, sentAmount == 1.0 ? 1 : 2, if (view != null) {
new DecimalFormat("#,###.##").format(sentAmount)); String message = getResources().getQuantityString(
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).show(); R.plurals.you_sent_a_tip, sentAmount == 1.0 ? 1 : 2,
new DecimalFormat("#,###.##").format(sentAmount));
Snackbar.make(view, message, Snackbar.LENGTH_LONG).show();
}
} }
}); });
Context context = getContext(); Context context = getContext();

View file

@ -149,21 +149,23 @@ public class ChannelManagerFragment extends BaseFragment implements ActionMode.C
@Override @Override
public void onSuccess(List<Claim> claims) { public void onSuccess(List<Claim> claims) {
Lbry.ownChannels = Helper.filterDeletedClaims(new ArrayList<>(claims)); Lbry.ownChannels = Helper.filterDeletedClaims(new ArrayList<>(claims));
Context context = getContext();
if (adapter == null) { if (adapter == null) {
adapter = new ClaimListAdapter(claims, context); Context context = getContext();
adapter.setCanEnterSelectionMode(true); if (context != null) {
adapter.setSelectionModeListener(ChannelManagerFragment.this); adapter = new ClaimListAdapter(claims, context);
adapter.setListener(new ClaimListAdapter.ClaimListItemListener() { adapter.setCanEnterSelectionMode(true);
@Override adapter.setSelectionModeListener(ChannelManagerFragment.this);
public void onClaimClicked(Claim claim) { adapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
if (context instanceof MainActivity) { @Override
((MainActivity) context).openChannelClaim(claim); public void onClaimClicked(Claim claim) {
if (context instanceof MainActivity) {
((MainActivity) context).openChannelClaim(claim);
}
} }
});
if (channelList != null) {
channelList.setAdapter(adapter);
} }
});
if (channelList != null) {
channelList.setAdapter(adapter);
} }
} else { } else {
adapter.setItems(claims); adapter.setItems(claims);

View file

@ -446,22 +446,25 @@ public class AllContentFragment extends BaseFragment implements DownloadActionLi
@Override @Override
public void onSuccess(List<Claim> claims, boolean hasReachedEnd) { public void onSuccess(List<Claim> claims, boolean hasReachedEnd) {
if (contentListAdapter == null) { if (contentListAdapter == null) {
contentListAdapter = new ClaimListAdapter(claims, getContext()); Context context = getContext();
contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() { if (context != null) {
@Override contentListAdapter = new ClaimListAdapter(claims, context);
public void onClaimClicked(Claim claim) { contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
Context context = getContext(); @Override
if (context instanceof MainActivity) { public void onClaimClicked(Claim claim) {
MainActivity activity = (MainActivity) context; Context context = getContext();
if (claim.getName().startsWith("@")) { if (context instanceof MainActivity) {
// channel claim MainActivity activity = (MainActivity) context;
activity.openChannelClaim(claim); if (claim.getName().startsWith("@")) {
} else { // channel claim
activity.openFileClaim(claim); activity.openChannelClaim(claim);
} else {
activity.openFileClaim(claim);
}
} }
} }
} });
}); }
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }

View file

@ -1719,31 +1719,41 @@ public class FileViewFragment extends BaseFragment implements
Fee fee = ((Claim.StreamMetadata) claim.getValue()).getFee(); Fee fee = ((Claim.StreamMetadata) claim.getValue()).getFee();
double cost = claim.getActualCost(Lbryio.LBCUSDRate).doubleValue(); double cost = claim.getActualCost(Lbryio.LBCUSDRate).doubleValue();
String formattedCost = Helper.LBC_CURRENCY_FORMAT.format(cost); String formattedCost = Helper.LBC_CURRENCY_FORMAT.format(cost);
String message = getResources().getQuantityString( Context context = getContext();
R.plurals.confirm_purchase_message, if (context != null) {
cost == 1 ? 1 : 2, try {
claim.getTitle(), String message = getResources().getQuantityString(
formattedCost.equals("0") ? Helper.FULL_LBC_CURRENCY_FORMAT.format(cost) : formattedCost); R.plurals.confirm_purchase_message,
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()). cost == 1 ? 1 : 2,
setTitle(R.string.confirm_purchase). claim.getTitle(),
setMessage(message) formattedCost.equals("0") ? Helper.FULL_LBC_CURRENCY_FORMAT.format(cost) : formattedCost);
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { AlertDialog.Builder builder = new AlertDialog.Builder(context).
@Override setTitle(R.string.confirm_purchase).
public void onClick(DialogInterface dialogInterface, int i) { setMessage(message)
Bundle bundle = new Bundle(); .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
bundle.putString("uri", currentUrl); @Override
bundle.putString("paid", "true"); public void onClick(DialogInterface dialogInterface, int i) {
bundle.putDouble("amount", Helper.parseDouble(fee.getAmount(), 0)); Bundle bundle = new Bundle();
bundle.putDouble("lbc_amount", cost); bundle.putString("uri", currentUrl);
bundle.putString("currency", fee.getCurrency()); bundle.putString("paid", "true");
LbryAnalytics.logEvent(LbryAnalytics.EVENT_PURCHASE_URI, bundle); bundle.putDouble("amount", Helper.parseDouble(fee.getAmount(), 0));
bundle.putDouble("lbc_amount", cost);
bundle.putString("currency", fee.getCurrency());
LbryAnalytics.logEvent(LbryAnalytics.EVENT_PURCHASE_URI, bundle);
getView().findViewById(R.id.file_view_main_action_button).setVisibility(View.INVISIBLE); View root = getView();
getView().findViewById(R.id.file_view_main_action_loading).setVisibility(View.VISIBLE); if (root != null) {
handleMainActionForClaim(); root.findViewById(R.id.file_view_main_action_button).setVisibility(View.INVISIBLE);
} root.findViewById(R.id.file_view_main_action_loading).setVisibility(View.VISIBLE);
}).setNegativeButton(R.string.no, null); }
builder.show(); handleMainActionForClaim();
}
}).setNegativeButton(R.string.no, null);
builder.show();
} catch (IllegalStateException ex) {
// pass
}
}
} }
} }
@ -2973,7 +2983,11 @@ public class FileViewFragment extends BaseFragment implements
@Override @Override
public void onError(Exception error) { public void onError(Exception error) {
showError(error.getMessage()); try {
showError(error != null ? error.getMessage() : getString(R.string.comment_error));
} catch (IllegalStateException ex) {
// pass
}
afterPostComment(); afterPostComment();
} }
}); });

View file

@ -598,22 +598,25 @@ public class FollowingFragment extends BaseFragment implements
@Override @Override
public void onSuccess(List<Claim> claims, boolean hasReachedEnd) { public void onSuccess(List<Claim> claims, boolean hasReachedEnd) {
if (contentListAdapter == null) { if (contentListAdapter == null) {
contentListAdapter = new ClaimListAdapter(claims, getContext()); Context context = getContext();
contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() { if (context != null) {
@Override contentListAdapter = new ClaimListAdapter(claims, context);
public void onClaimClicked(Claim claim) { contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
Context context = getContext(); @Override
if (context instanceof MainActivity) { public void onClaimClicked(Claim claim) {
MainActivity activity = (MainActivity) context; Context context = getContext();
if (claim.getName().startsWith("@")) { if (context instanceof MainActivity) {
// channel claim MainActivity activity = (MainActivity) context;
activity.openChannelClaim(claim); if (claim.getName().startsWith("@")) {
} else { // channel claim
activity.openFileClaim(claim); activity.openChannelClaim(claim);
} else {
activity.openFileClaim(claim);
}
} }
} }
} });
}); }
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }

View file

@ -192,7 +192,7 @@ public class SearchFragment extends BaseFragment implements
} }
if (resolved.isMature() && !canShowMatureContent) { if (resolved.isMature() && !canShowMatureContent) {
resultListAdapter.removeFeaturedItem(); resultListAdapter.removeFeaturedItem();
} else { } else if (unresolved != null) {
// only set the values we need // only set the values we need
unresolved.setClaimId(resolved.getClaimId()); unresolved.setClaimId(resolved.getClaimId());
unresolved.setName(resolved.getName()); unresolved.setName(resolved.getName());

View file

@ -352,24 +352,27 @@ public class LibraryFragment extends BaseFragment implements
} }
private void initContentListAdapter(List<Claim> claims) { private void initContentListAdapter(List<Claim> claims) {
contentListAdapter = new ClaimListAdapter(claims, getContext()); Context context = getContext();
contentListAdapter.setCanEnterSelectionMode(currentFilter == FILTER_DOWNLOADS); if (context != null) {
contentListAdapter.setSelectionModeListener(this); contentListAdapter = new ClaimListAdapter(claims, context);
contentListAdapter.setHideFee(currentFilter != FILTER_PURCHASES); contentListAdapter.setCanEnterSelectionMode(currentFilter == FILTER_DOWNLOADS);
contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() { contentListAdapter.setSelectionModeListener(this);
@Override contentListAdapter.setHideFee(currentFilter != FILTER_PURCHASES);
public void onClaimClicked(Claim claim) { contentListAdapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
Context context = getContext(); @Override
if (context instanceof MainActivity) { public void onClaimClicked(Claim claim) {
MainActivity activity = (MainActivity) getContext(); Context context = getContext();
if (claim.getName().startsWith("@")) { if (context instanceof MainActivity) {
activity.openChannelUrl(claim.getPermanentUrl()); MainActivity activity = (MainActivity) context;
} else { if (claim.getName().startsWith("@")) {
activity.openFileUrl(claim.getPermanentUrl()); activity.openChannelUrl(claim.getPermanentUrl());
} else {
activity.openFileUrl(claim.getPermanentUrl());
}
} }
} }
} });
}); }
} }
private void fetchDownloads() { private void fetchDownloads() {
@ -391,7 +394,7 @@ public class LibraryFragment extends BaseFragment implements
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }
if (contentList.getAdapter() == null) { if (contentListAdapter != null && contentList.getAdapter() == null) {
contentList.setAdapter(contentListAdapter); contentList.setAdapter(contentListAdapter);
} }
resolveMissingChannelNames(buildUrlsToResolve(claims)); resolveMissingChannelNames(buildUrlsToResolve(claims));
@ -423,7 +426,7 @@ public class LibraryFragment extends BaseFragment implements
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }
if (contentList.getAdapter() == null) { if (contentListAdapter != null && contentList.getAdapter() == null) {
contentList.setAdapter(contentListAdapter); contentList.setAdapter(contentListAdapter);
} }
checkListEmpty(); checkListEmpty();
@ -459,7 +462,7 @@ public class LibraryFragment extends BaseFragment implements
} else { } else {
contentListAdapter.addItems(claims); contentListAdapter.addItems(claims);
} }
if (contentList.getAdapter() == null) { if (contentListAdapter != null && contentList.getAdapter() == null) {
contentList.setAdapter(contentListAdapter); contentList.setAdapter(contentListAdapter);
} }
checkListEmpty(); checkListEmpty();
@ -637,18 +640,21 @@ public class LibraryFragment extends BaseFragment implements
public boolean onActionItemClicked(androidx.appcompat.view.ActionMode actionMode, MenuItem menuItem) { public boolean onActionItemClicked(androidx.appcompat.view.ActionMode actionMode, MenuItem menuItem) {
if (R.id.action_delete == menuItem.getItemId()) { if (R.id.action_delete == menuItem.getItemId()) {
if (contentListAdapter != null && contentListAdapter.getSelectedCount() > 0) { if (contentListAdapter != null && contentListAdapter.getSelectedCount() > 0) {
final List<Claim> selectedClaims = new ArrayList<>(contentListAdapter.getSelectedItems()); Context context = getContext();
String message = getResources().getQuantityString(R.plurals.confirm_delete_files, selectedClaims.size()); if (context != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()). final List<Claim> selectedClaims = new ArrayList<>(contentListAdapter.getSelectedItems());
setTitle(R.string.delete_selection). String message = getResources().getQuantityString(R.plurals.confirm_delete_files, selectedClaims.size());
setMessage(message) AlertDialog.Builder builder = new AlertDialog.Builder(context).
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { setTitle(R.string.delete_selection).
@Override setMessage(message)
public void onClick(DialogInterface dialogInterface, int i) { .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
handleDeleteSelectedClaims(selectedClaims); @Override
} public void onClick(DialogInterface dialogInterface, int i) {
}).setNegativeButton(R.string.no, null); handleDeleteSelectedClaims(selectedClaims);
builder.show(); }
}).setNegativeButton(R.string.no, null);
builder.show();
}
return true; return true;
} }
} }

View file

@ -728,7 +728,10 @@ public class PublishFormFragment extends BaseFragment implements
private void uploadThumbnail(String thumbnailPath) { private void uploadThumbnail(String thumbnailPath) {
if (uploading) { if (uploading) {
Snackbar.make(getView(), R.string.wait_for_upload, Snackbar.LENGTH_LONG).show(); View view = getView();
if (view != null) {
Snackbar.make(view, R.string.wait_for_upload, Snackbar.LENGTH_LONG).show();
}
return; return;
} }
@ -1294,7 +1297,11 @@ public class PublishFormFragment extends BaseFragment implements
@Override @Override
public void onStoragePermissionRefused() { public void onStoragePermissionRefused() {
if (!storageRefusedOnce) { if (!storageRefusedOnce) {
showError(getString(R.string.storage_permission_rationale_images)); try {
showError(getString(R.string.storage_permission_rationale_images));
} catch (IllegalStateException ex) {
// pass
}
storageRefusedOnce = true; storageRefusedOnce = true;
} }
launchPickerPending = false; launchPickerPending = false;

View file

@ -151,26 +151,28 @@ public class PublishesFragment extends BaseFragment implements ActionMode.Callba
@Override @Override
public void onSuccess(List<Claim> claims) { public void onSuccess(List<Claim> claims) {
Lbry.ownClaims = Helper.filterDeletedClaims(new ArrayList<>(claims)); Lbry.ownClaims = Helper.filterDeletedClaims(new ArrayList<>(claims));
Context context = getContext();
if (adapter == null) { if (adapter == null) {
adapter = new ClaimListAdapter(claims, context); Context context = getContext();
adapter.setCanEnterSelectionMode(true); if (context != null) {
adapter.setSelectionModeListener(PublishesFragment.this); adapter = new ClaimListAdapter(claims, context);
adapter.setListener(new ClaimListAdapter.ClaimListItemListener() { adapter.setCanEnterSelectionMode(true);
@Override adapter.setSelectionModeListener(PublishesFragment.this);
public void onClaimClicked(Claim claim) { adapter.setListener(new ClaimListAdapter.ClaimListItemListener() {
if (context instanceof MainActivity) { @Override
MainActivity activity = (MainActivity) context; public void onClaimClicked(Claim claim) {
if (claim.getName().startsWith("@")) { if (context instanceof MainActivity) {
activity.openChannelClaim(claim); MainActivity activity = (MainActivity) context;
} else { if (claim.getName().startsWith("@")) {
activity.openFileClaim(claim); activity.openChannelClaim(claim);
} else {
activity.openFileClaim(claim);
}
} }
} }
});
if (contentList != null) {
contentList.setAdapter(adapter);
} }
});
if (contentList != null) {
contentList.setAdapter(adapter);
} }
} else { } else {
adapter.setItems(claims); adapter.setItems(claims);

View file

@ -2,6 +2,7 @@ package io.lbry.browser.ui.verification;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -243,8 +244,10 @@ public class WalletVerificationFragment extends Fragment {
} }
private void showError(String message) { private void showError(String message) {
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).setBackgroundTint( View view = getView();
getResources().getColor(R.color.red) if (view != null) {
).show(); Snackbar.make(view, message, Snackbar.LENGTH_LONG).
setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
}
} }
} }

View file

@ -552,7 +552,11 @@ public final class Helper {
split[1] split[1]
}; };
return getDataColumn(context, contentUri, selection, selectionArgs); try {
return getDataColumn(context, contentUri, selection, selectionArgs);
} catch (Exception ex) {
return null;
}
} }
} }
// MediaStore (and general) // MediaStore (and general)

View file

@ -62,6 +62,7 @@
<string name="comments">Comments</string> <string name="comments">Comments</string>
<string name="no_comments">No comments to display at this time.</string> <string name="no_comments">No comments to display at this time.</string>
<string name="sdk_initializing_comments">Comments will display after the background service is initialized.</string> <string name="sdk_initializing_comments">Comments will display after the background service is initialized.</string>
<string name="comment_error">Your comment could not be posted at this time. Please try again later.</string>
<string name="share_lbry_content">Share LBRY content</string> <string name="share_lbry_content">Share LBRY content</string>
<string name="view">View</string> <string name="view">View</string>
<string name="play">Play</string> <string name="play">Play</string>
@ -233,6 +234,7 @@
<!-- Settings --> <!-- Settings -->
<string name="user_interface">Content &amp; User interface</string> <string name="user_interface">Content &amp; User interface</string>
<string name="other">Other</string> <string name="other">Other</string>
<string name="enable_background_playback">Enable background playback</string>
<string name="enable_dark_mode">Enable dark theme</string> <string name="enable_dark_mode">Enable dark theme</string>
<string name="show_mature_content">Show mature content</string> <string name="show_mature_content">Show mature content</string>
<string name="show_url_suggestions">Show URL suggestions</string> <string name="show_url_suggestions">Show URL suggestions</string>

View file

@ -5,6 +5,10 @@
<PreferenceCategory <PreferenceCategory
android:title="@string/user_interface" android:title="@string/user_interface"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<SwitchPreferenceCompat
app:key="io.lbry.browser.preference.userinterface.BackgroundPlayback"
app:title="@string/enable_background_playback"
app:iconSpaceReserved="false" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:key="io.lbry.browser.preference.userinterface.DarkMode" app:key="io.lbry.browser.preference.userinterface.DarkMode"
app:title="@string/enable_dark_mode" app:title="@string/enable_dark_mode"