Native rewrite #878
24 changed files with 854 additions and 40 deletions
|
@ -21,6 +21,7 @@ import android.os.Handler;
|
|||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
@ -74,6 +75,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import io.lbry.browser.adapter.NavigationMenuAdapter;
|
||||
import io.lbry.browser.adapter.UrlSuggestionListAdapter;
|
||||
import io.lbry.browser.data.DatabaseHelper;
|
||||
import io.lbry.browser.dialog.ContentScopeDialogFragment;
|
||||
import io.lbry.browser.exceptions.LbryUriException;
|
||||
import io.lbry.browser.listener.SdkStatusListener;
|
||||
import io.lbry.browser.listener.WalletBalanceListener;
|
||||
|
@ -86,9 +88,14 @@ import io.lbry.browser.model.WalletBalance;
|
|||
import io.lbry.browser.model.WalletSync;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.tasks.LighthouseAutoCompleteTask;
|
||||
import io.lbry.browser.tasks.MergeSubscriptionsTask;
|
||||
import io.lbry.browser.tasks.ResolveTask;
|
||||
import io.lbry.browser.tasks.wallet.DefaultSyncTaskHandler;
|
||||
import io.lbry.browser.tasks.wallet.LoadSharedUserStateTask;
|
||||
import io.lbry.browser.tasks.wallet.SaveSharedUserStateTask;
|
||||
import io.lbry.browser.tasks.wallet.SyncApplyTask;
|
||||
import io.lbry.browser.tasks.wallet.SyncGetTask;
|
||||
import io.lbry.browser.tasks.wallet.SyncSetTask;
|
||||
import io.lbry.browser.tasks.wallet.WalletBalanceTask;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
import io.lbry.browser.ui.channel.ChannelFragment;
|
||||
|
@ -104,7 +111,6 @@ import io.lbry.browser.utils.Lbryio;
|
|||
import io.lbry.lbrysdk.LbrynetService;
|
||||
import io.lbry.lbrysdk.ServiceHelper;
|
||||
import io.lbry.lbrysdk.Utils;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements SdkStatusListener {
|
||||
|
@ -190,6 +196,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
@Getter
|
||||
private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
private boolean walletBalanceUpdateScheduled;
|
||||
private boolean walletSyncScheduled;
|
||||
private String pendingAllContentTag;
|
||||
private String pendingChannelUrl;
|
||||
private boolean pendingFollowingReload;
|
||||
|
@ -836,6 +843,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
}, CHECK_SDK_READY_INTERVAL);
|
||||
} else {
|
||||
scheduleWalletBalanceUpdate();
|
||||
scheduleWalletSyncTask();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -843,7 +851,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
if (Lbryio.isSignedIn()) {
|
||||
checkSyncedWallet();
|
||||
}
|
||||
|
||||
//overrideRemoteWallet();
|
||||
scheduleWalletBalanceUpdate();
|
||||
scheduleWalletSyncTask();
|
||||
}
|
||||
|
||||
private void scheduleWalletBalanceUpdate() {
|
||||
|
@ -858,6 +869,157 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
}
|
||||
}
|
||||
|
||||
private void scheduleWalletSyncTask() {
|
||||
if (scheduler != null && !walletSyncScheduled) {
|
||||
scheduler.scheduleAtFixedRate(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
syncWalletAndLoadPreferences();
|
||||
}
|
||||
}, 0, 5, TimeUnit.MINUTES);
|
||||
walletSyncScheduled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void saveSharedUserState() {
|
||||
if (!userSyncEnabled()) {
|
||||
return;
|
||||
}
|
||||
SaveSharedUserStateTask saveTask = new SaveSharedUserStateTask(new SaveSharedUserStateTask.SaveSharedUserStateHandler() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
// push wallet sync changes
|
||||
pushCurrentWalletSync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
// pass
|
||||
}
|
||||
});
|
||||
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void loadSharedUserState() {
|
||||
// load wallet preferences
|
||||
LoadSharedUserStateTask loadTask = new LoadSharedUserStateTask(MainActivity.this, new LoadSharedUserStateTask.LoadSharedUserStateHandler() {
|
||||
@Override
|
||||
public void onSuccess(List<Subscription> subscriptions, List<Tag> followedTags) {
|
||||
if (subscriptions != null && subscriptions.size() > 0) {
|
||||
// reload subscriptions if wallet fragment is FollowingFragment
|
||||
//openNavFragments.get
|
||||
MergeSubscriptionsTask mergeTask = new MergeSubscriptionsTask(
|
||||
subscriptions, MainActivity.this, new MergeSubscriptionsTask.MergeSubscriptionsHandler() {
|
||||
@Override
|
||||
public void onSuccess(List<Subscription> subscriptions, List<Subscription> diff) {
|
||||
Lbryio.subscriptions = new ArrayList<>(subscriptions);
|
||||
if (diff != null && diff.size() > 0) {
|
||||
saveSharedUserState();
|
||||
}
|
||||
for (Fragment fragment : openNavFragments.values()) {
|
||||
if (fragment instanceof FollowingFragment) {
|
||||
// reload local subscriptions
|
||||
((FollowingFragment) fragment).fetchLoadedSubscriptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
Log.e(TAG, String.format("merge subscriptions failed: %s", error.getMessage()), error);
|
||||
}
|
||||
});
|
||||
mergeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
if (followedTags != null && followedTags.size() > 0) {
|
||||
List<Tag> previousTags = new ArrayList<>(Lbry.followedTags);
|
||||
Lbry.followedTags = new ArrayList<>(followedTags);
|
||||
for (Fragment fragment : openNavFragments.values()) {
|
||||
if (fragment instanceof AllContentFragment) {
|
||||
AllContentFragment acFragment = (AllContentFragment) fragment;
|
||||
if (!acFragment.isSingleTagView() &&
|
||||
acFragment.getCurrentContentScope() == ContentScopeDialogFragment.ITEM_TAGS &&
|
||||
!previousTags.equals(followedTags)) {
|
||||
acFragment.fetchClaimSearchContent(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
Log.e(TAG, String.format("load shared user state failed: %s", error != null ? error.getMessage() : "no error message"), error);
|
||||
}
|
||||
});
|
||||
loadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
public void pushCurrentWalletSync() {
|
||||
String password = Utils.getSecureValue(SECURE_VALUE_KEY_SAVED_PASSWORD, this, Lbry.KEYSTORE);
|
||||
SyncApplyTask fetchTask = new SyncApplyTask(true, password, new DefaultSyncTaskHandler() {
|
||||
@Override
|
||||
public void onSyncApplySuccess(String hash, String data) {
|
||||
SyncSetTask setTask = new SyncSetTask(Lbryio.lastRemoteHash, hash, data, null);
|
||||
setTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
@Override
|
||||
public void onSyncApplyError(Exception error) { }
|
||||
});
|
||||
fetchTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private boolean userSyncEnabled() {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
boolean walletSyncEnabled = sp.getBoolean(PREFERENCE_KEY_INTERNAL_WALLET_SYNC_ENABLED, false);
|
||||
return walletSyncEnabled && Lbryio.isSignedIn();
|
||||
}
|
||||
|
||||
private void syncWalletAndLoadPreferences() {
|
||||
if (!userSyncEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String password = Utils.getSecureValue(SECURE_VALUE_KEY_SAVED_PASSWORD, this, Lbry.KEYSTORE);
|
||||
SyncGetTask task = new SyncGetTask(password, true, null, new DefaultSyncTaskHandler() {
|
||||
@Override
|
||||
public void onSyncGetSuccess(WalletSync walletSync) {
|
||||
Lbryio.lastWalletSync = walletSync;
|
||||
Lbryio.lastRemoteHash = walletSync.getHash();
|
||||
loadSharedUserState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncGetWalletNotFound() {
|
||||
// pass. This actually shouldn't happen at this point.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncGetError(Exception error) {
|
||||
// pass
|
||||
Log.e(TAG, String.format("sync get failed: %s", error != null ? error.getMessage() : "no error message"), error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncApplySuccess(String hash, String data) {
|
||||
if (!hash.equalsIgnoreCase(Lbryio.lastRemoteHash)) {
|
||||
SyncSetTask setTask = new SyncSetTask(Lbryio.lastRemoteHash, hash, data, null);
|
||||
setTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
loadSharedUserState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncApplyError(Exception error) {
|
||||
// pass
|
||||
Log.e(TAG, String.format("sync apply failed: %s", error != null ? error.getMessage() : "no error message"), error);
|
||||
}
|
||||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void registerRequestsReceiver() {
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(ACTION_AUTH_TOKEN_GENERATED);
|
||||
|
@ -979,11 +1141,15 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
showSignedInUser();
|
||||
|
||||
if (requestCode == REQUEST_WALLET_SYNC_SIGN_IN) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_WALLET_SYNC_ENABLED, true).apply();
|
||||
|
||||
for (Fragment fragment : openNavFragments.values()) {
|
||||
if (fragment instanceof WalletFragment) {
|
||||
((WalletFragment) fragment).onWalletSyncEnabled();
|
||||
}
|
||||
}
|
||||
scheduleWalletSyncTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1063,7 +1229,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
Lbryio.newInstall(context);
|
||||
|
||||
// (light) fetch subscriptions
|
||||
if (Lbryio.cacheSubscriptions.size() == 0) {
|
||||
if (Lbryio.subscriptions.size() == 0) {
|
||||
List<Subscription> subscriptions = new ArrayList<>();
|
||||
List<String> subUrls = new ArrayList<>();
|
||||
JSONArray array = (JSONArray) Lbryio.parseResponse(Lbryio.call("subscription", "list", context));
|
||||
|
@ -1079,10 +1245,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
subscriptions.add(new Subscription(channelName, url.toString()));
|
||||
subUrls.add(url.toString());
|
||||
}
|
||||
Lbryio.cacheSubscriptions = subscriptions;
|
||||
Lbryio.subscriptions = subscriptions;
|
||||
|
||||
// resolve subscriptions
|
||||
if (subUrls.size() > 0 && Lbryio.cacheResolvedSubscriptions.size() != Lbryio.cacheSubscriptions.size()) {
|
||||
if (subUrls.size() > 0 && Lbryio.cacheResolvedSubscriptions.size() != Lbryio.subscriptions.size()) {
|
||||
List<Claim> resolvedSubs = Lbry.resolve(subUrls, Lbry.LBRY_TV_CONNECTION_STRING);
|
||||
Lbryio.cacheResolvedSubscriptions = resolvedSubs;
|
||||
}
|
||||
|
@ -1481,8 +1647,4 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
|
|||
});
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void loadTags() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.database.Cursor;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
import java.sql.SQLInput;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
@ -48,8 +49,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||
private static final String SQL_GET_RECENT_HISTORY = "SELECT value, url, type FROM history ORDER BY timestamp DESC LIMIT 10";
|
||||
|
||||
private static final String SQL_INSERT_TAG = "REPLACE INTO tags (name, is_followed) VALUES (?, ?)";
|
||||
private static final String SQL_SET_TAG_FOLLOWED = "UPDATE tags SET is_followed = ? WHERE name = ?";
|
||||
private static final String SQL_GET_KNOWN_TAGS = "SELECT name FROM tags";
|
||||
private static final String SQL_GET_KNOWN_TAGS = "SELECT name, is_followed FROM tags";
|
||||
private static final String SQL_UNFOLLOW_TAGS = "UPDATE tags SET is_followed = 0";
|
||||
private static final String SQL_GET_FOLLOWED_TAGS = "SELECT name FROM tags WHERE is_followed = 1";
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
|
@ -108,8 +109,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||
public static void createOrUpdateTag(Tag tag, SQLiteDatabase db) {
|
||||
db.execSQL(SQL_INSERT_TAG, new Object[] { tag.getLowercaseName(), tag.isFollowed() ? 1 : 0 });
|
||||
}
|
||||
public static void setTagFollowed(boolean followed, String name, SQLiteDatabase db) {
|
||||
db.execSQL(SQL_SET_TAG_FOLLOWED, new Object[] { followed ? 1 : 0, name });
|
||||
public static void setAllTagsUnfollowed(SQLiteDatabase db) {
|
||||
db.execSQL(SQL_UNFOLLOW_TAGS);
|
||||
}
|
||||
public static List<Tag> getTags(SQLiteDatabase db) {
|
||||
List<Tag> tags = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.lbry.browser.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EditorsChoiceItem {
|
||||
private boolean header;
|
||||
private String title;
|
||||
private String parent;
|
||||
private String description;
|
||||
private String thumbnailUrl;
|
||||
private String permanentUrl;
|
||||
|
||||
public static EditorsChoiceItem fromClaim(Claim claim) {
|
||||
EditorsChoiceItem item = new EditorsChoiceItem();
|
||||
item.setTitle(claim.getTitle());
|
||||
item.setDescription(claim.getDescription());
|
||||
item.setThumbnailUrl(claim.getThumbnailUrl());
|
||||
item.setPermanentUrl(claim.getPermanentUrl());
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -29,6 +29,9 @@ public class Tag implements Comparator<Tag> {
|
|||
return Predefined.MATURE_TAGS.contains(name.toLowerCase());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getLowercaseName();
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof Tag) && ((Tag) o).getName().equalsIgnoreCase(name);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package io.lbry.browser.model.lbryinc;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Data
|
||||
public class Subscription {
|
||||
@Getter
|
||||
@Setter
|
||||
private String channelName;
|
||||
@Getter
|
||||
@Setter
|
||||
private String url;
|
||||
|
||||
public Subscription() {
|
||||
|
@ -14,4 +18,11 @@ public class Subscription {
|
|||
this.channelName = channelName;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof Subscription) && url.equalsIgnoreCase(((Subscription) o).getUrl());
|
||||
}
|
||||
public int hashCode() {
|
||||
return url.toLowerCase().hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,12 @@ public class ChannelSubscribeTask extends AsyncTask<Void, Void, Boolean> {
|
|||
|
||||
String action = isUnsubscribing ? "delete" : "new";
|
||||
Lbryio.call("subscription", action, options, context);
|
||||
|
||||
if (!isUnsubscribing) {
|
||||
Lbryio.addSubscription(subscription);
|
||||
} else {
|
||||
Lbryio.removeSubscription(subscription);
|
||||
}
|
||||
} catch (LbryioRequestException | LbryioResponseException | SQLiteException ex) {
|
||||
error = ex;
|
||||
return false;
|
||||
|
|
|
@ -61,7 +61,7 @@ public class FetchSubscriptionsTask extends AsyncTask<Void, Void, List<Subscript
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (LbryioRequestException | LbryioResponseException | JSONException | ClassCastException ex) {
|
||||
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException | IllegalStateException ex) {
|
||||
error = ex;
|
||||
return null;
|
||||
} finally {
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package io.lbry.browser.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.data.DatabaseHelper;
|
||||
import io.lbry.browser.model.Tag;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
|
||||
public class FollowUnfollowTagTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private Tag tag;
|
||||
private boolean unfollowing;
|
||||
private Context context;
|
||||
private FollowUnfollowTagHandler handler;
|
||||
private Exception error;
|
||||
|
||||
public FollowUnfollowTagTask(Tag tag, boolean unfollowing, Context context, FollowUnfollowTagHandler handler) {
|
||||
this.tag = tag;
|
||||
this.context = context;
|
||||
this.unfollowing = unfollowing;
|
||||
this.handler = handler;
|
||||
}
|
||||
public Boolean doInBackground(Void... params) {
|
||||
try {
|
||||
SQLiteDatabase db = null;
|
||||
if (context instanceof MainActivity) {
|
||||
db = ((MainActivity) context).getDbHelper().getWritableDatabase();
|
||||
if (db != null) {
|
||||
if (!Lbry.knownTags.contains(tag)) {
|
||||
DatabaseHelper.createOrUpdateTag(tag, db);
|
||||
Lbry.addKnownTag(tag);
|
||||
}
|
||||
|
||||
tag.setFollowed(!unfollowing);
|
||||
DatabaseHelper.createOrUpdateTag(tag, db);
|
||||
if (unfollowing) {
|
||||
Lbry.removeFollowedTag(tag);
|
||||
} else {
|
||||
Lbry.addFollowedTag(tag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
error = ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (handler != null) {
|
||||
if (result) {
|
||||
handler.onSuccess(tag, unfollowing);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface FollowUnfollowTagHandler {
|
||||
void onSuccess(Tag tag, boolean unfollowing);
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package io.lbry.browser.tasks;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.data.DatabaseHelper;
|
||||
import io.lbry.browser.exceptions.LbryUriException;
|
||||
import io.lbry.browser.exceptions.LbryioRequestException;
|
||||
import io.lbry.browser.exceptions.LbryioResponseException;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.LbryUri;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
// background task to create a diff of local and remote subscriptions and try to merge
|
||||
public class MergeSubscriptionsTask extends AsyncTask<Void, Void, List<Subscription>> {
|
||||
private static final String TAG = "MergeSubscriptionsTask";
|
||||
private Context context;
|
||||
private List<Subscription> base;
|
||||
private List<Subscription> diff;
|
||||
private MergeSubscriptionsHandler handler;
|
||||
private Exception error;
|
||||
|
||||
public MergeSubscriptionsTask(List<Subscription> base, Context context, MergeSubscriptionsHandler handler) {
|
||||
this.base = base;
|
||||
this.context = context;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected List<Subscription> doInBackground(Void... params) {
|
||||
List<Subscription> combined = new ArrayList<>(base);
|
||||
List<Subscription> localSubs = new ArrayList<>();
|
||||
List<Subscription> remoteSubs = new ArrayList<>();
|
||||
diff = new ArrayList<>();
|
||||
SQLiteDatabase db = null;
|
||||
try {
|
||||
// fetch local subscriptions
|
||||
if (context instanceof MainActivity) {
|
||||
db = ((MainActivity) context).getDbHelper().getWritableDatabase();
|
||||
}
|
||||
if (db != null) {
|
||||
localSubs = DatabaseHelper.getSubscriptions(db);
|
||||
for (Subscription sub : localSubs) {
|
||||
if (!combined.contains(sub)) {
|
||||
combined.add(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fetch remote subscriptions
|
||||
JSONArray array = (JSONArray) Lbryio.parseResponse(Lbryio.call("subscription", "list", context));
|
||||
if (array != null) {
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject item = array.getJSONObject(i);
|
||||
String claimId = item.getString("claim_id");
|
||||
String channelName = item.getString("channel_name");
|
||||
|
||||
LbryUri url = new LbryUri();
|
||||
url.setChannelName(channelName);
|
||||
url.setClaimId(claimId);
|
||||
Subscription subscription = new Subscription(channelName, url.toString());
|
||||
remoteSubs.add(subscription);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < combined.size(); i++) {
|
||||
Subscription local = combined.get(i);
|
||||
if (!remoteSubs.contains(local)) {
|
||||
// add to remote subscriptions
|
||||
try {
|
||||
LbryUri uri = LbryUri.parse(local.getUrl());
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put("claim_id", uri.getChannelClaimId());
|
||||
options.put("channel_name", local.getChannelName());
|
||||
Lbryio.call("subscription", "new", options, context);
|
||||
} catch (LbryUriException | LbryioRequestException | LbryioResponseException ex) {
|
||||
// pass
|
||||
Log.e(TAG, String.format("subscription/new failed: %s", ex.getMessage()), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < localSubs.size(); i++) {
|
||||
Subscription local = localSubs.get(i);
|
||||
if (!base.contains(local) && !diff.contains(local)) {
|
||||
diff.add(local);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < remoteSubs.size(); i++) {
|
||||
Subscription remote = remoteSubs.get(i);
|
||||
if (!combined.contains(remote)) {
|
||||
combined.add(remote);
|
||||
if (!diff.contains(remote)) {
|
||||
diff.add(remote);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException | SQLiteException ex) {
|
||||
error = ex;
|
||||
return null;
|
||||
} finally {
|
||||
Helper.closeDatabase(db);
|
||||
}
|
||||
|
||||
return combined;
|
||||
}
|
||||
protected void onPostExecute(List<Subscription> subscriptions) {
|
||||
if (handler != null) {
|
||||
if (subscriptions != null) {
|
||||
handler.onSuccess(subscriptions, diff);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface MergeSubscriptionsHandler {
|
||||
void onSuccess(List<Subscription> subscriptions, List<Subscription> diff);
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package io.lbry.browser.tasks.wallet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.lbry.browser.MainActivity;
|
||||
import io.lbry.browser.data.DatabaseHelper;
|
||||
import io.lbry.browser.exceptions.ApiCallException;
|
||||
import io.lbry.browser.exceptions.LbryUriException;
|
||||
import io.lbry.browser.model.Tag;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
import io.lbry.browser.utils.LbryUri;
|
||||
|
||||
/*
|
||||
version: '0.1',
|
||||
value: {
|
||||
subscriptions?: Array<string>,
|
||||
tags?: Array<string>,
|
||||
blocked?: Array<string>,
|
||||
settings?: any,
|
||||
app_welcome_version?: number,
|
||||
sharing_3P?: boolean,
|
||||
},
|
||||
*/
|
||||
public class LoadSharedUserStateTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private static final String KEY = "shared";
|
||||
|
||||
private Context context;
|
||||
private LoadSharedUserStateHandler handler;
|
||||
private Exception error;
|
||||
|
||||
private List<Subscription> subscriptions;
|
||||
private List<Tag> followedTags;
|
||||
|
||||
public LoadSharedUserStateTask(Context context, LoadSharedUserStateHandler handler) {
|
||||
this.context = context;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
// data to save
|
||||
// current subscriptions
|
||||
// Get the previous saved state
|
||||
try {
|
||||
SQLiteDatabase db = null;
|
||||
JSONObject result = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_PREFERENCE_GET, Lbry.buildSingleParam("key", KEY));
|
||||
if (result != null) {
|
||||
if (context instanceof MainActivity) {
|
||||
db = ((MainActivity) context).getDbHelper().getWritableDatabase();
|
||||
}
|
||||
|
||||
JSONObject shared = result.getJSONObject("shared");
|
||||
if (shared.has("type")
|
||||
&& "object".equalsIgnoreCase(shared.getString("type"))
|
||||
&& shared.has("value")) {
|
||||
JSONObject value = shared.getJSONObject("value");
|
||||
|
||||
JSONArray subscriptionUrls =
|
||||
value.has("subscriptions") && !value.isNull("subscriptions") ? value.getJSONArray("subscriptions") : null;
|
||||
JSONArray tags =
|
||||
value.has("tags") && !value.isNull("tags") ? value.getJSONArray("tags") : null;
|
||||
|
||||
if (subscriptionUrls != null) {
|
||||
subscriptions = new ArrayList<>();
|
||||
for (int i = 0; i < subscriptionUrls.length(); i++) {
|
||||
String url = subscriptionUrls.getString(i);
|
||||
try {
|
||||
LbryUri uri = LbryUri.parse(LbryUri.normalize(url));
|
||||
Subscription subscription = new Subscription();
|
||||
subscription.setChannelName(uri.getChannelName());
|
||||
subscription.setUrl(url);
|
||||
subscriptions.add(subscription);
|
||||
if (db != null) {
|
||||
DatabaseHelper.createOrUpdateSubscription(subscription, db);
|
||||
}
|
||||
} catch (LbryUriException | SQLiteException ex) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tags != null) {
|
||||
if (db != null && tags.length() > 0) {
|
||||
DatabaseHelper.setAllTagsUnfollowed(db);
|
||||
}
|
||||
|
||||
followedTags = new ArrayList<>();
|
||||
for (int i = 0; i < tags.length(); i++) {
|
||||
String tagName = tags.getString(i);
|
||||
Tag tag = new Tag(tagName);
|
||||
tag.setFollowed(true);
|
||||
followedTags.add(tag);
|
||||
|
||||
try {
|
||||
if (db != null) {
|
||||
DatabaseHelper.createOrUpdateTag(tag, db);
|
||||
}
|
||||
} catch (SQLiteException ex) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (ApiCallException | JSONException ex) {
|
||||
// failed
|
||||
error = ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (handler != null) {
|
||||
if (result) {
|
||||
handler.onSuccess(subscriptions, followedTags);
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface LoadSharedUserStateHandler {
|
||||
void onSuccess(List<Subscription> subscriptions, List<Tag> followedTags);
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package io.lbry.browser.tasks.wallet;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.lbry.browser.exceptions.ApiCallException;
|
||||
import io.lbry.browser.model.lbryinc.Subscription;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
import io.lbry.browser.utils.Lbryio;
|
||||
|
||||
/*
|
||||
version: '0.1',
|
||||
value: {
|
||||
subscriptions?: Array<string>,
|
||||
tags?: Array<string>,
|
||||
blocked?: Array<string>,
|
||||
settings?: any,
|
||||
app_welcome_version?: number,
|
||||
sharing_3P?: boolean,
|
||||
},
|
||||
*/
|
||||
public class SaveSharedUserStateTask extends AsyncTask<Void, Void, Boolean> {
|
||||
private static final String KEY = "shared";
|
||||
private static final String VERSION = "0.1";
|
||||
private SaveSharedUserStateHandler handler;
|
||||
private Exception error;
|
||||
|
||||
public SaveSharedUserStateTask(SaveSharedUserStateHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
protected Boolean doInBackground(Void... params) {
|
||||
// data to save
|
||||
// current subscriptions
|
||||
List<String> subscriptionUrls = new ArrayList<>();
|
||||
for (Subscription subscription : Lbryio.subscriptions) {
|
||||
subscriptionUrls.add(subscription.getUrl());
|
||||
}
|
||||
|
||||
// followed tags
|
||||
List<String> followedTags = Helper.getTagsForTagObjects(Lbry.followedTags);
|
||||
|
||||
// Get the previous saved state
|
||||
try {
|
||||
boolean isExistingValid = false;
|
||||
JSONObject sharedObject = null;
|
||||
JSONObject result = (JSONObject) Lbry.genericApiCall(Lbry.METHOD_PREFERENCE_GET, Lbry.buildSingleParam("key", KEY));
|
||||
if (result != null) {
|
||||
JSONObject shared = result.getJSONObject("shared");
|
||||
if (shared.has("type")
|
||||
&& "object".equalsIgnoreCase(shared.getString("type"))
|
||||
&& shared.has("value")) {
|
||||
isExistingValid = true;
|
||||
JSONObject value = shared.getJSONObject("value");
|
||||
value.put("subscriptions", Helper.jsonArrayFromList(subscriptionUrls));
|
||||
value.put("tags", Helper.jsonArrayFromList(followedTags));
|
||||
sharedObject = shared;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isExistingValid) {
|
||||
// build a new object
|
||||
JSONObject value = new JSONObject();
|
||||
value.put("subscriptions", Helper.jsonArrayFromList(subscriptionUrls));
|
||||
value.put("tags", Helper.jsonArrayFromList(followedTags));
|
||||
|
||||
sharedObject = new JSONObject();
|
||||
sharedObject.put("type", "object");
|
||||
sharedObject.put("value", value);
|
||||
sharedObject.put("version", VERSION);
|
||||
}
|
||||
|
||||
Map<String, Object> options = new HashMap<>();
|
||||
options.put("key", KEY);
|
||||
options.put("value", sharedObject.toString());
|
||||
Lbry.genericApiCall(Lbry.METHOD_PREFERENCE_SET, options);
|
||||
|
||||
return true;
|
||||
} catch (ApiCallException | JSONException ex) {
|
||||
// failed
|
||||
error = ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Boolean result) {
|
||||
if (handler != null) {
|
||||
if (result) {
|
||||
handler.onSuccess();
|
||||
} else {
|
||||
handler.onError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface SaveSharedUserStateHandler {
|
||||
void onSuccess();
|
||||
void onError(Exception error);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package io.lbry.browser.tasks.wallet;
|
|||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -24,8 +25,9 @@ public class SyncApplyTask extends AsyncTask<Void, Void, Boolean> {
|
|||
private String syncHash;
|
||||
private String syncData;
|
||||
|
||||
public SyncApplyTask(boolean fetch, SyncTaskHandler handler) {
|
||||
public SyncApplyTask(boolean fetch, String password, SyncTaskHandler handler) {
|
||||
this.fetch = fetch;
|
||||
this.password = password;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public class SyncGetTask extends AsyncTask<Void, Void, WalletSync> {
|
|||
boolean unlockSuccessful =
|
||||
!isLocked || (boolean) Lbry.genericApiCall(Lbry.METHOD_WALLET_UNLOCK, Lbry.buildSingleParam("password", password));
|
||||
if (!unlockSuccessful) {
|
||||
throw new WalletException("The wallet could be unlocked with the provided password.");
|
||||
throw new WalletException("The wallet could not be unlocked with the provided password.");
|
||||
}
|
||||
|
||||
String hash = (String) Lbry.genericApiCall(Lbry.METHOD_SYNC_HASH);
|
||||
|
|
|
@ -33,14 +33,19 @@ import io.lbry.browser.dialog.CustomizeTagsDialogFragment;
|
|||
import io.lbry.browser.model.Claim;
|
||||
import io.lbry.browser.model.Tag;
|
||||
import io.lbry.browser.tasks.ClaimSearchTask;
|
||||
import io.lbry.browser.tasks.FollowUnfollowTagTask;
|
||||
import io.lbry.browser.tasks.GenericTaskHandler;
|
||||
import io.lbry.browser.tasks.wallet.SaveSharedUserStateTask;
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
import io.lbry.browser.utils.Helper;
|
||||
import io.lbry.browser.utils.Lbry;
|
||||
import io.lbry.browser.utils.Predefined;
|
||||
import lombok.Getter;
|
||||
|
||||
// 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 {
|
||||
|
||||
@Getter
|
||||
private boolean singleTagView;
|
||||
private List<String> tags;
|
||||
private View layoutFilterContainer;
|
||||
|
@ -55,6 +60,7 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
private RecyclerView contentList;
|
||||
private int currentSortBy;
|
||||
private int currentContentFrom;
|
||||
@Getter
|
||||
private int currentContentScope;
|
||||
private String contentReleaseTime;
|
||||
private List<String> contentSortOrder;
|
||||
|
@ -184,7 +190,6 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
});
|
||||
|
||||
checkParams(false);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
@ -204,7 +209,12 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
titleView.setText(Helper.capitalize(tagName));
|
||||
} else {
|
||||
singleTagView = false;
|
||||
tags = null;
|
||||
// default to followed Tags scope if any tags are followed
|
||||
tags = Helper.getTagsForTagObjects(Lbry.followedTags);
|
||||
if (tags.size() > 0) {
|
||||
currentContentScope = ContentScopeDialogFragment.ITEM_TAGS;
|
||||
Helper.setViewVisibility(customizeLink, View.VISIBLE);
|
||||
}
|
||||
titleView.setText(getString(R.string.all_content));
|
||||
}
|
||||
|
||||
|
@ -255,12 +265,16 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
public void onTagAdded(Tag tag) {
|
||||
// heavy-lifting
|
||||
// save to local, save to wallet and then sync
|
||||
FollowUnfollowTagTask task = new FollowUnfollowTagTask(tag, false, getContext(), followUnfollowHandler);
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTagRemoved(Tag tag) {
|
||||
// heavy-lifting
|
||||
// save to local, save to wallet and then sync
|
||||
FollowUnfollowTagTask task = new FollowUnfollowTagTask(tag, true, getContext(), followUnfollowHandler);
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
});
|
||||
Context context = getContext();
|
||||
|
@ -270,6 +284,30 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
}
|
||||
}
|
||||
|
||||
private FollowUnfollowTagTask.FollowUnfollowTagHandler followUnfollowHandler = new FollowUnfollowTagTask.FollowUnfollowTagHandler() {
|
||||
@Override
|
||||
public void onSuccess(Tag tag, boolean unfollowing) {
|
||||
if (tags != null) {
|
||||
if (unfollowing) {
|
||||
tags.remove(tag.getLowercaseName());
|
||||
} else {
|
||||
tags.add(tag.getLowercaseName());
|
||||
}
|
||||
fetchClaimSearchContent(true);
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).saveSharedUserState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception error) {
|
||||
// pass
|
||||
}
|
||||
};
|
||||
|
||||
private void onSortByChanged(int sortBy) {
|
||||
currentSortBy = sortBy;
|
||||
|
||||
|
@ -364,7 +402,7 @@ public class AllContentFragment extends BaseFragment implements SharedPreference
|
|||
fetchClaimSearchContent(false);
|
||||
}
|
||||
|
||||
private void fetchClaimSearchContent(boolean reset) {
|
||||
public void fetchClaimSearchContent(boolean reset) {
|
||||
if (reset && contentListAdapter != null) {
|
||||
contentListAdapter.clearItems();
|
||||
currentClaimSearchPage = 1;
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package io.lbry.browser.ui.editorschoice;
|
||||
|
||||
import io.lbry.browser.ui.BaseFragment;
|
||||
|
||||
public class EditorsChoiceFragment extends BaseFragment {
|
||||
}
|
|
@ -12,7 +12,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
@ -333,8 +332,18 @@ public class FollowingFragment extends BaseFragment implements
|
|||
showSuggestedChannels();
|
||||
}
|
||||
|
||||
if (Lbryio.cacheSubscriptions != null && Lbryio.cacheSubscriptions.size() > 0) {
|
||||
subscriptionsList = new ArrayList<>(Lbryio.cacheSubscriptions);
|
||||
if (Lbryio.subscriptions != null && Lbryio.subscriptions.size() > 0) {
|
||||
fetchLoadedSubscriptions();
|
||||
} else {
|
||||
fetchSubscriptions();
|
||||
}
|
||||
}
|
||||
public void onPause() {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onPause();
|
||||
}
|
||||
public void fetchLoadedSubscriptions() {
|
||||
subscriptionsList = new ArrayList<>(Lbryio.subscriptions);
|
||||
buildChannelIdsAndUrls();
|
||||
if (Lbryio.cacheResolvedSubscriptions.size() > 0) {
|
||||
updateChannelFilterListAdapter(Lbryio.cacheResolvedSubscriptions);
|
||||
|
@ -343,13 +352,6 @@ public class FollowingFragment extends BaseFragment implements
|
|||
}
|
||||
fetchClaimSearchContent();
|
||||
showSubscribedContent();
|
||||
} else {
|
||||
fetchSubscriptions();
|
||||
}
|
||||
}
|
||||
public void onPause() {
|
||||
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
public void loadFollowing() {
|
||||
|
@ -662,7 +664,7 @@ public class FollowingFragment extends BaseFragment implements
|
|||
fetchSuggestedChannels();
|
||||
showSuggestedChannels();
|
||||
} else {
|
||||
Lbryio.cacheSubscriptions = subscriptions;
|
||||
Lbryio.subscriptions = subscriptions;
|
||||
subscriptionsList = new ArrayList<>(subscriptions);
|
||||
showSubscribedContent();
|
||||
fetchAndResolveChannelList();
|
||||
|
@ -686,6 +688,7 @@ public class FollowingFragment extends BaseFragment implements
|
|||
if (discoverDialog != null) {
|
||||
fetchSubscriptions();
|
||||
}
|
||||
saveSharedUserState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -709,6 +712,7 @@ public class FollowingFragment extends BaseFragment implements
|
|||
if (discoverDialog != null) {
|
||||
fetchSubscriptions();
|
||||
}
|
||||
saveSharedUserState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -729,6 +733,13 @@ public class FollowingFragment extends BaseFragment implements
|
|||
Helper.setViewVisibility(noContentView, noContent ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
private void saveSharedUserState() {
|
||||
Context context = getContext();
|
||||
if (context instanceof MainActivity) {
|
||||
((MainActivity) context).saveSharedUserState();
|
||||
}
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
|
||||
if (key.equalsIgnoreCase(MainActivity.PREFERENCE_KEY_SHOW_MATURE_CONTENT)) {
|
||||
fetchClaimSearchContent(true);
|
||||
|
|
|
@ -188,7 +188,7 @@ public class WalletVerificationFragment extends Fragment {
|
|||
}
|
||||
|
||||
public void processNewWallet() {
|
||||
SyncApplyTask fetchTask = new SyncApplyTask(true, new DefaultSyncTaskHandler() {
|
||||
SyncApplyTask fetchTask = new SyncApplyTask(true, null, new DefaultSyncTaskHandler() {
|
||||
@Override
|
||||
public void onSyncApplySuccess(String hash, String data) { createNewRemoteSync(hash, data); }
|
||||
@Override
|
||||
|
|
|
@ -308,8 +308,6 @@ public class WalletFragment extends BaseFragment implements SdkStatusListener, W
|
|||
}
|
||||
|
||||
public void onWalletSyncEnabled() {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
sp.edit().putBoolean(MainActivity.PREFERENCE_KEY_INTERNAL_WALLET_SYNC_ENABLED, true).apply();
|
||||
switchSyncStatus.setText(R.string.on);
|
||||
switchSyncStatus.setChecked(true);
|
||||
textWalletHintSyncStatus.setText(R.string.backup_synced);
|
||||
|
|
|
@ -316,7 +316,7 @@ public final class Helper {
|
|||
}
|
||||
public static List<Tag> filterFollowedTags(List<Tag> tags) {
|
||||
List<Tag> followedTags = new ArrayList<>();
|
||||
for (Tag tag : followedTags) {
|
||||
for (Tag tag : tags) {
|
||||
if (tag.isFollowed()) {
|
||||
followedTags.add(tag);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import okhttp3.RequestBody;
|
|||
import okhttp3.Response;
|
||||
|
||||
public final class Lbry {
|
||||
private static final Object lock = new Object();
|
||||
public static LinkedHashMap<ClaimCacheKey, Claim> claimCache = new LinkedHashMap<>();
|
||||
public static LinkedHashMap<Map<String, Object>, ClaimSearchCacheValue> claimSearchCache = new LinkedHashMap<>();
|
||||
public static WalletBalance walletBalance = new WalletBalance();
|
||||
|
@ -85,7 +86,6 @@ public final class Lbry {
|
|||
public static final String METHOD_PREFERENCE_GET = "preference_get";
|
||||
public static final String METHOD_PREFERENCE_SET = "preference_set";
|
||||
|
||||
|
||||
public static KeyStore KEYSTORE;
|
||||
public static boolean SDK_READY = false;
|
||||
|
||||
|
@ -165,8 +165,10 @@ public final class Lbry {
|
|||
JSONObject json = new JSONObject(responseString);
|
||||
if (response.code() >= 200 && response.code() < 300) {
|
||||
if (json.has("result")) {
|
||||
Object result = json.get("result");
|
||||
return result;
|
||||
if (json.isNull("result")) {
|
||||
return null;
|
||||
}
|
||||
return json.get("result");
|
||||
} else {
|
||||
processErrorJson(json);
|
||||
}
|
||||
|
@ -417,4 +419,23 @@ public final class Lbry {
|
|||
public static Object genericApiCall(String method) throws ApiCallException {
|
||||
return genericApiCall(method, null);
|
||||
}
|
||||
public static void addFollowedTag(Tag tag) {
|
||||
synchronized (lock) {
|
||||
if (!followedTags.contains(tag)) {
|
||||
followedTags.add(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void removeFollowedTag(Tag tag) {
|
||||
synchronized (lock) {
|
||||
followedTags.remove(tag);
|
||||
}
|
||||
}
|
||||
public static void addKnownTag(Tag tag) {
|
||||
synchronized (lock) {
|
||||
if (!knownTags.contains(tag)) {
|
||||
knownTags.add(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public final class Lbryio {
|
|||
public static final String TAG = "Lbryio";
|
||||
public static final String CONNECTION_STRING = "https://api.lbry.com";
|
||||
public static final String AUTH_TOKEN_PARAM = "auth_token";
|
||||
public static List<Subscription> cacheSubscriptions = new ArrayList<>();
|
||||
public static List<Subscription> subscriptions = new ArrayList<>();
|
||||
public static List<Claim> cacheResolvedSubscriptions = new ArrayList<>();
|
||||
public static double LBCUSDRate = 0;
|
||||
public static String AUTH_TOKEN;
|
||||
|
@ -280,4 +280,17 @@ public final class Lbryio {
|
|||
lastRemoteHash = hash;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addSubscription(Subscription subscription) {
|
||||
synchronized (lock) {
|
||||
if (!subscriptions.contains(subscription)) {
|
||||
subscriptions.add(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void removeSubscription(Subscription subscription) {
|
||||
synchronized (lock) {
|
||||
subscriptions.remove(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
app/src/main/res/layout/fragment_editors_choice.xml
Normal file
11
app/src/main/res/layout/fragment_editors_choice.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/editors_choice_content_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
61
app/src/main/res/layout/list_item_editors_choice.xml
Normal file
61
app/src/main/res/layout/list_item_editors_choice.xml
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/editors_choice_header_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:clickable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
<TextView
|
||||
android:id="@+id/editors_choice_content_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<ImageView
|
||||
android:id="@+id/editors_choice_content_thumbnail"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_centerVertical="true"/>
|
||||
<TextView
|
||||
android:id="@+id/editors_choice_content_description"
|
||||
android:layout_toRightOf="@id/editors_choice_content_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="6"
|
||||
android:textFontWeight="300"
|
||||
android:textSize="14sp" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</LinearLayout>
|
|
@ -16,12 +16,14 @@
|
|||
android:id="@+id/tag_action"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="4dp"
|
||||
android:tint="@color/darkForeground" />
|
||||
<TextView
|
||||
android:id="@+id/tag_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:fontFamily="@font/inter"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:textSize="12sp"
|
||||
|
|
Loading…
Reference in a new issue