Library page. URL and view history.
This commit is contained in:
parent
47f56950a5
commit
244d54ed39
25 changed files with 1711 additions and 51 deletions
|
@ -169,9 +169,9 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
ClaimCacheKey key = new ClaimCacheKey();
|
ClaimCacheKey key = new ClaimCacheKey();
|
||||||
key.setClaimId(claimId);
|
key.setClaimId(claimId);
|
||||||
key.setUrl(url); // use the same url for the key so that we can match the key for any value that's the same
|
key.setUrl(url); // use the same url for the key so that we can match the key for any value that's the same
|
||||||
|
|
||||||
if (Lbry.claimCache.containsKey(key)) {
|
if (Lbry.claimCache.containsKey(key)) {
|
||||||
claim = Lbry.claimCache.get(key);
|
claim = Lbry.claimCache.get(key);
|
||||||
|
Helper.saveViewHistory(url, claim);
|
||||||
checkAndResetNowPlayingClaim();
|
checkAndResetNowPlayingClaim();
|
||||||
if (claim.getFile() == null) {
|
if (claim.getFile() == null) {
|
||||||
loadFile();
|
loadFile();
|
||||||
|
@ -314,6 +314,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
if (Lbry.claimCache.containsKey(key)) {
|
if (Lbry.claimCache.containsKey(key)) {
|
||||||
claim = Lbry.claimCache.get(key);
|
claim = Lbry.claimCache.get(key);
|
||||||
Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_FILE);
|
Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_FILE);
|
||||||
|
Helper.saveViewHistory(url, claim);
|
||||||
checkAndResetNowPlayingClaim();
|
checkAndResetNowPlayingClaim();
|
||||||
if (claim.getFile() == null) {
|
if (claim.getFile() == null) {
|
||||||
loadFile();
|
loadFile();
|
||||||
|
@ -423,7 +424,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
String claimId = claim.getClaimId();
|
String claimId = claim.getClaimId();
|
||||||
FileListTask task = new FileListTask(claimId, null, new FileListTask.FileListResultHandler() {
|
FileListTask task = new FileListTask(claimId, null, new FileListTask.FileListResultHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<LbryFile> files) {
|
public void onSuccess(List<LbryFile> files, boolean hasReachedEnd) {
|
||||||
if (files.size() > 0) {
|
if (files.size() > 0) {
|
||||||
claim.setFile(files.get(0));
|
claim.setFile(files.get(0));
|
||||||
checkIsFileComplete();
|
checkIsFileComplete();
|
||||||
|
@ -445,7 +446,7 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
if (initialFileLoadDone) {
|
if (initialFileLoadDone) {
|
||||||
restoreMainActionButton();
|
restoreMainActionButton();
|
||||||
}
|
}
|
||||||
if (claim != null && claim.isFree()) {
|
if (claim != null && claim.isFree() && (claim.isPlayable() || claim.isViewable())) {
|
||||||
onMainActionButtonClicked();
|
onMainActionButtonClicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,6 +492,8 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_FILE);
|
Helper.saveUrlHistory(url, claim.getTitle(), UrlSuggestion.TYPE_FILE);
|
||||||
|
|
||||||
// also save view history
|
// also save view history
|
||||||
|
Helper.saveViewHistory(url, claim);
|
||||||
|
|
||||||
checkAndResetNowPlayingClaim();
|
checkAndResetNowPlayingClaim();
|
||||||
loadFile();
|
loadFile();
|
||||||
renderClaim();
|
renderClaim();
|
||||||
|
@ -1576,9 +1579,11 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
String uri = intent.getStringExtra("uri");
|
String uri = intent.getStringExtra("uri");
|
||||||
String outpoint = intent.getStringExtra("outpoint");
|
String outpoint = intent.getStringExtra("outpoint");
|
||||||
String fileInfoJson = intent.getStringExtra("file_info");
|
String fileInfoJson = intent.getStringExtra("file_info");
|
||||||
|
double progress = intent.getDoubleExtra("progress", 0);
|
||||||
if (claim == null || uri == null || outpoint == null || (fileInfoJson == null && !"abort".equals(downloadAction))) {
|
if (claim == null || uri == null || outpoint == null || (fileInfoJson == null && !"abort".equals(downloadAction))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
onRelatedDownloadAction(downloadAction, uri, outpoint, fileInfoJson, progress);
|
||||||
if (claim != null && !claim.getPermanentUrl().equalsIgnoreCase(uri)) {
|
if (claim != null && !claim.getPermanentUrl().equalsIgnoreCase(uri)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1604,7 +1609,6 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
} else if (DownloadManager.ACTION_UPDATE.equals(downloadAction)) {
|
} else if (DownloadManager.ACTION_UPDATE.equals(downloadAction)) {
|
||||||
// handle download updated
|
// handle download updated
|
||||||
downloadInProgress = true;
|
downloadInProgress = true;
|
||||||
double progress = intent.getDoubleExtra("progress", 0);
|
|
||||||
Helper.setViewVisibility(downloadProgressView, View.VISIBLE);
|
Helper.setViewVisibility(downloadProgressView, View.VISIBLE);
|
||||||
downloadProgressView.setProgress(Double.valueOf(progress).intValue());
|
downloadProgressView.setProgress(Double.valueOf(progress).intValue());
|
||||||
downloadIconView.setImageResource(R.drawable.ic_stop);
|
downloadIconView.setImageResource(R.drawable.ic_stop);
|
||||||
|
@ -1692,6 +1696,26 @@ public class FileViewActivity extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onRelatedDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (relatedContentAdapter != null) {
|
||||||
|
relatedContentAdapter.clearFileForClaimOrUrl(outpoint, uri);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (relatedContentAdapter != null) {
|
||||||
|
relatedContentAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void bringMainTaskToFront() {
|
private void bringMainTaskToFront() {
|
||||||
if (backStackLost) {
|
if (backStackLost) {
|
||||||
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
|
|
@ -15,6 +15,7 @@ import android.content.pm.PackageManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
@ -32,11 +33,13 @@ import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||||
import com.google.android.exoplayer2.ext.cast.CastPlayer;
|
import com.google.android.exoplayer2.ext.cast.CastPlayer;
|
||||||
|
import com.google.android.exoplayer2.offline.Download;
|
||||||
import com.google.android.exoplayer2.ui.PlayerView;
|
import com.google.android.exoplayer2.ui.PlayerView;
|
||||||
import com.google.android.gms.cast.framework.CastContext;
|
import com.google.android.gms.cast.framework.CastContext;
|
||||||
import com.google.android.gms.tasks.OnCompleteListener;
|
import com.google.android.gms.tasks.OnCompleteListener;
|
||||||
|
@ -78,6 +81,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
@ -89,6 +93,7 @@ import io.lbry.browser.adapter.UrlSuggestionListAdapter;
|
||||||
import io.lbry.browser.data.DatabaseHelper;
|
import io.lbry.browser.data.DatabaseHelper;
|
||||||
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
||||||
import io.lbry.browser.exceptions.LbryUriException;
|
import io.lbry.browser.exceptions.LbryUriException;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.listener.FetchChannelsListener;
|
import io.lbry.browser.listener.FetchChannelsListener;
|
||||||
import io.lbry.browser.listener.SdkStatusListener;
|
import io.lbry.browser.listener.SdkStatusListener;
|
||||||
import io.lbry.browser.listener.WalletBalanceListener;
|
import io.lbry.browser.listener.WalletBalanceListener;
|
||||||
|
@ -121,6 +126,7 @@ import io.lbry.browser.ui.channel.ChannelFragment;
|
||||||
import io.lbry.browser.ui.channel.ChannelManagerFragment;
|
import io.lbry.browser.ui.channel.ChannelManagerFragment;
|
||||||
import io.lbry.browser.ui.editorschoice.EditorsChoiceFragment;
|
import io.lbry.browser.ui.editorschoice.EditorsChoiceFragment;
|
||||||
import io.lbry.browser.ui.following.FollowingFragment;
|
import io.lbry.browser.ui.following.FollowingFragment;
|
||||||
|
import io.lbry.browser.ui.library.LibraryFragment;
|
||||||
import io.lbry.browser.ui.other.AboutFragment;
|
import io.lbry.browser.ui.other.AboutFragment;
|
||||||
import io.lbry.browser.ui.search.SearchFragment;
|
import io.lbry.browser.ui.search.SearchFragment;
|
||||||
import io.lbry.browser.ui.other.SettingsFragment;
|
import io.lbry.browser.ui.other.SettingsFragment;
|
||||||
|
@ -133,6 +139,7 @@ import io.lbry.browser.utils.Lbry;
|
||||||
import io.lbry.browser.utils.LbryAnalytics;
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
import io.lbry.browser.utils.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
import io.lbry.lbrysdk.DownloadManager;
|
||||||
import io.lbry.lbrysdk.LbrynetService;
|
import io.lbry.lbrysdk.LbrynetService;
|
||||||
import io.lbry.lbrysdk.ServiceHelper;
|
import io.lbry.lbrysdk.ServiceHelper;
|
||||||
import io.lbry.lbrysdk.Utils;
|
import io.lbry.lbrysdk.Utils;
|
||||||
|
@ -246,6 +253,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
@Getter
|
@Getter
|
||||||
private DatabaseHelper dbHelper;
|
private DatabaseHelper dbHelper;
|
||||||
private int selectedMenuItemId = -1;
|
private int selectedMenuItemId = -1;
|
||||||
|
private List<DownloadActionListener> downloadActionListeners;
|
||||||
private List<SdkStatusListener> sdkStatusListeners;
|
private List<SdkStatusListener> sdkStatusListeners;
|
||||||
private List<WalletBalanceListener> walletBalanceListeners;
|
private List<WalletBalanceListener> walletBalanceListeners;
|
||||||
private List<FetchChannelsListener> fetchChannelsListeners;
|
private List<FetchChannelsListener> fetchChannelsListeners;
|
||||||
|
@ -278,6 +286,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
// your content
|
// your content
|
||||||
NavMenuItem.ID_ITEM_CHANNELS,
|
NavMenuItem.ID_ITEM_CHANNELS,
|
||||||
|
NavMenuItem.ID_ITEM_LIBRARY,
|
||||||
|
|
||||||
// wallet
|
// wallet
|
||||||
NavMenuItem.ID_ITEM_WALLET,
|
NavMenuItem.ID_ITEM_WALLET,
|
||||||
|
@ -336,6 +345,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
// other
|
// other
|
||||||
openNavFragments = new HashMap<>();
|
openNavFragments = new HashMap<>();
|
||||||
|
downloadActionListeners = new ArrayList<>();
|
||||||
sdkStatusListeners = new ArrayList<>();
|
sdkStatusListeners = new ArrayList<>();
|
||||||
walletBalanceListeners = new ArrayList<>();
|
walletBalanceListeners = new ArrayList<>();
|
||||||
fetchChannelsListeners = new ArrayList<>();
|
fetchChannelsListeners = new ArrayList<>();
|
||||||
|
@ -355,6 +365,14 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
shouldOpenUserSelectedMenuItem = false;
|
shouldOpenUserSelectedMenuItem = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDrawerSlide(View drawerView, float slideOffset) {
|
||||||
|
if (slideOffset != 0) {
|
||||||
|
clearWunderbarFocus(findViewById(R.id.wunderbar));
|
||||||
|
}
|
||||||
|
super.onDrawerSlide(drawerView, slideOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
drawer.addDrawerListener(toggle);
|
drawer.addDrawerListener(toggle);
|
||||||
toggle.syncState();
|
toggle.syncState();
|
||||||
|
@ -435,7 +453,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
specialRouteFragmentClassMap.put("channels", ChannelManagerFragment.class);
|
specialRouteFragmentClassMap.put("channels", ChannelManagerFragment.class);
|
||||||
specialRouteFragmentClassMap.put("invite", InvitesFragment.class);
|
specialRouteFragmentClassMap.put("invite", InvitesFragment.class);
|
||||||
specialRouteFragmentClassMap.put("invites", InvitesFragment.class);
|
specialRouteFragmentClassMap.put("invites", InvitesFragment.class);
|
||||||
//specialRouteFragmentClassMap.put("library", LibraryFragment.class);
|
specialRouteFragmentClassMap.put("library", LibraryFragment.class);
|
||||||
//specialRouteFragmentClassMap.put("publish", PublishFragment.class);
|
//specialRouteFragmentClassMap.put("publish", PublishFragment.class);
|
||||||
//specialRouteFragmentClassMap.put("publishes", PublishesFragment.class);
|
//specialRouteFragmentClassMap.put("publishes", PublishesFragment.class);
|
||||||
specialRouteFragmentClassMap.put("following", FollowingFragment.class);
|
specialRouteFragmentClassMap.put("following", FollowingFragment.class);
|
||||||
|
@ -452,6 +470,16 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
checkNotificationOpenIntent(intent);
|
checkNotificationOpenIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addDownloadActionListener(DownloadActionListener listener) {
|
||||||
|
if (!downloadActionListeners.contains(listener)) {
|
||||||
|
downloadActionListeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeDownloadActionListener(DownloadActionListener listener) {
|
||||||
|
downloadActionListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
public void addSdkStatusListener(SdkStatusListener listener) {
|
public void addSdkStatusListener(SdkStatusListener listener) {
|
||||||
if (!sdkStatusListeners.contains(listener)) {
|
if (!sdkStatusListeners.contains(listener)) {
|
||||||
sdkStatusListeners.add(listener);
|
sdkStatusListeners.add(listener);
|
||||||
|
@ -504,6 +532,9 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
case NavMenuItem.ID_ITEM_CHANNELS:
|
case NavMenuItem.ID_ITEM_CHANNELS:
|
||||||
openFragment(ChannelManagerFragment.class, true, NavMenuItem.ID_ITEM_CHANNELS);
|
openFragment(ChannelManagerFragment.class, true, NavMenuItem.ID_ITEM_CHANNELS);
|
||||||
break;
|
break;
|
||||||
|
case NavMenuItem.ID_ITEM_LIBRARY:
|
||||||
|
openFragment(LibraryFragment.class, true, NavMenuItem.ID_ITEM_LIBRARY);
|
||||||
|
break;
|
||||||
|
|
||||||
case NavMenuItem.ID_ITEM_WALLET:
|
case NavMenuItem.ID_ITEM_WALLET:
|
||||||
openFragment(WalletFragment.class, true, NavMenuItem.ID_ITEM_WALLET);
|
openFragment(WalletFragment.class, true, NavMenuItem.ID_ITEM_WALLET);
|
||||||
|
@ -1094,6 +1125,8 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
} else if (!appStarted) {
|
} else if (!appStarted) {
|
||||||
// first run completed, startup
|
// first run completed, startup
|
||||||
startup();
|
startup();
|
||||||
|
} else if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
|
||||||
|
openFragment(FollowingFragment.class, false, NavMenuItem.ID_ITEM_FOLLOWING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,9 +1179,12 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}
|
}
|
||||||
|
|
||||||
findViewById(R.id.global_sdk_initializing_status).setVisibility(View.GONE);
|
findViewById(R.id.global_sdk_initializing_status).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
syncWalletAndLoadPreferences();
|
||||||
scheduleWalletBalanceUpdate();
|
scheduleWalletBalanceUpdate();
|
||||||
scheduleWalletSyncTask();
|
scheduleWalletSyncTask();
|
||||||
fetchChannels();
|
fetchChannels();
|
||||||
|
|
||||||
initFloatingWalletBalance();
|
initFloatingWalletBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,7 +1353,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
return walletSyncEnabled && Lbryio.isSignedIn();
|
return walletSyncEnabled && Lbryio.isSignedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncWalletAndLoadPreferences() {
|
public void syncWalletAndLoadPreferences() {
|
||||||
if (!userSyncEnabled()) {
|
if (!userSyncEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1629,6 +1665,26 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
actionBar.show();
|
actionBar.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void renderStartupFailed(Map<Integer, Boolean> startupStages) {
|
||||||
|
Map<Integer, Integer> startupStageIconIds = new HashMap<>();
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_INSTALL_ID_LOADED, R.id.startup_stage_icon_install_id);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, R.id.startup_stage_icon_known_tags);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, R.id.startup_stage_icon_exchange_rate);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_USER_AUTHENTICATED, R.id.startup_stage_icon_user_authenticated);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_NEW_INSTALL_DONE, R.id.startup_stage_icon_install_new);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, R.id.startup_stage_icon_subscriptions_loaded);
|
||||||
|
startupStageIconIds.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, R.id.startup_stage_icon_subscriptions_resolved);
|
||||||
|
|
||||||
|
for (Integer key : startupStages.keySet()) {
|
||||||
|
boolean stageDone = startupStages.get(key);
|
||||||
|
ImageView icon = findViewById(startupStageIconIds.get(key));
|
||||||
|
icon.setImageResource(stageDone ? R.drawable.ic_check : R.drawable.ic_close);
|
||||||
|
icon.setColorFilter(stageDone ? Color.WHITE : Color.RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById(R.id.splash_view_loading_container).setVisibility(View.GONE);
|
||||||
|
findViewById(R.id.splash_view_error_container).setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
private void startup() {
|
private void startup() {
|
||||||
final Context context = this;
|
final Context context = this;
|
||||||
|
@ -1636,11 +1692,23 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
// perform some tasks before launching
|
// perform some tasks before launching
|
||||||
(new AsyncTask<Void, Void, Boolean>() {
|
(new AsyncTask<Void, Void, Boolean>() {
|
||||||
|
private Map<Integer, Boolean> startupStages = new HashMap<>();
|
||||||
|
|
||||||
|
private void initStartupStages() {
|
||||||
|
startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_USER_AUTHENTICATED, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_NEW_INSTALL_DONE, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, false);
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, false);
|
||||||
|
}
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
hideActionBar();
|
hideActionBar();
|
||||||
lockDrawer();
|
lockDrawer();
|
||||||
findViewById(R.id.splash_view).setVisibility(View.VISIBLE);
|
findViewById(R.id.splash_view).setVisibility(View.VISIBLE);
|
||||||
LbryAnalytics.setCurrentScreen(MainActivity.this, "Splash", "Splash");
|
LbryAnalytics.setCurrentScreen(MainActivity.this, "Splash", "Splash");
|
||||||
|
initStartupStages();
|
||||||
}
|
}
|
||||||
protected Boolean doInBackground(Void... params) {
|
protected Boolean doInBackground(Void... params) {
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
|
@ -1652,29 +1720,35 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
String installId = reader.readLine();
|
String installId = reader.readLine();
|
||||||
if (Helper.isNullOrEmpty(installId)) {
|
if (Helper.isNullOrEmpty(installId)) {
|
||||||
// no install_id found (first run didn't start the sdk successfully?)
|
// no install_id found (first run didn't start the sdk successfully?)
|
||||||
|
startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Lbry.INSTALLATION_ID = installId;
|
||||||
|
startupStages.put(STARTUP_STAGE_INSTALL_ID_LOADED, true);
|
||||||
|
|
||||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||||
List<Tag> fetchedTags = DatabaseHelper.getTags(db);
|
List<Tag> fetchedTags = DatabaseHelper.getTags(db);
|
||||||
Lbry.knownTags = Helper.mergeKnownTags(fetchedTags);
|
Lbry.knownTags = Helper.mergeKnownTags(fetchedTags);
|
||||||
Collections.sort(Lbry.knownTags, new Tag());
|
Collections.sort(Lbry.knownTags, new Tag());
|
||||||
Lbry.followedTags = Helper.filterFollowedTags(Lbry.knownTags);
|
Lbry.followedTags = Helper.filterFollowedTags(Lbry.knownTags);
|
||||||
|
startupStages.put(STARTUP_STAGE_KNOWN_TAGS_LOADED, true);
|
||||||
|
|
||||||
// load the exchange rate
|
// load the exchange rate
|
||||||
if (Lbryio.LBCUSDRate == 0) {
|
|
||||||
Lbryio.loadExchangeRate();
|
Lbryio.loadExchangeRate();
|
||||||
|
if (Lbryio.LBCUSDRate == 0) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
startupStages.put(STARTUP_STAGE_EXCHANGE_RATE_LOADED, true);
|
||||||
|
|
||||||
Lbry.INSTALLATION_ID = installId;
|
|
||||||
if (Lbryio.currentUser == null) {
|
|
||||||
Lbryio.authenticate(context);
|
Lbryio.authenticate(context);
|
||||||
}
|
|
||||||
if (Lbryio.currentUser == null) {
|
if (Lbryio.currentUser == null) {
|
||||||
throw new Exception("Did not retrieve authenticated user.");
|
throw new Exception("Did not retrieve authenticated user.");
|
||||||
}
|
}
|
||||||
|
startupStages.put(STARTUP_STAGE_USER_AUTHENTICATED, true);
|
||||||
|
|
||||||
Lbryio.newInstall(context);
|
Lbryio.newInstall(context);
|
||||||
|
startupStages.put(STARTUP_STAGE_NEW_INSTALL_DONE, true);
|
||||||
|
|
||||||
// (light) fetch subscriptions
|
// (light) fetch subscriptions
|
||||||
if (Lbryio.subscriptions.size() == 0) {
|
if (Lbryio.subscriptions.size() == 0) {
|
||||||
|
@ -1701,6 +1775,13 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
Lbryio.cacheResolvedSubscriptions = resolvedSubs;
|
Lbryio.cacheResolvedSubscriptions = resolvedSubs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if no exceptions occurred here, subscriptions have been loaded and resolved
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true);
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true);
|
||||||
|
} else {
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_LOADED, true);
|
||||||
|
startupStages.put(STARTUP_STAGE_SUBSCRIPTIONS_RESOLVED, true);
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// nope
|
// nope
|
||||||
|
@ -1714,8 +1795,8 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
}
|
}
|
||||||
protected void onPostExecute(Boolean startupSuccessful) {
|
protected void onPostExecute(Boolean startupSuccessful) {
|
||||||
if (!startupSuccessful) {
|
if (!startupSuccessful) {
|
||||||
Toast.makeText(context, R.string.startup_failed, Toast.LENGTH_LONG).show();
|
// show which startup stage failed
|
||||||
finish();
|
renderStartupFailed(startupStages);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1901,6 +1982,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
private void registerServiceActionsReceiver() {
|
private void registerServiceActionsReceiver() {
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
|
intentFilter.addAction(DownloadManager.ACTION_DOWNLOAD_EVENT);
|
||||||
intentFilter.addAction(LbrynetService.LBRY_SDK_SERVICE_STARTED);
|
intentFilter.addAction(LbrynetService.LBRY_SDK_SERVICE_STARTED);
|
||||||
intentFilter.addAction(LbrynetService.ACTION_STOP_SERVICE);
|
intentFilter.addAction(LbrynetService.ACTION_STOP_SERVICE);
|
||||||
serviceActionsReceiver = new BroadcastReceiver() {
|
serviceActionsReceiver = new BroadcastReceiver() {
|
||||||
|
@ -1920,6 +2002,19 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
notificationManager.notify(1, svcNotification);
|
notificationManager.notify(1, svcNotification);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
} else if (DownloadManager.ACTION_DOWNLOAD_EVENT.equalsIgnoreCase(action)) {
|
||||||
|
String downloadAction = intent.getStringExtra("action");
|
||||||
|
String uri = intent.getStringExtra("uri");
|
||||||
|
String outpoint = intent.getStringExtra("outpoint");
|
||||||
|
String fileInfoJson = intent.getStringExtra("file_info");
|
||||||
|
double progress = intent.getDoubleExtra("progress", 0);
|
||||||
|
if (uri == null || outpoint == null || (fileInfoJson == null && !"abort".equals(downloadAction))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DownloadActionListener listener : downloadActionListeners) {
|
||||||
|
listener.onDownloadAction(downloadAction, uri, outpoint, fileInfoJson, progress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1968,8 +2063,8 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
||||||
|
|
||||||
yourContentGroup.setItems(Arrays.asList(
|
yourContentGroup.setItems(Arrays.asList(
|
||||||
//new NavMenuItem(NavMenuItem.ID_ITEM_NEW_PUBLISH, R.string.fa_upload, R.string.new_publish, "NewPublish", context),
|
//new NavMenuItem(NavMenuItem.ID_ITEM_NEW_PUBLISH, R.string.fa_upload, R.string.new_publish, "NewPublish", context),
|
||||||
new NavMenuItem(NavMenuItem.ID_ITEM_CHANNELS, R.string.fa_at, R.string.channels, "Channels", context)
|
new NavMenuItem(NavMenuItem.ID_ITEM_CHANNELS, R.string.fa_at, R.string.channels, "Channels", context),
|
||||||
//new NavMenuItem(NavMenuItem.ID_ITEM_LIBRARY, R.string.fa_download, R.string.library, "Library", context)
|
new NavMenuItem(NavMenuItem.ID_ITEM_LIBRARY, R.string.fa_download, R.string.library, "Library", context)
|
||||||
//new NavMenuItem(NavMenuItem.ID_ITEM_PUBLISHES, R.string.fa_cloud_upload, R.string.publishes, "Publishes", context)
|
//new NavMenuItem(NavMenuItem.ID_ITEM_PUBLISHES, R.string.fa_cloud_upload, R.string.publishes, "Publishes", context)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
@ -17,11 +18,14 @@ import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.lbry.browser.R;
|
import io.lbry.browser.R;
|
||||||
import io.lbry.browser.listener.SelectionModeListener;
|
import io.lbry.browser.listener.SelectionModeListener;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import io.lbry.browser.utils.Lbryio;
|
import io.lbry.browser.utils.Lbryio;
|
||||||
|
@ -33,6 +37,11 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
private static final int VIEW_TYPE_CHANNEL = 2;
|
private static final int VIEW_TYPE_CHANNEL = 2;
|
||||||
private static final int VIEW_TYPE_FEATURED = 3; // featured search result
|
private static final int VIEW_TYPE_FEATURED = 3; // featured search result
|
||||||
|
|
||||||
|
private Map<String, Claim> quickClaimIdMap;
|
||||||
|
private Map<String, Claim> quickClaimUrlMap;
|
||||||
|
private Map<String, Boolean> notFoundClaimIdMap;
|
||||||
|
private Map<String, Boolean> notFoundClaimUrlMap;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private boolean canEnterSelectionMode;
|
private boolean canEnterSelectionMode;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
@ -50,6 +59,10 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.items = new ArrayList<>(items);
|
this.items = new ArrayList<>(items);
|
||||||
this.selectedItems = new ArrayList<>();
|
this.selectedItems = new ArrayList<>();
|
||||||
|
quickClaimIdMap = new HashMap<>();
|
||||||
|
quickClaimUrlMap = new HashMap<>();
|
||||||
|
notFoundClaimIdMap = new HashMap<>();
|
||||||
|
notFoundClaimUrlMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Claim> getSelectedItems() {
|
public List<Claim> getSelectedItems() {
|
||||||
|
@ -77,6 +90,10 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
public void clearItems() {
|
public void clearItems() {
|
||||||
clearSelectedItems();
|
clearSelectedItems();
|
||||||
this.items.clear();
|
this.items.clear();
|
||||||
|
quickClaimIdMap.clear();
|
||||||
|
quickClaimUrlMap.clear();
|
||||||
|
notFoundClaimIdMap.clear();
|
||||||
|
notFoundClaimUrlMap.clear();
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +108,9 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
items.add(claim);
|
items.add(claim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notFoundClaimUrlMap.clear();
|
||||||
|
notFoundClaimIdMap.clear();
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
public void setItems(List<Claim> claims) {
|
public void setItems(List<Claim> claims) {
|
||||||
|
@ -119,6 +139,9 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
protected View repostInfoView;
|
protected View repostInfoView;
|
||||||
protected TextView repostChannelView;
|
protected TextView repostChannelView;
|
||||||
protected View selectedOverlayView;
|
protected View selectedOverlayView;
|
||||||
|
protected TextView fileSizeView;
|
||||||
|
protected ProgressBar downloadProgressView;
|
||||||
|
protected TextView deviceView;
|
||||||
public ViewHolder(View v) {
|
public ViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
feeContainer = v.findViewById(R.id.claim_fee_container);
|
feeContainer = v.findViewById(R.id.claim_fee_container);
|
||||||
|
@ -135,6 +158,9 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
repostInfoView = v.findViewById(R.id.claim_repost_info);
|
repostInfoView = v.findViewById(R.id.claim_repost_info);
|
||||||
repostChannelView = v.findViewById(R.id.claim_repost_channel);
|
repostChannelView = v.findViewById(R.id.claim_repost_channel);
|
||||||
selectedOverlayView = v.findViewById(R.id.claim_selected_overlay);
|
selectedOverlayView = v.findViewById(R.id.claim_selected_overlay);
|
||||||
|
fileSizeView = v.findViewById(R.id.claim_file_size);
|
||||||
|
downloadProgressView = v.findViewById(R.id.claim_download_progress);
|
||||||
|
deviceView = v.findViewById(R.id.claim_view_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +182,68 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
return Claim.TYPE_CHANNEL.equalsIgnoreCase(actualClaim.getValueType()) ? VIEW_TYPE_CHANNEL : VIEW_TYPE_STREAM;
|
return Claim.TYPE_CHANNEL.equalsIgnoreCase(actualClaim.getValueType()) ? VIEW_TYPE_CHANNEL : VIEW_TYPE_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateFileForClaimByIdOrUrl(LbryFile file, String claimId, String url) {
|
||||||
|
updateFileForClaimByIdOrUrl(file, claimId, url, false);
|
||||||
|
}
|
||||||
|
public void updateFileForClaimByIdOrUrl(LbryFile file, String claimId, String url, boolean skipNotFound) {
|
||||||
|
if (!skipNotFound) {
|
||||||
|
if (notFoundClaimIdMap.containsKey(claimId) && notFoundClaimUrlMap.containsKey(url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quickClaimIdMap.containsKey(claimId)) {
|
||||||
|
quickClaimIdMap.get(claimId).setFile(file);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (quickClaimUrlMap.containsKey(claimId)) {
|
||||||
|
quickClaimUrlMap.get(claimId).setFile(file);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean claimFound = false;
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
Claim claim = items.get(i);
|
||||||
|
if (claimId.equalsIgnoreCase(claim.getClaimId()) || url.equalsIgnoreCase(claim.getPermanentUrl())) {
|
||||||
|
quickClaimIdMap.put(claimId, claim);
|
||||||
|
quickClaimUrlMap.put(url, claim);
|
||||||
|
claim.setFile(file);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
claimFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!claimFound) {
|
||||||
|
notFoundClaimIdMap.put(claimId, true);
|
||||||
|
notFoundClaimUrlMap.put(url, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void clearFileForClaimOrUrl(String outpoint, String url) {
|
||||||
|
clearFileForClaimOrUrl(outpoint, url, false);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void clearFileForClaimOrUrl(String outpoint, String url, boolean remove) {
|
||||||
|
int claimIndex = -1;
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
Claim claim = items.get(i);
|
||||||
|
if (outpoint.equalsIgnoreCase(claim.getOutpoint()) || url.equalsIgnoreCase(claim.getPermanentUrl())) {
|
||||||
|
claimIndex = i;
|
||||||
|
claim.setFile(null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (remove && claimIndex > -1) {
|
||||||
|
Claim removed = items.remove(claimIndex);
|
||||||
|
selectedItems.remove(removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClaimListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ClaimListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
int viewResourceId = -1;
|
int viewResourceId = -1;
|
||||||
|
@ -290,6 +378,24 @@ public class ClaimListAdapter extends RecyclerView.Adapter<ClaimListAdapter.View
|
||||||
publishTime, System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
publishTime, System.currentTimeMillis(), 0, DateUtils.FORMAT_ABBREV_RELATIVE));
|
||||||
vh.durationView.setVisibility(duration > 0 ? View.VISIBLE : View.GONE);
|
vh.durationView.setVisibility(duration > 0 ? View.VISIBLE : View.GONE);
|
||||||
vh.durationView.setText(Helper.formatDuration(duration));
|
vh.durationView.setText(Helper.formatDuration(duration));
|
||||||
|
|
||||||
|
LbryFile claimFile = item.getFile();
|
||||||
|
boolean isDownloading = false;
|
||||||
|
int progress = 0;
|
||||||
|
String fileSizeString = claimFile == null ? null : Helper.formatBytes(claimFile.getTotalBytes(), false);
|
||||||
|
if (claimFile != null && !claimFile.isCompleted() && claimFile.getWrittenBytes() < claimFile.getTotalBytes()) {
|
||||||
|
isDownloading = true;
|
||||||
|
progress = claimFile.getTotalBytes() > 0 ?
|
||||||
|
Double.valueOf(((double) claimFile.getWrittenBytes() / (double) claimFile.getTotalBytes()) * 100.0).intValue() : 0;
|
||||||
|
fileSizeString = String.format("%s / %s",
|
||||||
|
Helper.formatBytes(claimFile.getWrittenBytes(), false),
|
||||||
|
Helper.formatBytes(claimFile.getTotalBytes(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
Helper.setViewText(vh.fileSizeView, fileSizeString);
|
||||||
|
Helper.setViewVisibility(vh.downloadProgressView, isDownloading ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
Helper.setViewProgress(vh.downloadProgressView, progress);
|
||||||
|
Helper.setViewText(vh.deviceView, item.getDevice());
|
||||||
} else if (Claim.TYPE_CHANNEL.equalsIgnoreCase(item.getValueType())) {
|
} else if (Claim.TYPE_CHANNEL.equalsIgnoreCase(item.getValueType())) {
|
||||||
if (!Helper.isNullOrEmpty(thumbnailUrl)) {
|
if (!Helper.isNullOrEmpty(thumbnailUrl)) {
|
||||||
Glide.with(context.getApplicationContext()).
|
Glide.with(context.getApplicationContext()).
|
||||||
|
|
|
@ -4,7 +4,10 @@ import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.opengl.Visibility;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -66,6 +69,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final String SQL_INSERT_VIEW_HISTORY =
|
private static final String SQL_INSERT_VIEW_HISTORY =
|
||||||
"REPLACE INTO view_history (url, claim_id, claim_name, cost, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
"REPLACE INTO view_history (url, claim_id, claim_name, cost, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
private static final String SQL_GET_VIEW_HISTORY =
|
||||||
|
"SELECT url, claim_id, claim_name, cost, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp " +
|
||||||
|
"FROM view_history WHERE '' = ? OR timestamp < ? ORDER BY timestamp DESC LIMIT %d";
|
||||||
private static final String SQL_CLEAR_VIEW_HISTORY = "DELETE FROM view_history";
|
private static final String SQL_CLEAR_VIEW_HISTORY = "DELETE FROM view_history";
|
||||||
private static final String SQL_CLEAR_VIEW_HISTORY_BY_DEVICE = "DELETE FROM view_history WHERE device = ?";
|
private static final String SQL_CLEAR_VIEW_HISTORY_BY_DEVICE = "DELETE FROM view_history WHERE device = ?";
|
||||||
private static final String SQL_CLEAR_VIEW_HISTORY_BEFORE_TIME = "DELETE FROM view_history WHERE timestamp < ?";
|
private static final String SQL_CLEAR_VIEW_HISTORY_BEFORE_TIME = "DELETE FROM view_history WHERE timestamp < ?";
|
||||||
|
@ -147,6 +153,41 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<ViewHistory> getViewHistory(String lastTimestamp, int pageLimit, SQLiteDatabase db) {
|
||||||
|
List<ViewHistory> history = new ArrayList<>();
|
||||||
|
Cursor cursor = null;
|
||||||
|
try {
|
||||||
|
String arg = lastTimestamp == null ? "" : lastTimestamp;
|
||||||
|
cursor = db.rawQuery(String.format(SQL_GET_VIEW_HISTORY, pageLimit), new String[] { arg, arg });
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
ViewHistory item = new ViewHistory();
|
||||||
|
int cursorIndex = 0;
|
||||||
|
item.setUri(LbryUri.tryParse(cursor.getString(cursorIndex++)));
|
||||||
|
item.setClaimId(cursor.getString(cursorIndex++));
|
||||||
|
item.setClaimName(cursor.getString(cursorIndex++));
|
||||||
|
item.setCost(new BigDecimal(cursor.getDouble(cursorIndex++)));
|
||||||
|
item.setTitle(cursor.getString(cursorIndex++));
|
||||||
|
item.setPublisherClaimId(cursor.getString(cursorIndex++));
|
||||||
|
item.setPublisherName(cursor.getString(cursorIndex++));
|
||||||
|
item.setPublisherTitle(cursor.getString(cursorIndex++));
|
||||||
|
item.setThumbnailUrl(cursor.getString(cursorIndex++));
|
||||||
|
item.setDevice(cursor.getString(cursorIndex++));
|
||||||
|
item.setReleaseTime(cursor.getLong(cursorIndex++));
|
||||||
|
try {
|
||||||
|
item.setTimestamp(new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).parse(cursor.getString(cursorIndex)));
|
||||||
|
} catch (ParseException ex) {
|
||||||
|
// invalid timestamp (which shouldn't happen). Skip this item
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
history.add(item);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Helper.closeCursor(cursor);
|
||||||
|
}
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
public static void createOrUpdateTag(Tag tag, SQLiteDatabase db) {
|
public static void createOrUpdateTag(Tag tag, SQLiteDatabase db) {
|
||||||
db.execSQL(SQL_INSERT_TAG, new Object[] { tag.getLowercaseName(), tag.isFollowed() ? 1 : 0 });
|
db.execSQL(SQL_INSERT_TAG, new Object[] { tag.getLowercaseName(), tag.isFollowed() ? 1 : 0 });
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package io.lbry.browser.listener;
|
||||||
|
|
||||||
|
public interface DownloadActionListener {
|
||||||
|
void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress);
|
||||||
|
}
|
|
@ -82,6 +82,9 @@ public class Claim {
|
||||||
private GenericMetadata value;
|
private GenericMetadata value;
|
||||||
private LbryFile file; // associated file if it exists
|
private LbryFile file; // associated file if it exists
|
||||||
|
|
||||||
|
// device it was viewed on (for view history)
|
||||||
|
private String device;
|
||||||
|
|
||||||
public static Claim claimFromOutput(JSONObject item) {
|
public static Claim claimFromOutput(JSONObject item) {
|
||||||
// we only need name, permanent_url, txid and nout
|
// we only need name, permanent_url, txid and nout
|
||||||
Claim claim = new Claim();
|
Claim claim = new Claim();
|
||||||
|
@ -93,6 +96,10 @@ public class Claim {
|
||||||
return claim;
|
return claim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOutpoint() {
|
||||||
|
return String.format("%s:%d", txid, nout);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isFree() {
|
public boolean isFree() {
|
||||||
if (!(value instanceof StreamMetadata)) {
|
if (!(value instanceof StreamMetadata)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -246,6 +253,8 @@ public class Claim {
|
||||||
claim.setName(viewHistory.getClaimName());
|
claim.setName(viewHistory.getClaimName());
|
||||||
claim.setValueType(TYPE_STREAM);
|
claim.setValueType(TYPE_STREAM);
|
||||||
claim.setPermanentUrl(viewHistory.getUri().toString());
|
claim.setPermanentUrl(viewHistory.getUri().toString());
|
||||||
|
claim.setDevice(viewHistory.getDevice());
|
||||||
|
claim.setConfirmations(1);
|
||||||
|
|
||||||
StreamMetadata value = new StreamMetadata();
|
StreamMetadata value = new StreamMetadata();
|
||||||
value.setTitle(viewHistory.getTitle());
|
value.setTitle(viewHistory.getTitle());
|
||||||
|
|
|
@ -9,9 +9,12 @@ import org.json.JSONObject;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
import io.lbry.browser.utils.LbryUri;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
public class LbryFile {
|
public class LbryFile {
|
||||||
private Claim.StreamMetadata metadata;
|
private Claim.StreamMetadata metadata;
|
||||||
private long addedOn;
|
private long addedOn;
|
||||||
|
@ -20,6 +23,7 @@ public class LbryFile {
|
||||||
private int blobsRemaining;
|
private int blobsRemaining;
|
||||||
private String channelClaimId;
|
private String channelClaimId;
|
||||||
private String channelName;
|
private String channelName;
|
||||||
|
@EqualsAndHashCode.Include
|
||||||
private String claimId;
|
private String claimId;
|
||||||
private String claimName;
|
private String claimName;
|
||||||
private boolean completed;
|
private boolean completed;
|
||||||
|
@ -39,16 +43,50 @@ public class LbryFile {
|
||||||
private String streamName;
|
private String streamName;
|
||||||
private String streamingUrl;
|
private String streamingUrl;
|
||||||
private String suggestedFileName;
|
private String suggestedFileName;
|
||||||
|
private long timestamp;
|
||||||
private long totalBytes;
|
private long totalBytes;
|
||||||
private long totalBytesLowerBound;
|
private long totalBytesLowerBound;
|
||||||
private String txid;
|
private String txid;
|
||||||
private long writtenBytes;
|
private long writtenBytes;
|
||||||
|
|
||||||
|
private Claim generatedClaim;
|
||||||
|
|
||||||
|
public Claim getClaim() {
|
||||||
|
if (generatedClaim != null) {
|
||||||
|
return generatedClaim;
|
||||||
|
}
|
||||||
|
|
||||||
|
generatedClaim = new Claim();
|
||||||
|
generatedClaim.setValueType(Claim.TYPE_STREAM);
|
||||||
|
generatedClaim.setPermanentUrl(LbryUri.tryParse(String.format("%s#%s", claimName, claimId)).toString());
|
||||||
|
generatedClaim.setClaimId(claimId);
|
||||||
|
generatedClaim.setName(claimName);
|
||||||
|
generatedClaim.setValue(metadata);
|
||||||
|
generatedClaim.setConfirmations(1);
|
||||||
|
generatedClaim.setTxid(txid);
|
||||||
|
generatedClaim.setNout(nout);
|
||||||
|
generatedClaim.setFile(this);
|
||||||
|
|
||||||
|
if (channelClaimId != null) {
|
||||||
|
Claim signingChannel = new Claim();
|
||||||
|
signingChannel.setClaimId(channelClaimId);
|
||||||
|
signingChannel.setName(channelName);
|
||||||
|
signingChannel.setPermanentUrl(LbryUri.tryParse(String.format("%s#%s", claimName, claimId)).toString());
|
||||||
|
generatedClaim.setSigningChannel(signingChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return generatedClaim;
|
||||||
|
}
|
||||||
|
|
||||||
public static LbryFile fromJSONObject(JSONObject fileObject) {
|
public static LbryFile fromJSONObject(JSONObject fileObject) {
|
||||||
String fileJson = fileObject.toString();
|
String fileJson = fileObject.toString();
|
||||||
Type type = new TypeToken<LbryFile>(){}.getType();
|
Type type = new TypeToken<LbryFile>(){}.getType();
|
||||||
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||||
LbryFile file = gson.fromJson(fileJson, type);
|
LbryFile file = gson.fromJson(fileJson, type);
|
||||||
|
|
||||||
|
if (file.getMetadata() != null && file.getMetadata().getReleaseTime() == 0) {
|
||||||
|
file.getMetadata().setReleaseTime(file.getTimestamp());
|
||||||
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import io.lbry.browser.exceptions.LbryUriException;
|
import io.lbry.browser.exceptions.LbryUriException;
|
||||||
import io.lbry.browser.utils.LbryUri;
|
import io.lbry.browser.utils.LbryUri;
|
||||||
|
import io.lbry.browser.utils.Lbryio;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -39,9 +40,12 @@ public class ViewHistory {
|
||||||
Claim.StreamMetadata value = (Claim.StreamMetadata) metadata;
|
Claim.StreamMetadata value = (Claim.StreamMetadata) metadata;
|
||||||
history.setReleaseTime(value.getReleaseTime());
|
history.setReleaseTime(value.getReleaseTime());
|
||||||
if (value.getFee() != null) {
|
if (value.getFee() != null) {
|
||||||
history.setCost(new BigDecimal(value.getFee().getAmount()));
|
history.setCost(claim.getActualCost(Lbryio.LBCUSDRate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (history.getReleaseTime() == 0) {
|
||||||
|
history.setReleaseTime(claim.getTimestamp());
|
||||||
|
}
|
||||||
|
|
||||||
Claim signingChannel = claim.getSigningChannel();
|
Claim signingChannel = claim.getSigningChannel();
|
||||||
if (signingChannel != null) {
|
if (signingChannel != null) {
|
||||||
|
|
|
@ -12,12 +12,18 @@ import io.lbry.browser.utils.Lbry;
|
||||||
|
|
||||||
public class FileListTask extends AsyncTask<Void, Void, List<LbryFile>> {
|
public class FileListTask extends AsyncTask<Void, Void, List<LbryFile>> {
|
||||||
private String claimId;
|
private String claimId;
|
||||||
|
private boolean downloads;
|
||||||
|
private int page;
|
||||||
|
private int pageSize;
|
||||||
private FileListResultHandler handler;
|
private FileListResultHandler handler;
|
||||||
private View progressView;
|
private View progressView;
|
||||||
private ApiCallException error;
|
private ApiCallException error;
|
||||||
|
|
||||||
public FileListTask(View progressView, FileListResultHandler handler) {
|
public FileListTask(int page, int pageSize, boolean downloads, View progressView, FileListResultHandler handler) {
|
||||||
this(null, progressView, handler);
|
this(null, progressView, handler);
|
||||||
|
this.page = page;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.downloads = downloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileListTask(String claimId, View progressView, FileListResultHandler handler) {
|
public FileListTask(String claimId, View progressView, FileListResultHandler handler) {
|
||||||
|
@ -30,7 +36,7 @@ public class FileListTask extends AsyncTask<Void, Void, List<LbryFile>> {
|
||||||
}
|
}
|
||||||
protected List<LbryFile> doInBackground(Void... params) {
|
protected List<LbryFile> doInBackground(Void... params) {
|
||||||
try {
|
try {
|
||||||
return Lbry.fileList(claimId);
|
return Lbry.fileList(claimId, downloads, page, pageSize);
|
||||||
} catch (ApiCallException ex) {
|
} catch (ApiCallException ex) {
|
||||||
error = ex;
|
error = ex;
|
||||||
return null;
|
return null;
|
||||||
|
@ -40,7 +46,7 @@ public class FileListTask extends AsyncTask<Void, Void, List<LbryFile>> {
|
||||||
Helper.setViewVisibility(progressView, View.GONE);
|
Helper.setViewVisibility(progressView, View.GONE);
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
handler.onSuccess(files);
|
handler.onSuccess(files, files.size() < pageSize);
|
||||||
} else {
|
} else {
|
||||||
handler.onError(error);
|
handler.onError(error);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +54,7 @@ public class FileListTask extends AsyncTask<Void, Void, List<LbryFile>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface FileListResultHandler {
|
public interface FileListResultHandler {
|
||||||
void onSuccess(List<LbryFile> files);
|
void onSuccess(List<LbryFile> files, boolean hasReachedEnd);
|
||||||
void onError(Exception error);
|
void onError(Exception error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package io.lbry.browser.tasks.localdata;
|
||||||
|
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteException;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.lbry.browser.data.DatabaseHelper;
|
||||||
|
import io.lbry.browser.model.UrlSuggestion;
|
||||||
|
import io.lbry.browser.model.ViewHistory;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
|
||||||
|
public class FetchViewHistoryTask extends AsyncTask<Void, Void, List<ViewHistory>> {
|
||||||
|
private DatabaseHelper dbHelper;
|
||||||
|
private FetchViewHistoryHandler handler;
|
||||||
|
private int pageSize;
|
||||||
|
private Date lastDate;
|
||||||
|
public FetchViewHistoryTask(Date lastDate, int pageSize, DatabaseHelper dbHelper, FetchViewHistoryHandler handler) {
|
||||||
|
this.lastDate = lastDate;
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
this.dbHelper = dbHelper;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
protected List<ViewHistory> doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||||
|
return DatabaseHelper.getViewHistory(
|
||||||
|
lastDate == null ? null : new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).format(lastDate), pageSize, db);
|
||||||
|
} catch (SQLiteException ex) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected void onPostExecute(List<ViewHistory> history) {
|
||||||
|
if (handler != null) {
|
||||||
|
handler.onSuccess(history, history.size() < pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface FetchViewHistoryHandler {
|
||||||
|
void onSuccess(List<ViewHistory> history, boolean hasReachedEnd);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,45 @@
|
||||||
package io.lbry.browser.tasks.localdata;
|
package io.lbry.browser.tasks.localdata;
|
||||||
|
|
||||||
public class SaveViewHistoryTask {
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
|
||||||
|
import io.lbry.browser.data.DatabaseHelper;
|
||||||
|
import io.lbry.browser.model.ViewHistory;
|
||||||
|
|
||||||
|
public class SaveViewHistoryTask extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
private DatabaseHelper dbHelper;
|
||||||
|
private ViewHistory history;
|
||||||
|
private SaveViewHistoryHandler handler;
|
||||||
|
private Exception error;
|
||||||
|
|
||||||
|
public SaveViewHistoryTask(ViewHistory history, DatabaseHelper dbHelper, SaveViewHistoryHandler handler) {
|
||||||
|
this.history = history;
|
||||||
|
this.dbHelper = dbHelper;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
protected Boolean doInBackground(Void... params) {
|
||||||
|
try {
|
||||||
|
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||||
|
DatabaseHelper.createOrUpdateViewHistoryItem(history, db);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
error = ex;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (handler != null) {
|
||||||
|
if (result) {
|
||||||
|
handler.onSuccess(history);
|
||||||
|
} else {
|
||||||
|
handler.onError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface SaveViewHistoryHandler {
|
||||||
|
void onSuccess(ViewHistory item);
|
||||||
|
void onError(Exception error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,12 @@ import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.offline.Download;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -30,8 +34,10 @@ import io.lbry.browser.dialog.ContentFromDialogFragment;
|
||||||
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
||||||
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
||||||
import io.lbry.browser.dialog.CustomizeTagsDialogFragment;
|
import io.lbry.browser.dialog.CustomizeTagsDialogFragment;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.listener.TagListener;
|
import io.lbry.browser.listener.TagListener;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.model.Tag;
|
import io.lbry.browser.model.Tag;
|
||||||
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
||||||
import io.lbry.browser.tasks.FollowUnfollowTagTask;
|
import io.lbry.browser.tasks.FollowUnfollowTagTask;
|
||||||
|
@ -43,7 +49,7 @@ import io.lbry.browser.utils.Predefined;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
// TODO: Similar code to FollowingFragment and Channel page fragment. Probably make common operations (sorting/filtering) into a control
|
// TODO: Similar code to FollowingFragment and Channel page fragment. Probably make common operations (sorting/filtering) into a control
|
||||||
public class AllContentFragment extends BaseFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class AllContentFragment extends BaseFragment implements DownloadActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private boolean singleTagView;
|
private boolean singleTagView;
|
||||||
|
@ -374,6 +380,7 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
} else {
|
} else {
|
||||||
LbryAnalytics.setCurrentScreen(activity, "All Content", "AllContent");
|
LbryAnalytics.setCurrentScreen(activity, "All Content", "AllContent");
|
||||||
}
|
}
|
||||||
|
activity.addDownloadActionListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
||||||
|
@ -384,7 +391,11 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
((MainActivity) context).removeDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,4 +502,24 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
||||||
fetchClaimSearchContent(true);
|
fetchClaimSearchContent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearFileForClaimOrUrl(outpoint, uri);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -27,14 +30,16 @@ import io.lbry.browser.R;
|
||||||
import io.lbry.browser.adapter.ClaimListAdapter;
|
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||||
import io.lbry.browser.dialog.ContentFromDialogFragment;
|
import io.lbry.browser.dialog.ContentFromDialogFragment;
|
||||||
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
||||||
import io.lbry.browser.utils.Helper;
|
import io.lbry.browser.utils.Helper;
|
||||||
import io.lbry.browser.utils.Lbry;
|
import io.lbry.browser.utils.Lbry;
|
||||||
import io.lbry.browser.utils.Predefined;
|
import io.lbry.browser.utils.Predefined;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class ChannelContentFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener {
|
public class ChannelContentFragment extends Fragment implements DownloadActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private String channelId;
|
private String channelId;
|
||||||
|
@ -189,12 +194,20 @@ public class ChannelContentFragment extends Fragment implements SharedPreference
|
||||||
|
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
((MainActivity) context).addDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
|
||||||
fetchClaimSearchContent();
|
fetchClaimSearchContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
((MainActivity) context).removeDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,4 +313,24 @@ public class ChannelContentFragment extends Fragment implements SharedPreference
|
||||||
fetchClaimSearchContent(true);
|
fetchClaimSearchContent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearFileForClaimOrUrl(outpoint, uri);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -35,7 +38,9 @@ import io.lbry.browser.dialog.ContentFromDialogFragment;
|
||||||
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
||||||
import io.lbry.browser.dialog.DiscoverDialogFragment;
|
import io.lbry.browser.dialog.DiscoverDialogFragment;
|
||||||
import io.lbry.browser.exceptions.LbryUriException;
|
import io.lbry.browser.exceptions.LbryUriException;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.model.lbryinc.Subscription;
|
import io.lbry.browser.model.lbryinc.Subscription;
|
||||||
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
|
||||||
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
||||||
|
@ -53,7 +58,9 @@ import io.lbry.browser.utils.Predefined;
|
||||||
|
|
||||||
public class FollowingFragment extends BaseFragment implements
|
public class FollowingFragment extends BaseFragment implements
|
||||||
FetchSubscriptionsTask.FetchSubscriptionsHandler,
|
FetchSubscriptionsTask.FetchSubscriptionsHandler,
|
||||||
ChannelItemSelectionListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
ChannelItemSelectionListener,
|
||||||
|
DownloadActionListener,
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
public static boolean resetClaimSearchContent;
|
public static boolean resetClaimSearchContent;
|
||||||
private static final int SUGGESTED_PAGE_SIZE = 45;
|
private static final int SUGGESTED_PAGE_SIZE = 45;
|
||||||
|
@ -334,6 +341,7 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
LbryAnalytics.setCurrentScreen(activity, "Subscriptions", "Subscriptions");
|
LbryAnalytics.setCurrentScreen(activity, "Subscriptions", "Subscriptions");
|
||||||
|
activity.addDownloadActionListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if subscriptions exist
|
// check if subscriptions exist
|
||||||
|
@ -351,7 +359,11 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
((MainActivity) context).removeDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
public void fetchLoadedSubscriptions() {
|
public void fetchLoadedSubscriptions() {
|
||||||
|
@ -767,4 +779,24 @@ public class FollowingFragment extends BaseFragment implements
|
||||||
fetchClaimSearchContent(true);
|
fetchClaimSearchContent(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearFileForClaimOrUrl(outpoint, uri);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
package io.lbry.browser.ui.library;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.lbry.browser.MainActivity;
|
||||||
|
import io.lbry.browser.R;
|
||||||
|
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||||
|
import io.lbry.browser.data.DatabaseHelper;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
|
import io.lbry.browser.listener.SdkStatusListener;
|
||||||
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
|
import io.lbry.browser.model.ViewHistory;
|
||||||
|
import io.lbry.browser.tasks.file.FileListTask;
|
||||||
|
import io.lbry.browser.tasks.localdata.FetchViewHistoryTask;
|
||||||
|
import io.lbry.browser.ui.BaseFragment;
|
||||||
|
import io.lbry.browser.utils.Helper;
|
||||||
|
import io.lbry.browser.utils.Lbry;
|
||||||
|
import io.lbry.browser.utils.LbryAnalytics;
|
||||||
|
|
||||||
|
public class LibraryFragment extends BaseFragment implements DownloadActionListener, SdkStatusListener {
|
||||||
|
|
||||||
|
private static final int FILTER_DOWNLOADS = 1;
|
||||||
|
private static final int FILTER_HISTORY = 2;
|
||||||
|
private static final int PAGE_SIZE = 50;
|
||||||
|
|
||||||
|
private int currentFilter;
|
||||||
|
private List<LbryFile> currentFiles;
|
||||||
|
private View layoutSdkInitializing;
|
||||||
|
private RecyclerView contentList;
|
||||||
|
private ClaimListAdapter contentListAdapter;
|
||||||
|
private ProgressBar listLoading;
|
||||||
|
private TextView linkFilterDownloads;
|
||||||
|
private TextView linkFilterHistory;
|
||||||
|
private View layoutListEmpty;
|
||||||
|
private TextView textListEmpty;
|
||||||
|
private int currentPage;
|
||||||
|
private Date lastDate;
|
||||||
|
private boolean listReachedEnd;
|
||||||
|
|
||||||
|
private CardView cardStats;
|
||||||
|
private TextView linkStats;
|
||||||
|
private TextView linkHide;
|
||||||
|
private View viewStatsDistribution;
|
||||||
|
private View viewVideoStatsBar;
|
||||||
|
private View viewAudioStatsBar;
|
||||||
|
private View viewImageStatsBar;
|
||||||
|
private View viewOtherStatsBar;
|
||||||
|
private TextView textStatsTotalSize;
|
||||||
|
private TextView textStatsTotalSizeUnits;
|
||||||
|
private TextView textStatsVideoSize;
|
||||||
|
private TextView textStatsAudioSize;
|
||||||
|
private TextView textStatsImageSize;
|
||||||
|
private TextView textStatsOtherSize;
|
||||||
|
private View legendVideo;
|
||||||
|
private View legendAudio;
|
||||||
|
private View legendImage;
|
||||||
|
private View legendOther;
|
||||||
|
|
||||||
|
private long totalBytes;
|
||||||
|
private long totalVideoBytes;
|
||||||
|
private long totalAudioBytes;
|
||||||
|
private long totalImageBytes;
|
||||||
|
private long totalOtherBytes;
|
||||||
|
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View root = inflater.inflate(R.layout.fragment_library, container, false);
|
||||||
|
|
||||||
|
layoutSdkInitializing = root.findViewById(R.id.container_library_sdk_initializing);
|
||||||
|
|
||||||
|
LinearLayoutManager llm = new LinearLayoutManager(getContext());
|
||||||
|
contentList = root.findViewById(R.id.library_list);
|
||||||
|
contentList.setLayoutManager(llm);
|
||||||
|
|
||||||
|
listLoading = root.findViewById(R.id.library_list_loading);
|
||||||
|
linkFilterDownloads = root.findViewById(R.id.library_filter_link_downloads);
|
||||||
|
linkFilterHistory = root.findViewById(R.id.library_filter_link_history);
|
||||||
|
|
||||||
|
layoutListEmpty = root.findViewById(R.id.library_empty_container);
|
||||||
|
textListEmpty = root.findViewById(R.id.library_list_empty_text);
|
||||||
|
|
||||||
|
currentFilter = FILTER_DOWNLOADS;
|
||||||
|
linkFilterDownloads.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
showDownloads();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
linkFilterHistory.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
showHistory();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// stats
|
||||||
|
linkStats = root.findViewById(R.id.library_show_stats);
|
||||||
|
linkHide = root.findViewById(R.id.library_hide_stats);
|
||||||
|
cardStats = root.findViewById(R.id.library_storage_stats_card);
|
||||||
|
viewStatsDistribution = root.findViewById(R.id.library_storage_stat_distribution);
|
||||||
|
viewVideoStatsBar = root.findViewById(R.id.library_storage_stat_video_bar);
|
||||||
|
viewAudioStatsBar = root.findViewById(R.id.library_storage_stat_audio_bar);
|
||||||
|
viewImageStatsBar = root.findViewById(R.id.library_storage_stat_image_bar);
|
||||||
|
viewOtherStatsBar = root.findViewById(R.id.library_storage_stat_other_bar);
|
||||||
|
textStatsTotalSize = root.findViewById(R.id.library_storage_stat_used);
|
||||||
|
textStatsTotalSizeUnits = root.findViewById(R.id.library_storage_stat_unit);
|
||||||
|
textStatsVideoSize = root.findViewById(R.id.library_storage_stat_video_size);
|
||||||
|
textStatsAudioSize = root.findViewById(R.id.library_storage_stat_audio_size);
|
||||||
|
textStatsImageSize = root.findViewById(R.id.library_storage_stat_image_size);
|
||||||
|
textStatsOtherSize = root.findViewById(R.id.library_storage_stat_other_size);
|
||||||
|
legendVideo = root.findViewById(R.id.library_storage_legend_video);
|
||||||
|
legendAudio = root.findViewById(R.id.library_storage_legend_audio);
|
||||||
|
legendImage = root.findViewById(R.id.library_storage_legend_image);
|
||||||
|
legendOther = root.findViewById(R.id.library_storage_legend_other);
|
||||||
|
|
||||||
|
linkStats.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
updateStats();
|
||||||
|
cardStats.setVisibility(View.VISIBLE);
|
||||||
|
checkStatsLink();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
linkHide.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
cardStats.setVisibility(View.GONE);
|
||||||
|
checkStatsLink();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
LbryAnalytics.setCurrentScreen(activity, "Library", "Library");
|
||||||
|
activity.addDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutSdkInitializing.setVisibility(
|
||||||
|
!Lbry.SDK_READY && currentFilter == FILTER_DOWNLOADS ? View.VISIBLE : View.GONE);
|
||||||
|
if (!Lbry.SDK_READY) {
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.addSdkStatusListener(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onSdkReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause() {
|
||||||
|
Context context = getContext();
|
||||||
|
if (context instanceof MainActivity) {
|
||||||
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.removeSdkStatusListener(this);
|
||||||
|
activity.removeDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSdkReady() {
|
||||||
|
layoutSdkInitializing.setVisibility(View.GONE);
|
||||||
|
if (currentFilter == FILTER_DOWNLOADS) {
|
||||||
|
showDownloads();
|
||||||
|
} else if (currentFilter == FILTER_HISTORY) {
|
||||||
|
showHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDownloads() {
|
||||||
|
currentFilter = FILTER_DOWNLOADS;
|
||||||
|
linkFilterDownloads.setTypeface(null, Typeface.BOLD);
|
||||||
|
linkFilterHistory.setTypeface(null, Typeface.NORMAL);
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearItems();
|
||||||
|
contentListAdapter.setCanEnterSelectionMode(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkStatsLink();
|
||||||
|
layoutSdkInitializing.setVisibility(Lbry.SDK_READY ? View.GONE : View.VISIBLE);
|
||||||
|
currentPage = 1;
|
||||||
|
if (Lbry.SDK_READY) {
|
||||||
|
fetchDownloads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showHistory() {
|
||||||
|
currentFilter = FILTER_HISTORY;
|
||||||
|
linkFilterDownloads.setTypeface(null, Typeface.NORMAL);
|
||||||
|
linkFilterHistory.setTypeface(null, Typeface.BOLD);
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearItems();
|
||||||
|
contentListAdapter.setCanEnterSelectionMode(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
cardStats.setVisibility(View.GONE);
|
||||||
|
checkStatsLink();
|
||||||
|
|
||||||
|
layoutSdkInitializing.setVisibility(View.GONE);
|
||||||
|
lastDate = null;
|
||||||
|
fetchHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initContentListAdapter(List<Claim> claims) {
|
||||||
|
contentListAdapter = new ClaimListAdapter(claims, getContext());
|
||||||
|
contentListAdapter.setCanEnterSelectionMode(true);
|
||||||
|
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 {
|
||||||
|
MainActivity.openFileUrl(claim.getPermanentUrl(), context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchDownloads() {
|
||||||
|
Helper.setViewVisibility(linkStats, View.GONE);
|
||||||
|
Helper.setViewVisibility(layoutListEmpty, View.GONE);
|
||||||
|
FileListTask task = new FileListTask(currentPage, PAGE_SIZE, true, listLoading, new FileListTask.FileListResultHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<LbryFile> files, boolean hasReachedEnd) {
|
||||||
|
listReachedEnd = hasReachedEnd;
|
||||||
|
List<LbryFile> filteredFiles = Helper.filterDownloads(files);
|
||||||
|
List<Claim> claims = Helper.claimsFromFiles(filteredFiles);
|
||||||
|
|
||||||
|
addFiles(filteredFiles);
|
||||||
|
updateStats();
|
||||||
|
checkStatsLink();
|
||||||
|
|
||||||
|
if (contentListAdapter == null) {
|
||||||
|
initContentListAdapter(claims);
|
||||||
|
} else {
|
||||||
|
contentListAdapter.addItems(claims);
|
||||||
|
}
|
||||||
|
contentList.setAdapter(contentListAdapter);
|
||||||
|
checkListEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Exception error) {
|
||||||
|
// pass
|
||||||
|
checkStatsLink();
|
||||||
|
checkListEmpty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchHistory() {
|
||||||
|
Helper.setViewVisibility(layoutListEmpty, View.GONE);
|
||||||
|
DatabaseHelper dbHelper = DatabaseHelper.getInstance();
|
||||||
|
if (dbHelper != null) {
|
||||||
|
FetchViewHistoryTask task = new FetchViewHistoryTask(lastDate, PAGE_SIZE, dbHelper, new FetchViewHistoryTask.FetchViewHistoryHandler() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<ViewHistory> history, boolean hasReachedEnd) {
|
||||||
|
listReachedEnd = hasReachedEnd;
|
||||||
|
List<Claim> claims = Helper.claimsFromViewHistory(history);
|
||||||
|
if (contentListAdapter == null) {
|
||||||
|
initContentListAdapter(claims);
|
||||||
|
} else {
|
||||||
|
contentListAdapter.addItems(claims);
|
||||||
|
}
|
||||||
|
contentList.setAdapter(contentListAdapter);
|
||||||
|
checkListEmpty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
} else {
|
||||||
|
checkListEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.clearFileForClaimOrUrl(outpoint, uri, currentFilter == FILTER_DOWNLOADS);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (contentListAdapter != null) {
|
||||||
|
contentListAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri, true);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkListEmpty() {
|
||||||
|
layoutListEmpty.setVisibility(contentListAdapter == null || contentListAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
||||||
|
textListEmpty.setText(currentFilter == FILTER_DOWNLOADS ? R.string.library_no_downloads : R.string.library_no_history);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFiles(List<LbryFile> files) {
|
||||||
|
if (currentFiles == null) {
|
||||||
|
currentFiles = new ArrayList<>();
|
||||||
|
}
|
||||||
|
for (LbryFile file : files) {
|
||||||
|
if (!currentFiles.contains(file)) {
|
||||||
|
currentFiles.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStats() {
|
||||||
|
totalBytes = 0;
|
||||||
|
totalVideoBytes = 0;
|
||||||
|
totalAudioBytes = 0;
|
||||||
|
totalImageBytes = 0;
|
||||||
|
totalOtherBytes = 0;
|
||||||
|
if (currentFiles != null) {
|
||||||
|
for (LbryFile file : currentFiles) {
|
||||||
|
long writtenBytes = file.getWrittenBytes();
|
||||||
|
String mime = file.getMimeType();
|
||||||
|
if (mime != null) {
|
||||||
|
if (mime.startsWith("video/")) {
|
||||||
|
totalVideoBytes += writtenBytes;
|
||||||
|
} else if (mime.startsWith("audio/")) {
|
||||||
|
totalAudioBytes += writtenBytes;
|
||||||
|
} else if (mime.startsWith("image/")) {
|
||||||
|
totalImageBytes += writtenBytes;
|
||||||
|
} else {
|
||||||
|
totalOtherBytes += writtenBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalBytes += writtenBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderStats() {
|
||||||
|
String[] totalSizeParts = Helper.formatBytesParts(totalBytes, false);
|
||||||
|
textStatsTotalSize.setText(totalSizeParts[0]);
|
||||||
|
textStatsTotalSizeUnits.setText(totalSizeParts[1]);
|
||||||
|
|
||||||
|
viewStatsDistribution.setVisibility(totalBytes > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
int percentVideo = normalizePercent((double) totalVideoBytes / (double) totalBytes * 100.0);
|
||||||
|
legendVideo.setVisibility(totalVideoBytes > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
textStatsVideoSize.setText(Helper.formatBytes(totalVideoBytes, false));
|
||||||
|
applyLayoutWeight(viewVideoStatsBar, percentVideo);
|
||||||
|
|
||||||
|
int percentAudio = normalizePercent((double) totalAudioBytes / (double) totalBytes * 100.0);
|
||||||
|
legendAudio.setVisibility(totalAudioBytes > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
textStatsAudioSize.setText(Helper.formatBytes(totalAudioBytes, false));
|
||||||
|
applyLayoutWeight(viewAudioStatsBar, percentAudio);
|
||||||
|
|
||||||
|
int percentImage = normalizePercent((double) totalImageBytes / (double) totalBytes * 100.0);
|
||||||
|
legendImage.setVisibility(totalImageBytes > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
textStatsImageSize.setText(Helper.formatBytes(totalImageBytes, false));
|
||||||
|
applyLayoutWeight(viewImageStatsBar, percentImage);
|
||||||
|
|
||||||
|
int percentOther = normalizePercent((double) totalOtherBytes / (double) totalBytes * 100.0);
|
||||||
|
legendOther.setVisibility(totalOtherBytes > 0 ? View.VISIBLE : View.GONE);
|
||||||
|
textStatsOtherSize.setText(Helper.formatBytes(totalOtherBytes, false));
|
||||||
|
applyLayoutWeight(viewOtherStatsBar, percentOther);
|
||||||
|
|
||||||
|
// We have to get to 100 (or adjust the container accordingly)
|
||||||
|
int totalPercent = percentVideo + percentAudio + percentImage + percentOther;
|
||||||
|
((LinearLayout) viewStatsDistribution).setWeightSum(totalPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyLayoutWeight(View view, int weight) {
|
||||||
|
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams();
|
||||||
|
params.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int normalizePercent(double value) {
|
||||||
|
if (value > 0 && value < 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return Double.valueOf(Math.floor(value)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkStatsLink() {
|
||||||
|
linkStats.setVisibility(cardStats.getVisibility() == View.VISIBLE ||
|
||||||
|
listLoading.getVisibility() == View.VISIBLE ||
|
||||||
|
currentFilter == FILTER_HISTORY ?
|
||||||
|
View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,13 +15,20 @@ import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.offline.Download;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.lbry.browser.MainActivity;
|
import io.lbry.browser.MainActivity;
|
||||||
import io.lbry.browser.R;
|
import io.lbry.browser.R;
|
||||||
import io.lbry.browser.adapter.ClaimListAdapter;
|
import io.lbry.browser.adapter.ClaimListAdapter;
|
||||||
|
import io.lbry.browser.listener.DownloadActionListener;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
import io.lbry.browser.model.ClaimCacheKey;
|
import io.lbry.browser.model.ClaimCacheKey;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
|
||||||
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
import io.lbry.browser.tasks.claim.ClaimSearchTask;
|
||||||
import io.lbry.browser.tasks.LighthouseSearchTask;
|
import io.lbry.browser.tasks.LighthouseSearchTask;
|
||||||
|
@ -34,10 +41,10 @@ import io.lbry.browser.utils.LbryUri;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class SearchFragment extends BaseFragment implements
|
public class SearchFragment extends BaseFragment implements
|
||||||
ClaimListAdapter.ClaimListItemListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
ClaimListAdapter.ClaimListItemListener, DownloadActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private ClaimListAdapter resultListAdapter;
|
|
||||||
private static final int PAGE_SIZE = 25;
|
private static final int PAGE_SIZE = 25;
|
||||||
|
|
||||||
|
private ClaimListAdapter resultListAdapter;
|
||||||
private ProgressBar loadingView;
|
private ProgressBar loadingView;
|
||||||
private RecyclerView resultList;
|
private RecyclerView resultList;
|
||||||
private TextView noQueryView;
|
private TextView noQueryView;
|
||||||
|
@ -95,6 +102,7 @@ public class SearchFragment extends BaseFragment implements
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
LbryAnalytics.setCurrentScreen(activity, "Search", "Search");
|
LbryAnalytics.setCurrentScreen(activity, "Search", "Search");
|
||||||
|
activity.addDownloadActionListener(this);
|
||||||
}
|
}
|
||||||
if (!Helper.isNullOrEmpty(currentQuery)) {
|
if (!Helper.isNullOrEmpty(currentQuery)) {
|
||||||
logSearch(currentQuery);
|
logSearch(currentQuery);
|
||||||
|
@ -106,7 +114,11 @@ public class SearchFragment extends BaseFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
|
Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
((MainActivity) context).removeDownloadActionListener(this);
|
||||||
|
}
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,4 +274,24 @@ public class SearchFragment extends BaseFragment implements
|
||||||
search(currentQuery, currentFrom);
|
search(currentQuery, currentFrom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDownloadAction(String downloadAction, String uri, String outpoint, String fileInfoJson, double progress) {
|
||||||
|
if ("abort".equals(downloadAction)) {
|
||||||
|
if (resultListAdapter != null) {
|
||||||
|
resultListAdapter.clearFileForClaimOrUrl(outpoint, uri);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject fileInfo = new JSONObject(fileInfoJson);
|
||||||
|
LbryFile claimFile = LbryFile.fromJSONObject(fileInfo);
|
||||||
|
String claimId = claimFile.getClaimId();
|
||||||
|
if (resultListAdapter != null) {
|
||||||
|
resultListAdapter.updateFileForClaimByIdOrUrl(claimFile, claimId, uri);
|
||||||
|
}
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
// invalid file info for download
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -401,11 +401,11 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
||||||
LbryAnalytics.setCurrentScreen(activity, "Wallet", "Wallet");
|
LbryAnalytics.setCurrentScreen(activity, "Wallet", "Wallet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Helper.setViewVisibility(layoutAccountRecommended, hasSkippedAccount() || Lbryio.isSignedIn() ? View.GONE : View.VISIBLE);
|
||||||
if (!Lbry.SDK_READY) {
|
if (!Lbry.SDK_READY) {
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
MainActivity activity = (MainActivity) context;
|
MainActivity activity = (MainActivity) context;
|
||||||
activity.addSdkStatusListener(this);
|
activity.addSdkStatusListener(this);
|
||||||
activity.addWalletBalanceListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkReceiveAddress();
|
checkReceiveAddress();
|
||||||
|
@ -441,7 +441,9 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
||||||
public void onSdkReady() {
|
public void onSdkReady() {
|
||||||
Context context = getContext();
|
Context context = getContext();
|
||||||
if (context instanceof MainActivity) {
|
if (context instanceof MainActivity) {
|
||||||
((MainActivity) context).removeSdkStatusListener(this);
|
MainActivity activity = (MainActivity) context;
|
||||||
|
activity.syncWalletAndLoadPreferences();
|
||||||
|
activity.addWalletBalanceListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update view
|
// update view
|
||||||
|
|
|
@ -19,6 +19,7 @@ import android.provider.DocumentsContract;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
@ -45,9 +46,12 @@ import io.lbry.browser.data.DatabaseHelper;
|
||||||
import io.lbry.browser.dialog.ContentFromDialogFragment;
|
import io.lbry.browser.dialog.ContentFromDialogFragment;
|
||||||
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
import io.lbry.browser.dialog.ContentSortDialogFragment;
|
||||||
import io.lbry.browser.model.Claim;
|
import io.lbry.browser.model.Claim;
|
||||||
|
import io.lbry.browser.model.LbryFile;
|
||||||
import io.lbry.browser.model.Tag;
|
import io.lbry.browser.model.Tag;
|
||||||
import io.lbry.browser.model.UrlSuggestion;
|
import io.lbry.browser.model.UrlSuggestion;
|
||||||
|
import io.lbry.browser.model.ViewHistory;
|
||||||
import io.lbry.browser.tasks.localdata.SaveUrlHistoryTask;
|
import io.lbry.browser.tasks.localdata.SaveUrlHistoryTask;
|
||||||
|
import io.lbry.browser.tasks.localdata.SaveViewHistoryTask;
|
||||||
import okhttp3.MediaType;
|
import okhttp3.MediaType;
|
||||||
|
|
||||||
public final class Helper {
|
public final class Helper {
|
||||||
|
@ -61,6 +65,7 @@ public final class Helper {
|
||||||
public static final int CONTENT_PAGE_SIZE = 25;
|
public static final int CONTENT_PAGE_SIZE = 25;
|
||||||
public static final double MIN_DEPOSIT = 0.05;
|
public static final double MIN_DEPOSIT = 0.05;
|
||||||
public static final String LBC_CURRENCY_FORMAT_PATTERN = "#,###.##";
|
public static final String LBC_CURRENCY_FORMAT_PATTERN = "#,###.##";
|
||||||
|
public static final String FILE_SIZE_FORMAT_PATTERN = "#,###.#";
|
||||||
public static final DecimalFormat LBC_CURRENCY_FORMAT = new DecimalFormat(LBC_CURRENCY_FORMAT_PATTERN);
|
public static final DecimalFormat LBC_CURRENCY_FORMAT = new DecimalFormat(LBC_CURRENCY_FORMAT_PATTERN);
|
||||||
public static final DecimalFormat USD_CURRENCY_FORMAT = new DecimalFormat("#,##0.00");
|
public static final DecimalFormat USD_CURRENCY_FORMAT = new DecimalFormat("#,##0.00");
|
||||||
public static final String EXPLORER_TX_PREFIX = "https://explorer.lbry.com/tx";
|
public static final String EXPLORER_TX_PREFIX = "https://explorer.lbry.com/tx";
|
||||||
|
@ -121,6 +126,12 @@ public final class Helper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setViewProgress(ProgressBar progressBar, int progress) {
|
||||||
|
if (progressBar != null) {
|
||||||
|
progressBar.setProgress(progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void setViewText(TextView view, int stringResourceId) {
|
public static void setViewText(TextView view, int stringResourceId) {
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
view.setText(stringResourceId);
|
view.setText(stringResourceId);
|
||||||
|
@ -183,6 +194,43 @@ public final class Helper {
|
||||||
}
|
}
|
||||||
return String.format("%d:%02d", minutes, seconds);
|
return String.format("%d:%02d", minutes, seconds);
|
||||||
}
|
}
|
||||||
|
public static String[] formatBytesParts(long bytes, boolean showTB) {
|
||||||
|
DecimalFormat formatter = new DecimalFormat(FILE_SIZE_FORMAT_PATTERN);
|
||||||
|
if (bytes < 1048576) {
|
||||||
|
// less than 1MB
|
||||||
|
return new String[] { formatter.format(bytes / 1024.0), "KB" };
|
||||||
|
}
|
||||||
|
if (bytes < 1073741824) {
|
||||||
|
// less than 1GB
|
||||||
|
return new String[] { formatter.format(bytes / (1024.0 * 1024.0)), "MB" };
|
||||||
|
}
|
||||||
|
if (showTB) {
|
||||||
|
if (bytes < (1073741824L * 1024L)) {
|
||||||
|
return new String[] { formatter.format(bytes / (1024.0 * 1024.0 * 1024.0)), "GB" };
|
||||||
|
}
|
||||||
|
return new String[] { formatter.format(bytes / (1024.0 * 1024.0 * 1024.0 * 1024.0)), "TB" };
|
||||||
|
}
|
||||||
|
return new String[] { formatter.format(bytes / (1024.0 * 1024.0 * 1024.0)), "GB" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatBytes(long bytes, boolean showTB) {
|
||||||
|
DecimalFormat formatter = new DecimalFormat(FILE_SIZE_FORMAT_PATTERN);
|
||||||
|
if (bytes < 1048576) {
|
||||||
|
// less than 1MB
|
||||||
|
return String.format("%sKB", formatter.format(bytes / 1024.0));
|
||||||
|
}
|
||||||
|
if (bytes < 1073741824) {
|
||||||
|
// less than 1GB
|
||||||
|
return String.format("%sMB", formatter.format(bytes / (1024.0 * 1024.0)));
|
||||||
|
}
|
||||||
|
if (showTB) {
|
||||||
|
if (bytes < (1073741824L * 1024L)) {
|
||||||
|
return String.format("%sGB", formatter.format(bytes / (1024.0 * 1024.0 * 1024.0)));
|
||||||
|
}
|
||||||
|
return String.format("%sTB", formatter.format(bytes / (1024.0 * 1024.0 * 1024.0 * 1024.0)));
|
||||||
|
}
|
||||||
|
return String.format("%sGB", formatter.format(bytes / (1024.0 * 1024.0 * 1024.0)));
|
||||||
|
}
|
||||||
|
|
||||||
public static JSONObject getJSONObject(String name, JSONObject object) {
|
public static JSONObject getJSONObject(String name, JSONObject object) {
|
||||||
try {
|
try {
|
||||||
|
@ -571,6 +619,33 @@ public final class Helper {
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<LbryFile> filterDownloads(List<LbryFile> files) {
|
||||||
|
List<LbryFile> filtered = new ArrayList<>();
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
LbryFile file = files.get(i);
|
||||||
|
if (!Helper.isNullOrEmpty(file.getDownloadPath())) {
|
||||||
|
filtered.add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Claim> claimsFromFiles(List<LbryFile> files) {
|
||||||
|
List<Claim> claims = new ArrayList<>();
|
||||||
|
for (LbryFile file : files) {
|
||||||
|
claims.add(file.getClaim());
|
||||||
|
}
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Claim> claimsFromViewHistory(List<ViewHistory> history) {
|
||||||
|
List<Claim> claims = new ArrayList<>();
|
||||||
|
for (ViewHistory item : history) {
|
||||||
|
claims.add(Claim.fromViewHistory(item));
|
||||||
|
}
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
public static void saveUrlHistory(String url, String title, int type) {
|
public static void saveUrlHistory(String url, String title, int type) {
|
||||||
DatabaseHelper dbHelper = DatabaseHelper.getInstance();
|
DatabaseHelper dbHelper = DatabaseHelper.getInstance();
|
||||||
if (dbHelper != null) {
|
if (dbHelper != null) {
|
||||||
|
@ -581,4 +656,12 @@ public final class Helper {
|
||||||
new SaveUrlHistoryTask(suggestion, dbHelper, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
new SaveUrlHistoryTask(suggestion, dbHelper, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void saveViewHistory(String url, Claim claim) {
|
||||||
|
DatabaseHelper dbHelper = DatabaseHelper.getInstance();
|
||||||
|
if (dbHelper != null) {
|
||||||
|
ViewHistory viewHistory = ViewHistory.fromClaimWithUrlAndDeviceName(claim, url, getDeviceName());
|
||||||
|
new SaveViewHistoryTask(viewHistory, dbHelper, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,12 +307,22 @@ public final class Lbry {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<LbryFile> fileList(String claimId) throws ApiCallException {
|
public static List<LbryFile> fileList(String claimId, boolean downloads, int page, int pageSize) throws ApiCallException {
|
||||||
List<LbryFile> files = new ArrayList<>();
|
List<LbryFile> files = new ArrayList<>();
|
||||||
Map<String, Object> params = new HashMap<>();
|
Map<String, Object> params = new HashMap<>();
|
||||||
if (!Helper.isNullOrEmpty(claimId)) {
|
if (!Helper.isNullOrEmpty(claimId)) {
|
||||||
params.put("claim_id", claimId);
|
params.put("claim_id", claimId);
|
||||||
}
|
}
|
||||||
|
/*if (downloads) {
|
||||||
|
params.put("file_name", null);
|
||||||
|
params.put("comparison", "ne");
|
||||||
|
}*/
|
||||||
|
if (page > 0) {
|
||||||
|
params.put("page", page);
|
||||||
|
}
|
||||||
|
if (pageSize > 0) {
|
||||||
|
params.put("page_size", pageSize);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
JSONObject result = (JSONObject) parseResponse(apiCall(METHOD_FILE_LIST, params));
|
JSONObject result = (JSONObject) parseResponse(apiCall(METHOD_FILE_LIST, params));
|
||||||
JSONArray items = result.getJSONArray("items");
|
JSONArray items = result.getJSONArray("items");
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/splash_view_loading_container"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -89,6 +90,198 @@
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginTop="48dp" />
|
android:layout_marginTop="48dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/splash_view_error_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:padding="24dp">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/oops_something_went_wrong"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/startup_failed"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_install_id"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/installation_id_loaded"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_known_tags"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/known_tags_loaded"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_exchange_rate"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/exchange_rate_loaded"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_user_authenticated"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/user_authenticated"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_install_new"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/installation_registered"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_subscriptions_loaded"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/subscriptions_loaded"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/startup_stage_icon_subscriptions_resolved"
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:tint="@color/white"
|
||||||
|
android:src="@drawable/ic_check" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/subscriptions_resolved"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
347
app/src/main/res/layout/fragment_library.xml
Normal file
347
app/src/main/res/layout/fragment_library.xml
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/pageBackground">
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/library_filter_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="16dp">
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="12dp">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_filter_link_downloads"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/downloads"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_filter_link_history"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_toRightOf="@id/library_filter_link_downloads"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/history"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/library_list_loading"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_show_stats"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/stats"
|
||||||
|
android:textColor="@color/lbryGreen"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/library_storage_stats_card"
|
||||||
|
android:layout_below="@id/library_filter_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_used"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero"
|
||||||
|
android:textColor="@color/lbryGreen"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="30sp" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_unit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="3dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/mb"
|
||||||
|
android:textColor="@color/lbryGreen"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_hide_stats"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:clickable="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/hide"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/library_storage_stat_distribution"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="100"
|
||||||
|
android:visibility="gone">
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_stat_video_bar"
|
||||||
|
android:background="@color/statsVideo"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_stat_audio_bar"
|
||||||
|
android:background="@color/statsAudio"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_stat_image_bar"
|
||||||
|
android:background="@color/statsImage"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_stat_other_bar"
|
||||||
|
android:background="@color/statsOther"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/library_storage_legend_video"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_legend_video_icon"
|
||||||
|
android:background="@color/statsVideo"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_centerVertical="true" />
|
||||||
|
<TextView
|
||||||
|
android:layout_toRightOf="@id/library_storage_legend_video_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/video"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_video_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_mb"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/library_storage_legend_audio"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_legend_audio_icon"
|
||||||
|
android:background="@color/statsAudio"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_centerVertical="true" />
|
||||||
|
<TextView
|
||||||
|
android:layout_toRightOf="@id/library_storage_legend_audio_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/audio"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_audio_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_mb"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/library_storage_legend_image"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_legend_image_icon"
|
||||||
|
android:background="@color/statsImage"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_centerVertical="true" />
|
||||||
|
<TextView
|
||||||
|
android:layout_toRightOf="@id/library_storage_legend_image_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/images"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_image_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_mb"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/library_storage_legend_other"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
<View
|
||||||
|
android:id="@+id/library_storage_legend_other_icon"
|
||||||
|
android:background="@color/statsOther"
|
||||||
|
android:layout_width="10dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_centerVertical="true" />
|
||||||
|
<TextView
|
||||||
|
android:layout_toRightOf="@id/library_storage_legend_other_icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/other"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_storage_stat_other_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/zero_mb"
|
||||||
|
android:textFontWeight="300"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/library_list"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:layout_below="@id/library_storage_stats_card"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingBottom="16dp" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/library_empty_container"
|
||||||
|
android:background="@color/pageBackground"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:padding="36dp">
|
||||||
|
<ImageView
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_width="160dp"
|
||||||
|
android:layout_height="300dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:src="@drawable/gerbil_happy" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/library_list_empty_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:text="@string/library_no_downloads"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textFontWeight="300" />
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/container_library_sdk_initializing"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/library_filter_card"
|
||||||
|
android:visibility="gone">
|
||||||
|
<include layout="@layout/container_sdk_initializing" android:visibility="visible" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
|
@ -168,6 +168,9 @@
|
||||||
android:textColor="@color/lbryGreen"
|
android:textColor="@color/lbryGreen"
|
||||||
android:fontFamily="@font/inter"
|
android:fontFamily="@font/inter"
|
||||||
android:textSize="12sp" />
|
android:textSize="12sp" />
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/claim_publish_time"
|
android:id="@+id/claim_publish_time"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -185,7 +188,36 @@
|
||||||
android:textStyle="italic"
|
android:textStyle="italic"
|
||||||
android:textFontWeight="300"
|
android:textFontWeight="300"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/claim_file_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:textSize="11sp"
|
||||||
|
android:textFontWeight="300" />
|
||||||
|
</RelativeLayout>
|
||||||
<!-- download progress bar -->
|
<!-- download progress bar -->
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/claim_download_progress"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:visibility="invisible"
|
||||||
|
style="?android:progressBarStyleHorizontal" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/claim_view_device"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="@font/inter"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textColor="@color/lightGrey"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textFontWeight="300" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -48,6 +48,7 @@
|
||||||
<color name="uriDescBlue">#3971DB</color>
|
<color name="uriDescBlue">#3971DB</color>
|
||||||
<color name="rewardDriverBlue">#2196f3</color>
|
<color name="rewardDriverBlue">#2196f3</color>
|
||||||
|
|
||||||
|
<color name="statsVideo">@color/nextLbryGreen</color>
|
||||||
<color name="statsAudio">#F6A637</color>
|
<color name="statsAudio">#F6A637</color>
|
||||||
<color name="statsImage">#FF4A7D</color>
|
<color name="statsImage">#FF4A7D</color>
|
||||||
<color name="statsOther">#26BCF7</color>
|
<color name="statsOther">#26BCF7</color>
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
<color name="uriDescBlue">#3971DB</color>
|
<color name="uriDescBlue">#3971DB</color>
|
||||||
<color name="rewardDriverBlue">#2196f3</color>
|
<color name="rewardDriverBlue">#2196f3</color>
|
||||||
|
|
||||||
|
<color name="statsVideo">@color/nextLbryGreen</color>
|
||||||
<color name="statsAudio">#F6A637</color>
|
<color name="statsAudio">#F6A637</color>
|
||||||
<color name="statsImage">#FF4A7D</color>
|
<color name="statsImage">#FF4A7D</color>
|
||||||
<color name="statsOther">#26BCF7</color>
|
<color name="statsOther">#26BCF7</color>
|
||||||
|
|
|
@ -93,6 +93,16 @@
|
||||||
<item quantity="other">%1$s followers</item>
|
<item quantity="other">%1$s followers</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
|
<!-- Splash -->
|
||||||
|
<string name="oops_something_went_wrong">Oops! Something went wrong.</string>
|
||||||
|
<string name="installation_id_loaded">Loaded Installation ID.</string>
|
||||||
|
<string name="known_tags_loaded">Loaded local known and followed tags.</string>
|
||||||
|
<string name="exchange_rate_loaded">Loaded LBC/USD exchange rate.</string>
|
||||||
|
<string name="user_authenticated">User authenticated.</string>
|
||||||
|
<string name="installation_registered">Installation registered.</string>
|
||||||
|
<string name="subscriptions_loaded">Loaded subscriptions.</string>
|
||||||
|
<string name="subscriptions_resolved">Resolved subscriptions.</string>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
<string name="user_interface">Content & User interface</string>
|
<string name="user_interface">Content & User interface</string>
|
||||||
<string name="other">Other</string>
|
<string name="other">Other</string>
|
||||||
|
@ -363,6 +373,21 @@
|
||||||
<string name="invite_link_copied">Invite link copied.</string>
|
<string name="invite_link_copied">Invite link copied.</string>
|
||||||
<string name="invite_sent_to">Invite sent to %1$s</string>
|
<string name="invite_sent_to">Invite sent to %1$s</string>
|
||||||
|
|
||||||
|
<!-- Library -->
|
||||||
|
<string name="downloads">Downloads</string>
|
||||||
|
<string name="history">History</string>
|
||||||
|
<string name="library_no_downloads">You have not downloaded any content to this device.</string>
|
||||||
|
<string name="library_no_history">You have not viewed any content on this device.</string>
|
||||||
|
<string name="hide">Hide</string>
|
||||||
|
<string name="stats">Stats</string>
|
||||||
|
<string name="video">Video</string>
|
||||||
|
<string name="audio">Audio</string>
|
||||||
|
<string name="images">Images</string>
|
||||||
|
<string name="mb">MB</string>
|
||||||
|
<string name="kb">KB</string>
|
||||||
|
<string name="gb">GB</string>
|
||||||
|
<string name="zero_mb">0MB</string>
|
||||||
|
|
||||||
<!-- About -->
|
<!-- About -->
|
||||||
<string name="about_lbry">About LBRY</string>
|
<string name="about_lbry">About LBRY</string>
|
||||||
<string name="content_freedom">Content Freedom</string>
|
<string name="content_freedom">Content Freedom</string>
|
||||||
|
|
Loading…
Reference in a new issue