diff --git a/.travis.yml b/.travis.yml
index bb4eb1c6d..edd221c68 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,8 @@ before_install:
jdk:
- oraclejdk8
+ - oraclejdk9
+ - oraclejdk11
sudo: required
android:
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 7c8fbd0e4..5d15189e6 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -54,6 +54,7 @@
android:label="@string/application_name"
android:resizeableActivity="true"
android:theme="@style/Theme.Amahi"
+ android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
+
diff --git a/src/main/java/org/amahi/anywhere/AmahiModule.java b/src/main/java/org/amahi/anywhere/AmahiModule.java
index 7dbf6598a..33a68928a 100644
--- a/src/main/java/org/amahi/anywhere/AmahiModule.java
+++ b/src/main/java/org/amahi/anywhere/AmahiModule.java
@@ -23,6 +23,7 @@
import android.content.Context;
import org.amahi.anywhere.activity.AuthenticationActivity;
+import org.amahi.anywhere.activity.FriendsActivity;
import org.amahi.anywhere.activity.NativeVideoActivity;
import org.amahi.anywhere.activity.NavigationActivity;
import org.amahi.anywhere.activity.OfflineFilesActivity;
@@ -35,6 +36,8 @@
import org.amahi.anywhere.activity.ServerFilesActivity;
import org.amahi.anywhere.cache.CacheModule;
import org.amahi.anywhere.fragment.AudioListFragment;
+import org.amahi.anywhere.fragment.FriendRequestsFragment;
+import org.amahi.anywhere.fragment.FriendsFragment;
import org.amahi.anywhere.fragment.NavigationFragment;
import org.amahi.anywhere.fragment.ServerAppsFragment;
import org.amahi.anywhere.fragment.ServerFileAudioFragment;
@@ -107,7 +110,10 @@
TvPlaybackVideoActivity.class,
TvPlaybackAudioActivity.class,
TvPlaybackAudioFragment.class,
- AudioMetadataRetrievingTask.class
+ AudioMetadataRetrievingTask.class,
+ FriendsFragment.class,
+ FriendRequestsFragment.class,
+ FriendsActivity.class
}
)
class AmahiModule {
diff --git a/src/main/java/org/amahi/anywhere/activity/FriendsActivity.java b/src/main/java/org/amahi/anywhere/activity/FriendsActivity.java
new file mode 100644
index 000000000..16730dfd9
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/activity/FriendsActivity.java
@@ -0,0 +1,121 @@
+package org.amahi.anywhere.activity;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.viewpager.widget.ViewPager;
+
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import com.google.android.material.tabs.TabLayout;
+
+import org.amahi.anywhere.AmahiApplication;
+import org.amahi.anywhere.R;
+import org.amahi.anywhere.adapter.FriendsPagerAdapter;
+import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.fragment.FriendRequestsFragment;
+import org.amahi.anywhere.fragment.FriendsFragment;
+import org.amahi.anywhere.server.client.ServerClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+public class FriendsActivity extends AppCompatActivity {
+
+ @Inject
+ ServerClient serverClient;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_friends);
+
+ setUpHomeNavigation();
+
+ setUpInjections();
+
+ setUpPager();
+
+ getTabLayout().setupWithViewPager(getPager());
+
+
+ }
+
+ private void setUpInjections() {
+ AmahiApplication.from(this).inject(this);
+ }
+
+ private void setUpHomeNavigation() {
+ getSupportActionBar().setTitle("Friends");
+ getSupportActionBar().setHomeButtonEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ private void setUpPager() {
+
+ List fragmentList = getFragments();
+
+ List fragmentTitles = getFragmentTitles();
+
+ FriendsPagerAdapter adapter = new FriendsPagerAdapter(getSupportFragmentManager(), fragmentList, fragmentTitles);
+ getPager().setAdapter(adapter);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem menuItem) {
+ switch (menuItem.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(menuItem);
+ }
+ }
+
+ private List getFragments() {
+
+ Fragment friendsFragment = new FriendsFragment();
+ Fragment friendRequestsFragment = new FriendRequestsFragment();
+ List fragmentList = new ArrayList<>();
+ fragmentList.add(friendsFragment);
+ fragmentList.add(friendRequestsFragment);
+
+ return fragmentList;
+ }
+
+ private List getFragmentTitles() {
+
+ List fragmentTitles = new ArrayList<>();
+ fragmentTitles.add("Friends");
+ fragmentTitles.add("Friend Requests");
+
+ return fragmentTitles;
+ }
+
+ private ViewPager getPager() {
+ return findViewById(R.id.pager_friends);
+ }
+
+ private TabLayout getTabLayout() {
+ return findViewById(R.id.tablayout_friends);
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ BusProvider.getBus().register(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ BusProvider.getBus().unregister(this);
+ }
+
+}
diff --git a/src/main/java/org/amahi/anywhere/activity/NavigationActivity.java b/src/main/java/org/amahi/anywhere/activity/NavigationActivity.java
index 20b8d5c89..9a596af23 100644
--- a/src/main/java/org/amahi/anywhere/activity/NavigationActivity.java
+++ b/src/main/java/org/amahi/anywhere/activity/NavigationActivity.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
+
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.drawerlayout.widget.DrawerLayout;
@@ -30,6 +31,7 @@
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
+
import android.view.MenuItem;
import android.view.View;
import android.view.ViewStub;
@@ -43,6 +45,7 @@
import org.amahi.anywhere.bus.AppSelectedEvent;
import org.amahi.anywhere.bus.AppsSelectedEvent;
import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendsSelectedEvent;
import org.amahi.anywhere.bus.OfflineFilesSelectedEvent;
import org.amahi.anywhere.bus.RecentFilesSelectedEvent;
import org.amahi.anywhere.bus.SettingsSelectedEvent;
@@ -345,6 +348,21 @@ private void showRecentFiles() {
startActivity(intent);
}
+ @Subscribe
+ public void onFriendsSelected(FriendsSelectedEvent event) {
+
+ showFriends();
+
+ if (isNavigationDrawerAvailable()) {
+ hideNavigationDrawer();
+ }
+ }
+
+ private void showFriends() {
+ Intent intent = Intents.Builder.with(this).buildFriendsActivity();
+ startActivity(intent);
+ }
+
@Subscribe
public void onShareSelected(ShareSelectedEvent event) {
setUpShare(event.getShare());
diff --git a/src/main/java/org/amahi/anywhere/adapter/FriendRequestsListAdapter.java b/src/main/java/org/amahi/anywhere/adapter/FriendRequestsListAdapter.java
new file mode 100644
index 000000000..c244351a2
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/adapter/FriendRequestsListAdapter.java
@@ -0,0 +1,86 @@
+package org.amahi.anywhere.adapter;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.amahi.anywhere.R;
+import org.amahi.anywhere.server.model.FriendRequestItem;
+
+import java.util.List;
+
+public class FriendRequestsListAdapter extends RecyclerView.Adapter {
+ private List friendRequestsList;
+ private Context context;
+
+ public FriendRequestsListAdapter(Context context, List friendRequestsList) {
+ this.context = context;
+ this.friendRequestsList = friendRequestsList;
+
+ }
+
+
+ @NonNull
+ @Override
+ public FriendRequestsListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new FriendRequestsListViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.friend_requests_list_item, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull FriendRequestsListViewHolder holder, int position) {
+ holder.friendEmailText.setText(friendRequestsList.get(position).getEmail());
+ int status = friendRequestsList.get(position).getStatus();
+
+ //set status text and color based on status value
+ String statusText = "Active";
+ int colorResourceId = R.color.status_active;
+ switch (status) {
+ case 0:
+ statusText = "Active";
+ colorResourceId = R.color.status_active;
+ break;
+ case 1:
+ statusText = "Expired";
+ colorResourceId = R.color.status_expired;
+ break;
+ case 2:
+ statusText = "Accepted";
+ colorResourceId = R.color.status_accepted;
+ break;
+ case 3:
+ statusText = "Rejected";
+ colorResourceId = R.color.status_rejected;
+ break;
+
+ }
+ holder.friendRequestStatus.setText(statusText);
+ GradientDrawable drawable = (GradientDrawable) holder.friendRequestStatus.getBackground();
+ drawable.setColor(context.getResources().getColor(colorResourceId));
+ holder.friendRequestStatus.setBackground(drawable);
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return friendRequestsList.size();
+ }
+
+ class FriendRequestsListViewHolder extends RecyclerView.ViewHolder {
+ TextView friendEmailText;
+ TextView friendRequestStatus;
+
+ FriendRequestsListViewHolder(View itemView) {
+ super(itemView);
+ friendEmailText = itemView.findViewById(R.id.text_friend_request_email);
+ friendRequestStatus = itemView.findViewById(R.id.text_friend_request_status);
+ }
+ }
+}
+
+
diff --git a/src/main/java/org/amahi/anywhere/adapter/FriendsListAdapter.java b/src/main/java/org/amahi/anywhere/adapter/FriendsListAdapter.java
new file mode 100644
index 000000000..3fc1a0352
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/adapter/FriendsListAdapter.java
@@ -0,0 +1,61 @@
+package org.amahi.anywhere.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.amahi.anywhere.R;
+import org.amahi.anywhere.server.model.FriendUserItem;
+
+import java.util.List;
+
+public class FriendsListAdapter extends RecyclerView.Adapter {
+ private List friendsList;
+ private Context context;
+
+ public FriendsListAdapter(Context context, List friendsList) {
+ this.context = context;
+ this.friendsList = friendsList;
+
+ }
+
+ @NonNull
+ @Override
+ public FriendsListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new FriendsListViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.friends_list_item, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull FriendsListViewHolder holder, int position) {
+ holder.friendEmailText.setText(friendsList.get(position).getEmail());
+ StringBuilder builder = new StringBuilder();
+ builder.append("Friends since ");
+ builder.append(friendsList.get(position).getCreatedAt());
+ holder.createdAt.setText(builder);
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return friendsList.size();
+ }
+
+ class FriendsListViewHolder extends RecyclerView.ViewHolder {
+ TextView friendEmailText;
+ TextView createdAt;
+
+ FriendsListViewHolder(View itemView) {
+ super(itemView);
+ friendEmailText = itemView.findViewById(R.id.text_friend_email);
+ createdAt = itemView.findViewById(R.id.text_friend_created_at);
+
+ }
+ }
+}
+
+
diff --git a/src/main/java/org/amahi/anywhere/adapter/FriendsPagerAdapter.java b/src/main/java/org/amahi/anywhere/adapter/FriendsPagerAdapter.java
new file mode 100644
index 000000000..fea1093e6
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/adapter/FriendsPagerAdapter.java
@@ -0,0 +1,36 @@
+package org.amahi.anywhere.adapter;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+
+import java.util.List;
+
+public class FriendsPagerAdapter extends FragmentStatePagerAdapter {
+ private List fragmentList;
+ private List fragmentTitles;
+
+ public FriendsPagerAdapter(FragmentManager fm, List fragmentList,
+ List fragmentTitles) {
+ super(fm);
+ this.fragmentList = fragmentList;
+ this.fragmentTitles = fragmentTitles;
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return fragmentTitles.get(position);
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ return fragmentList.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return fragmentList.size();
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadFailedEvent.java b/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadFailedEvent.java
new file mode 100644
index 000000000..4a213935a
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadFailedEvent.java
@@ -0,0 +1,5 @@
+package org.amahi.anywhere.bus;
+
+
+public class FriendRequestsLoadFailedEvent implements BusEvent {
+}
diff --git a/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadedEvent.java b/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadedEvent.java
new file mode 100644
index 000000000..2c585e7b5
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/bus/FriendRequestsLoadedEvent.java
@@ -0,0 +1,18 @@
+package org.amahi.anywhere.bus;
+
+
+import org.amahi.anywhere.server.model.FriendRequestItem;
+
+import java.util.List;
+
+public class FriendRequestsLoadedEvent implements BusEvent {
+ private final List friendRequests;
+
+ public FriendRequestsLoadedEvent(List friendRequests) {
+ this.friendRequests = friendRequests;
+ }
+
+ public List getFriendRequests() {
+ return friendRequests;
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadFailedEvent.java b/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadFailedEvent.java
new file mode 100644
index 000000000..003e6bf57
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadFailedEvent.java
@@ -0,0 +1,4 @@
+package org.amahi.anywhere.bus;
+
+public class FriendUsersLoadFailedEvent implements BusEvent {
+}
diff --git a/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadedEvent.java b/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadedEvent.java
new file mode 100644
index 000000000..69210e354
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/bus/FriendUsersLoadedEvent.java
@@ -0,0 +1,21 @@
+package org.amahi.anywhere.bus;
+
+import android.util.Log;
+
+import org.amahi.anywhere.server.model.FriendUserItem;
+
+import java.util.List;
+
+public class FriendUsersLoadedEvent implements BusEvent {
+ private final List friendUsers;
+
+ public FriendUsersLoadedEvent(List friendUsers) {
+ this.friendUsers = friendUsers;
+
+ }
+
+ public List getFriendUsers() {
+ Log.d("entered", "getLEFriendUsrs:");
+ return friendUsers;
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/bus/FriendsSelectedEvent.java b/src/main/java/org/amahi/anywhere/bus/FriendsSelectedEvent.java
new file mode 100644
index 000000000..d66e9ab09
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/bus/FriendsSelectedEvent.java
@@ -0,0 +1,4 @@
+package org.amahi.anywhere.bus;
+
+public class FriendsSelectedEvent implements BusEvent {
+}
diff --git a/src/main/java/org/amahi/anywhere/fragment/AlertDialogFragment.java b/src/main/java/org/amahi/anywhere/fragment/AlertDialogFragment.java
index c67c26360..5212ff670 100644
--- a/src/main/java/org/amahi/anywhere/fragment/AlertDialogFragment.java
+++ b/src/main/java/org/amahi/anywhere/fragment/AlertDialogFragment.java
@@ -3,10 +3,13 @@
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
+
import androidx.annotation.NonNull;
import android.app.AlertDialog;
+
import androidx.fragment.app.DialogFragment;
+
import android.util.Log;
import org.amahi.anywhere.R;
@@ -40,6 +43,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) {
case DUPLICATE_FILE_DIALOG:
buildDuplicateDialog();
break;
+
}
return builder.create();
@@ -60,6 +64,8 @@ private void buildDuplicateDialog() {
.setNegativeButton(getString(R.string.button_no), this);
}
+
+
@Override
public void onClick(DialogInterface dialog, int which) {
diff --git a/src/main/java/org/amahi/anywhere/fragment/FriendRequestsFragment.java b/src/main/java/org/amahi/anywhere/fragment/FriendRequestsFragment.java
new file mode 100644
index 000000000..0f37ecbd7
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/fragment/FriendRequestsFragment.java
@@ -0,0 +1,106 @@
+package org.amahi.anywhere.fragment;
+
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.squareup.otto.Subscribe;
+
+import org.amahi.anywhere.AmahiApplication;
+import org.amahi.anywhere.R;
+import org.amahi.anywhere.adapter.FriendRequestsListAdapter;
+import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendRequestsLoadedEvent;
+import org.amahi.anywhere.server.client.ServerClient;
+import org.amahi.anywhere.server.model.FriendRequestItem;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * Friend Requests Fragment, shows list of friend requests.
+ */
+public class FriendRequestsFragment extends Fragment {
+
+ @Inject
+ ServerClient serverClient;
+ private List friendRequestsList = new ArrayList<>();
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_friend_requests, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ setUpInjections();
+
+ setUpFriendRequestsList(savedInstanceState);
+
+ }
+
+ private void setUpInjections() {
+ AmahiApplication.from(getActivity()).inject(this);
+ }
+
+ private RecyclerView getRecyclerView() {
+ return getView().findViewById(R.id.list_friend_requests);
+ }
+
+ private void setUpFriendRequestsList(Bundle state) {
+ if (serverClient.isConnected()) {
+ serverClient.getFriendRequests();
+ }
+ setUpListAdapter();
+
+
+ }
+
+
+
+ private void setUpListAdapter() {
+
+ FriendRequestsListAdapter adapter = new FriendRequestsListAdapter(getContext(), friendRequestsList);
+ getRecyclerView().setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
+ getRecyclerView().setAdapter(adapter);
+ }
+
+ private FriendRequestsListAdapter getListAdapter() {
+ return (FriendRequestsListAdapter) getRecyclerView().getAdapter();
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ BusProvider.getBus().register(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ BusProvider.getBus().unregister(this);
+ }
+
+
+ @Subscribe
+ public void onFriendRequestsLoaded(FriendRequestsLoadedEvent event) {
+ friendRequestsList = event.getFriendRequests();
+ setUpListAdapter();
+ }
+
+}
diff --git a/src/main/java/org/amahi/anywhere/fragment/FriendsFragment.java b/src/main/java/org/amahi/anywhere/fragment/FriendsFragment.java
new file mode 100644
index 000000000..5da358b36
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/fragment/FriendsFragment.java
@@ -0,0 +1,108 @@
+package org.amahi.anywhere.fragment;
+
+import android.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.squareup.otto.Subscribe;
+
+import org.amahi.anywhere.AmahiApplication;
+import org.amahi.anywhere.R;
+import org.amahi.anywhere.adapter.FriendsListAdapter;
+import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendUsersLoadedEvent;
+import org.amahi.anywhere.server.client.ServerClient;
+import org.amahi.anywhere.server.model.FriendUserItem;
+
+import java.util.ArrayList;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+/**
+ * Friends Fragment, shows list of friended users.
+ */
+public class FriendsFragment extends Fragment{
+
+ @Inject
+ ServerClient serverClient;
+ private List friendsList = new ArrayList<>();
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ return inflater.inflate(R.layout.fragment_friends, container, false);
+
+ }
+
+ private void setUpInjections() {
+ AmahiApplication.from(getActivity()).inject(this);
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ setUpInjections();
+
+ setUpFriendsList(savedInstanceState);
+
+
+ }
+
+ private RecyclerView getRecyclerView() {
+ return (RecyclerView) getView().findViewById(R.id.list_friends);
+ }
+
+ private void setUpFriendsList(Bundle state) {
+ if (serverClient.isConnected()) {
+ serverClient.getFriendUsers();
+ }
+ setUpListAdapter();
+ }
+
+
+
+
+ private FriendsListAdapter getListAdapter() {
+ return (FriendsListAdapter) getRecyclerView().getAdapter();
+ }
+
+
+ private void setUpListAdapter() {
+
+ FriendsListAdapter adapter = new FriendsListAdapter(getContext(), friendsList);
+ getRecyclerView().setLayoutManager(new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false));
+ getRecyclerView().setAdapter(adapter);
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ BusProvider.getBus().register(this);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ BusProvider.getBus().unregister(this);
+ }
+
+ @Subscribe
+ public void onFriendUsersLoaded(FriendUsersLoadedEvent event) {
+ friendsList = event.getFriendUsers();
+ setUpListAdapter();
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java b/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java
index d3d2fe9b9..dc6ef38f4 100644
--- a/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java
+++ b/src/main/java/org/amahi/anywhere/fragment/NavigationFragment.java
@@ -31,6 +31,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.preference.PreferenceManager;
+
import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -54,6 +55,7 @@
import org.amahi.anywhere.adapter.NavigationDrawerAdapter;
import org.amahi.anywhere.bus.AppsSelectedEvent;
import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendsSelectedEvent;
import org.amahi.anywhere.bus.OfflineFilesSelectedEvent;
import org.amahi.anywhere.bus.RecentFilesSelectedEvent;
import org.amahi.anywhere.bus.ServerConnectedEvent;
@@ -355,6 +357,7 @@ private void setUpNavigationList() {
showServers();
hideOfflineLayout();
hideRecentLayout();
+ hideFriendsLayout();
}
}
@@ -367,6 +370,10 @@ private void hideRecentLayout() {
getRecentFilesLayout().setVisibility(View.GONE);
}
+ private void hideFriendsLayout() {
+ getFriendsLayout().setVisibility(View.GONE);
+ }
+
private void setUpNavigationAdapter() {
//Setting the layout of a vertical list dynamically.
@@ -394,6 +401,10 @@ private LinearLayout getRecentFilesLayout() {
return getView().findViewById(R.id.recent_files_layout);
}
+ private LinearLayout getFriendsLayout() {
+ return getView().findViewById(R.id.friends_layout);
+ }
+
private LinearLayout getLinearLayoutSelectedServer() {
return getView().findViewById(R.id.server_select_LinearLayout);
}
@@ -418,6 +429,8 @@ private void setUpNavigationListener() {
getOfflineFilesLayout().setOnClickListener(view -> showOfflineFiles());
getRecentFilesLayout().setOnClickListener(view -> showRecentFiles());
+
+ getFriendsLayout().setOnClickListener(view -> showFriends());
}
private void selectedServerListener(int position) {
@@ -492,6 +505,7 @@ private void setUpServerSelectListener() {
showServers();
hideOfflineLayout();
hideRecentLayout();
+ hideFriendsLayout();
}
});
}
@@ -505,6 +519,7 @@ private void showNavigationItems() {
getOfflineFilesLayout().setVisibility(View.VISIBLE);
getRecentFilesLayout().setVisibility(View.VISIBLE);
+ getFriendsLayout().setVisibility(View.VISIBLE);
}
@Subscribe
@@ -613,6 +628,10 @@ private void showRecentFiles() {
BusProvider.getBus().post(new RecentFilesSelectedEvent());
}
+ private void showFriends() {
+ BusProvider.getBus().post(new FriendsSelectedEvent());
+ }
+
@Subscribe
public void onServerConnectionChanged(ServerConnectionChangedEvent event) {
areServersVisible = false;
diff --git a/src/main/java/org/amahi/anywhere/server/api/ServerApi.java b/src/main/java/org/amahi/anywhere/server/api/ServerApi.java
index 937c789f8..677817e2b 100644
--- a/src/main/java/org/amahi/anywhere/server/api/ServerApi.java
+++ b/src/main/java/org/amahi/anywhere/server/api/ServerApi.java
@@ -19,6 +19,8 @@
package org.amahi.anywhere.server.api;
+import org.amahi.anywhere.server.model.FriendRequestResponse;
+import org.amahi.anywhere.server.model.FriendUserResponse;
import org.amahi.anywhere.server.model.ServerApp;
import org.amahi.anywhere.server.model.ServerFile;
import org.amahi.anywhere.server.model.ServerFileMetadata;
@@ -74,4 +76,14 @@ Call getFileMetadata(
@GET("/apps")
Call> getApps(
@Header("Session") String session);
+
+ @GET("/frnd/users")
+ Call getFriendUsers(
+ @Header("api-key") String apiKey);
+
+
+ @GET("/frnd/requests")
+ Call getFriendRequests(
+ @Header("api-key") String apiKey);
+
}
diff --git a/src/main/java/org/amahi/anywhere/server/client/ServerClient.java b/src/main/java/org/amahi/anywhere/server/client/ServerClient.java
index b5dd13282..0c20df7f1 100644
--- a/src/main/java/org/amahi/anywhere/server/client/ServerClient.java
+++ b/src/main/java/org/amahi/anywhere/server/client/ServerClient.java
@@ -43,6 +43,8 @@
import org.amahi.anywhere.server.model.ServerFileMetadata;
import org.amahi.anywhere.server.model.ServerRoute;
import org.amahi.anywhere.server.model.ServerShare;
+import org.amahi.anywhere.server.response.FriendRequestsResponse;
+import org.amahi.anywhere.server.response.FriendUsersResponse;
import org.amahi.anywhere.server.response.ServerAppsResponse;
import org.amahi.anywhere.server.response.ServerFileDeleteResponse;
import org.amahi.anywhere.server.response.ServerFileUploadResponse;
@@ -85,6 +87,9 @@ public class ServerClient {
private String serverAddress;
private ApiConnection serverConnection;
+ private static final String BASE_URL = "https://friending-testing.herokuapp.com";
+ private static final String apiKey = "abcdef";
+
private int network;
@Inject
@@ -129,7 +134,7 @@ private boolean isServerRouteLoaded() {
}
private void startServerConnectionDetection() {
- this.serverAddress = serverRoute.getLocalAddress();
+ this.serverAddress = BASE_URL;
this.serverApi = buildServerApi();
ServerConnectionDetectingTask.execute(serverRoute);
@@ -141,7 +146,8 @@ private ServerApi buildServerApi() {
@Subscribe
public void onServerConnectionDetected(ServerConnectionDetectedEvent event) {
- this.serverAddress = event.getServerAddress();
+ this.serverAddress = BASE_URL;
+ //this.serverAddress = event.getServerAddress();
this.serverApi = buildServerApi();
finishServerConnectionDetection();
@@ -220,7 +226,8 @@ public void connectLocal() {
if (!isServerRouteLoaded()) {
return;
}
- this.serverAddress = serverRoute.getLocalAddress();
+ this.serverAddress = BASE_URL;
+ //this.serverAddress = serverRoute.getLocalAddress();
this.serverApi = buildServerApi();
finishServerConnectionDetection();
}
@@ -230,7 +237,8 @@ public void connectRemote() {
if (!isServerRouteLoaded()) {
return;
}
- this.serverAddress = serverRoute.getRemoteAddress();
+ this.serverAddress = BASE_URL;
+ //this.serverAddress = serverRoute.getRemoteAddress();
this.serverApi = buildServerApi();
finishServerConnectionDetection();
}
@@ -327,4 +335,12 @@ public void getFileMetadata(ServerShare share, ServerFile file, Callback friendRequests;
+
+ public void setSuccess(boolean success){
+ this.success = success;
+ }
+
+ public boolean isSuccess(){
+ return success;
+ }
+
+ public void setFriendRequests(List friendRequests){
+ this.friendRequests = friendRequests;
+ }
+
+ public List getFriendRequests(){
+ return friendRequests;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "FriendRequestResponse{" +
+ "success = '" + success + '\'' +
+ ",friend_request = '" + friendRequests + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/FriendUserItem.java b/src/main/java/org/amahi/anywhere/server/model/FriendUserItem.java
new file mode 100644
index 000000000..95b03a687
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/FriendUserItem.java
@@ -0,0 +1,85 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class FriendUserItem{
+
+ @SerializedName("amahi_user_id")
+ private int amahiUserId;
+
+ @SerializedName("updated_at")
+ private String updatedAt;
+
+ @SerializedName("system_id")
+ private int systemId;
+
+ @SerializedName("created_at")
+ private String createdAt;
+
+ @SerializedName("id")
+ private int id;
+
+ @SerializedName("email")
+ private String email;
+
+ public void setAmahiUserId(int amahiUserId){
+ this.amahiUserId = amahiUserId;
+ }
+
+ public int getAmahiUserId(){
+ return amahiUserId;
+ }
+
+ public void setUpdatedAt(String updatedAt){
+ this.updatedAt = updatedAt;
+ }
+
+ public String getUpdatedAt(){
+ return updatedAt;
+ }
+
+ public void setSystemId(int systemId){
+ this.systemId = systemId;
+ }
+
+ public int getSystemId(){
+ return systemId;
+ }
+
+ public void setCreatedAt(String createdAt){
+ this.createdAt = createdAt;
+ }
+
+ public String getCreatedAt(){
+ return createdAt;
+ }
+
+ public void setId(int id){
+ this.id = id;
+ }
+
+ public int getId(){
+ return id;
+ }
+
+ public void setEmail(String email){
+ this.email = email;
+ }
+
+ public String getEmail(){
+ return email;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "FriendUserItem{" +
+ "amahi_user_id = '" + amahiUserId + '\'' +
+ ",updated_at = '" + updatedAt + '\'' +
+ ",system_id = '" + systemId + '\'' +
+ ",created_at = '" + createdAt + '\'' +
+ ",id = '" + id + '\'' +
+ ",email = '" + email + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/FriendUserResponse.java b/src/main/java/org/amahi/anywhere/server/model/FriendUserResponse.java
new file mode 100644
index 000000000..7d3f53e4d
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/FriendUserResponse.java
@@ -0,0 +1,39 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.List;
+
+public class FriendUserResponse{
+
+ @SerializedName("data")
+ private List friendUsers;
+
+ @SerializedName("success")
+ private boolean success;
+
+ public void setFriendUsers(List friendUsers){
+ this.friendUsers = friendUsers;
+ }
+
+ public List getFriendUsers(){
+ return friendUsers;
+ }
+
+ public void setSuccess(boolean success){
+ this.success = success;
+ }
+
+ public boolean isSuccess(){
+ return success;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "FriendUserResponse{" +
+ "friend_user = '" + friendUsers + '\'' +
+ ",success = '" + success + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/NewFriendRequest.java b/src/main/java/org/amahi/anywhere/server/model/NewFriendRequest.java
new file mode 100644
index 000000000..fab3c6a04
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/NewFriendRequest.java
@@ -0,0 +1,49 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class NewFriendRequest{
+
+ @SerializedName("id")
+ private String id;
+
+ @SerializedName("status_txt")
+ private String statusTxt;
+
+ @SerializedName("email")
+ private String email;
+
+ public void setId(String id){
+ this.id = id;
+ }
+
+ public String getId(){
+ return id;
+ }
+
+ public void setStatusTxt(String statusTxt){
+ this.statusTxt = statusTxt;
+ }
+
+ public String getStatusTxt(){
+ return statusTxt;
+ }
+
+ public void setEmail(String email){
+ this.email = email;
+ }
+
+ public String getEmail(){
+ return email;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "NewFriendRequest{" +
+ "id = '" + id + '\'' +
+ ",status_txt = '" + statusTxt + '\'' +
+ ",email = '" + email + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/NewFriendRequestResponse.java b/src/main/java/org/amahi/anywhere/server/model/NewFriendRequestResponse.java
new file mode 100644
index 000000000..01ba8df12
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/NewFriendRequestResponse.java
@@ -0,0 +1,49 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class NewFriendRequestResponse{
+
+ @SerializedName("success")
+ private boolean success;
+
+ @SerializedName("message")
+ private String message;
+
+ @SerializedName("request")
+ private NewFriendRequest newFriendRequest;
+
+ public void setSuccess(boolean success){
+ this.success = success;
+ }
+
+ public boolean isSuccess(){
+ return success;
+ }
+
+ public void setMessage(String message){
+ this.message = message;
+ }
+
+ public String getMessage(){
+ return message;
+ }
+
+ public void setNewFriendRequest(NewFriendRequest newFriendRequest){
+ this.newFriendRequest = newFriendRequest;
+ }
+
+ public NewFriendRequest getNewFriendRequest(){
+ return newFriendRequest;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "NewFriendRequestResponse{" +
+ "success = '" + success + '\'' +
+ ",message = '" + message + '\'' +
+ ",“new_friend_request” = '" + newFriendRequest + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/PostFriendRequest.java b/src/main/java/org/amahi/anywhere/server/model/PostFriendRequest.java
new file mode 100644
index 000000000..b504fbdb0
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/PostFriendRequest.java
@@ -0,0 +1,28 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class PostFriendRequest {
+
+ @SerializedName("email")
+ private String email;
+
+ @SerializedName("pin")
+ private int pin;
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public int getPin() {
+ return pin;
+ }
+
+ public void setPin(int pin) {
+ this.pin = pin;
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/model/ResendFriendRequestResponse.java b/src/main/java/org/amahi/anywhere/server/model/ResendFriendRequestResponse.java
new file mode 100644
index 000000000..809d168cc
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/model/ResendFriendRequestResponse.java
@@ -0,0 +1,37 @@
+package org.amahi.anywhere.server.model;
+
+import com.google.gson.annotations.SerializedName;
+
+public class ResendFriendRequestResponse{
+
+ @SerializedName("message")
+ private String message;
+
+ @SerializedName("success")
+ private boolean success;
+
+ public void setMessage(String message){
+ this.message = message;
+ }
+
+ public String getMessage(){
+ return message;
+ }
+
+ public void setSuccess(boolean success){
+ this.success = success;
+ }
+
+ public boolean isSuccess(){
+ return success;
+ }
+
+ @Override
+ public String toString(){
+ return
+ "ResendFriendRequestResponse{" +
+ "“message” = '" + message + '\'' +
+ ",“success” = '" + success + '\'' +
+ "}";
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/response/FriendRequestsResponse.java b/src/main/java/org/amahi/anywhere/server/response/FriendRequestsResponse.java
new file mode 100644
index 000000000..413f1fef9
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/response/FriendRequestsResponse.java
@@ -0,0 +1,29 @@
+package org.amahi.anywhere.server.response;
+
+import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendRequestsLoadFailedEvent;
+import org.amahi.anywhere.bus.FriendRequestsLoadedEvent;
+import org.amahi.anywhere.server.model.FriendRequestResponse;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.HttpException;
+import retrofit2.Response;
+
+public class FriendRequestsResponse implements Callback {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()) {
+ FriendRequestResponse friendRequestResponse = response.body();
+ BusProvider.getBus().post(new FriendRequestsLoadedEvent(friendRequestResponse.getFriendRequests()));
+ } else
+ this.onFailure(call, new HttpException(response));
+
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ BusProvider.getBus().post(new FriendRequestsLoadFailedEvent());
+
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/server/response/FriendUsersResponse.java b/src/main/java/org/amahi/anywhere/server/response/FriendUsersResponse.java
new file mode 100644
index 000000000..7d80d6202
--- /dev/null
+++ b/src/main/java/org/amahi/anywhere/server/response/FriendUsersResponse.java
@@ -0,0 +1,31 @@
+package org.amahi.anywhere.server.response;
+
+
+import org.amahi.anywhere.bus.BusProvider;
+import org.amahi.anywhere.bus.FriendUsersLoadFailedEvent;
+import org.amahi.anywhere.bus.FriendUsersLoadedEvent;
+import org.amahi.anywhere.server.model.FriendUserResponse;
+
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.HttpException;
+import retrofit2.Response;
+
+
+public class FriendUsersResponse implements Callback {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if (response.isSuccessful()) {
+ FriendUserResponse friendUserResponse = response.body();
+ BusProvider.getBus().post(new FriendUsersLoadedEvent(friendUserResponse.getFriendUsers()));
+ } else {
+ this.onFailure(call, new HttpException(response));
+ }
+
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ BusProvider.getBus().post(new FriendUsersLoadFailedEvent());
+ }
+}
diff --git a/src/main/java/org/amahi/anywhere/util/Fragments.java b/src/main/java/org/amahi/anywhere/util/Fragments.java
index 97d52d05e..fa38f9f1f 100644
--- a/src/main/java/org/amahi/anywhere/util/Fragments.java
+++ b/src/main/java/org/amahi/anywhere/util/Fragments.java
@@ -21,7 +21,9 @@
import android.content.Context;
import android.os.Bundle;
+
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
+
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.appcompat.app.AppCompatActivity;
@@ -187,6 +189,7 @@ public static BottomSheetDialogFragment buildOfflineFileOptionsDialogFragment()
return fragment;
}
+
}
public static final class Operator {
diff --git a/src/main/java/org/amahi/anywhere/util/Intents.java b/src/main/java/org/amahi/anywhere/util/Intents.java
index 92b45abaa..b2abb6e18 100644
--- a/src/main/java/org/amahi/anywhere/util/Intents.java
+++ b/src/main/java/org/amahi/anywhere/util/Intents.java
@@ -27,9 +27,11 @@
import android.net.Uri;
import android.os.Parcelable;
import android.provider.MediaStore;
+
import androidx.annotation.NonNull;
import org.amahi.anywhere.R;
+import org.amahi.anywhere.activity.FriendsActivity;
import org.amahi.anywhere.activity.IntroductionActivity;
import org.amahi.anywhere.activity.OfflineFilesActivity;
import org.amahi.anywhere.activity.RecentFilesActivity;
@@ -117,6 +119,10 @@ public Intent buildRecentFilesActivity() {
return new Intent(context, RecentFilesActivity.class);
}
+ public Intent buildFriendsActivity() {
+ return new Intent(context, FriendsActivity.class);
+ }
+
public Intent buildServerTvFilesActivity(ServerShare share, ServerFile file) {
Intent intent = new Intent(context, ServerFileTvActivity.class);
intent.putExtra(Extras.SERVER_FILE, file);
diff --git a/src/main/res/drawable-notnight/ic_friends.xml b/src/main/res/drawable-notnight/ic_friends.xml
new file mode 100644
index 000000000..087a5904b
--- /dev/null
+++ b/src/main/res/drawable-notnight/ic_friends.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/src/main/res/drawable/friend_status_background.xml b/src/main/res/drawable/friend_status_background.xml
new file mode 100644
index 000000000..49ba6fea1
--- /dev/null
+++ b/src/main/res/drawable/friend_status_background.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/src/main/res/drawable/ic_add_friend.xml b/src/main/res/drawable/ic_add_friend.xml
new file mode 100644
index 000000000..c273ca40b
--- /dev/null
+++ b/src/main/res/drawable/ic_add_friend.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/src/main/res/drawable/ic_friends.xml b/src/main/res/drawable/ic_friends.xml
new file mode 100644
index 000000000..e9c32676b
--- /dev/null
+++ b/src/main/res/drawable/ic_friends.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/src/main/res/drawable/ic_resend.xml b/src/main/res/drawable/ic_resend.xml
new file mode 100644
index 000000000..0ff0a64d7
--- /dev/null
+++ b/src/main/res/drawable/ic_resend.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/src/main/res/layout/activity_friends.xml b/src/main/res/layout/activity_friends.xml
new file mode 100644
index 000000000..e2c2ae16c
--- /dev/null
+++ b/src/main/res/layout/activity_friends.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/dialog_add_friend.xml b/src/main/res/layout/dialog_add_friend.xml
new file mode 100644
index 000000000..d73a7b6f1
--- /dev/null
+++ b/src/main/res/layout/dialog_add_friend.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/src/main/res/layout/fragment_friend_requests.xml b/src/main/res/layout/fragment_friend_requests.xml
new file mode 100644
index 000000000..7ff8ef9db
--- /dev/null
+++ b/src/main/res/layout/fragment_friend_requests.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/src/main/res/layout/fragment_friends.xml b/src/main/res/layout/fragment_friends.xml
new file mode 100644
index 000000000..626116caa
--- /dev/null
+++ b/src/main/res/layout/fragment_friends.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/src/main/res/layout/fragment_navigation.xml b/src/main/res/layout/fragment_navigation.xml
index edf107c4c..0052faa59 100644
--- a/src/main/res/layout/fragment_navigation.xml
+++ b/src/main/res/layout/fragment_navigation.xml
@@ -151,6 +151,29 @@
android:textStyle="bold" />
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/friend_requests_list_item.xml b/src/main/res/layout/friend_requests_list_item.xml
new file mode 100644
index 000000000..74ff3f05e
--- /dev/null
+++ b/src/main/res/layout/friend_requests_list_item.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/friends_list_item.xml b/src/main/res/layout/friends_list_item.xml
new file mode 100644
index 000000000..b15c262f5
--- /dev/null
+++ b/src/main/res/layout/friends_list_item.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/values-v21/themes.xml b/src/main/res/values-v21/themes.xml
index 68f84ae63..e0b24fe84 100644
--- a/src/main/res/values-v21/themes.xml
+++ b/src/main/res/values-v21/themes.xml
@@ -37,6 +37,14 @@
- 8dp
+
+
+
+
+
+