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";
// 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_SHOW_MATURE_CONTENT = "io.lbry.browser.preference.userinterface.ShowMatureContent";
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
public void onError(Exception error) {
showError(error.getMessage());
try {
showError(error != null ? error.getMessage() : getString(R.string.comment_error));
} catch (IllegalStateException ex) {
// pass
}
afterPostComment();
}
});

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -728,7 +728,10 @@ public class PublishFormFragment extends BaseFragment implements
private void uploadThumbnail(String thumbnailPath) {
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;
}
@ -1294,7 +1297,11 @@ public class PublishFormFragment extends BaseFragment implements
@Override
public void onStoragePermissionRefused() {
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;
}
launchPickerPending = false;

View file

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

View file

@ -2,6 +2,7 @@ package io.lbry.browser.ui.verification;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -243,8 +244,10 @@ public class WalletVerificationFragment extends Fragment {
}
private void showError(String message) {
Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).setBackgroundTint(
getResources().getColor(R.color.red)
).show();
View view = getView();
if (view != null) {
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]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
try {
return getDataColumn(context, contentUri, selection, selectionArgs);
} catch (Exception ex) {
return null;
}
}
}
// MediaStore (and general)

View file

@ -62,6 +62,7 @@
<string name="comments">Comments</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="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="view">View</string>
<string name="play">Play</string>
@ -233,6 +234,7 @@
<!-- Settings -->
<string name="user_interface">Content &amp; User interface</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="show_mature_content">Show mature content</string>
<string name="show_url_suggestions">Show URL suggestions</string>

View file

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