From 60df3dd016fabf4b26660cef5346f554f0d043b1 Mon Sep 17 00:00:00 2001 From: nuclearfog Date: Mon, 10 Jul 2023 21:12:45 +0200 Subject: [PATCH] finalized user field support, restructured ViewPager adapter --- .../api/mastodon/impl/MastodonField.java | 50 ----------- .../api/mastodon/impl/MastodonStatus.java | 25 +----- .../api/mastodon/impl/MastodonUser.java | 43 +++++++++ .../twidda/backend/utils/StringUtils.java | 30 +++++++ .../nuclearfog/twidda/model/lists/Fields.java | 6 ++ .../twidda/ui/activities/MainActivity.java | 2 +- .../twidda/ui/activities/ProfileActivity.java | 18 ++-- .../twidda/ui/activities/SearchActivity.java | 2 +- .../ui/activities/UserlistActivity.java | 2 +- .../ui/activities/UserlistsActivity.java | 2 +- .../twidda/ui/activities/UsersActivity.java | 2 +- .../twidda/ui/adapter/FieldAdapter.java | 50 +++++++++-- .../{ => fragments}/FragmentAdapter.java | 2 +- .../ui/adapter/fragments/ProfileAdapter.java | 89 +++++++++++++++++++ .../adapter/fragments/ViewPagerAdapter.java | 76 ++++++++++++++++ .../twidda/ui/adapter/holder/FieldHolder.java | 35 +++++++- .../twidda/ui/fragments/FieldFragment.java | 33 ++++++- app/src/main/res/layout/item_field.xml | 6 +- app/src/main/res/layout/item_message.xml | 6 +- app/src/main/res/values/arrays.xml | 7 ++ app/src/main/res/values/strings.xml | 2 +- 21 files changed, 384 insertions(+), 104 deletions(-) delete mode 100644 app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonField.java rename app/src/main/java/org/nuclearfog/twidda/ui/adapter/{ => fragments}/FragmentAdapter.java (99%) create mode 100644 app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ProfileAdapter.java create mode 100644 app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ViewPagerAdapter.java diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonField.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonField.java deleted file mode 100644 index 61997804..00000000 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonField.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.nuclearfog.twidda.backend.api.mastodon.impl; - -import org.json.JSONException; -import org.json.JSONObject; -import org.nuclearfog.twidda.backend.utils.StringUtils; -import org.nuclearfog.twidda.model.User.Field; - -/** - * User fields implementation of Mastodon - * - * @author nuclearfog - */ -public class MastodonField implements Field { - - private static final long serialVersionUID = 2278113885084330065L; - - private String key; - private String value; - private long timestamp = 0L; - - /** - * @param json fields json - */ - public MastodonField(JSONObject json) throws JSONException { - key = json.getString("name"); - value = json.getString("value"); - String timeStr = json.getString("verified_at"); - if (!timeStr.equals("null")) { - timestamp = StringUtils.getTime(timeStr, StringUtils.TIME_MASTODON); - } - } - - - @Override - public String getKey() { - return key; - } - - - @Override - public String getValue() { - return value; - } - - - @Override - public long getTimestamp() { - return timestamp; - } -} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonStatus.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonStatus.java index 37684e30..6d7e0971 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonStatus.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonStatus.java @@ -6,10 +6,6 @@ import androidx.annotation.Nullable; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Document.OutputSettings; -import org.jsoup.safety.Safelist; import org.nuclearfog.twidda.backend.utils.StringUtils; import org.nuclearfog.twidda.model.Card; import org.nuclearfog.twidda.model.Emoji; @@ -31,8 +27,6 @@ public class MastodonStatus implements Status { private static final long serialVersionUID = 1184375228249441241L; - private static final OutputSettings OUTPUT_SETTINGS = new OutputSettings().prettyPrint(false); - private long id; private long replyId; private long replyUserId; @@ -90,24 +84,7 @@ public class MastodonStatus implements Status { sensitive = json.optBoolean("sensitive", false); spoiler = json.optBoolean("spoiler_text", false); bookmarked = json.optBoolean("bookmarked", false); - String text = json.optString("content", ""); - - try { - // create newlines at every
or

tag - Document jsoupDoc = Jsoup.parse(text); - jsoupDoc.outputSettings(OUTPUT_SETTINGS); - jsoupDoc.select("br").after("\\n"); - jsoupDoc.select("p").before("\\n"); - String str = jsoupDoc.html().replace("\\n", "\n"); - text = Jsoup.clean(str, "", Safelist.none(), OUTPUT_SETTINGS); - text = text.replace("<", "<").replace(">", ">").replace("&", "&").replace(" ", "\u00A0"); - if (text.startsWith("\n")) { - text = text.substring(1); - } - } catch (Exception exception) { - // use fallback text string from json - } - this.text = text; + text = StringUtils.extractText(json.optString("content", "")); if (author.getId() != currentUserId) mentions = author.getScreenname() + ' '; diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java index 09b6b3d4..f04a450c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java @@ -248,4 +248,47 @@ public class MastodonUser implements User { public String toString() { return "name=\"" + getScreenname() + "\""; } + + /** + * + */ + private static class MastodonField implements Field { + + private static final long serialVersionUID = 2278113885084330065L; + + private String key; + private String value; + private long timestamp = 0L; + + /** + * @param json fields json + */ + public MastodonField(JSONObject json) throws JSONException { + key = json.getString("name"); + value = StringUtils.extractText(json.optString("value", "")); + + String timeStr = json.getString("verified_at"); + if (!timeStr.equals("null")) { + timestamp = StringUtils.getTime(timeStr, StringUtils.TIME_MASTODON); + } + } + + + @Override + public String getKey() { + return key; + } + + + @Override + public String getValue() { + return value; + } + + + @Override + public long getTimestamp() { + return timestamp; + } + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/utils/StringUtils.java b/app/src/main/java/org/nuclearfog/twidda/backend/utils/StringUtils.java index a5567345..32f8865d 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/utils/StringUtils.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/utils/StringUtils.java @@ -3,6 +3,9 @@ package org.nuclearfog.twidda.backend.utils; import android.content.res.Resources; import android.util.Base64; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.safety.Safelist; import org.nuclearfog.twidda.BuildConfig; import org.nuclearfog.twidda.R; @@ -61,6 +64,8 @@ public class StringUtils { private static final TimeZone TIME_ZONE = TimeZone.getDefault(); + private static final Document.OutputSettings OUTPUT_SETTINGS = new Document.OutputSettings().prettyPrint(false); + /** * fallback date if parsing failed */ @@ -194,6 +199,31 @@ public class StringUtils { return buf.toString(); } + /** + * extract text from html doc + * + * @param text html string + * @return text string + */ + public static String extractText(String text) { + try { + // create newlines at every
or

tag + Document jsoupDoc = Jsoup.parse(text); + jsoupDoc.outputSettings(OUTPUT_SETTINGS); + jsoupDoc.select("br").after("\\n"); + jsoupDoc.select("p").before("\\n"); + String str = jsoupDoc.html().replace("\\n", "\n"); + text = Jsoup.clean(str, "", Safelist.none(), OUTPUT_SETTINGS); + text = text.replace("<", "<").replace(">", ">").replace("&", "&").replace(" ", "\u00A0"); + if (text.startsWith("\n")) { + text = text.substring(1); + } + } catch (Exception exception) { + // use fallback text string from json + } + return text; + } + /** * convert time strings from different APIs to the local format * diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java index 50f72b2c..63b66158 100644 --- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java +++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import org.nuclearfog.twidda.model.User.Field; +import java.util.Arrays; import java.util.LinkedList; /** @@ -24,6 +25,11 @@ public class Fields extends LinkedList { } + public Fields(Field[] fields) { + super(Arrays.asList(fields)); + } + + @NonNull @Override public String toString() { diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java index f75de238..12ecab4a 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/MainActivity.java @@ -25,7 +25,7 @@ import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.config.GlobalSettings; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.FragmentAdapter; import org.nuclearfog.twidda.ui.dialogs.ProgressDialog; import org.nuclearfog.twidda.ui.views.TabSelector; import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java index d1cf6a45..491c3f1c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/ProfileActivity.java @@ -66,7 +66,7 @@ import org.nuclearfog.twidda.config.Configuration; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Relation; import org.nuclearfog.twidda.model.User; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.ProfileAdapter; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener; import org.nuclearfog.twidda.ui.views.LockableLinearLayout; @@ -137,7 +137,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult private AsyncCallback usernameUpdate = this::onUsernameUpdate; private AsyncCallback userDescriptionUpdate = this::onUserDescriptionUpdate; - private FragmentAdapter adapter; + private ProfileAdapter adapter; private GlobalSettings settings; private Picasso picasso; private ConfirmDialog confirmDialog; @@ -192,7 +192,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult tabSelector = findViewById(R.id.profile_tab); viewPager = findViewById(R.id.profile_pager); - adapter = new FragmentAdapter(this); + adapter = new ProfileAdapter(this); relationLoader = new RelationLoader(this); domainAction = new DomainAction(this); userLoader = new UserLoader(this); @@ -261,13 +261,14 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult RelationParam param = new RelationParam(userId, RelationParam.LOAD); relationLoader.execute(param, relationCallback); } - adapter.setupProfilePage(userId); - if (settings.likeEnabled()) { + adapter.setUser(userId); + if (settings.getLogin().getConfiguration() == Configuration.MASTODON && userId != settings.getLogin().getId()) { + tabSelector.addTabIcons(R.array.profile_tab_icons); + } else if (settings.likeEnabled()) { tabSelector.addTabIcons(R.array.profile_tab_icons_like); } else { - tabSelector.addTabIcons(R.array.profile_tab_icons); + tabSelector.addTabIcons(R.array.profile_tab_icons_favorite); } - tabSelector.addOnTabSelectedListener(this); following.setOnClickListener(this); follower.setOnClickListener(this); @@ -863,6 +864,9 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult emojiLoader.execute(param, userDescriptionUpdate); } } + if (user.getFields().length > 0) { + adapter.setFields(user.getFields()); + } } /** diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java index 1b7460aa..ddbcdde2 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/SearchActivity.java @@ -27,7 +27,7 @@ import org.nuclearfog.twidda.backend.utils.ErrorUtils; import org.nuclearfog.twidda.config.Configuration; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.Trend; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.FragmentAdapter; import org.nuclearfog.twidda.ui.views.TabSelector; import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java index 58e663a8..2624cc91 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistActivity.java @@ -34,7 +34,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorUtils; import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.UserList; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.FragmentAdapter; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener; import org.nuclearfog.twidda.ui.views.TabSelector; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java index cb09a1a0..de65637b 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UserlistsActivity.java @@ -20,7 +20,7 @@ import androidx.viewpager2.widget.ViewPager2; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.config.GlobalSettings; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.FragmentAdapter; import org.nuclearfog.twidda.ui.views.TabSelector; import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java index d0715822..52fab93c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/UsersActivity.java @@ -27,7 +27,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.ErrorUtils; import org.nuclearfog.twidda.config.Configuration; import org.nuclearfog.twidda.config.GlobalSettings; -import org.nuclearfog.twidda.ui.adapter.FragmentAdapter; +import org.nuclearfog.twidda.ui.adapter.fragments.FragmentAdapter; import org.nuclearfog.twidda.ui.views.TabSelector; import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FieldAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FieldAdapter.java index bd6fab90..5426483c 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FieldAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FieldAdapter.java @@ -5,25 +5,33 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView.Adapter; +import org.nuclearfog.tag.Tagger.OnTagClickListener; import org.nuclearfog.twidda.model.lists.Fields; import org.nuclearfog.twidda.ui.adapter.holder.FieldHolder; /** + * RecyclerView adapter used to show a list of {@link org.nuclearfog.twidda.model.User.Field} + * * @author nuclearfog */ -public class FieldAdapter extends Adapter { +public class FieldAdapter extends Adapter implements OnTagClickListener { + + private OnLinkClickListener listener; private Fields fields = new Fields(); - public FieldAdapter() { - + /** + * + */ + public FieldAdapter(OnLinkClickListener listener) { + this.listener = listener; } @NonNull @Override public FieldHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new FieldHolder(parent); + return new FieldHolder(parent, this); } @@ -39,14 +47,46 @@ public class FieldAdapter extends Adapter { } + @Override + public void onTagClick(String tag) { + } + + + @Override + public void onLinkClick(String link) { + listener.onLinkClick(link); + } + + /** + * replace all existing items with new ones + * + * @param fields items to insert + */ public void replaceItems(Fields fields) { this.fields.clear(); this.fields.addAll(fields); notifyDataSetChanged(); } - + /** + * get all items + * + * @return Field list + */ public Fields getItems() { return new Fields(fields); } + + /** + * Click listener for url + */ + public interface OnLinkClickListener { + + /** + * called on url click + * + * @param url url string + */ + void onLinkClick(String url); + } } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/FragmentAdapter.java similarity index 99% rename from app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java rename to app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/FragmentAdapter.java index af31d007..c978ffbc 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/FragmentAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/FragmentAdapter.java @@ -1,4 +1,4 @@ -package org.nuclearfog.twidda.ui.adapter; +package org.nuclearfog.twidda.ui.adapter.fragments; import android.os.Bundle; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ProfileAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ProfileAdapter.java new file mode 100644 index 00000000..37726a94 --- /dev/null +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ProfileAdapter.java @@ -0,0 +1,89 @@ +package org.nuclearfog.twidda.ui.adapter.fragments; + +import android.os.Bundle; + +import androidx.fragment.app.FragmentActivity; + +import org.nuclearfog.twidda.config.GlobalSettings; +import org.nuclearfog.twidda.model.User; +import org.nuclearfog.twidda.model.lists.Fields; +import org.nuclearfog.twidda.ui.fragments.FieldFragment; +import org.nuclearfog.twidda.ui.fragments.ListFragment; +import org.nuclearfog.twidda.ui.fragments.StatusFragment; + +/** + * ViewPager adapter used to show profile timelines + * + * @author nuclearfog + */ +public class ProfileAdapter extends ViewPagerAdapter { + + private GlobalSettings settings; + + /** + * + */ + public ProfileAdapter(FragmentActivity fragmentActivity) { + super(fragmentActivity); + settings = GlobalSettings.get(fragmentActivity); + } + + /** + * create adapter items + * + * @param userId ID of the user profile + */ + public void setUser(long userId) { + // user timeline + Bundle paramUser = new Bundle(); + paramUser.putLong(StatusFragment.KEY_ID, userId); + paramUser.putInt(StatusFragment.KEY_MODE, StatusFragment.MODE_USER); + ListFragment statusFragment = new StatusFragment(); + statusFragment.setArguments(paramUser); + // user favorits + Bundle paramFavorite = new Bundle(); + paramFavorite.putLong(StatusFragment.KEY_ID, userId); + paramFavorite.putInt(StatusFragment.KEY_MODE, StatusFragment.MODE_FAVORIT); + ListFragment favoriteFragment = new StatusFragment(); + favoriteFragment.setArguments(paramFavorite); + // user bookmarks + Bundle paramBookmark = new Bundle(); + paramBookmark.putLong(StatusFragment.KEY_ID, userId); + paramBookmark.putInt(StatusFragment.KEY_MODE, StatusFragment.MODE_BOOKMARK); + ListFragment bookmarkFragment = new StatusFragment(); + bookmarkFragment.setArguments(paramBookmark); + // user fields + ListFragment fieldFragment = new FieldFragment(); + + fragments.clear(); + fragments.add(statusFragment); + switch (settings.getLogin().getConfiguration()) { + case MASTODON: + if (settings.getLogin().getId() == userId) { + fragments.add(favoriteFragment); + fragments.add(bookmarkFragment); + } + fragments.add(fieldFragment); + break; + + case TWITTER1: + case TWITTER2: + fragments.add(favoriteFragment); + break; + } + notifyDataSetChanged(); + } + + /** + * put user fields into FieldFragment + * + * @param fields user fields + */ + public void setFields(User.Field[] fields) { + for (ListFragment fragment : fragments) { + if (fragment instanceof FieldFragment) { + ((FieldFragment) fragment).setItems(new Fields(fields)); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ViewPagerAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ViewPagerAdapter.java new file mode 100644 index 00000000..fd71f92a --- /dev/null +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/fragments/ViewPagerAdapter.java @@ -0,0 +1,76 @@ +package org.nuclearfog.twidda.ui.adapter.fragments; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.viewpager2.adapter.FragmentStateAdapter; + +import org.nuclearfog.twidda.ui.fragments.ListFragment; + +import java.util.ArrayList; + +/** + * @author nuclearfog + */ +public class ViewPagerAdapter extends FragmentStateAdapter { + + protected ArrayList fragments = new ArrayList<>(); + + /** + * + */ + public ViewPagerAdapter(FragmentActivity fragmentActivity) { + super(fragmentActivity); + } + + + @Override + public final long getItemId(int position) { + return fragments.get(position).getSessionId(); + } + + + @Override + public final boolean containsItem(long itemId) { + for (ListFragment fragment : fragments) { + if (fragment.getSessionId() == itemId) + return true; + } + return false; + } + + + @NonNull + @Override + public final Fragment createFragment(int position) { + return fragments.get(position); + } + + + @Override + public final int getItemCount() { + return fragments.size(); + } + + /** + * called when app settings change + */ + public void notifySettingsChanged() { + for (ListFragment fragment : fragments) { + if (!fragment.isDetached()) { + fragment.reset(); + } + } + } + + /** + * called to scroll page to top + * + * @param index tab position of page + */ + public void scrollToTop(int index) { + if (!fragments.get(index).isDetached()) { + fragments.get(index).onTabChange(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/FieldHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/FieldHolder.java index 8aef252c..7389cce5 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/FieldHolder.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/holder/FieldHolder.java @@ -1,37 +1,64 @@ package org.nuclearfog.twidda.ui.adapter.holder; +import android.graphics.Color; +import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView.ViewHolder; +import org.nuclearfog.tag.Tagger; +import org.nuclearfog.tag.Tagger.OnTagClickListener; import org.nuclearfog.twidda.R; +import org.nuclearfog.twidda.backend.utils.AppStyles; import org.nuclearfog.twidda.backend.utils.StringUtils; +import org.nuclearfog.twidda.config.GlobalSettings; import org.nuclearfog.twidda.model.User.Field; +/** + * ViewHolder for {@link org.nuclearfog.twidda.ui.adapter.FieldAdapter} + * + * @author nuclearfog + */ public class FieldHolder extends ViewHolder { private View verified; private TextView key, value, time; + private GlobalSettings settings; + private OnTagClickListener listener; - public FieldHolder(ViewGroup parent) { + /** + * + */ + public FieldHolder(ViewGroup parent, OnTagClickListener listener) { super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_field, parent, false)); + CardView background = (CardView) itemView; + ViewGroup container = itemView.findViewById(R.id.item_field_container); verified = itemView.findViewById(R.id.item_field_verified); key = itemView.findViewById(R.id.item_field_key); value = itemView.findViewById(R.id.item_field_value); time = itemView.findViewById(R.id.item_field_timestamp); + settings = GlobalSettings.get(parent.getContext()); + this.listener = listener; + + value.setMovementMethod(LinkMovementMethod.getInstance()); + background.setCardBackgroundColor(settings.getCardColor()); + AppStyles.setTheme(container, Color.TRANSPARENT); } - + /** + * set view content + */ public void setContent(Field field) { key.setText(field.getKey()); - value.setText(field.getValue()); + value.setText(Tagger.makeTextWithLinks(field.getValue(), settings.getHighlightColor(), listener)); if (field.getTimestamp() != 0L) { verified.setVisibility(View.VISIBLE); - time.setText(R.string.field_verified_in); + time.setText(R.string.field_verified); time.append(StringUtils.formatCreationTime(time.getResources(), field.getTimestamp())); } else { verified.setVisibility(View.GONE); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/FieldFragment.java b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/FieldFragment.java index 7b9ac2e6..370cfca5 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/FieldFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/FieldFragment.java @@ -6,10 +6,19 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.nuclearfog.twidda.backend.utils.LinkUtils; import org.nuclearfog.twidda.model.lists.Fields; import org.nuclearfog.twidda.ui.adapter.FieldAdapter; +import org.nuclearfog.twidda.ui.adapter.FieldAdapter.OnLinkClickListener; -public class FieldFragment extends ListFragment { +/** + * User field list fragment + * + * @author nuclearfog + */ +public class FieldFragment extends ListFragment implements OnLinkClickListener { + + private static final String KEY_SAVE = "fields-save"; private FieldAdapter adapter; @@ -17,18 +26,32 @@ public class FieldFragment extends ListFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - adapter = new FieldAdapter(); + adapter = new FieldAdapter(this); setAdapter(adapter); + if (savedInstanceState != null) { + Object data = savedInstanceState.getSerializable(KEY_SAVE); + if (data instanceof Fields) { + adapter.replaceItems((Fields) data); + } + } disableSwipe(); } @Override public void onSaveInstanceState(@NonNull Bundle outState) { + Fields items = adapter.getItems(); + outState.putSerializable(KEY_SAVE, items); super.onSaveInstanceState(outState); } + @Override + public void onLinkClick(String url) { + LinkUtils.openLink(requireActivity(), url); + } + + @Override protected void onReload() { } @@ -38,7 +61,11 @@ public class FieldFragment extends ListFragment { protected void onReset() { } - + /** + * set field items + * + * @param items new items to show in a list + */ public void setItems(Fields items) { if (adapter != null) { adapter.replaceItems(items); diff --git a/app/src/main/res/layout/item_field.xml b/app/src/main/res/layout/item_field.xml index a4f9b703..0a2dcf95 100644 --- a/app/src/main/res/layout/item_field.xml +++ b/app/src/main/res/layout/item_field.xml @@ -1,11 +1,13 @@ @@ -18,7 +20,8 @@ android:layout_margin="@dimen/item_field_layout_margin" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/item_field_key" - app:layout_constraintBottom_toBottomOf="@id/item_field_key" /> + app:layout_constraintBottom_toBottomOf="@id/item_field_key" + tools:ignore="ContentDescription" /> diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index 1017390a..dcf8e24c 100644 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -69,15 +69,14 @@ @@ -104,6 +103,7 @@ android:id="@+id/item_message_attachment_list" android:layout_width="wrap_content" android:layout_height="@dimen/dmitem_indicator_size" + android:layout_marginTop="@dimen/dmitem_text_margin" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/item_message_text" app:layout_constraintEnd_toEndOf="parent" /> diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 89b5a9ab..bd755542 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -49,15 +49,22 @@ + @drawable/home + @drawable/info + + + @drawable/home @drawable/favorite @drawable/bookmark + @drawable/info @drawable/home @drawable/like @drawable/bookmark + @drawable/info diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a60bae00..b825f901 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -321,7 +321,7 @@ translate Translated by:\u0020 Language:\u0020 - verified in\u0020 + verified:\u0020 remove account from list? delete filter? \'unnamed\'