Add insertion results to the AddFeedActivity layout

This commit is contained in:
Shinokuni 2019-03-15 16:06:54 +01:00
parent 594f3d1c5e
commit 0b389dd080
14 changed files with 437 additions and 280 deletions

View File

@ -13,11 +13,13 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.adapters.ItemAdapter;
import com.readrops.app.R;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.Utils;
import com.readrops.app.utils.ParsingResult;
import com.readrops.app.viewmodels.AddFeedsViewModel;
@ -36,9 +38,16 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
private Button load;
private ProgressBar progressBar;
private Button validate;
private RecyclerView recyclerView;
private RecyclerView parseResultsRecyclerView;
private TextView resultsTextView;
private ProgressBar feedInsertionProgressBar;
private RecyclerView insertionResultsRecyclerView;
private ItemAdapter<ParsingResult> parseItemsAdapter;
private ItemAdapter<FeedInsertionResult> insertionResultsAdapter;
private ItemAdapter<ParsingResult> itemAdapter;
private AddFeedsViewModel viewModel;
private ArrayList<Feed> feedsToUpdate;
@ -51,16 +60,20 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
feedInput = findViewById(R.id.add_feed_text_input);
load = findViewById(R.id.add_feed_load);
validate = findViewById(R.id.add_feed_ok);
progressBar = findViewById(R.id.fadd_feed_loading);
recyclerView = findViewById(R.id.add_feed_results);
progressBar = findViewById(R.id.add_feed_loading);
parseResultsRecyclerView = findViewById(R.id.add_feed_results);
resultsTextView = findViewById(R.id.add_feed_results_text_view);
feedInsertionProgressBar = findViewById(R.id.add_feed_insert_progressbar);
insertionResultsRecyclerView = findViewById(R.id.add_feed_inserted_results_recyclerview);
load.setOnClickListener(this);
validate.setOnClickListener(this);
validate.setEnabled(false);
viewModel = ViewModelProviders.of(this).get(AddFeedsViewModel.class);
itemAdapter = new ItemAdapter<>();
FastAdapter<ParsingResult> fastAdapter = FastAdapter.with(itemAdapter);
parseItemsAdapter = new ItemAdapter<>();
FastAdapter<ParsingResult> fastAdapter = FastAdapter.with(parseItemsAdapter);
fastAdapter.withSelectable(true);
fastAdapter.withOnClickListener((v, adapter, item, position) -> {
if (item.isChecked()) {
@ -74,11 +87,17 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
return true;
});
recyclerView.setAdapter(fastAdapter);
parseResultsRecyclerView.setAdapter(fastAdapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
parseResultsRecyclerView.setLayoutManager(layoutManager);
DividerItemDecoration decoration = new DividerItemDecoration(this, ((LinearLayoutManager) layoutManager).getOrientation());
recyclerView.addItemDecoration(decoration);
//parseResultsRecyclerView.addItemDecoration(decoration);
insertionResultsAdapter = new ItemAdapter<>();
RecyclerView.LayoutManager layoutManager1 = new LinearLayoutManager(this);
insertionResultsRecyclerView.setAdapter(FastAdapter.with(insertionResultsAdapter));
insertionResultsRecyclerView.setLayoutManager(layoutManager1);
//insertionResultsRecyclerView.addItemDecoration(decoration);
feedsToUpdate = new ArrayList<>();
}
@ -112,8 +131,11 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
}
private void insertFeeds() {
feedInsertionProgressBar.setVisibility(View.VISIBLE);
validate.setEnabled(false);
List<ParsingResult> feedsToInsert = new ArrayList<>();
for (ParsingResult result : itemAdapter.getAdapterItems()) {
for (ParsingResult result : parseItemsAdapter.getAdapterItems()) {
if (result.isChecked())
feedsToInsert.add(result);
}
@ -121,15 +143,15 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
viewModel.addFeeds(feedsToInsert)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<List<Feed>>() {
.subscribe(new SingleObserver<List<FeedInsertionResult>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(List<Feed> feeds) {
feedsToUpdate.addAll(feeds);
public void onSuccess(List<FeedInsertionResult> feedInsertionResults) {
processResults(feedInsertionResults);
}
@Override
@ -139,6 +161,18 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
});
}
private void processResults(List<FeedInsertionResult> feedInsertionResults) {
feedInsertionProgressBar.setVisibility(View.GONE);
insertionResultsRecyclerView.setVisibility(View.VISIBLE);
for (FeedInsertionResult feedInsertionResult : feedInsertionResults) {
if (feedInsertionResult.getFeed() != null)
feedsToUpdate.add(feedInsertionResult.getFeed());
}
insertionResultsAdapter.add(feedInsertionResults);
}
private void loadFeed() {
String url = feedInput.getText().toString().trim();
@ -170,10 +204,14 @@ public class AddFeedActivity extends AppCompatActivity implements View.OnClickLi
}
private void displayResults(List<ParsingResult> parsingResultList) {
recyclerView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
if (parsingResultList.size() > 0) {
parseResultsRecyclerView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
resultsTextView.setVisibility(View.VISIBLE);
itemAdapter.add(parsingResultList);
parseItemsAdapter.add(parsingResultList);
validate.setEnabled(true);
}
}
@Override

View File

@ -236,44 +236,6 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
public void onRefresh() {
Log.d(TAG, "syncing started");
presync(null);
}
public void displayAddFeedDialog(View view) {
actionMenu.close(true);
//Dialog dialog = new AddFeedDialog(this, R.layout.add_feed_layout);
//dialog.show();
Intent intent = new Intent(this, AddFeedActivity.class);
startActivityForResult(intent, ADD_FEED_REQUEST);
}
public void addFolder(View view) {
actionMenu.close(true);
Intent intent = new Intent(this, ManageFeedsActivity.class);
startActivity(intent);
}
public void insertNewFeed(ParsingResult result) {
refreshLayout.setRefreshing(true);
viewModel.addFeed(result);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == ADD_FEED_REQUEST && resultCode == RESULT_OK) {
ArrayList<Feed> feeds = data.getParcelableArrayListExtra("feedIds");
if (feeds != null && feeds.size() > 0) {
refreshLayout.setRefreshing(true);
presync(feeds);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void presync(List<Feed> feeds) {
viewModel.getFeedCount()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@ -281,14 +243,13 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
@Override
public void onSubscribe(Disposable d) {
syncProgressLayout.setVisibility(View.VISIBLE);
syncProgressBar.setProgress(0);
}
@Override
public void onSuccess(Integer integer) {
feedNb = integer;
sync(feeds);
sync(null);
}
@Override
@ -298,6 +259,40 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
});
}
public void displayAddFeedDialog(View view) {
actionMenu.close(true);
Intent intent = new Intent(this, AddFeedActivity.class);
startActivityForResult(intent, ADD_FEED_REQUEST);
}
public void addFolder(View view) {
actionMenu.close(true);
Intent intent = new Intent(this, ManageFeedsActivity.class);
startActivity(intent);
}
public void insertNewFeed(ParsingResult result) {
refreshLayout.setRefreshing(true);
viewModel.addFeed(result);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == ADD_FEED_REQUEST && resultCode == RESULT_OK) {
ArrayList<Feed> feeds = data.getParcelableArrayListExtra("feedIds");
if (feeds != null && feeds.size() > 0) {
refreshLayout.setRefreshing(true);
feedNb = feeds.size();
sync(feeds);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void sync(List<Feed> feeds) {
viewModel.sync(feeds)
.subscribeOn(Schedulers.io())
@ -305,7 +300,8 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
.subscribe(new Observer<Feed>() {
@Override
public void onSubscribe(Disposable d) {
syncProgressLayout.setVisibility(View.VISIBLE);
syncProgressBar.setProgress(0);
}
@Override

View File

@ -1,17 +1,23 @@
package com.readrops.app.repositories;
import android.app.Application;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.graphics.Palette;
import android.util.Patterns;
import com.readrops.app.database.pojo.FeedWithFolder;
import com.readrops.app.utils.SyncError;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.HtmlParser;
import com.readrops.app.utils.Utils;
import com.readrops.app.views.SimpleCallback;
import com.readrops.app.database.Database;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Folder;
import com.readrops.app.utils.ParsingResult;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@ -40,7 +46,7 @@ public abstract class ARepository {
public abstract void addFeed(ParsingResult result);
public abstract Single<List<Feed>> addFeeds(List<ParsingResult> results);
public abstract Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results);
public abstract void updateFeed(Feed feed);
@ -71,6 +77,24 @@ public abstract class ARepository {
});
}
protected void setFavIconUtils(Feed feed) throws IOException {
String favUrl = HtmlParser.getFaviconLink(feed.getSiteUrl());
if (favUrl != null && Patterns.WEB_URL.matcher(favUrl).matches()) {
feed.setIconUrl(favUrl);
setFeedColors(favUrl, feed);
}
}
protected void setFeedColors(String favUrl, Feed feed) throws IOException {
Bitmap favicon = Utils.getImageFromUrl(favUrl);
Palette palette = Palette.from(favicon).generate();
feed.setTextColor(palette.getDominantSwatch().getRgb());
if (palette.getMutedSwatch() != null)
feed.setBackgroundColor(palette.getMutedSwatch().getRgb());
}
protected void failureCallBackInMainThread(Exception e) {
Handler handler = new Handler(Looper.getMainLooper());

View File

@ -3,20 +3,16 @@ package com.readrops.app.repositories;
import android.accounts.NetworkErrorException;
import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.graphics.Bitmap;
import android.support.v7.graphics.Palette;
import android.util.Patterns;
import com.readrops.app.database.entities.Folder;
import com.readrops.app.database.pojo.FeedWithFolder;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Item;
import com.readrops.app.utils.SyncError;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.Utils;
import com.readrops.app.utils.HtmlParser;
import com.readrops.app.utils.ParsingResult;
import com.readrops.readropslibrary.QueryCallback;
import com.readrops.readropslibrary.Utils.LibUtils;
import com.readrops.readropslibrary.Utils.UnknownFormatException;
import com.readrops.readropslibrary.localfeed.AFeed;
@ -26,7 +22,6 @@ import com.readrops.readropslibrary.localfeed.atom.ATOMFeed;
import com.readrops.readropslibrary.localfeed.json.JSONFeed;
import com.readrops.readropslibrary.localfeed.rss.RSSFeed;
import org.joda.time.LocalDateTime;
import org.jsoup.Jsoup;
import java.io.IOException;
@ -36,13 +31,12 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;
public class LocalFeedRepository extends ARepository implements QueryCallback {
public class LocalFeedRepository extends ARepository {
private static final String TAG = LocalFeedRepository.class.getSimpleName();
@ -69,11 +63,11 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
feedList = new ArrayList<>(feeds);
RSSQuery rssQuery = new RSSQuery();
List<SyncError> syncErrors = new ArrayList<>();
List<FeedInsertionResult> syncErrors = new ArrayList<>();
for (Feed feed : feedList) {
emitter.onNext(feed);
SyncError syncError = new SyncError();
FeedInsertionResult syncError = new FeedInsertionResult();
try {
HashMap<String, String> headers = new HashMap<>();
@ -89,18 +83,18 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
Exception e = queryResult.getException();
if (e instanceof UnknownFormatException)
syncError.setInsertionError(SyncError.FeedInsertionError.FORMAT_ERROR);
syncError.setInsertionError(FeedInsertionResult.FeedInsertionError.FORMAT_ERROR);
else if (e instanceof NetworkErrorException)
syncError.setInsertionError(SyncError.FeedInsertionError.NETWORK_ERROR);
syncError.setInsertionError(FeedInsertionResult.FeedInsertionError.NETWORK_ERROR);
syncError.setFeed(feed);
syncErrors.add(syncError);
}
} catch (Exception e) {
if (e instanceof IOException)
syncError.setInsertionError(SyncError.FeedInsertionError.NETWORK_ERROR);
syncError.setInsertionError(FeedInsertionResult.FeedInsertionError.NETWORK_ERROR);
else
syncError.setInsertionError(SyncError.FeedInsertionError.PARSE_ERROR);
syncError.setInsertionError(FeedInsertionResult.FeedInsertionError.PARSE_ERROR);
syncError.setFeed(feed);
syncErrors.add(syncError);
@ -130,22 +124,43 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
}
@Override
public Single<List<Feed>> addFeeds(List<ParsingResult> results) {
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results) {
return Single.create(emitter -> {
List<Feed> insertedFeeds = new ArrayList<>();
List<FeedInsertionResult> insertionResults = new ArrayList<>();
for (ParsingResult result : results) {
RSSQuery rssNet = new RSSQuery();
RSSQueryResult queryResult = rssNet.queryUrl(result.getUrl(), new HashMap<>());
for (ParsingResult parsingResult : results) {
FeedInsertionResult insertionResult = new FeedInsertionResult();
if (queryResult != null && queryResult.getException() == null) {
Feed feed = insertFeed(queryResult.getFeed(), queryResult.getRssType());
if (feed != null)
insertedFeeds.add(feed);
}
}
try {
RSSQuery rssNet = new RSSQuery();
RSSQueryResult queryResult = rssNet.queryUrl(parsingResult.getUrl(), new HashMap<>());
emitter.onSuccess(insertedFeeds);
if (queryResult != null && queryResult.getException() == null) {
Feed feed = insertFeed(queryResult.getFeed(), queryResult.getRssType());
if (feed != null) {
insertionResult.setFeed(feed);
insertionResults.add(insertionResult);
}
} else if (queryResult != null && queryResult.getException() != null) {
insertionResult.setParsingResult(parsingResult);
insertionResult.setInsertionError(getErrorFromException(queryResult.getException()));
insertionResults.add(insertionResult);
} else {
// error 304
}
} catch (Exception e) {
if (e instanceof IOException)
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.NETWORK_ERROR);
else
insertionResult.setInsertionError(FeedInsertionResult.FeedInsertionError.PARSE_ERROR);
insertionResult.setParsingResult(parsingResult);
insertionResults.add(insertionResult);
}
}
emitter.onSuccess(insertionResults);
});
}
@ -184,26 +199,6 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
});
}
@Override
public void onSyncSuccess(AFeed feed, RSSQuery.RSSType type) {
switch (type) {
case RSS_2:
parseRSSItems(((RSSFeed) feed));
break;
case RSS_ATOM:
parseATOMItems(((ATOMFeed) feed));
break;
case RSS_JSON:
parseJSONItems(((JSONFeed) feed));
break;
}
}
@Override
public void onSyncFailure(Exception e) {
failureCallBackInMainThread(e);
}
private void insertNewItems(AFeed feed, RSSQuery.RSSType type) throws ParseException {
Feed dbFeed = null;
List<Item> items = null;
@ -256,80 +251,6 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
return dbFeed;
}
private void parseRSSItems(RSSFeed rssFeed) {
try {
Feed dbFeed = database.feedDao().getFeedByUrl(rssFeed.getChannel().getFeedUrl());
if (dbFeed == null) {
dbFeed = Feed.feedFromRSS(rssFeed);
setFavIconUtils(dbFeed);
dbFeed.setId((int)(database.feedDao().insert(dbFeed)));
} else
database.feedDao().updateHeaders(rssFeed.getEtag(), rssFeed.getLastModified(), dbFeed.getId());
List<Item> dbItems = Item.itemsFromRSS(rssFeed.getChannel().getItems(), dbFeed);
TreeMap<LocalDateTime, Item> sortedItems = new TreeMap<>(LocalDateTime::compareTo);
for (Item item : dbItems) {
sortedItems.put(item.getPubDate(), item);
}
insertItems(sortedItems.values(), dbFeed);
} catch (Exception e) {
failureCallBackInMainThread(e);
}
}
private void parseATOMItems(ATOMFeed feed) {
try {
Feed dbFeed = database.feedDao().getFeedByUrl(feed.getUrl());
if (dbFeed == null) {
dbFeed = Feed.feedFromATOM(feed);
setFavIconUtils(dbFeed);
dbFeed.setId((int)(database.feedDao().insert(dbFeed)));
} else
database.feedDao().updateHeaders(feed.getEtag(), feed.getLastModified(), dbFeed.getId());
List<Item> dbItems = Item.itemsFromATOM(feed.getEntries(), dbFeed);
TreeMap<LocalDateTime, Item> sortedItems = new TreeMap<>(LocalDateTime::compareTo);
for (Item item : dbItems) {
sortedItems.put(item.getPubDate(), item);
}
insertItems(sortedItems.values(), dbFeed);
} catch (Exception e) {
failureCallBackInMainThread(e);
}
}
private void parseJSONItems(JSONFeed feed) {
try {
Feed dbFeed = database.feedDao().getFeedByUrl(feed.getFeedUrl());
if (dbFeed == null) {
dbFeed = Feed.feedFromJSON(feed);
setFavIconUtils(dbFeed);
dbFeed.setId((int)(database.feedDao().insert(dbFeed)));
} else
database.feedDao().updateHeaders(feed.getEtag(), feed.getLastModified(), dbFeed.getId());
List<Item> dbItems = Item.itemsFromJSON(feed.getItems(), dbFeed);
TreeMap<LocalDateTime, Item> sortedItems = new TreeMap<>(LocalDateTime::compareTo);
for (Item item : dbItems) {
sortedItems.put(item.getPubDate(), item);
}
insertItems(sortedItems.values(), dbFeed);
} catch (Exception e) {
failureCallBackInMainThread(e);
}
}
private void insertItems(Collection<Item> items, Feed feed) {
for (Item dbItem : items) {
if (!Boolean.valueOf(database.itemDao().guidExist(dbItem.getGuid()))) {
@ -364,23 +285,16 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
}
}
private void setFavIconUtils(Feed feed) throws IOException {
String favUrl = HtmlParser.getFaviconLink(feed.getSiteUrl());
if (favUrl != null && Patterns.WEB_URL.matcher(favUrl).matches()) {
feed.setIconUrl(favUrl);
setFeedColors(favUrl, feed);
}
private FeedInsertionResult.FeedInsertionError getErrorFromException(Exception e) {
if (e instanceof UnknownFormatException)
return FeedInsertionResult.FeedInsertionError.FORMAT_ERROR;
else if (e instanceof NetworkErrorException)
return FeedInsertionResult.FeedInsertionError.NETWORK_ERROR;
else
return FeedInsertionResult.FeedInsertionError.UNKNOWN_ERROR;
}
private void setFeedColors(String favUrl, Feed feed) throws IOException {
Bitmap favicon = Utils.getImageFromUrl(favUrl);
Palette palette = Palette.from(favicon).generate();
feed.setTextColor(palette.getDominantSwatch().getRgb());
if (palette.getMutedSwatch() != null)
feed.setBackgroundColor(palette.getMutedSwatch().getRgb());
}
}

View File

@ -0,0 +1,134 @@
package com.readrops.app.utils;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.readrops.app.R;
import com.readrops.app.database.entities.Feed;
import java.util.List;
public class FeedInsertionResult extends AbstractItem<FeedInsertionResult, FeedInsertionResult.ViewHolder> {
private Feed feed;
private ParsingResult parsingResult;
private FeedInsertionError insertionError;
public FeedInsertionResult() {
}
public Feed getFeed() {
return feed;
}
public void setFeed(Feed feed) {
this.feed = feed;
}
public ParsingResult getParsingResult() {
return parsingResult;
}
public void setParsingResult(ParsingResult parsingResult) {
this.parsingResult = parsingResult;
}
public FeedInsertionError getInsertionError() {
return insertionError;
}
public void setInsertionError(FeedInsertionError insertionError) {
this.insertionError = insertionError;
}
@Override
public boolean isSelectable() {
return false;
}
@NonNull
@Override
public ViewHolder getViewHolder(View v) {
return new ViewHolder(v);
}
@Override
public int getType() {
return 0;
}
@Override
public int getLayoutRes() {
return R.layout.feed_insertion_result;
}
public enum FeedInsertionError {
NETWORK_ERROR,
DB_ERROR,
PARSE_ERROR,
FORMAT_ERROR,
UNKNOWN_ERROR
}
class ViewHolder extends FastAdapter.ViewHolder<FeedInsertionResult> {
private TextView feedInsertionRes;
private ImageView feedInsertionIcon;
public ViewHolder(View itemView) {
super(itemView);
feedInsertionRes = itemView.findViewById(R.id.feed_insertion_result_text_view);
feedInsertionIcon = itemView.findViewById(R.id.feed_insertion_result_icon);
}
@Override
public void bindView(FeedInsertionResult item, List<Object> payloads) {
if (item.getFeed() != null) {
feedInsertionRes.setText(itemView.getContext().getString(R.string.feed_insertion_successfull, item.feed.getName()));
feedInsertionIcon.setImageResource(R.drawable.ic_check_green);
}
else {
switch (item.getInsertionError()) {
case NETWORK_ERROR:
setErrorText(R.string.feed_insertion_network_failed, item.parsingResult);
break;
case DB_ERROR:
break;
case PARSE_ERROR:
setErrorText(R.string.feed_insertion_parse_failed, item.parsingResult);
break;
case FORMAT_ERROR:
setErrorText(R.string.feed_insertion_wrong_format, item.parsingResult);
break;
case UNKNOWN_ERROR:
setErrorText(R.string.feed_insertion_unknown_error, item.parsingResult);
break;
}
feedInsertionIcon.setImageResource(R.drawable.ic_warning_red);
}
}
private void setErrorText(@StringRes int stringRes, ParsingResult parsingResult) {
feedInsertionRes.setText(itemView.getContext().getString(stringRes,
parsingResult.getLabel() != null ? parsingResult.getLabel() :
parsingResult.getUrl()));
}
@Override
public void unbindView(FeedInsertionResult item) {
}
}
}

View File

@ -1,41 +0,0 @@
package com.readrops.app.utils;
import com.readrops.app.database.entities.Feed;
public class SyncError {
private Feed feed;
private FeedInsertionError insertionError;
public SyncError() {
}
public SyncError(Feed feed, FeedInsertionError insertionError) {
this.feed = feed;
this.insertionError = insertionError;
}
public Feed getFeed() {
return feed;
}
public void setFeed(Feed feed) {
this.feed = feed;
}
public FeedInsertionError getInsertionError() {
return insertionError;
}
public void setInsertionError(FeedInsertionError insertionError) {
this.insertionError = insertionError;
}
public enum FeedInsertionError {
NETWORK_ERROR,
DB_ERROR,
PARSE_ERROR,
FORMAT_ERROR
}
}

View File

@ -6,6 +6,7 @@ import android.support.annotation.NonNull;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.repositories.LocalFeedRepository;
import com.readrops.app.utils.FeedInsertionResult;
import com.readrops.app.utils.HtmlParser;
import com.readrops.app.utils.ParsingResult;
import com.readrops.readropslibrary.localfeed.RSSQuery;
@ -25,7 +26,7 @@ public class AddFeedsViewModel extends AndroidViewModel {
repository = new LocalFeedRepository(application);
}
public Single<List<Feed>> addFeeds(List<ParsingResult> results) {
public Single<List<FeedInsertionResult>> addFeeds(List<ParsingResult> results) {
return repository.addFeeds(results);
}

View File

@ -8,13 +8,11 @@ import android.support.annotation.NonNull;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.repositories.LocalFeedRepository;
import com.readrops.app.utils.SyncError;
import com.readrops.app.views.SimpleCallback;
import com.readrops.app.utils.ParsingResult;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Observable;
import io.reactivex.Single;

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#11FF00"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</vector>

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FF6200"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>

View File

@ -1,77 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
tools:context=".activities.AddFeedActivity">
<android.support.constraint.ConstraintLayout
android:id="@+id/add_feed_main_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:padding="20dp">
<android.support.design.widget.TextInputLayout
android:id="@+id/add_feed_input_layout"
<android.support.constraint.ConstraintLayout
android:id="@+id/add_feed_main_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<android.support.design.widget.TextInputEditText
android:id="@+id/add_feed_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/feed_url" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/add_feed_load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/load"
android:animateLayoutChanges="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_input_layout" />
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputLayout
android:id="@+id/add_feed_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.design.widget.TextInputEditText
android:id="@+id/add_feed_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/feed_url" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/add_feed_load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/load"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_input_layout" />
<ProgressBar
android:id="@+id/add_feed_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_load"
tools:visibility="gone" />
<TextView
android:id="@+id/add_feed_results_text_view"
style="@style/TextAppearance.Design.Hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/results"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/add_feed_loading"
tools:visibility="visible" />
<android.support.v7.widget.RecyclerView
android:id="@+id/add_feed_results"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_results_text_view"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
<Button
android:id="@+id/add_feed_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:enabled="true"
android:text="@string/validate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_main_layout" />
<ProgressBar
android:id="@+id/fadd_feed_loading"
android:id="@+id/add_feed_insert_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_load"
app:layout_constraintTop_toBottomOf="@+id/add_feed_ok"
tools:visibility="gone" />
<android.support.v7.widget.RecyclerView
android:id="@+id/add_feed_results"
android:id="@+id/add_feed_inserted_results_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/fadd_feed_loading"
tools:visibility="gone" />
app:layout_constraintTop_toBottomOf="@+id/add_feed_insert_progressbar"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
<Button
android:id="@+id/add_feed_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/validate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_feed_main_layout"
android:enabled="true"/>
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dp">
<ImageView
android:id="@+id/feed_insertion_result_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentStart="true" />
<TextView
android:id="@+id/feed_insertion_result_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="6dp"
android:layout_toEndOf="@id/feed_insertion_result_icon"
android:ellipsize="end"
android:maxLines="2"
android:minLines="1"
tools:text="Inserting feed Nextinpact with success" />
</RelativeLayout>

View File

@ -32,5 +32,11 @@
<string name="delete_feed">Supprimer le flux ?</string>
<string name="load">Charger</string>
<string name="updating_feed">Mise à jour du flux : %1$s</string>
<string name="results">Résultats</string>
<string name="feed_insertion_successfull">Le flux %1$s a été ajouté</string>
<string name="feed_insertion_network_failed">Erreur d\'accès au flux %1$s</string>
<string name="feed_insertion_parse_failed">Erreur de traitement pour le flux %1$s</string>
<string name="feed_insertion_wrong_format">Mauvais format pour le flux %1$s</string>
<string name="feed_insertion_unknown_error">Erreur inconnue pour le flux %1$s</string>
</resources>

View File

@ -34,4 +34,10 @@
<string name="delete_feed">Delete feed ?</string>
<string name="load">Load</string>
<string name="updating_feed">Updating feed : %1$s</string>
<string name="results">Results</string>
<string name="feed_insertion_successfull">Feed %1$s added successfully</string>
<string name="feed_insertion_network_failed">Network failure when accessing feed %1$s</string>
<string name="feed_insertion_parse_failed">Failure when parsing feed %1$s</string>
<string name="feed_insertion_wrong_format">Wrong format for feed %1$s</string>
<string name="feed_insertion_unknown_error">Unknown error for feed %1$s</string>
</resources>