diff options
author | Alex Ning <chineseperson5@gmail.com> | 2018-07-29 12:25:55 +0000 |
---|---|---|
committer | Alex Ning <chineseperson5@gmail.com> | 2018-07-29 12:25:55 +0000 |
commit | ddc7b36e72dee19b87204beacc8322ca221b5524 (patch) | |
tree | d3e6475c0e135d732b0d2591142113c88898a491 /app | |
parent | e3653eb503f4396903bcdd1423510f7c4893dde9 (diff) | |
download | infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar.gz infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar.bz2 infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar.lz infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar.xz infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.tar.zst infinity-for-reddit-ddc7b36e72dee19b87204beacc8322ca221b5524.zip |
Save subscribed subreddits and users to the SQLite database by using Room Persistence Library. Add a following section in the navigation drawer to display all the followed users. Add a NestedScrollView in the navigation drawer to wrap all the elements. Disable nested scrolling feature in all the RecyclerViews in the navigation drawer.
Diffstat (limited to 'app')
22 files changed, 662 insertions, 162 deletions
diff --git a/app/build.gradle b/app/build.gradle index 0d69fae8..95becfb6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,10 +28,10 @@ repositories { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') - implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' - implementation 'com.android.support:design:28.0.0-alpha3' + implementation 'com.android.support:appcompat-v7:28.0.0-beta01' + implementation 'com.android.support:design:28.0.0-beta01' implementation 'com.android.support.constraint:constraint-layout:1.1.2' - implementation 'com.android.support:support-v4:28.0.0-alpha3' + implementation 'com.android.support:support-v4:28.0.0-beta01' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' @@ -39,10 +39,17 @@ dependencies { implementation 'de.hdodenhof:circleimageview:2.2.0' implementation 'com.google.android.exoplayer:exoplayer:2.7.0' implementation 'com.google.android.exoplayer:exoplayer-dash:2.7.0' - implementation 'com.android.support:customtabs:28.0.0-alpha3' + implementation 'com.android.support:customtabs:28.0.0-beta01' implementation 'com.alexvasilkov:gesture-views:2.5.2' - implementation 'com.android.support:cardview-v7:28.0.0-alpha3' + implementation 'com.android.support:cardview-v7:28.0.0-beta01' implementation 'com.github.bumptech.glide:glide:4.6.1' implementation 'com.github.pwittchen:swipe-rx2:0.3.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1' + // Room components + implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion" + annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion" + androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion" + // Lifecycle components + implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion" + annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion" } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AcquireAccessToken.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AcquireAccessToken.java index 7895ce0d..aeefa753 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AcquireAccessToken.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AcquireAccessToken.java @@ -64,7 +64,7 @@ class AcquireAccessToken { public void onErrorResponse(VolleyError error) { Toast.makeText(mContext, "Error getting the new access token", Toast.LENGTH_SHORT).show(); mAcquireAccessTokenListener.onAcquireAccessTokenFail(); - Log.i("error get access token", error.getMessage()); + Log.i("Error", "getting access token"); } }) { @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedSubreddits.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java index 999a6dc1..4a902c16 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedSubreddits.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java @@ -2,7 +2,6 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; import android.net.Uri; -import android.util.Log; import com.android.volley.AuthFailureError; import com.android.volley.Request; @@ -14,23 +13,27 @@ import com.android.volley.toolbox.StringRequest; import java.util.ArrayList; import java.util.Map; -class FetchSubscribedSubreddits { +class FetchSubscribedThing { interface FetchSubscribedSubredditsListener { - void onFetchSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData); + void onFetchSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData); void onFetchSubscribedSubredditsFail(); } private Context context; private RequestQueue requestQueue; private FetchSubscribedSubredditsListener mFetchSubscribedSubredditsListener; - private ArrayList<SubredditData> mSubredditData; + private ArrayList<SubscribedSubredditData> mSubscribedSubredditData; + private ArrayList<SubscribedUserData> mSubscribedUserData; private String mLastItem; - FetchSubscribedSubreddits(Context context, RequestQueue requestQueue, ArrayList<SubredditData> subredditData) { + FetchSubscribedThing(Context context, RequestQueue requestQueue, ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData) { this.context = context; this.requestQueue = requestQueue; - mSubredditData = subredditData; + mSubscribedSubredditData = subscribedSubredditData; + mSubscribedUserData = subscribedUserData; } void fetchSubscribedSubreddits(FetchSubscribedSubredditsListener fetchUserInfoListener, final int refreshTime) { @@ -47,15 +50,20 @@ class FetchSubscribedSubreddits { StringRequest commentRequest = new StringRequest(Request.Method.GET, uri.toString(), new Response.Listener<String>() { @Override public void onResponse(String response) { - new ParseSubscribedSubreddits().parseSubscribedSubreddits(response, mSubredditData, - new ParseSubscribedSubreddits.ParseSubscribedSubredditsListener() { + new ParseSubscribedThing().parseSubscribedSubreddits(response, mSubscribedSubredditData, + mSubscribedUserData, + new ParseSubscribedThing.ParseSubscribedSubredditsListener() { + @Override - public void onParseSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData, String lastItem) { - mSubredditData = subredditData; + public void onParseSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData, + String lastItem) { + mSubscribedSubredditData = subscribedSubredditData; + mSubscribedUserData = subscribedUserData; mLastItem = lastItem; - Log.i("last item", lastItem); if(mLastItem.equals("null")) { - mFetchSubscribedSubredditsListener.onFetchSubscribedSubredditsSuccess(mSubredditData); + mFetchSubscribedSubredditsListener.onFetchSubscribedSubredditsSuccess(mSubscribedSubredditData, + mSubscribedUserData); } else { fetchSubscribedSubreddits(mFetchSubscribedSubredditsListener, refreshTime); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java index 9f5ae9fc..35484961 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/JSONUtils.java @@ -57,4 +57,7 @@ class JSONUtils { static final String LINK_KARMA_KEY = "link_karma"; static final String COMMENT_KARMA_KEY = "comment_karma"; static final String DISPLAY_NAME = "display_name"; + static final String SUBREDDIT_TYPE_KEY = "subreddit_type"; + + static final String SUBREDDIT_TYPE_VALUE_USER = "user"; } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java index 92b73aae..a7f07ed5 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/MainActivity.java @@ -2,10 +2,14 @@ package ml.docilealligator.infinityforreddit; import android.app.Fragment; import android.app.FragmentTransaction; +import android.arch.lifecycle.Observer; +import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; @@ -22,8 +26,7 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; +import java.util.List; import de.hdodenhof.circleimageview.CircleImageView; @@ -38,7 +41,6 @@ public class MainActivity extends AppCompatActivity { private TextView mKarmaTextView; private CircleImageView mProfileImageView; private ImageView mBannerImageView; - private RecyclerView mSubscribedSubredditRecyclerView; private Fragment mFragment; private RequestManager glide; @@ -49,7 +51,8 @@ public class MainActivity extends AppCompatActivity { private String mKarma; private boolean mFetchUserInfoSuccess; - private ArrayList<SubredditData> mSubredditData; + private SubscribedSubredditViewModel mSubscribedSubredditViewModel; + private SubscribedUserViewModel mSubscribedUserViewModel; @Override protected void onCreate(Bundle savedInstanceState) { @@ -70,8 +73,15 @@ public class MainActivity extends AppCompatActivity { mProfileImageView = header.findViewById(R.id.profile_image_view_nav_header_main); mBannerImageView = header.findViewById(R.id.banner_image_view_nav_header_main); - mSubscribedSubredditRecyclerView = findViewById(R.id.subscribed_subreddit_recycler_view_main_activity); - mSubscribedSubredditRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + RecyclerView subscribedSubredditRecyclerView = findViewById(R.id.subscribed_subreddit_recycler_view_main_activity); + subscribedSubredditRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + subscribedSubredditRecyclerView.setNestedScrollingEnabled(false); + final TextView subscriptionsLabelTextView = findViewById(R.id.subscriptions_label_main_activity); + + RecyclerView subscribedUserRecyclerView = findViewById(R.id.subscribed_user_recycler_view_main_activity); + subscribedUserRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + subscribedUserRecyclerView.setNestedScrollingEnabled(false); + final TextView followingLabelTextView = findViewById(R.id.following_label_main_activity); mName = getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.USER_KEY, ""); mProfileImageUrl = getSharedPreferences(SharedPreferencesUtils.USER_INFO_FILE_KEY, Context.MODE_PRIVATE).getString(SharedPreferencesUtils.PROFILE_IMAGE_URL_KEY, ""); @@ -147,19 +157,55 @@ public class MainActivity extends AppCompatActivity { } }, 1); } - new FetchSubscribedSubreddits(this, Volley.newRequestQueue(this), new ArrayList<SubredditData>()) - .fetchSubscribedSubreddits(new FetchSubscribedSubreddits.FetchSubscribedSubredditsListener() { + + final SubscribedSubredditRecyclerViewAdapter subredditadapter = new SubscribedSubredditRecyclerViewAdapter(this); + subscribedSubredditRecyclerView.setAdapter(subredditadapter); + mSubscribedSubredditViewModel = ViewModelProviders.of(this).get(SubscribedSubredditViewModel.class); + mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, new Observer<List<SubscribedSubredditData>>() { + @Override + public void onChanged(@Nullable final List<SubscribedSubredditData> subscribedSubredditData) { + // Update the cached copy of the words in the adapter. + if(subscribedSubredditData == null || subscribedSubredditData.size() == 0) { + subscriptionsLabelTextView.setVisibility(View.GONE); + } else { + subscriptionsLabelTextView.setVisibility(View.VISIBLE); + } + + subredditadapter.setSubscribedSubreddits(subscribedSubredditData); + } + }); + + final SubscribedUserRecyclerViewAdapter userAdapter = new SubscribedUserRecyclerViewAdapter(this); + subscribedUserRecyclerView.setAdapter(userAdapter); + mSubscribedUserViewModel = ViewModelProviders.of(this).get(SubscribedUserViewModel.class); + mSubscribedUserViewModel.getAllSubscribedUsers().observe(this, new Observer<List<SubscribedUserData>>() { + @Override + public void onChanged(@Nullable final List<SubscribedUserData> subscribedUserData) { + // Update the cached copy of the words in the adapter. + if(subscribedUserData == null || subscribedUserData.size() == 0) { + followingLabelTextView.setVisibility(View.GONE); + } else { + followingLabelTextView.setVisibility(View.VISIBLE); + } + userAdapter.setSubscribedUsers(subscribedUserData); + } + }); + + new FetchSubscribedThing(this, Volley.newRequestQueue(this), new ArrayList<SubscribedSubredditData>(), + new ArrayList<SubscribedUserData>()) + .fetchSubscribedSubreddits(new FetchSubscribedThing.FetchSubscribedSubredditsListener() { @Override - public void onFetchSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData) { - Collections.sort(subredditData, new Comparator<SubredditData>() { - @Override - public int compare(SubredditData subredditData, SubredditData t1) { - return subredditData.getName().toLowerCase().compareTo(t1.getName().toLowerCase()); - } - }); - mSubredditData = subredditData; - mSubscribedSubredditRecyclerView.setAdapter(new SubscribedSubredditRecyclerViewAdapter( - MainActivity.this, mSubredditData)); + public void onFetchSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData) { + new InsertSubscribedThingsAsyncTask( + SubscribedSubredditRoomDatabase.getDatabase(MainActivity.this), + SubscribedUserRoomDatabase.getDatabase(MainActivity.this), + subscribedSubredditData, + subscribedUserData).execute(); + + /*new InsertSubscribedUsersAsyncTask( + SubscribedUserRoomDatabase.getDatabase(MainActivity.this), + subscribedUserData).execute();*/ } @Override @@ -207,4 +253,52 @@ public class MainActivity extends AppCompatActivity { glide.load(mBannerImageUrl).into(mBannerImageView); } } + + private static class InsertSubscribedThingsAsyncTask extends AsyncTask<Void, Void, Void> { + + private final SubscribedSubredditDao mSubredditDao; + private final SubscribedUserDao mUserDao; + private List<SubscribedSubredditData> subscribedSubredditData; + private List<SubscribedUserData> subscribedUserData; + + InsertSubscribedThingsAsyncTask(SubscribedSubredditRoomDatabase subredditDb, + SubscribedUserRoomDatabase userDb, + List<SubscribedSubredditData> subscribedSubredditData, + List<SubscribedUserData> subscribedUserData) { + mSubredditDao = subredditDb.subscribedSubredditDao(); + mUserDao = userDb.subscribedUserDao(); + this.subscribedSubredditData = subscribedSubredditData; + this.subscribedUserData = subscribedUserData; + } + + @Override + protected Void doInBackground(final Void... params) { + for(SubscribedSubredditData s : subscribedSubredditData) { + mSubredditDao.insert(s); + } + for(SubscribedUserData s : subscribedUserData) { + mUserDao.insert(s); + } + return null; + } + } + + /*private static class InsertSubscribedUsersAsyncTask extends AsyncTask<Void, Void, Void> { + + private final SubscribedUserDao mDao; + private List<SubscribedUserData> subscribedUserData; + + InsertSubscribedUsersAsyncTask(SubscribedUserRoomDatabase db, List<SubscribedUserData> subscribedUserData) { + mDao = db.subscribedUserDao(); + this.subscribedUserData = subscribedUserData; + } + + @Override + protected Void doInBackground(final Void... params) { + for(SubscribedUserData s : subscribedUserData) { + mDao.insert(s); + } + return null; + } + }*/ } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java index a0e93404..e8168e0f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseBestPost.java @@ -152,7 +152,7 @@ class ParseBestPost { videoPostData.setDownloadableGifOrVideo(false); bestPostData.add(videoPostData); - } else { + } else if(data.has(JSONUtils.PREVIEW_KEY)){ JSONObject variations = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); if (variations.has(JSONUtils.VARIANTS_KEY) && variations.getJSONObject(JSONUtils.VARIANTS_KEY).has(JSONUtils.MP4_KEY)) { //Gif video post (MP4) @@ -194,6 +194,19 @@ class ParseBestPost { bestPostData.add(linkPostData); } } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + Log.i("CP no preview image", Integer.toString(i)); + int postType = BestPostData.IMAGE_TYPE; + bestPostData.add(new BestPostData(id, fullName, subredditName, formattedPostTime, title, url, url, permalink, score, postType, voteType, nsfw)); + } else { + //Link post + Log.i("CP no preview link", Integer.toString(i)); + int postType = BestPostData.LINK_TYPE; + BestPostData linkPostData = new BestPostData(id, fullName, subredditName, formattedPostTime, title, previewUrl, url, permalink, score, postType, voteType, nsfw); + bestPostData.add(linkPostData); + } } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedSubreddits.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java index 24d83b40..4aed5743 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedSubreddits.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java @@ -9,33 +9,41 @@ import org.json.JSONObject; import java.util.ArrayList; -class ParseSubscribedSubreddits { +class ParseSubscribedThing { interface ParseSubscribedSubredditsListener { - void onParseSubscribedSubredditsSuccess(ArrayList<SubredditData> subredditData, String lastItem); + void onParseSubscribedSubredditsSuccess(ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData, + String lastItem); void onParseSubscribedSubredditsFail(); } private ParseSubscribedSubredditsListener mParseSubscribedSubredditsListener; - void parseSubscribedSubreddits(String response, ArrayList<SubredditData> subredditData, + void parseSubscribedSubreddits(String response, ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData, ParseSubscribedSubredditsListener parseSubscribedSubredditsListener) { mParseSubscribedSubredditsListener = parseSubscribedSubredditsListener; - new ParseSubscribedSubredditsAsyncTask(response, subredditData).execute(); + new ParseSubscribedSubredditsAsyncTask(response, subscribedSubredditData, subscribedUserData).execute(); } private class ParseSubscribedSubredditsAsyncTask extends AsyncTask<Void, Void, Void> { private JSONObject jsonResponse; private boolean parseFailed; private String lastItem; - private ArrayList<SubredditData> subredditData; - private ArrayList<SubredditData> newSubredditData; + private ArrayList<SubscribedSubredditData> subscribedSubredditData; + private ArrayList<SubscribedUserData> subscribedUserData; + private ArrayList<SubscribedSubredditData> newSubscribedSubredditData; + private ArrayList<SubscribedUserData> newSubscribedUserData; - ParseSubscribedSubredditsAsyncTask(String response, ArrayList<SubredditData> subredditData){ + ParseSubscribedSubredditsAsyncTask(String response, ArrayList<SubscribedSubredditData> subscribedSubredditData, + ArrayList<SubscribedUserData> subscribedUserData){ try { jsonResponse = new JSONObject(response); parseFailed = false; - this.subredditData = subredditData; - newSubredditData = new ArrayList<>(); + this.subscribedSubredditData = subscribedSubredditData; + this.subscribedUserData = subscribedUserData; + newSubscribedSubredditData = new ArrayList<>(); + newSubscribedUserData = new ArrayList<>(); } catch (JSONException e) { Log.i("user info json error", e.getMessage()); mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); @@ -49,7 +57,18 @@ class ParseSubscribedSubreddits { for(int i = 0; i < children.length(); i++) { String name = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.DISPLAY_NAME); String iconUrl = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ICON_IMG_KEY); - newSubredditData.add(new SubredditData(name, iconUrl)); + String id = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); + if(iconUrl.equals("null")) { + iconUrl = ""; + } + + if(children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.SUBREDDIT_TYPE_KEY) + .equals(JSONUtils.SUBREDDIT_TYPE_VALUE_USER)) { + //It's a user + newSubscribedUserData.add(new SubscribedUserData(id, name.substring(2), iconUrl)); + } else { + newSubscribedSubredditData.add(new SubscribedSubredditData(id, name, iconUrl)); + } } lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); } catch (JSONException e) { @@ -62,8 +81,10 @@ class ParseSubscribedSubreddits { @Override protected void onPostExecute(Void aVoid) { if(!parseFailed) { - subredditData.addAll(newSubredditData); - mParseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subredditData, lastItem); + subscribedSubredditData.addAll(newSubscribedSubredditData); + subscribedUserData.addAll(newSubscribedUserData); + mParseSubscribedSubredditsListener.onParseSubscribedSubredditsSuccess(subscribedSubredditData, + subscribedUserData, lastItem); } else { mParseSubscribedSubredditsListener.onParseSubscribedSubredditsFail(); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditData.java deleted file mode 100644 index dcf0cdaf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditData.java +++ /dev/null @@ -1,50 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.os.Parcel; -import android.os.Parcelable; - -class SubredditData implements Parcelable { - private String name; - private String iconUrl; - - SubredditData(String name, String iconUrl) { - this.name = name; - this.iconUrl = iconUrl; - } - - protected SubredditData(Parcel in) { - name = in.readString(); - iconUrl = in.readString(); - } - - public static final Creator<SubredditData> CREATOR = new Creator<SubredditData>() { - @Override - public SubredditData createFromParcel(Parcel in) { - return new SubredditData(in); - } - - @Override - public SubredditData[] newArray(int size) { - return new SubredditData[size]; - } - }; - - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(name); - parcel.writeString(iconUrl); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditDao.java new file mode 100644 index 00000000..9ced85c1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditDao.java @@ -0,0 +1,21 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.lifecycle.LiveData; +import android.arch.persistence.room.Dao; +import android.arch.persistence.room.Insert; +import android.arch.persistence.room.OnConflictStrategy; +import android.arch.persistence.room.Query; + +import java.util.List; + +@Dao +public interface SubscribedSubredditDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubscribedSubredditData subscribedSubredditData); + + @Query("DELETE FROM subscribed_subreddits") + void deleteAllSubscribedSubreddits(); + + @Query("SELECT * from subscribed_subreddits ORDER BY name COLLATE NOCASE ASC") + LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits(); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditData.java new file mode 100644 index 00000000..10b2c8e0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditData.java @@ -0,0 +1,38 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.persistence.room.ColumnInfo; +import android.arch.persistence.room.Entity; +import android.arch.persistence.room.PrimaryKey; +import android.support.annotation.NonNull; + +@Entity(tableName = "subscribed_subreddits") +class SubscribedSubredditData { + + @PrimaryKey + @NonNull + @ColumnInfo(name = "id") + private String id; + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + + SubscribedSubredditData(@NonNull String id, String name, String iconUrl) { + this.id = id; + this.name = name; + this.iconUrl = iconUrl; + } + + @NonNull + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRecyclerViewAdapter.java index 73f40a40..88d194d7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRecyclerViewAdapter.java @@ -11,18 +11,17 @@ import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.RequestManager; -import java.util.ArrayList; +import java.util.List; import de.hdodenhof.circleimageview.CircleImageView; class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { - Context mContext; - ArrayList<SubredditData> mSubredditData; - RequestManager glide; + private Context mContext; + private List<SubscribedSubredditData> mSubscribedSubredditData; + private RequestManager glide; - SubscribedSubredditRecyclerViewAdapter(Context context, ArrayList<SubredditData> subredditData) { + SubscribedSubredditRecyclerViewAdapter(Context context) { mContext = context; - mSubredditData = subredditData; glide = Glide.with(context); } @@ -34,17 +33,20 @@ class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<Recycl @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { - if(!mSubredditData.get(i).getIconUrl().equals("")) { - glide.load(mSubredditData.get(i).getIconUrl()).into(((SubredditViewHolder) viewHolder).iconCircleImageView); + if(!mSubscribedSubredditData.get(i).getIconUrl().equals("")) { + glide.load(mSubscribedSubredditData.get(i).getIconUrl()).into(((SubredditViewHolder) viewHolder).iconCircleImageView); } else { glide.load(R.drawable.subreddit_default_icon).into(((SubredditViewHolder) viewHolder).iconCircleImageView); } - ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(mSubredditData.get(i).getName()); + ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(mSubscribedSubredditData.get(i).getName()); } @Override public int getItemCount() { - return mSubredditData.size(); + if(mSubscribedSubredditData != null) { + return mSubscribedSubredditData.size(); + } + return 0; } @Override @@ -52,9 +54,15 @@ class SubscribedSubredditRecyclerViewAdapter extends RecyclerView.Adapter<Recycl glide.clear(((SubredditViewHolder) holder).iconCircleImageView); } + void setSubscribedSubreddits(List<SubscribedSubredditData> subscribedSubreddits){ + mSubscribedSubredditData = subscribedSubreddits; + notifyDataSetChanged(); + } + + private class SubredditViewHolder extends RecyclerView.ViewHolder { - private CircleImageView iconCircleImageView; - private TextView subredditNameTextView; + private final CircleImageView iconCircleImageView; + private final TextView subredditNameTextView; public SubredditViewHolder(View itemView) { super(itemView); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRepository.java new file mode 100644 index 00000000..3173bba4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRepository.java @@ -0,0 +1,41 @@ +package ml.docilealligator.infinityforreddit; + +import android.app.Application; +import android.arch.lifecycle.LiveData; +import android.os.AsyncTask; + +import java.util.List; + +public class SubscribedSubredditRepository { + private SubscribedSubredditDao mSubscribedSubredditDao; + private LiveData<List<SubscribedSubredditData>> mAllSubscribedSubreddits; + + SubscribedSubredditRepository(Application application) { + SubscribedSubredditRoomDatabase db = SubscribedSubredditRoomDatabase.getDatabase(application); + mSubscribedSubredditDao = db.subscribedSubredditDao(); + mAllSubscribedSubreddits = mSubscribedSubredditDao.getAllSubscribedSubreddits(); + } + + LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits() { + return mAllSubscribedSubreddits; + } + + public void insert(SubscribedSubredditData subscribedSubredditData) { + new insertAsyncTask(mSubscribedSubredditDao).execute(subscribedSubredditData); + } + + private static class insertAsyncTask extends AsyncTask<SubscribedSubredditData, Void, Void> { + + private SubscribedSubredditDao mAsyncTaskDao; + + insertAsyncTask(SubscribedSubredditDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final SubscribedSubredditData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRoomDatabase.java new file mode 100644 index 00000000..d4b1f710 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditRoomDatabase.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.persistence.room.Database; +import android.arch.persistence.room.Room; +import android.arch.persistence.room.RoomDatabase; +import android.content.Context; + +@Database(entities = {SubscribedSubredditData.class}, version = 1) +public abstract class SubscribedSubredditRoomDatabase extends RoomDatabase { + private static SubscribedSubredditRoomDatabase INSTANCE; + + public abstract SubscribedSubredditDao subscribedSubredditDao(); + + public static SubscribedSubredditRoomDatabase getDatabase(final Context context) { + if(INSTANCE == null) { + synchronized (SubscribedSubredditRoomDatabase.class) { + if(INSTANCE == null) { + INSTANCE = Room.databaseBuilder(context.getApplicationContext(), + SubscribedSubredditRoomDatabase.class, "subscribed_subreddits") + .build(); + } + } + } + return INSTANCE; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditViewModel.java new file mode 100644 index 00000000..bd092640 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubredditViewModel.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit; + +import android.app.Application; +import android.arch.lifecycle.AndroidViewModel; +import android.arch.lifecycle.LiveData; + +import java.util.List; + +public class SubscribedSubredditViewModel extends AndroidViewModel { + private SubscribedSubredditRepository mSubscribedSubredditRepository; + private LiveData<List<SubscribedSubredditData>> mAllSubscribedSubreddits; + + public SubscribedSubredditViewModel(Application application) { + super(application); + mSubscribedSubredditRepository = new SubscribedSubredditRepository(application); + mAllSubscribedSubreddits = mSubscribedSubredditRepository.getAllSubscribedSubreddits(); + } + + public LiveData<List<SubscribedSubredditData>> getAllSubscribedSubreddits() { + return mAllSubscribedSubreddits; + } + + public void insert(SubscribedSubredditData subscribedSubredditData) { + mSubscribedSubredditRepository.insert(subscribedSubredditData); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDao.java new file mode 100644 index 00000000..a2979dcd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDao.java @@ -0,0 +1,21 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.lifecycle.LiveData; +import android.arch.persistence.room.Dao; +import android.arch.persistence.room.Insert; +import android.arch.persistence.room.OnConflictStrategy; +import android.arch.persistence.room.Query; + +import java.util.List; + +@Dao +public interface SubscribedUserDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubscribedUserData subscribedUserData); + + @Query("DELETE FROM subscribed_users") + void deleteAllSubscribedUsers(); + + @Query("SELECT * from subscribed_users ORDER BY name COLLATE NOCASE ASC") + LiveData<List<SubscribedUserData>> getAllSubscribedUsers(); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserData.java new file mode 100644 index 00000000..9bf58700 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserData.java @@ -0,0 +1,37 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.persistence.room.ColumnInfo; +import android.arch.persistence.room.Entity; +import android.arch.persistence.room.PrimaryKey; +import android.support.annotation.NonNull; + +@Entity(tableName = "subscribed_users") +class SubscribedUserData { + @PrimaryKey + @NonNull + @ColumnInfo(name = "id") + private String id; + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + + SubscribedUserData(@NonNull String id, String name, String iconUrl) { + this.id = id; + this.name = name; + this.iconUrl = iconUrl; + } + + @NonNull + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java new file mode 100644 index 00000000..cb779a2c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRecyclerViewAdapter.java @@ -0,0 +1,73 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import java.util.List; + +import de.hdodenhof.circleimageview.CircleImageView; + +class SubscribedUserRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private Context mContext; + private List<SubscribedUserData> mSubscribedUserData; + private RequestManager glide; + + SubscribedUserRecyclerViewAdapter(Context context) { + mContext = context; + glide = Glide.with(context); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + return new UserViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_subscribed_subreddit, viewGroup, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { + if(!mSubscribedUserData.get(i).getIconUrl().equals("")) { + glide.load(mSubscribedUserData.get(i).getIconUrl()).into(((UserViewHolder) viewHolder).iconCircleImageView); + } else { + glide.load(R.drawable.subreddit_default_icon).into(((UserViewHolder) viewHolder).iconCircleImageView); + } + ((UserViewHolder) viewHolder).subredditNameTextView.setText(mSubscribedUserData.get(i).getName()); + } + + @Override + public int getItemCount() { + if(mSubscribedUserData != null) { + return mSubscribedUserData.size(); + } + return 0; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + glide.clear(((UserViewHolder) holder).iconCircleImageView); + } + + void setSubscribedUsers(List<SubscribedUserData> subscribedUsers){ + mSubscribedUserData = subscribedUsers; + notifyDataSetChanged(); + } + + + private class UserViewHolder extends RecyclerView.ViewHolder { + private final CircleImageView iconCircleImageView; + private final TextView subredditNameTextView; + + public UserViewHolder(View itemView) { + super(itemView); + iconCircleImageView = itemView.findViewById(R.id.subreddit_icon_circle_image_view_item_subscribed_subreddit); + subredditNameTextView = itemView.findViewById(R.id.subreddit_name_text_view_item_subscribed_subreddit); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRepository.java new file mode 100644 index 00000000..8dfc4204 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRepository.java @@ -0,0 +1,41 @@ +package ml.docilealligator.infinityforreddit; + +import android.app.Application; +import android.arch.lifecycle.LiveData; +import android.os.AsyncTask; + +import java.util.List; + +public class SubscribedUserRepository { + private SubscribedUserDao mSubscribedUserDao; + private LiveData<List<SubscribedUserData>> mAllSubscribedUsers; + + SubscribedUserRepository(Application application) { + SubscribedUserRoomDatabase db = SubscribedUserRoomDatabase.getDatabase(application); + mSubscribedUserDao = db.subscribedUserDao(); + mAllSubscribedUsers = mSubscribedUserDao.getAllSubscribedUsers(); + } + + LiveData<List<SubscribedUserData>> getAllSubscribedSubreddits() { + return mAllSubscribedUsers; + } + + public void insert(SubscribedUserData subscribedUserData) { + new SubscribedUserRepository.insertAsyncTask(mSubscribedUserDao).execute(subscribedUserData); + } + + private static class insertAsyncTask extends AsyncTask<SubscribedUserData, Void, Void> { + + private SubscribedUserDao mAsyncTaskDao; + + insertAsyncTask(SubscribedUserDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final SubscribedUserData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRoomDatabase.java new file mode 100644 index 00000000..0f6575d7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserRoomDatabase.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit; + +import android.arch.persistence.room.Database; +import android.arch.persistence.room.Room; +import android.arch.persistence.room.RoomDatabase; +import android.content.Context; + +@Database(entities = {SubscribedUserData.class}, version = 1) +public abstract class SubscribedUserRoomDatabase extends RoomDatabase { + private static SubscribedUserRoomDatabase INSTANCE; + + public abstract SubscribedUserDao subscribedUserDao(); + + public static SubscribedUserRoomDatabase getDatabase(final Context context) { + if(INSTANCE == null) { + synchronized (SubscribedUserRoomDatabase.class) { + if(INSTANCE == null) { + INSTANCE = Room.databaseBuilder(context.getApplicationContext(), + SubscribedUserRoomDatabase.class, "subscribed_users") + .build(); + } + } + } + return INSTANCE; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserViewModel.java new file mode 100644 index 00000000..44e40fe5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserViewModel.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit; + +import android.app.Application; +import android.arch.lifecycle.AndroidViewModel; +import android.arch.lifecycle.LiveData; + +import java.util.List; + +public class SubscribedUserViewModel extends AndroidViewModel { + private SubscribedUserRepository mSubscribedUserRepository; + private LiveData<List<SubscribedUserData>> mAllSubscribedUsers; + + public SubscribedUserViewModel(Application application) { + super(application); + mSubscribedUserRepository = new SubscribedUserRepository(application); + mAllSubscribedUsers = mSubscribedUserRepository.getAllSubscribedSubreddits(); + } + + public LiveData<List<SubscribedUserData>> getAllSubscribedUsers() { + return mAllSubscribedUsers; + } + + public void insert(SubscribedUserData subscribedUserData) { + mSubscribedUserRepository.insert(subscribedUserData); + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8d43bd79..5f50b6fa 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -13,64 +13,83 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - <android.support.design.widget.NavigationView - android:id="@+id/nav_view" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_gravity="start" - android:fitsSystemWindows="true"> - - <LinearLayout - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - <include - android:id="@+id/nav_header_main_activity" - layout="@layout/nav_header_main" /> - - <LinearLayout + <android.support.design.widget.NavigationView + android:id="@+id/nav_view" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="start" + android:fitsSystemWindows="true"> + + <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="16dp" - android:clickable="true" - android:focusable="true" - android:background="?attr/selectableItemBackground"> - - <ImageView - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_marginEnd="32dp" - android:layout_gravity="center_vertical" - android:src="@drawable/ic_account_circle_grey_24dp"/> - - <TextView - android:layout_width="wrap_content" + android:layout_height="match_parent"> + + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/profile" - android:textColor="@android:color/black" - android:layout_gravity="center_vertical"/> + android:orientation="vertical"> - </LinearLayout> + <include + android:id="@+id/nav_header_main_activity" + layout="@layout/nav_header_main" /> - <View - android:layout_width="match_parent" - android:layout_height="1dp" - android:background="#E0E0E0"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="16dp" + android:clickable="true" + android:focusable="true" + android:background="?attr/selectableItemBackground"> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/subscriptions" - android:layout_margin="16dp"/> + <ImageView + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginEnd="32dp" + android:layout_gravity="center_vertical" + android:src="@drawable/ic_account_circle_grey_24dp"/> - <android.support.v7.widget.RecyclerView - android:id="@+id/subscribed_subreddit_recycler_view_main_activity" - android:layout_width="match_parent" - android:layout_height="wrap_content" /> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/profile" + android:textColor="@android:color/black" + android:layout_gravity="center_vertical"/> + + </LinearLayout> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="#E0E0E0"/> + + <TextView + android:id="@+id/following_label_main_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/following" + android:layout_margin="16dp"/> + + <android.support.v7.widget.RecyclerView + android:id="@+id/subscribed_user_recycler_view_main_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/subscriptions_label_main_activity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/subscriptions" + android:layout_margin="16dp"/> + + <android.support.v7.widget.RecyclerView + android:id="@+id/subscribed_subreddit_recycler_view_main_activity" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </LinearLayout> - </LinearLayout> + </android.support.v4.widget.NestedScrollView> - </android.support.design.widget.NavigationView> + </android.support.design.widget.NavigationView> </android.support.v4.widget.DrawerLayout> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38b51769..1b973d6b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -17,5 +17,6 @@ <string name="karma_info">Karma: %1$d</string> <string name="profile">Profile</string> + <string name="following">Following</string> <string name="subscriptions">Subscriptions</string> </resources> |