From 73c7882cc0bbce1b9eec2e039564cc28060206dc Mon Sep 17 00:00:00 2001 From: Daniel Lublin Date: Tue, 20 Apr 2021 11:55:37 +0200 Subject: [PATCH] Introduce RssFeedViewModel Furnishing the RssFeed function as a single activity with fragments for Manage and Import. --- briar-android/src/main/AndroidManifest.xml | 28 +-- .../android/activity/ActivityComponent.java | 19 +- .../briar/android/blog/BlogModule.java | 4 + .../briar/android/blog/FeedFragment.java | 11 +- .../briar/android/blog/RssFeedActivity.java | 69 +++++++ .../briar/android/blog/RssFeedAdapter.java | 120 ++++++------ .../blog/RssFeedDeleteFeedDialogFragment.java | 64 +++++++ .../android/blog/RssFeedImportActivity.java | 170 ----------------- .../RssFeedImportFailedDialogFragment.java | 53 ++++++ .../android/blog/RssFeedImportFragment.java | 124 ++++++++++++ .../android/blog/RssFeedManageActivity.java | 178 ----------------- .../android/blog/RssFeedManageFragment.java | 123 ++++++++++++ .../briar/android/blog/RssFeedViewModel.java | 180 ++++++++++++++++++ ...mport.xml => fragment_rss_feed_import.xml} | 3 +- .../res/layout/fragment_rss_feed_manage.xml | 10 + .../src/main/res/menu/blogs_feed_actions.xml | 9 +- .../src/main/res/values-ar/strings.xml | 2 - .../src/main/res/values-az/strings.xml | 2 - .../src/main/res/values-bg/strings.xml | 2 - .../src/main/res/values-bs/strings.xml | 2 - .../src/main/res/values-ca/strings.xml | 2 - .../src/main/res/values-cs/strings.xml | 2 - .../src/main/res/values-de/strings.xml | 2 - .../src/main/res/values-es/strings.xml | 2 - .../src/main/res/values-eu/strings.xml | 2 - .../src/main/res/values-fa/strings.xml | 2 - .../src/main/res/values-fi/strings.xml | 2 - .../src/main/res/values-fr/strings.xml | 2 - .../src/main/res/values-gl/strings.xml | 2 - .../src/main/res/values-he/strings.xml | 2 - .../src/main/res/values-hi/strings.xml | 2 - .../src/main/res/values-hu/strings.xml | 2 - .../src/main/res/values-is/strings.xml | 2 - .../src/main/res/values-it/strings.xml | 2 - .../src/main/res/values-ja/strings.xml | 2 - .../src/main/res/values-ko/strings.xml | 2 - .../src/main/res/values-lt/strings.xml | 2 - .../src/main/res/values-mk/strings.xml | 2 - .../src/main/res/values-nb/strings.xml | 2 - .../src/main/res/values-nl/strings.xml | 2 - .../src/main/res/values-oc/strings.xml | 2 - .../src/main/res/values-pl/strings.xml | 2 - .../src/main/res/values-pt-rBR/strings.xml | 2 - .../src/main/res/values-ro/strings.xml | 2 - .../src/main/res/values-ru/strings.xml | 2 - .../src/main/res/values-sq/strings.xml | 2 - .../src/main/res/values-sr/strings.xml | 2 - .../src/main/res/values-sv/strings.xml | 2 - .../src/main/res/values-sw/strings.xml | 2 - .../src/main/res/values-tr/strings.xml | 2 - .../src/main/res/values-uk/strings.xml | 2 - .../src/main/res/values-zh-rCN/strings.xml | 2 - .../src/main/res/values-zh-rTW/strings.xml | 2 - briar-android/src/main/res/values/strings.xml | 4 +- .../org/briarproject/briar/api/feed/Feed.java | 11 +- .../briar/api/feed/FeedManager.java | 7 +- .../briar/feed/FeedManagerImpl.java | 17 +- .../briar/feed/FeedManagerImplTest.java | 8 +- 58 files changed, 741 insertions(+), 545 deletions(-) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedActivity.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedDeleteFeedDialogFragment.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFailedDialogFragment.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFragment.java delete mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageFragment.java create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java rename briar-android/src/main/res/layout/{activity_rss_feed_import.xml => fragment_rss_feed_import.xml} (94%) create mode 100644 briar-android/src/main/res/layout/fragment_rss_feed_manage.xml diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml index 87d431f37..feeec1655 100644 --- a/briar-android/src/main/AndroidManifest.xml +++ b/briar-android/src/main/AndroidManifest.xml @@ -322,25 +322,6 @@ android:value="org.briarproject.briar.android.blog.BlogActivity" /> - - - - - - - - + + + + { +@NotNullByDefault +class RssFeedAdapter extends ListAdapter { private final RssFeedListener listener; - RssFeedAdapter(Context ctx, RssFeedListener listener) { - super(ctx, Feed.class); + RssFeedAdapter(RssFeedListener listener) { + super(new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(Feed a, Feed b) { + return a.getUrl().equals(b.getUrl()) && + a.getBlogId().equals(b.getBlogId()) && + a.getAdded() == b.getAdded(); + } + + @Override + public boolean areContentsTheSame(Feed a, Feed b) { + return a.getUpdated() == b.getUpdated(); + } + }); this.listener = listener; } @Override public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View v = LayoutInflater.from(ctx).inflate( + View v = LayoutInflater.from(parent.getContext()).inflate( R.layout.list_item_rss_feed, parent, false); return new FeedViewHolder(v); } @Override public void onBindViewHolder(FeedViewHolder ui, int position) { - Feed item = getItemAt(position); - if (item == null) return; - - // Feed Title - ui.title.setText(item.getTitle()); - - // Delete Button - ui.delete.setOnClickListener(v -> listener.onDeleteClick(item)); - - // Author - if (item.getRssAuthor() != null) { - ui.author.setText(item.getRssAuthor()); - ui.author.setVisibility(VISIBLE); - ui.authorLabel.setVisibility(VISIBLE); - } else { - ui.author.setVisibility(GONE); - ui.authorLabel.setVisibility(GONE); - } - - // Imported and Last Updated - ui.imported.setText(UiUtils.formatDate(ctx, item.getAdded())); - ui.updated.setText(UiUtils.formatDate(ctx, item.getUpdated())); - - // Description - if (item.getDescription() != null) { - ui.description.setText(item.getDescription()); - ui.description.setVisibility(VISIBLE); - } else { - ui.description.setVisibility(GONE); - } - - // Open feed's blog when clicked - ui.layout.setOnClickListener(v -> listener.onFeedClick(item)); + ui.bindItem(getItem(position)); } - @Override - public int compare(Feed a, Feed b) { - if (a == b) return 0; - long aTime = a.getAdded(), bTime = b.getAdded(); - if (aTime > bTime) return -1; - if (aTime < bTime) return 1; - return 0; - } - - @Override - public boolean areContentsTheSame(Feed a, Feed b) { - return a.getUpdated() == b.getUpdated(); - } - - @Override - public boolean areItemsTheSame(Feed a, Feed b) { - return a.getUrl().equals(b.getUrl()) && - a.getBlogId().equals(b.getBlogId()) && - a.getAdded() == b.getAdded(); - } - - static class FeedViewHolder extends RecyclerView.ViewHolder { + class FeedViewHolder extends RecyclerView.ViewHolder { + private final Context ctx; private final View layout; private final TextView title; private final ImageButton delete; @@ -104,6 +67,7 @@ class RssFeedAdapter extends BriarAdapter { private FeedViewHolder(View v) { super(v); + ctx = v.getContext(); layout = v; title = v.findViewById(R.id.titleView); delete = v.findViewById(R.id.deleteButton); @@ -113,10 +77,44 @@ class RssFeedAdapter extends BriarAdapter { authorLabel = v.findViewById(R.id.author); description = v.findViewById(R.id.descriptionView); } + + private void bindItem(Feed item) { + // Feed Title + title.setText(item.getTitle()); + + // Delete Button + delete.setOnClickListener(v -> listener.onDeleteClick(item)); + + // Author + if (item.getRssAuthor() != null) { + author.setText(item.getRssAuthor()); + author.setVisibility(VISIBLE); + authorLabel.setVisibility(VISIBLE); + } else { + author.setVisibility(GONE); + authorLabel.setVisibility(GONE); + } + + // Imported and Last Updated + imported.setText(formatDate(ctx, item.getAdded())); + updated.setText(formatDate(ctx, item.getUpdated())); + + // Description + if (item.getDescription() != null) { + description.setText(item.getDescription()); + description.setVisibility(VISIBLE); + } else { + description.setVisibility(GONE); + } + + // Open feed's blog when clicked + layout.setOnClickListener(v -> listener.onFeedClick(item)); + } } interface RssFeedListener { void onFeedClick(Feed feed); + void onDeleteClick(Feed feed); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedDeleteFeedDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedDeleteFeedDialogFragment.java new file mode 100644 index 000000000..8fa06e113 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedDeleteFeedDialogFragment.java @@ -0,0 +1,64 @@ +package org.briarproject.briar.android.blog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.bramble.api.sync.GroupId; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.BaseActivity; + +import javax.inject.Inject; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; + +import static java.util.Objects.requireNonNull; +import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class RssFeedDeleteFeedDialogFragment extends DialogFragment { + final static String TAG = RssFeedDeleteFeedDialogFragment.class.getName(); + + @Inject + ViewModelProvider.Factory viewModelFactory; + private RssFeedViewModel viewModel; + + static RssFeedDeleteFeedDialogFragment newInstance(GroupId groupId) { + Bundle args = new Bundle(); + args.putByteArray(GROUP_ID, groupId.getBytes()); + RssFeedDeleteFeedDialogFragment f = + new RssFeedDeleteFeedDialogFragment(); + f.setArguments(args); + return f; + } + + @Override + public void onAttach(Context ctx) { + super.onAttach(ctx); + ((BaseActivity) requireActivity()).getActivityComponent().inject(this); + + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(RssFeedViewModel.class); + } + + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + GroupId groupId = new GroupId( + requireNonNull(requireArguments().getByteArray(GROUP_ID))); + AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity(), + R.style.BriarDialogTheme); + builder.setTitle(getString(R.string.blogs_rss_remove_feed)); + builder.setMessage( + getString(R.string.blogs_rss_remove_feed_dialog_message)); + builder.setPositiveButton(R.string.cancel, null); + builder.setNegativeButton(R.string.blogs_rss_remove_feed_ok, + (dialog, which) -> viewModel.removeFeed(groupId)); + return builder.create(); + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java deleted file mode 100644 index 08ac68ace..000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportActivity.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.briarproject.briar.android.blog; - -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ProgressBar; - -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.lifecycle.IoExecutor; -import org.briarproject.briar.R; -import org.briarproject.briar.android.activity.ActivityComponent; -import org.briarproject.briar.android.activity.BriarActivity; -import org.briarproject.briar.api.feed.FeedManager; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.concurrent.Executor; -import java.util.logging.Logger; - -import javax.annotation.Nullable; -import javax.inject.Inject; - -import androidx.appcompat.app.AlertDialog; - -import static android.view.View.GONE; -import static android.view.View.VISIBLE; -import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE; -import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.util.LogUtils.logException; -import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; - -public class RssFeedImportActivity extends BriarActivity { - - private static final Logger LOG = - Logger.getLogger(RssFeedImportActivity.class.getName()); - - private EditText urlInput; - private Button importButton; - private ProgressBar progressBar; - - @Inject - @IoExecutor - Executor ioExecutor; - - @Inject - @SuppressWarnings("WeakerAccess") - volatile FeedManager feedManager; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_rss_feed_import); - - urlInput = findViewById(R.id.urlInput); - urlInput.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - } - - @Override - public void afterTextChanged(Editable s) { - enableOrDisableImportButton(); - } - }); - urlInput.setOnEditorActionListener((v, actionId, event) -> { - if (actionId == IME_ACTION_DONE && importButton.isEnabled() && - importButton.getVisibility() == VISIBLE) { - publish(); - return true; - } - return false; - }); - - importButton = findViewById(R.id.importButton); - importButton.setOnClickListener(v -> publish()); - - progressBar = findViewById(R.id.progressBar); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } - - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); - } - - private void enableOrDisableImportButton() { - String url = urlInput.getText().toString(); - importButton.setEnabled(validateAndNormaliseUrl(url) != null); - } - - @Nullable - private String validateAndNormaliseUrl(String url) { - if (!Patterns.WEB_URL.matcher(url).matches()) return null; - try { - return new URL(url).toString(); - } catch (MalformedURLException e) { - return null; - } - } - - private void publish() { - // hide import button, show progress bar - importButton.setVisibility(GONE); - progressBar.setVisibility(VISIBLE); - hideSoftKeyboard(urlInput); - - String url = validateAndNormaliseUrl(urlInput.getText().toString()); - if (url == null) throw new AssertionError(); - importFeed(url); - } - - private void importFeed(String url) { - ioExecutor.execute(() -> { - try { - feedManager.addFeed(url); - feedImported(); - } catch (DbException | IOException e) { - logException(LOG, WARNING, e); - importFailed(); - } - }); - } - - private void feedImported() { - runOnUiThreadUnlessDestroyed(this::supportFinishAfterTransition); - } - - private void importFailed() { - runOnUiThreadUnlessDestroyed(() -> { - // hide progress bar, show publish button - progressBar.setVisibility(GONE); - importButton.setVisibility(VISIBLE); - - // show error dialog - AlertDialog.Builder builder = - new AlertDialog.Builder(RssFeedImportActivity.this, - R.style.BriarDialogTheme); - builder.setMessage(R.string.blogs_rss_feeds_import_error); - builder.setNegativeButton(R.string.cancel, null); - builder.setPositiveButton(R.string.try_again_button, - (dialog, which) -> publish()); - AlertDialog dialog = builder.create(); - dialog.show(); - }); - } - -} - diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFailedDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFailedDialogFragment.java new file mode 100644 index 000000000..ad1363adc --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFailedDialogFragment.java @@ -0,0 +1,53 @@ +package org.briarproject.briar.android.blog; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.BaseActivity; + +import javax.inject.Inject; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProvider; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class RssFeedImportFailedDialogFragment extends DialogFragment { + final static String TAG = RssFeedImportFailedDialogFragment.class.getName(); + + @Inject + ViewModelProvider.Factory viewModelFactory; + private RssFeedViewModel viewModel; + + static RssFeedImportFailedDialogFragment newInstance() { + return new RssFeedImportFailedDialogFragment(); + } + + @Override + public void onAttach(Context ctx) { + super.onAttach(ctx); + ((BaseActivity) requireActivity()).getActivityComponent().inject(this); + + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(RssFeedViewModel.class); + } + + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + AlertDialog.Builder builder = + new AlertDialog.Builder(requireActivity(), + R.style.BriarDialogTheme); + builder.setMessage(R.string.blogs_rss_feeds_import_error); + builder.setNegativeButton(R.string.cancel, null); + builder.setPositiveButton(R.string.try_again_button, + (dialog, which) -> viewModel.retryImportFeed()); + + return builder.create(); + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFragment.java new file mode 100644 index 000000000..96845f9bc --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedImportFragment.java @@ -0,0 +1,124 @@ +package org.briarproject.briar.android.blog; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ProgressBar; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +import androidx.lifecycle.ViewModelProvider; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; +import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE; +import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class RssFeedImportFragment extends BaseFragment { + public static final String TAG = RssFeedImportFragment.class.getName(); + + @Inject + ViewModelProvider.Factory viewModelFactory; + private RssFeedViewModel viewModel; + + private EditText urlInput; + private Button importButton; + private ProgressBar progressBar; + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(RssFeedViewModel.class); + } + + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import)); + View v = inflater.inflate(R.layout.fragment_rss_feed_import, + container, false); + + urlInput = v.findViewById(R.id.urlInput); + urlInput.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, + int count) { + } + + @Override + public void afterTextChanged(Editable s) { + enableOrDisableImportButton(); + } + }); + urlInput.setOnEditorActionListener((view, actionId, event) -> { + if (actionId == IME_ACTION_DONE && importButton.isEnabled() && + importButton.getVisibility() == VISIBLE) { + publish(); + return true; + } + return false; + }); + + importButton = v.findViewById(R.id.importButton); + importButton.setOnClickListener(view -> publish()); + + progressBar = v.findViewById(R.id.progressBar); + + viewModel.getIsImporting().observe(getViewLifecycleOwner(), + this::onIsImporting); + + return v; + } + + @Override + public String getUniqueTag() { + return TAG; + } + + private void enableOrDisableImportButton() { + String url = urlInput.getText().toString(); + importButton.setEnabled(viewModel.validateAndNormaliseUrl(url) != null); + } + + private void publish() { + String url = viewModel + .validateAndNormaliseUrl(urlInput.getText().toString()); + if (url == null) throw new AssertionError(); + viewModel.importFeed(url); + } + + private void onIsImporting(Boolean importing) { + if (importing) { + // show progress bar, hide import button + importButton.setVisibility(GONE); + progressBar.setVisibility(VISIBLE); + hideSoftKeyboard(urlInput); + } else { + // show publish button, hide progress bar + importButton.setVisibility(VISIBLE); + progressBar.setVisibility(GONE); + } + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java deleted file mode 100644 index 0f6819c37..000000000 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageActivity.java +++ /dev/null @@ -1,178 +0,0 @@ -package org.briarproject.briar.android.blog; - -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; - -import com.google.android.material.snackbar.Snackbar; - -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.briar.R; -import org.briarproject.briar.android.activity.ActivityComponent; -import org.briarproject.briar.android.activity.BriarActivity; -import org.briarproject.briar.android.blog.RssFeedAdapter.RssFeedListener; -import org.briarproject.briar.android.view.BriarRecyclerView; -import org.briarproject.briar.api.feed.Feed; -import org.briarproject.briar.api.feed.FeedManager; - -import java.util.List; -import java.util.logging.Logger; - -import javax.inject.Inject; - -import androidx.appcompat.app.AlertDialog; -import androidx.recyclerview.widget.LinearLayoutManager; - -import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; -import static com.google.android.material.snackbar.Snackbar.LENGTH_LONG; -import static java.util.logging.Level.WARNING; -import static org.briarproject.bramble.util.LogUtils.logException; - -public class RssFeedManageActivity extends BriarActivity - implements RssFeedListener { - - private static final Logger LOG = - Logger.getLogger(RssFeedManageActivity.class.getName()); - - private BriarRecyclerView list; - private RssFeedAdapter adapter; - - @Inject - @SuppressWarnings("WeakerAccess") - volatile FeedManager feedManager; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_rss_feed_manage); - - adapter = new RssFeedAdapter(this, this); - - list = findViewById(R.id.feedList); - list.setLayoutManager(new LinearLayoutManager(this)); - list.setAdapter(adapter); - } - - @Override - public void onStart() { - super.onStart(); - loadFeeds(); - } - - @Override - public void onStop() { - super.onStop(); - adapter.clear(); - list.showProgressBar(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.rss_feed_manage_actions, menu); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } else if (item.getItemId() == R.id.action_rss_feeds_import) { - Intent i = new Intent(this, RssFeedImportActivity.class); - startActivity(i); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public void injectActivity(ActivityComponent component) { - component.inject(this); - } - - @Override - public void onFeedClick(Feed feed) { - Intent i = new Intent(this, BlogActivity.class); - i.putExtra(GROUP_ID, feed.getBlogId().getBytes()); - i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); - startActivity(i); - } - - @Override - public void onDeleteClick(Feed feed) { - DialogInterface.OnClickListener okListener = - (dialog, which) -> deleteFeed(feed); - AlertDialog.Builder builder = new AlertDialog.Builder(this, - R.style.BriarDialogTheme); - builder.setTitle(getString(R.string.blogs_rss_remove_feed)); - builder.setMessage( - getString(R.string.blogs_rss_remove_feed_dialog_message)); - builder.setPositiveButton(R.string.cancel, null); - builder.setNegativeButton(R.string.blogs_rss_remove_feed_ok, - okListener); - builder.show(); - } - - private void loadFeeds() { - int revision = adapter.getRevision(); - runOnDbThread(() -> { - try { - displayFeeds(revision, feedManager.getFeeds()); - } catch (DbException e) { - logException(LOG, WARNING, e); - onLoadError(); - } - }); - } - - private void displayFeeds(int revision, List feeds) { - runOnUiThreadUnlessDestroyed(() -> { - if (revision == adapter.getRevision()) { - adapter.incrementRevision(); - if (feeds.isEmpty()) list.showData(); - else adapter.addAll(feeds); - } else { - LOG.info("Concurrent update, reloading"); - loadFeeds(); - } - }); - } - - private void deleteFeed(Feed feed) { - runOnDbThread(() -> { - try { - feedManager.removeFeed(feed); - onFeedDeleted(feed); - } catch (DbException e) { - logException(LOG, WARNING, e); - onDeleteError(); - } - }); - } - - private void onLoadError() { - runOnUiThreadUnlessDestroyed(() -> { - list.setEmptyText(R.string.blogs_rss_feeds_manage_error); - list.showData(); - }); - } - - private void onFeedDeleted(Feed feed) { - runOnUiThreadUnlessDestroyed(() -> { - adapter.incrementRevision(); - adapter.remove(feed); - }); - } - - private void onDeleteError() { - runOnUiThreadUnlessDestroyed(() -> Snackbar.make(list, - R.string.blogs_rss_feeds_manage_delete_error, - LENGTH_LONG).show()); - } -} - diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageFragment.java new file mode 100644 index 000000000..adf97443f --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedManageFragment.java @@ -0,0 +1,123 @@ +package org.briarproject.briar.android.blog; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; +import org.briarproject.briar.android.view.BriarRecyclerView; +import org.briarproject.briar.api.feed.Feed; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; + +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; +import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID; +import static org.briarproject.briar.android.blog.RssFeedAdapter.RssFeedListener; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class RssFeedManageFragment extends BaseFragment + implements RssFeedListener { + public static final String TAG = RssFeedManageFragment.class.getName(); + + @Inject + ViewModelProvider.Factory viewModelFactory; + private RssFeedViewModel viewModel; + + private BriarRecyclerView list; + private final RssFeedAdapter adapter = new RssFeedAdapter(this); + + public static RssFeedManageFragment newInstance() { + return new RssFeedManageFragment(); + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) + .get(RssFeedViewModel.class); + } + + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + requireActivity().setTitle(R.string.blogs_rss_feeds); + View v = inflater.inflate(R.layout.fragment_rss_feed_manage, + container, false); + + list = v.findViewById(R.id.feedList); + list.setLayoutManager(new LinearLayoutManager(getActivity())); + list.setAdapter(adapter); + + viewModel.getFeeds().observe(getViewLifecycleOwner(), result -> result + .onError(e -> { + list.setEmptyText(R.string.blogs_rss_feeds_manage_error); + list.showData(); + }) + .onSuccess(feeds -> { + adapter.submitList(feeds); + if (requireNonNull(feeds).size() == 0) { + list.showData(); + } + }) + ); + + return v; + } + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.rss_feed_manage_actions, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + requireActivity().onBackPressed(); + return true; + } else if (item.getItemId() == R.id.action_rss_feeds_import) { + showNextFragment(new RssFeedImportFragment()); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onFeedClick(Feed feed) { + Intent i = new Intent(getActivity(), BlogActivity.class); + i.putExtra(GROUP_ID, feed.getBlogId().getBytes()); + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + } + + @Override + public void onDeleteClick(Feed feed) { + RssFeedDeleteFeedDialogFragment dialog = + RssFeedDeleteFeedDialogFragment.newInstance(feed.getBlogId()); + dialog.show(getParentFragmentManager(), + RssFeedDeleteFeedDialogFragment.TAG); + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java new file mode 100644 index 000000000..6c0772685 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/RssFeedViewModel.java @@ -0,0 +1,180 @@ +package org.briarproject.briar.android.blog; + +import android.app.Application; +import android.util.Patterns; + +import org.briarproject.bramble.api.db.DatabaseExecutor; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.db.TransactionManager; +import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.sync.GroupId; +import org.briarproject.bramble.api.system.AndroidExecutor; +import org.briarproject.briar.android.viewmodel.DbViewModel; +import org.briarproject.briar.android.viewmodel.LiveEvent; +import org.briarproject.briar.android.viewmodel.LiveResult; +import org.briarproject.briar.android.viewmodel.MutableLiveEvent; +import org.briarproject.briar.api.feed.Feed; +import org.briarproject.briar.api.feed.FeedManager; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.logging.Logger; + +import javax.inject.Inject; + +import androidx.annotation.Nullable; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.LogUtils.logDuration; +import static org.briarproject.bramble.util.LogUtils.logException; +import static org.briarproject.bramble.util.LogUtils.now; +import static org.briarproject.briar.android.blog.RssFeedViewModel.ImportResult.EXISTS; +import static org.briarproject.briar.android.blog.RssFeedViewModel.ImportResult.FAILED; +import static org.briarproject.briar.android.blog.RssFeedViewModel.ImportResult.IMPORTED; + +@NotNullByDefault +class RssFeedViewModel extends DbViewModel { + enum ImportResult {IMPORTED, FAILED, EXISTS} + + private static final Logger LOG = + getLogger(RssFeedViewModel.class.getName()); + + private final FeedManager feedManager; + private final Executor ioExecutor; + private final Executor dbExecutor; + + private final MutableLiveData>> feeds = + new MutableLiveData<>(); + + @Nullable + private volatile String urlFailedImport = null; + private final MutableLiveData isImporting = + new MutableLiveData<>(false); + private final MutableLiveEvent importResult = + new MutableLiveEvent<>(); + + @Inject + RssFeedViewModel(Application app, + FeedManager feedManager, + @IoExecutor Executor ioExecutor, + @DatabaseExecutor Executor dbExecutor, + LifecycleManager lifecycleManager, + TransactionManager db, + AndroidExecutor androidExecutor) { + super(app, dbExecutor, lifecycleManager, db, androidExecutor); + this.feedManager = feedManager; + this.ioExecutor = ioExecutor; + this.dbExecutor = dbExecutor; + + loadFeeds(); + } + + @Nullable + String validateAndNormaliseUrl(String url) { + if (!Patterns.WEB_URL.matcher(url).matches()) return null; + try { + return new URL(url).toString(); + } catch (MalformedURLException e) { + return null; + } + } + + LiveData>> getFeeds() { + return feeds; + } + + private void loadFeeds() { + loadFromDb(this::loadFeeds, feeds::setValue); + } + + @DatabaseExecutor + private List loadFeeds(Transaction txn) throws DbException { + long start = now(); + List feeds = feedManager.getFeeds(txn); + Collections.sort(feeds); + logDuration(LOG, "Loading feeds", start); + return feeds; + } + + void removeFeed(GroupId groupId) { + dbExecutor.execute(() -> { + List updated = removeListItems(getList(feeds), feed -> { + if (feed.getBlogId().equals(groupId)) { + try { + feedManager.removeFeed(feed); + return true; + } catch (DbException e) { + handleException(e); + } + } + return false; + }); + if (updated != null) { + feeds.postValue(new LiveResult<>(updated)); + } + }); + } + + LiveEvent getImportResult() { + return importResult; + } + + LiveData getIsImporting() { + return isImporting; + } + + void importFeed(String url) { + isImporting.setValue(true); + urlFailedImport = null; + ioExecutor.execute(() -> { + try { + if (exists(url)) { + importResult.postEvent(EXISTS); + return; + } + Feed feed = feedManager.addFeed(url); + List updated = addListItem(getList(feeds), feed); + if (updated != null) { + Collections.sort(updated); + feeds.postValue(new LiveResult<>(updated)); + } + importResult.postEvent(IMPORTED); + } catch (DbException | IOException e) { + logException(LOG, WARNING, e); + urlFailedImport = url; + importResult.postEvent(FAILED); + } finally { + isImporting.postValue(false); + } + }); + } + + void retryImportFeed() { + if (urlFailedImport == null) { + throw new AssertionError(); + } + importFeed(urlFailedImport); + } + + private boolean exists(String url) { + List list = getList(feeds); + if (list != null) { + for (Feed feed : list) { + if (url.equals(feed.getUrl())) { + return true; + } + } + } + return false; + } +} diff --git a/briar-android/src/main/res/layout/activity_rss_feed_import.xml b/briar-android/src/main/res/layout/fragment_rss_feed_import.xml similarity index 94% rename from briar-android/src/main/res/layout/activity_rss_feed_import.xml rename to briar-android/src/main/res/layout/fragment_rss_feed_import.xml index 725c991b2..9ee118e4d 100644 --- a/briar-android/src/main/res/layout/activity_rss_feed_import.xml +++ b/briar-android/src/main/res/layout/fragment_rss_feed_import.xml @@ -5,8 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:padding="@dimen/margin_medium" - tools:context=".android.blog.RssFeedImportActivity"> + android:padding="@dimen/margin_medium"> + diff --git a/briar-android/src/main/res/menu/blogs_feed_actions.xml b/briar-android/src/main/res/menu/blogs_feed_actions.xml index 22cf36961..5daa3f73b 100644 --- a/briar-android/src/main/res/menu/blogs_feed_actions.xml +++ b/briar-android/src/main/res/menu/blogs_feed_actions.xml @@ -10,13 +10,8 @@ app:showAsAction="always"/> - - \ No newline at end of file diff --git a/briar-android/src/main/res/values-ar/strings.xml b/briar-android/src/main/res/values-ar/strings.xml index 08562cc75..84bc65e6a 100644 --- a/briar-android/src/main/res/values-ar/strings.xml +++ b/briar-android/src/main/res/values-ar/strings.xml @@ -461,14 +461,12 @@ إستيراد ادخال رابط تحديثات RSS معذرة! حدث خطأ في استيراد التحديثات. - إدارة تحديثات RSS تم استيراد: المؤلف/ة: آخر تحديث: ازالة الخلاصة هل أنت متأكد/ة من رغبتك في حذف هذه الخلاصة؟\n\nالمنشورات ستحذف من جهازك وليس من أجهزة الآخرين.\n\nأي جهة اتصال قمت/ي بمشاركة هذه الخلاصة معها قد لا تتمكن من استلام التحديثات. حذف - لا يمكن حذف الخلاصة! لا خلاصات RSS للعرض\n\nالرجاء لمس علامة + لإستيراد خلاصة. حدث خطأ في جلب خلاصاتك. الرجاء المحاولة لاحقًا. diff --git a/briar-android/src/main/res/values-az/strings.xml b/briar-android/src/main/res/values-az/strings.xml index 7d98403dd..435e92c09 100644 --- a/briar-android/src/main/res/values-az/strings.xml +++ b/briar-android/src/main/res/values-az/strings.xml @@ -348,13 +348,11 @@ İdxal RSS kanalın linkini daxil edin Üzr istəyirik! Feed-inizdə idxal bir xəta baş verdi. - RSS Feeds idarəetmə İdxal olundu: Müəllif: Son yeniləmə: Feed\'i sil Sil - Feed silinmədi Xeyr RSS əks etdirmir\n\nİdxal etmək üçün + düyməsinə toxunun Kanal yükləmədə bir problem var. Zəhmət olmasa bir az sonra yenə cəhd edin. diff --git a/briar-android/src/main/res/values-bg/strings.xml b/briar-android/src/main/res/values-bg/strings.xml index 5a815155f..a69357e29 100644 --- a/briar-android/src/main/res/values-bg/strings.xml +++ b/briar-android/src/main/res/values-bg/strings.xml @@ -238,13 +238,11 @@ Внасяне Въведете URL адреса на RSS емисията Възникна грешка при внасянето на емисия. - Управление на RSS емисии Внесена: Автор: Последно актуализиране: Премахване на емисия Премахване - Емисията не можа да бъде изтрита! Възникна проблем при зареждането на емисиите ви. Моля, опитайте пак по-късно. diff --git a/briar-android/src/main/res/values-bs/strings.xml b/briar-android/src/main/res/values-bs/strings.xml index 10a43b106..336a6c1be 100644 --- a/briar-android/src/main/res/values-bs/strings.xml +++ b/briar-android/src/main/res/values-bs/strings.xml @@ -332,14 +332,12 @@ Uvezi Unesi URL od RSS kanala Žao nam je! Došlo je do greške pri unosu vašeg kanala. - Upravljanje RSS kanalima Uvezeno: Autor: Zadnje ažuriranje: Uklonite kanal Jeste li sigurni da želite da uklonite kanal?\n\nPostovi će biti uklonjeni sa vašeg uređaja ali ne is uređaja drugih ljudi.\n\nKontakti kojima ste podijelili ovaj blog će možda prestati da dobijaju novosti. Ukloni - Kanal nije bilo moguće ukloniti! Nema RSS kanala za prikazivanje\n\nDotaknite + ikonu da uvezete kanal Došlo je do problema pri učitavanju vaših kanala. Probajte opet kasnije. diff --git a/briar-android/src/main/res/values-ca/strings.xml b/briar-android/src/main/res/values-ca/strings.xml index be6a52432..9e0f08986 100644 --- a/briar-android/src/main/res/values-ca/strings.xml +++ b/briar-android/src/main/res/values-ca/strings.xml @@ -421,14 +421,12 @@ Així que l\'actualitzi li veureu una icona diferent . Subscriu-me Escriviu l\'URL del canal de notícies RSS Ens sap greu! S\'ha produït un error en subscriure-us al vostre canal de notícies. - Gestiona els canals de notícies RSS Importat: Autor: Darrera actualització: Suprimeix la subscripció al canal de notícies Segur que voleu suprimir la subscripció a aquest canal de notícies?\n\nLes notícies d\'aquest canal s\'eliminaran del vostre dispositiu però no del d\'altres persones.\n\nEls contactes amb els que hàgeu compartit aquest canal poden deixar de rebre les actualitzacions. Suprimeix la subscripció - La subscripció al canal de notícies no s\'ha pogut suprimir. No hi ha cap notícia per mostrar\n\nFeu un toc sobre la icona + per subscriure-us a un canal de notícies S\'ha produït un problema en actualitzar els vostres canals de notícies. Torneu-ho a provar més endavant. diff --git a/briar-android/src/main/res/values-cs/strings.xml b/briar-android/src/main/res/values-cs/strings.xml index 73610748a..d40259c2d 100644 --- a/briar-android/src/main/res/values-cs/strings.xml +++ b/briar-android/src/main/res/values-cs/strings.xml @@ -302,13 +302,11 @@ Import Zadejte URL adresu RSS kanálu Omlouváme se! Vyskytla se chyba při importu vašeho kanálu. - Správa RSS kanálů Importováno: Autor: Naposledy aktualizováno: Odstranit kanál Odstranit - Kanál nemohl být odstraněn ! Žádné RSS kanály k zobrazení\n\nKlikněte na ikonu + pro nahrání příspěvků Vyskytl se problém s načtením vašeho kanálu příspěvků. Zkuste to prosím později. diff --git a/briar-android/src/main/res/values-de/strings.xml b/briar-android/src/main/res/values-de/strings.xml index 0d014c9e8..c418224b2 100644 --- a/briar-android/src/main/res/values-de/strings.xml +++ b/briar-android/src/main/res/values-de/strings.xml @@ -457,14 +457,12 @@ Importieren URL des RSS-Feeds eingeben Es tut uns Leid! Es gab einen Fehler beim Importieren deines Feeds. - RSS-Feeds verwalten Importiert: Autor: Letzte Aktualisierung: Feed entfernen Bist du sicher, dass du diesen Feed löschen willst?\n\nBeiträge werden von deinem Gerät entfernt, aber nicht von den Geräten anderer Personen.\n\nAlle Kontakte, für die du diesen Feed freigegeben hast, können keine Updates mehr erhalten. Aufheben - Der Feed konnte nicht gelöscht werden! Keine RSS-Feeds vorhanden\n\nTippe auf das + Symbol, um einen Feed zu importieren Es gab ein Problem beim Laden deiner Feeds. Bitte versuche es später erneut. diff --git a/briar-android/src/main/res/values-es/strings.xml b/briar-android/src/main/res/values-es/strings.xml index f6a6f7bdd..864613ef5 100644 --- a/briar-android/src/main/res/values-es/strings.xml +++ b/briar-android/src/main/res/values-es/strings.xml @@ -457,14 +457,12 @@ Importar Introduce la URL del canal RSS ¡Lo sentimos! Hubo un error importando tu canal. - Administrar canales RSS Importado: Autor: Última actualización: Eliminar canal RSS ¿Estás seguro de que quieres quitar este canal RSS?\n\nLos mensajes se eliminarán de tu dispositivo, pero no de los dispositivos de otras personas.\n\nEs posible que los contactos con los que hayas compartido este canal dejen de recibir actualizaciones. Eliminar - ¡El canal no pudo ser eliminado! No hay canales RSS que mostrar\n\nGolpea el icono + para importar uno Hubo un problema cargando tus canales RSS. Por favor, prueba más tarde. diff --git a/briar-android/src/main/res/values-eu/strings.xml b/briar-android/src/main/res/values-eu/strings.xml index f317cdd4f..f270f40e9 100644 --- a/briar-android/src/main/res/values-eu/strings.xml +++ b/briar-android/src/main/res/values-eu/strings.xml @@ -395,14 +395,12 @@ Inportatu Sartu RSS jarioaren URLa Sentitzen dugu! Zure jarioa inportatzean errore bat gertatu da. - Kudeatu RSS jarioak Inportatuta: Egilea: Azken eguneratzea: Kendu jarioa Ziur zaude jario hau kendu nahi duzula?\n\nSarrerak zure gailutik kenduko dira baina ez besteen gailuetatik.\n\nJario hau beste inorekin partekatu baduzu agian eguneratzeak jasotzeari utziko diote. Kendu - Ezin izan da jarioa ezabatu! Ez dago erakusteko RSS jariorik\n\nSakatu + ikonoa jario bat inportatzeko Arazo bat egon da zure jarioak kargatzean. Saiatu berriro geroago. diff --git a/briar-android/src/main/res/values-fa/strings.xml b/briar-android/src/main/res/values-fa/strings.xml index 454d7ee5d..1ce2d7226 100644 --- a/briar-android/src/main/res/values-fa/strings.xml +++ b/briar-android/src/main/res/values-fa/strings.xml @@ -488,7 +488,6 @@ وارد کردن آدرس خوراک RSS را وارد کنید متاسفیم! وارد کردن خوراک شما با خطا مواجه شده است. - مدیریت خوراک های RSS وارد شده: نویسنده: آخرین به روز رسانی: @@ -499,7 +498,6 @@ هر مخاطبی که با آن این خوراک را به اشتراک گذاشته اید ممکن است دیگر آپدیت دریافت نکند. حذف - خوراک نمی تواند پاک شود! هیچ خوراک RSS برای نمایش وجود ندارد برای وارد کردن خوراک روی آیکون + ضربه بزنید diff --git a/briar-android/src/main/res/values-fi/strings.xml b/briar-android/src/main/res/values-fi/strings.xml index 0a5b356aa..7b064f02c 100644 --- a/briar-android/src/main/res/values-fi/strings.xml +++ b/briar-android/src/main/res/values-fi/strings.xml @@ -314,14 +314,12 @@ Tuo Syötä RSS syötteen URL osoite Pahoittelemme! Syötteen noutamisessa tapahtui virhe. - Muokkaa RSS syötteitä Tuotu: Tekijä: Viimeksi päivitetty: Poista syöte Oletko varma, että haluat poistaa tämän syötteen?\n\nKirjoitukset poistuvat sinun laitteelta, mutta ei muiden laitteilta.\n\nKäyttäjät joiden kanssa olet jakanut tämän syötteen eivät välttämättä saa uusia päivityksiä. Poista - Syötteen poistaminen epäonnistui! Ei RSS syötteitä\n\nNapauta + nappia lisätäksesi syötteen Syötteiden lataamisessa tapahtui virhe. Yritä myöhemmin uudelleen. diff --git a/briar-android/src/main/res/values-fr/strings.xml b/briar-android/src/main/res/values-fr/strings.xml index 9681398dc..20390c653 100644 --- a/briar-android/src/main/res/values-fr/strings.xml +++ b/briar-android/src/main/res/values-fr/strings.xml @@ -453,14 +453,12 @@ Importer Saisir l’URL du fil RSS Nous sommes désolés ! Une erreur est survenue lors de l’importation de votre fil. - Gérer les fils RSS Importés : Auteur : Dernière mise à jour : Supprimer le fil Voulez-vous vraiment supprimer ce fil ?\nLes billets seront supprimés de votre appareil mais pas des appareils d’autrui.\n\nLes contacts avec qui vous avez partagé ce fil pourraient ne plus en recevoir les mises à jour. Supprimer - Impossible de supprimer le fil ! Aucun fil RSS à afficher\n\nTouchez l’icône + pour importer un fil Un problème est survenu lors du chargement de vos fils. Veuillez réessayer plus tard. diff --git a/briar-android/src/main/res/values-gl/strings.xml b/briar-android/src/main/res/values-gl/strings.xml index 5aedba8cd..25d48dcc4 100644 --- a/briar-android/src/main/res/values-gl/strings.xml +++ b/briar-android/src/main/res/values-gl/strings.xml @@ -454,14 +454,12 @@ Importar Escribe o URL da fonte RSS Lamentámolo! Algo fallou ao importar a fonte. - Xestionar Fontes RSS Importado: Autor/a: Última actualización: Eliminar fonte Tes a certeza de querer eliminar esta fonte?\n\nAs entradas eliminaranse do teu dispositivo pero non dos dispositivos doutras persoas\n\nTodas as persoas coas que compartiches esta fonte poderían deixar de recibir actualizacións. Eliminar - Non se puido eliminar a fonte! Sen fontes RSS que mostrar\n\nToque na icona + para importar unha fonte Aconteceu un problema ao cargar as túas fontes. Por favor, inténtao máis tarde. diff --git a/briar-android/src/main/res/values-he/strings.xml b/briar-android/src/main/res/values-he/strings.xml index eda80446a..a99bb958f 100644 --- a/briar-android/src/main/res/values-he/strings.xml +++ b/briar-android/src/main/res/values-he/strings.xml @@ -444,14 +444,12 @@ ייבא הכנס את כתובת האתר של הזנת ה־RSS אנחנו מצטערים! הייתה שגיאה ביבוא ההזנה שלך. - נהל הזנות RSS מיובא: מחבר: עודכן לאחרונה: הסר הזנה האם אכן ברצונך להסיר הזנה זו?\n\nרשומות יוסרו ממכשירך אבל לא ממכשירים של אנשים אחרים.\n\nאנשי קשר כלשהם ששיתפת איתם הזנה זו עלולים להפסיק לקבל עדכונים. הסר - ההזנה לא יכלה להימחק! אין הזנות RSS להראות\n\nהקש על הצלמית + כדי לייבא הזנה הייתה בעיה בטעינת ההזנות שלך. אנא נסה שוב מאוחר יותר. diff --git a/briar-android/src/main/res/values-hi/strings.xml b/briar-android/src/main/res/values-hi/strings.xml index 6c4ca9f11..5b1b8ad14 100644 --- a/briar-android/src/main/res/values-hi/strings.xml +++ b/briar-android/src/main/res/values-hi/strings.xml @@ -378,14 +378,12 @@ आयात आरएसएस फ़ीड का यूआरएल दर्ज करें हमें खेद है! आपकी फ़ीड आयात करने में एक त्रुटि हुई - आरएसएस फ़ीड प्रबंधित करें आयातित: लेखक: आखरी अपडेट: फ़ीड निकालें क्या आप वाकई इस फीड को हटाना चाहते हैं? \ N \ n पोस्ट आपके डिवाइस से हटा दिए जाएंगे, लेकिन अन्य लोगों के डिवाइस से नहीं। \ N \ n आपके द्वारा इस फ़ीड को साझा करने वाले किसी भी संपर्क को अपडेट प्राप्त करना बंद हो सकता है। हटाना - फीड हटाया नहीं जा सका! कोई आरएसएस फ़ीड दिखाने के लिए फ़ीड नहीं करता \ n \ n फ़ीड आयात करने के लिए + आइकन टैप करें आपकी फ़ीड लोड करने में एक समस्या थी बाद में पुन: प्रयास करें। diff --git a/briar-android/src/main/res/values-hu/strings.xml b/briar-android/src/main/res/values-hu/strings.xml index a74869f38..097282e14 100644 --- a/briar-android/src/main/res/values-hu/strings.xml +++ b/briar-android/src/main/res/values-hu/strings.xml @@ -461,7 +461,6 @@ Kapcsolatai, akivel megosztotta ezt a blogot, lehet nem kapnak többé frissít Importálás Adja meg az RSS feed URL címét Elnézését kérjük! Probléma akadt a feed-je importálásával. - RSS feed-ek kezelés Importálva: Szerző: Utolsó frissítés: @@ -469,7 +468,6 @@ Kapcsolatai, akivel megosztotta ezt a blogot, lehet nem kapnak többé frissít Biztosan eltávolítja ezt a feed-et? \n\nA bejegyzések törlődni fognak az Ön eszközéről, de nem a többi ember eszközéről.\n\nKapcsolatai, akivel megosztotta ezt a feed-et, lehet nem kapnak többé frissítést. Eltávolít - A feed nem törölhető! Nincs megjelenítendő Hiba történt a feed-jei betöltésével. Kérjük próbálja újra később. diff --git a/briar-android/src/main/res/values-is/strings.xml b/briar-android/src/main/res/values-is/strings.xml index a59787bd7..8e4f37f47 100644 --- a/briar-android/src/main/res/values-is/strings.xml +++ b/briar-android/src/main/res/values-is/strings.xml @@ -454,14 +454,12 @@ Flytja inn Settu inn slóðina á RSS-streymið Því miður! Það kom upp villa við að flytja inn streymið. - Sýsla með RSS-streymi Flutt inn: Höfundur: Síðast uppfært: Fjarlægja streymi Ertu viss um að þú viljir fjarlægja þetta streymi?\n\nFærslur verða fjarlægðar af tækinu þínu en ekki tækjum annars fólks.\n\nAllir tengiliðir sem þú hefur deilt þessu streymi með gætu hætt að fá uppfærslur. Fjarlægja - Ekki var hægt að eyða streyminu! Engin RSS-streymi til að birta\n\nÝttu á + táknið til að flytja inn streymi Vandamál hefur komið upp með að hlaða inn streymunum þínum. Reyndu aftur síðar. diff --git a/briar-android/src/main/res/values-it/strings.xml b/briar-android/src/main/res/values-it/strings.xml index dd6a47308..13500bdfa 100644 --- a/briar-android/src/main/res/values-it/strings.xml +++ b/briar-android/src/main/res/values-it/strings.xml @@ -420,14 +420,12 @@ Importa Inserire l\'URL dell\'RSS feed Ci dispiace! C\'è stato un errore nell\'importazione del tuo feed. - Gestisci gli RSS Feed Importato: Autore: Ultimo Aggiornamento: Rimuovi feed Sei sicuro di voler rimuovere questo feed?\n\nI post saranno rimossi dal tuo dispositivo ma non dai dispositivi delle altre persone.\n\nTutti i contatti con cui hai condiviso questo feed potrebbero smettere di ricevere aggiornamenti. Rimuovi - Non è stato possibile cancellare il feed! Nessun feed RSS da mostrare\n\nClicca l\'icona + per importare un feed C\'è stato un problema nel caricare i tuoi feeds. Per favore riprova fra poco. diff --git a/briar-android/src/main/res/values-ja/strings.xml b/briar-android/src/main/res/values-ja/strings.xml index cba15adcd..3e5cd347c 100644 --- a/briar-android/src/main/res/values-ja/strings.xml +++ b/briar-android/src/main/res/values-ja/strings.xml @@ -369,14 +369,12 @@ インポート RSSフィードのURLを入力してください 申し訳ありません! フィードのインポート中にエラーが発生しました。 - RSSフィードを管理 インポート済み: 著者: 最終更新: フィードを削除 このフィードを削除してもよろしいですか?\n\n投稿はデバイスから削除されますが、他の人のデバイスからは削除されません。\n\nこのフィードを共有した人は更新の受信を停止されます。 解除 - フィードを削除できませんでした! 表示するRSSフィードはありません\n\n「+」アイコンをタップしてフィードをインポートします フィードの読み込み中に問題が発生しました。 後でもう一度やり直してください。 diff --git a/briar-android/src/main/res/values-ko/strings.xml b/briar-android/src/main/res/values-ko/strings.xml index 29800e59d..d8e111d14 100644 --- a/briar-android/src/main/res/values-ko/strings.xml +++ b/briar-android/src/main/res/values-ko/strings.xml @@ -410,14 +410,12 @@ 가져오기 RSS 피드 URL을 입력하세요 죄송합니다! 피드를 불러오는 과정에서 문제가 있었습니다. - RSS 피드 관리하기 다음을 불러왔습니다: 작성자: 최종 업데이트: 피드 제거하기 정말로 이 피드를 제거하시겠어요?\n\n기기에서 게시물은 제거되지만 다른 사람의 기기에서는 제거되지 않습니다.\n\n이 피드를 공유하던 지인이 업데이트를 받지 못하게 될 수 있습니다. 제거하기 - 피드를 삭제할 수 없었습니다! 보여드릴 RSS 피드가 없습니다\n\n+ 상징을 눌러 피드를 불러오세요 피드를 불러오는 과정에서 문제가 있었습니다. 나중에 다시 시도해 주세요. diff --git a/briar-android/src/main/res/values-lt/strings.xml b/briar-android/src/main/res/values-lt/strings.xml index 2a80a7f27..bf2041ca7 100644 --- a/briar-android/src/main/res/values-lt/strings.xml +++ b/briar-android/src/main/res/values-lt/strings.xml @@ -481,14 +481,12 @@ Importuoti Įveskite RSS kanalo URL Atleiskite! Importuojant jūsų kanalą, įvyko klaida. - Tvarkyti RSS kanalus Importuota: Autorius: Paskutinį kartą atnaujinta: Šalinti kanalą Ar tikrai norite pašalinti šį kanalą?\n\nĮrašai bus pašalinti iš jūsų įrenginio, tačiau liks kitų žmonių įrenginiuose.\n\nBet kokie adresatai, su kuriais bendrinote šį kanalą, gali nustoti gauti atnaujinimus. Šalinti - Nepavyko ištrinti kanalo! Nėra rodytinų RSS kanalų\n\nNorėdami importuoti kanalą, bakstelėkite + piktogramą Įkeliant jūsų kanalus, atsirado problemų. Vėliau bandykite dar kartą. diff --git a/briar-android/src/main/res/values-mk/strings.xml b/briar-android/src/main/res/values-mk/strings.xml index d5cbdce32..964e1aa6f 100644 --- a/briar-android/src/main/res/values-mk/strings.xml +++ b/briar-android/src/main/res/values-mk/strings.xml @@ -419,14 +419,12 @@ Увези Внеси URL на RSS тековник Жал ни е! Настана гршка при увезувањето на вашиот тековник. - Уредување на RSS тековници Увезени: Автор: Последен пат ажуриран: Отстрани тековник Дали сте сигурни дека сакате да го отстраните овој тековник?\n\nОбјавите ќе бидат отстранети од вашиот уред но не и од уредите на другите луѓе.\n\nБило кои од контактите со кои сте го споделиле овој тековник може да престанат да добиваат ажурирања. Отстрани - Тековникот не може да биде избришан! Нема RSS тековници за прикажување\n\nДопрете ја + иконата за да увезете тековник Настана проблем при вчитувањето на вашите тековници. Ве молиме обидете се повторно подоцна. diff --git a/briar-android/src/main/res/values-nb/strings.xml b/briar-android/src/main/res/values-nb/strings.xml index f0e4c10cb..5a4325a65 100644 --- a/briar-android/src/main/res/values-nb/strings.xml +++ b/briar-android/src/main/res/values-nb/strings.xml @@ -259,13 +259,11 @@ Importer Skriv inn nettadresse for RSS-strøm Vi beklager! Feil under importering av strøm. - Behandle RSS-strømmer Importert: Forfatter: Sist oppdatert: Fjern strøm Fjern - Strømmen kunne ikke fjernes! Feil ved lasting av dine strømmer. Prøv igjen senere. Vis diff --git a/briar-android/src/main/res/values-nl/strings.xml b/briar-android/src/main/res/values-nl/strings.xml index 131fb8f04..2b5ab0bdb 100644 --- a/briar-android/src/main/res/values-nl/strings.xml +++ b/briar-android/src/main/res/values-nl/strings.xml @@ -420,14 +420,12 @@ Importeer Voer de URL van de RSS-feed in Excuses! Er trad een fout op bij het importeren van je feed. - Beheer RSS-feeds Geïmporteerd: Auteur: Laatst bijgewerkt: Verwijder feed Weet je zeker dat je deze feed wil verwijderen?\n\nPosts zullen van je apparaat worden verwijderd maar niet van apparaten van andere mensen.\n\nContacten met wie je deze feed hebt gedeeld zullen geen updates meer ontvangen. Verwijderen - De feed kon niet worden verwijderd. Geen RSS-feeds om te tonen\n\nTik op het +-icoon om een feed te importeren Er was een probleem met het laden van je feeds. Probeer het alsjeblieft later nog een keer. diff --git a/briar-android/src/main/res/values-oc/strings.xml b/briar-android/src/main/res/values-oc/strings.xml index d1a716a4a..d31757476 100644 --- a/briar-android/src/main/res/values-oc/strings.xml +++ b/briar-android/src/main/res/values-oc/strings.xml @@ -392,7 +392,6 @@ Volètz suprimir vòstre compte e ne crear un nòu ?\n Importar Marcar l’URL del flux RSS Una error s’es produisida en importar lo flux - Gerir lo flux RSS Importat : Autor : Darrièra mesa a jorn : @@ -402,7 +401,6 @@ levadas de vòstre aparelh mas pas dels aparelhs del monde.\n\nTotes los contactes qu’avètz partejat aqueste flux quitaràn benlèu de recebre las mesas a jorn. Suprimir - Impossible de suprimir lo flux ! Cap de flux RSS de far veire.\n\nTocatz l’icòna + per n’importar un Error en cargar vòstres fluxes. Ensajatz mai tard. diff --git a/briar-android/src/main/res/values-pl/strings.xml b/briar-android/src/main/res/values-pl/strings.xml index ac82e1218..e4f71af31 100644 --- a/briar-android/src/main/res/values-pl/strings.xml +++ b/briar-android/src/main/res/values-pl/strings.xml @@ -400,14 +400,12 @@ Zaimportuj Wprowadź adres URL do kanału RSS Przepraszamy! Wystąpił błąd podczas importowania twojego kanału RSS - Zarządzaj kanałami RSS Zaimportowane: Autor: Ostatnio Zaktualizowane: Usuń kanał RSS Jesteś pewny, że chcesz usunąć ten kanał RSS?\n\nPosty będą usunięte z Twojego urządzenia, ale nie z urządzeń innych ludzi.\n\nWszystkie kontakty którym udostępniłeś ten kanał mogą przestać otrzymywać jego uaktualnienia Usuń - Kanał nie mógł zostać usunięty! Brak RSS do wyświetlenia\n\nDotknij ikonki + aby zaimportować kanał. Wystąpił problem podczas ładowania twoich kanałów RSS. Proszę spróbować ponownie później. diff --git a/briar-android/src/main/res/values-pt-rBR/strings.xml b/briar-android/src/main/res/values-pt-rBR/strings.xml index 562d714e4..0e0539129 100644 --- a/briar-android/src/main/res/values-pt-rBR/strings.xml +++ b/briar-android/src/main/res/values-pt-rBR/strings.xml @@ -420,14 +420,12 @@ Importar Entre a URL do feed RSS Nós lamentamos! Houve um erro ao importar seu Feed. - Gerenciar Feeds RSS Importado: Autor: Última Atualização: Remover Feed Você tem certeza que deseja remover este feed?\n\nOs posts serão removidos do seus dispositivo mas não dos dispositivos de outras pessoas.\n\nContatos com quem você tenha compartilhado este feed vão parar de receber atualizações dele. Remover - O Feed não pode ser deletado! Nenhum feed RSS para ser exibido\n\nPressione o ícone + para importar um feed Houve um problema ao carregar seus Feeds. Por favor tente novamente. diff --git a/briar-android/src/main/res/values-ro/strings.xml b/briar-android/src/main/res/values-ro/strings.xml index 0e56c945e..5c6f1a45e 100644 --- a/briar-android/src/main/res/values-ro/strings.xml +++ b/briar-android/src/main/res/values-ro/strings.xml @@ -445,14 +445,12 @@ Importă Introduceți URL-ul fluxului RSS Ne pare rău! A apărut o eroare la importul fluxului dumneavoastră. - Administrare fluxuri RSS Importat: Autor: Actualizat ultima dată: Șterge flux Sunteți siguri că doriți să eliminați acest flux?\n\nMesajele vor fi eliminate de pe dispozitiv, dar nu și de pe dispozitivele altor persoane.\n\nOrice persoană de contact către care ați distribuit acest flux s-ar putea sa nu mai primească actualizări. Eliminare - Fluxul nu a putut fi șters! Nici un flux RSS de arătat\n\nAtingeți iconița + pentru a adăuga un flux A apărut o eroare la încărcarea fluxurilor dumneavoastră. Vă rugăm să încercați din nou mai târziu. diff --git a/briar-android/src/main/res/values-ru/strings.xml b/briar-android/src/main/res/values-ru/strings.xml index da557b24d..bd0707b46 100644 --- a/briar-android/src/main/res/values-ru/strings.xml +++ b/briar-android/src/main/res/values-ru/strings.xml @@ -476,14 +476,12 @@ Импорт Введите URL-адрес RSS-ленты Мы сожалеем! Произошла ошибка при импорте ленты. - Управление RSS-лентами Импортирован: Автор: Последнее обновление: Удалить RSS-ленту Вы уверены, что хотите удалить эту ленту?\n\nПосты будут удалены только с вашего устройства.\n\nВсе контакты, с которыми вы поделились этой лентой, могут перестать получать обновления. Удалить - Не удалось удалить ленту! Нет RSS-лент для отображения\n\nКоснитесь значка + для импорта ленты Ошибка при загрузке вашей ленты. Повторите попытку позже. diff --git a/briar-android/src/main/res/values-sq/strings.xml b/briar-android/src/main/res/values-sq/strings.xml index 618b314cb..6252bc96e 100644 --- a/briar-android/src/main/res/values-sq/strings.xml +++ b/briar-android/src/main/res/values-sq/strings.xml @@ -457,14 +457,12 @@ Importo Jepni URL-në e prurjes RSS Na ndjeni! Pati një gabim me importimin e prurjes tuaj. - Administroni Prurje RSS Të importuara: Autor: Përditësuar Së Fundi: Hiqe Prurjen Jeni i sigurt se doni të hiqet kjo prurje?\n\nPostimet do të hiqen nga pajisja juaj, por jo nga pajisjet e personave të tjerë.\n\nÇfarëdo kontaktesh me të cilët e keni ndarë këtë prurje mund të reshtin së marri përditësime. Hiqe - S\’u fshi dot prurja! S’ka prurje RSS për shfaqje\n\nPrekni ikonën + që të importohet një prurje Pati një problem me ngarkimin e prurjeve tuaja. Ju lutemi, riprovoni më vonë. diff --git a/briar-android/src/main/res/values-sr/strings.xml b/briar-android/src/main/res/values-sr/strings.xml index b4c9ade7c..4889c4717 100644 --- a/briar-android/src/main/res/values-sr/strings.xml +++ b/briar-android/src/main/res/values-sr/strings.xml @@ -340,7 +340,6 @@ Kontakti kojima ste podijelili ovaj blog će možda prestati da dobijaju novosti Uvezi Unesi URL od RSS kanala Žao nam je! Došlo je do greške pri unosu vašeg kanala. - Rukujte RSS kanalima Uvezeno: Autor: Zadnje ažuriranje: @@ -351,7 +350,6 @@ Postovi će biti uklonjeni sa vašeg uređaja ali ne is uređaja drugih ljudi. Kontakti kojima ste podijelili ovaj blog će možda prestati da dobijaju novosti. Ukloni - Kanal nije bilo moguće ukloniti! Nema RSS kanala za prikazivanje Dotaknite + ikonu da uvezete kanal diff --git a/briar-android/src/main/res/values-sv/strings.xml b/briar-android/src/main/res/values-sv/strings.xml index 00f548e40..f926de390 100644 --- a/briar-android/src/main/res/values-sv/strings.xml +++ b/briar-android/src/main/res/values-sv/strings.xml @@ -420,14 +420,12 @@ Importera Skriv URL till RSS-flödet Tyvärr! Något gick fel när flödet skulle importeras. - Hantera RSS-flöden Importerade: Författare: Senast uppdaterad: Ta bort flöde Är du säker på att du vill ta bort det här flödet?\n\nInlägg kommer att tas bort från din enhet, men inte från andras.\n\nKontakter som du har delat det här flödet med kommer kanske inte längre få uppdateringar från det. &Ta bort - Flödet kunde ej tas bort! Inga RSS-flöden\n\nTryck plus-ikonen (+) för att importera ett flöde Något gick fel när dina flöden skulle laddas. Försök ingen senare. diff --git a/briar-android/src/main/res/values-sw/strings.xml b/briar-android/src/main/res/values-sw/strings.xml index 13d48c5a4..c85bda548 100644 --- a/briar-android/src/main/res/values-sw/strings.xml +++ b/briar-android/src/main/res/values-sw/strings.xml @@ -400,7 +400,6 @@ Umepoteza nenosiri. Ingiza Ingiza URL za RSS taarifa Samahani! Kulikuwa na hitilafu wakati wakuingiza taarifa - Simamia taarifa za RSS Zilizoingizwa Mwandishi: huwisho la mwisho @@ -408,7 +407,6 @@ Umepoteza nenosiri. Ondoa taarifa Unauhakika unataka kutoa hii taarifa?\n\nChapisho lako litaondolewa kwenye kifaa chako ila sio kwenye vifaa vya watu wengine.\n\nMawasiliano yoyote utliokwisha kuyaunganisha wanaweza wasiendelea kupata taarifa. Ondoa - Taharifa haziwezekani kuzifuta! Hakuna RSS taharifa zaku onyesha\n\nBonyeza + ikoni kuleta taharifa Kulikuwa na tatizo la kufungua taharifa . Tafathali jaribu baadae kidogo. diff --git a/briar-android/src/main/res/values-tr/strings.xml b/briar-android/src/main/res/values-tr/strings.xml index 588a6e32c..6a4322bfd 100644 --- a/briar-android/src/main/res/values-tr/strings.xml +++ b/briar-android/src/main/res/values-tr/strings.xml @@ -454,14 +454,12 @@ İçe Aktar RSS beslemesi URL\'sini girin Üzgünüz! RSS beslemeniz içe aktarılırken bir hata oluştu. - RSS Beslemelerini Yönet İçe Aktarıldı: Yazar: Son Güncelleme: Beslemeyi Kaldır Bu beslemeyi kaldırmak istediğinizden emin misiniz?\n\nGönderiler sizin aygıtınızdan değil, diğer insanların aygıtlarından kaldırılacaktır.\n\nBu beslemeyi paylaştığınız kişiler güncellemeleri alması durabilir. Kaldır - Besleme silinemedi! Gösterilecek RSS beslemesi yok\n\nBir beslemeyi içe aktarmak için + simgesine dokunun Beslemeleriniz yüklenirken bir hata oluştu. Lütfen daha sonra tekrar deneyin. diff --git a/briar-android/src/main/res/values-uk/strings.xml b/briar-android/src/main/res/values-uk/strings.xml index b30074bd8..a6e905804 100644 --- a/briar-android/src/main/res/values-uk/strings.xml +++ b/briar-android/src/main/res/values-uk/strings.xml @@ -400,14 +400,12 @@ Імпортувати Введіть URL-посилання RSS-стрічки Нам шкода! Виникла помилка під час імпорту вашої стрічки. - Kерувати RSS-стрічками Імпортовано: Автор: Востаннє оновлювалося: Видалити стрічку Ви впевнені, що хочете видалити цю стрічку?\n\nДописи буде видалено з вашого пристрою, але не з пристроїв інших осіб.\n\nБудь-хто з контактів, з якими ви поділилися цією стрічкою, можуть припинити отримувати оноволення. Вилучити - Ця стрічка не може бути видалена! Немає RSS-стрічок до відображення\n\nНатисніть на символ \"+\", щоб імпортувати стрічку Під час завантаження ваших стрічок виникла проблема. Будь ласка, спробуйте пізніше. diff --git a/briar-android/src/main/res/values-zh-rCN/strings.xml b/briar-android/src/main/res/values-zh-rCN/strings.xml index 20507e7c1..e54ebef6a 100644 --- a/briar-android/src/main/res/values-zh-rCN/strings.xml +++ b/briar-android/src/main/res/values-zh-rCN/strings.xml @@ -444,14 +444,12 @@ 导入 输入 RSS 订阅源链接 抱歉!导入订阅源时发生错误。 - 管理 RSS 订阅源 已导入: 作者: 最后更新于: 删除订阅源 确认要删除该订阅源吗?\n\n博文将从您的设备上移除,但仍将存在于其他人的设备。\n\n那些经过您的分享而订阅该源的联系人可能不会再收到更新。 删除 - 该订阅源无法被删除! 尚无订阅源可供显示\n\n轻按 + 号导入一个订阅源 加载订阅源时出错。请稍候再试。 diff --git a/briar-android/src/main/res/values-zh-rTW/strings.xml b/briar-android/src/main/res/values-zh-rTW/strings.xml index e511457dc..4a68d8821 100644 --- a/briar-android/src/main/res/values-zh-rTW/strings.xml +++ b/briar-android/src/main/res/values-zh-rTW/strings.xml @@ -362,14 +362,12 @@ 導入 輸入 RSS 訂閱源鏈接 抱歉!導入訂閱源時發生錯誤。 - 管理 RSS 訂閱源 已導入: 作者: 最後更新於: 刪除訂閱源 確認要刪除該訂閱源嗎?\n\n博文將從您的裝置上移除,但仍將存在於其他人的裝置。\n\n那些經過您的分享而訂閱該源的聯絡人可能不會再收到更新。 刪除 - 無法刪除這訂閱源! 尚無訂閱源可供顯示\n\n輕按 + 號導入訂閱源 加載訂閱源時出錯。請稍候再試。 diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 5d0e5c0ec..42af8d838 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -486,14 +486,14 @@ Import Enter the URL of the RSS feed We are sorry! There was an error importing your feed. - Manage RSS Feeds + That feed is already imported. + RSS Feeds Imported: Author: Last Updated: Remove Feed Are you sure that you want to remove this feed?\n\nPosts will be removed from your device but not from other people\'s devices.\n\nAny contacts you\'ve shared this feed with might stop receiving updates. Remove - The feed could not be deleted! No RSS feeds to show\n\nTap the + icon to import a feed There was a problem loading your feeds. Please try again later. diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java index 9be4387ea..ef747723d 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java @@ -10,7 +10,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class Feed { +public class Feed implements Comparable { private final String url; private final Blog blog; @@ -94,4 +94,13 @@ public class Feed { return false; } + @Override + public int compareTo(Feed o) { + if (this == o) return 0; + long aTime = getAdded(), bTime = o.getAdded(); + if (aTime > bTime) return -1; + if (aTime < bTime) return 1; + return 0; + } + } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedManager.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedManager.java index 98adcea29..f0fcf5cd3 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/FeedManager.java @@ -1,6 +1,7 @@ package org.briarproject.briar.api.feed; import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.ClientId; @@ -23,7 +24,7 @@ public interface FeedManager { /** * Adds an RSS feed as a new dedicated blog. */ - void addFeed(String url) throws DbException, IOException; + Feed addFeed(String url) throws DbException, IOException; /** * Removes an RSS feed. @@ -35,4 +36,8 @@ public interface FeedManager { */ List getFeeds() throws DbException; + /** + * Returns a list of all added RSS feeds + */ + List getFeeds(Transaction txn) throws DbException; } diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index b2ac62c83..b694908a2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -166,7 +166,7 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook, } @Override - public void addFeed(String url) throws DbException, IOException { + public Feed addFeed(String url) throws DbException, IOException { // fetch syndication feed to get its metadata SyndFeed f = fetchSyndFeed(url); @@ -198,6 +198,8 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook, } finally { db.endTransaction(txn); } + + return updatedFeed; } @Override @@ -232,18 +234,11 @@ class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook, @Override public List getFeeds() throws DbException { - List feeds; - Transaction txn = db.startTransaction(true); - try { - feeds = getFeeds(txn); - db.commitTransaction(txn); - } finally { - db.endTransaction(txn); - } - return feeds; + return db.transactionWithResult(true, this::getFeeds); } - private List getFeeds(Transaction txn) throws DbException { + @Override + public List getFeeds(Transaction txn) throws DbException { List feeds = new ArrayList<>(); Group g = getLocalGroup(); try { diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java index 42bc69ef8..fb94c9b82 100644 --- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerImplTest.java @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.TaskScheduler; import org.briarproject.bramble.test.BrambleMockTestCase; +import org.briarproject.bramble.test.DbExpectations; import org.briarproject.bramble.test.ImmediateExecutor; import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.BlogManager; @@ -145,17 +146,14 @@ public class FeedManagerImplTest extends BrambleMockTestCase { BdfDictionary feedsDict = BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList)); expectGetLocalGroup(); - context.checking(new Expectations() {{ - oneOf(db).startTransaction(true); - will(returnValue(txn)); + context.checking(new DbExpectations() {{ + oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(clientHelper).getGroupMetadataAsDictionary(txn, localGroupId); will(returnValue(feedsDict)); if (feedList.size() == 1) { oneOf(feedFactory).createFeed(feedDict); will(returnValue(feed)); } - oneOf(db).commitTransaction(txn); - oneOf(db).endTransaction(txn); }}); } -- GitLab