diff --git a/.idea/misc.xml b/.idea/misc.xml
index fbb6828..5d19981 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -37,7 +37,7 @@
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 97f9ac0..1a818a5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,18 +9,12 @@ buildscript {
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
+apply plugin: 'realm-android'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
-
-repositories {
- maven { url 'https://maven.fabric.io/public' }
-}
-
-apply plugin: 'io.fabric'
-
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
@@ -40,6 +34,14 @@ android {
}
productFlavors {
}
+
+ configurations.all {
+ resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
+ }
+
+ realm {
+ syncEnabled = true;
+ }
}
dependencies {
@@ -64,7 +66,6 @@ dependencies {
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true;
}
+ compile 'de.hdodenhof:circleimageview:2.1.0'
+ compile "com.squareup.picasso:picasso:2.4.0"
}
-
-
-
diff --git a/app/src/main/java/io/devsummit/android/Activities/MainActivity.java b/app/src/main/java/io/devsummit/android/Activities/MainActivity.java
index 2d0b980..23ae334 100644
--- a/app/src/main/java/io/devsummit/android/Activities/MainActivity.java
+++ b/app/src/main/java/io/devsummit/android/Activities/MainActivity.java
@@ -7,77 +7,116 @@
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
import android.view.MenuItem;
import android.view.View;
-import android.widget.FrameLayout;
import android.widget.ProgressBar;
-
-import io.devsummit.android.Helpers.ExitAppHelper;
-import io.devsummit.android.R;
+import io.devsummit.android.Controllers.UserFeedController;
import io.devsummit.android.Controllers.UserTicketController;
import io.devsummit.android.Fragments.FeedFragment;
+import io.devsummit.android.Fragments.TicketFragment;
+import io.devsummit.android.Helpers.ExitAppHelper;
import io.devsummit.android.Helpers.UserAuthenticationHelper;
+import io.devsummit.android.R;
+import io.devsummit.android.ViewAdapters.MainViewPagerAdapter;
+import io.realm.Realm;
public class MainActivity extends AppCompatActivity {
+ public static UserTicketController userTicketController;
+ public static UserFeedController userFeedController;
+ public static TicketFragment ticketFragment;
+ public static FeedFragment feedFragment;
private UserAuthenticationHelper authHelper;
- private UserTicketController userTicketController;
private ProgressBar mProgressView;
private BottomNavigationView navigation;
+ private ViewPager viewPager;
+ MenuItem prevMenuItem;
@Override
public void onBackPressed() {
ExitAppHelper.exitTheApp(this);
}
- private FrameLayout mContainer;
+ public static MainActivity mMainActivity;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
- mContainer.removeAllViews();
- Fragment frag = null;
- String token = authHelper.getAccessToken();
switch (item.getItemId()) {
case R.id.navigation_home:
- frag = FeedFragment.newInstance();
+ viewPager.setCurrentItem(0);
break;
case R.id.tickets:
- userTicketController.getUserTickets(token, MainActivity.this);
+ viewPager.setCurrentItem(1);
break;
}
- if (frag != null) {
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- ft.add(R.id.container, frag, frag.getTag());
- ft.commit();
- }
return true;
}
};
+ private ViewPager.OnPageChangeListener mOnPageChangeListerner
+ = new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ if (prevMenuItem != null) {
+ prevMenuItem.setChecked(false);
+ }
+ else
+ {
+ navigation.getMenu().getItem(0).setChecked(false);
+ }
+ Log.d("page", "onPageSelected: "+position);
+ navigation.getMenu().getItem(position).setChecked(true);
+
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+
+ }
+
+ };
+
+ private void setupViewPager(ViewPager viewPager) {
+ MainViewPagerAdapter adapter = new MainViewPagerAdapter(getSupportFragmentManager());
+ feedFragment=new FeedFragment();
+ ticketFragment=new TicketFragment();
+ adapter.addFragment(feedFragment);
+ adapter.addFragment(ticketFragment);
+ viewPager.setAdapter(adapter);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ //Initializing viewPager
+ viewPager = (ViewPager) findViewById(R.id.viewpager);
+ mMainActivity = MainActivity.this;
authHelper = new UserAuthenticationHelper(this);
mProgressView = (ProgressBar) findViewById(R.id.main_activity_loader);
navigation = (BottomNavigationView) findViewById(R.id.navigation);
userTicketController = new UserTicketController(MainActivity.this);
- mContainer = (FrameLayout) findViewById(R.id.container);
- }
+ userFeedController = new UserFeedController(MainActivity.this);
- @Override
- protected void onResume() {
- super.onResume();
+ setupViewPager(viewPager);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
- userTicketController.getUserTickets(authHelper.getAccessToken(), MainActivity.this);
+ viewPager.addOnPageChangeListener(mOnPageChangeListerner);
+ userTicketController.getUserTickets(authHelper.getAccessToken());
+
+ Realm.init(getApplicationContext());
}
/**
diff --git a/app/src/main/java/io/devsummit/android/Controllers/UserFeedController.java b/app/src/main/java/io/devsummit/android/Controllers/UserFeedController.java
new file mode 100644
index 0000000..6fdf36c
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Controllers/UserFeedController.java
@@ -0,0 +1,62 @@
+package io.devsummit.android.Controllers;
+
+import android.content.Context;
+
+import io.devsummit.android.Activities.MainActivity;
+import io.devsummit.android.Helpers.InetConnectionHelper;
+import io.devsummit.android.Helpers.RealmHelper;
+import io.devsummit.android.Models.UserFeedModel;
+import io.devsummit.android.Remote.APIService;
+import io.devsummit.android.Remote.ApiUtils;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+/**
+ * Created by wlisrausr on 04/10/17.
+ */
+
+public class UserFeedController {
+ private APIService mAPIService;
+ private MainActivity mMainActivity;
+ private UserFeedModel userFeedResponse;
+
+ public UserFeedController(MainActivity act) {
+ mMainActivity = act;
+ userFeedResponse = new UserFeedModel();
+ mAPIService = ApiUtils.getAPIService();
+ }
+
+ public void getUserFeed(String token, final Context context, final int page) {
+ if (mMainActivity != null) {
+ mMainActivity.showProgress(true);
+ }
+
+ if (InetConnectionHelper.isNetworkAvailable(context)) {
+ mAPIService.fetchUserFeed(token, page).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ userFeedResponse = response.body();
+
+ if (userFeedResponse.getMeta().getSuccess().booleanValue()) {
+ RealmHelper rh = new RealmHelper();
+
+ for (int i = 0; i < userFeedResponse.getData().size(); i++) {
+ rh.receiveData(userFeedResponse.getData().get(i));
+ }
+
+ if (page == 1) {
+ mMainActivity.feedFragment.attachAdapter();
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ }
+ });
+ }
+
+ mMainActivity.showProgress(false);
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/Controllers/UserTicketController.java b/app/src/main/java/io/devsummit/android/Controllers/UserTicketController.java
index 0c83138..6e965d3 100644
--- a/app/src/main/java/io/devsummit/android/Controllers/UserTicketController.java
+++ b/app/src/main/java/io/devsummit/android/Controllers/UserTicketController.java
@@ -1,12 +1,6 @@
package io.devsummit.android.Controllers;
-import android.content.Context;
-import android.support.v4.app.Fragment;
-import android.support.v7.app.AppCompatActivity;
-
-import io.devsummit.android.R;
import io.devsummit.android.Activities.MainActivity;
-import io.devsummit.android.Fragments.TicketFragment;
import io.devsummit.android.Models.UserTicketModel;
import io.devsummit.android.Remote.APIService;
import io.devsummit.android.Remote.ApiUtils;
@@ -30,17 +24,13 @@ public UserTicketController(MainActivity act) {
mAPIService = ApiUtils.getAPIService();
}
- public void getUserTickets(String token, final Context context) {
+ public UserTicketModel getUserTickets(String token) {
mMainActivity.showProgress(true);
mAPIService.fetchUserTicket(token).enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
UserTickets = response.body();
- AppCompatActivity activity = (AppCompatActivity) context;
- Fragment frag = TicketFragment.newInstance(response.body());
- android.support.v4.app.FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
- ft.add(R.id.container, frag, frag.getTag());
- ft.commit();
+ mMainActivity.ticketFragment.attachItemToAdapter(UserTickets.getData());
mMainActivity.showProgress(false);
}
@@ -50,6 +40,8 @@ public void onFailure(Call call, Throwable t) {
mMainActivity.showProgress(false);
}
});
+
+ return UserTickets;
}
}
diff --git a/app/src/main/java/io/devsummit/android/Fragments/FeedFragment.java b/app/src/main/java/io/devsummit/android/Fragments/FeedFragment.java
index 0585a3a..4b8c319 100644
--- a/app/src/main/java/io/devsummit/android/Fragments/FeedFragment.java
+++ b/app/src/main/java/io/devsummit/android/Fragments/FeedFragment.java
@@ -3,45 +3,86 @@
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import java.util.List;
+
+import io.devsummit.android.Activities.MainActivity;
+import io.devsummit.android.Helpers.EndlessRecyclerViewScrollListener;
+import io.devsummit.android.Helpers.UserAuthenticationHelper;
+import io.devsummit.android.Models.userfeed.FeedData;
import io.devsummit.android.R;
+import io.devsummit.android.ViewAdapters.FeedListViewAdapter;
+import io.realm.Realm;
+import io.realm.Sort;
/**
* Created by ganesh on 27/09/17.
*/
public class FeedFragment extends Fragment {
- private static final String ARG_TEXT = "arg_text";
- private static final String ARG_COLOR = "arg_color";
-
- private View mContent;
-
- public static Fragment newInstance() {
- Fragment frag = new FeedFragment();
- Bundle args = new Bundle();
- frag.setArguments(args);
- return frag;
- }
-
+ private UserAuthenticationHelper authHelper;
+ private RecyclerView mRecyclerView;
+ private LinearLayoutManager mLayoutManager;
+ private RecyclerView.Adapter mAdapter;
+ private List feedData;
+ private EndlessRecyclerViewScrollListener scrollListener;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+
+ authHelper = new UserAuthenticationHelper(getActivity());
+ String token = authHelper.getAccessToken();
+ MainActivity.userFeedController.getUserFeed(token, getContext(), 1);
+
// Inflate the layout for this fragment
- return inflater.inflate(R.layout.feed_fragment, container, false);
+ View layout = inflater.inflate(R.layout.feed_fragment, container, false);
+
+ mRecyclerView = (RecyclerView) layout.findViewById(R.id.feeds_recycler_view);
+
+ // use a linear layout manager
+ mLayoutManager = new LinearLayoutManager(getContext());
+ mRecyclerView.setLayoutManager(mLayoutManager);
+
+ //attachAdapter();
+
+ scrollListener = new EndlessRecyclerViewScrollListener(mLayoutManager) {
+ @Override
+ public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
+ loadNextDataFromApi(page, totalItemsCount);
+ }
+ };
+
+ mRecyclerView.addOnScrollListener(scrollListener);
+
+ return layout;
}
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
+ public void attachAdapter(){
+ Realm realm = Realm.getDefaultInstance();
+ feedData = realm.where(FeedData.class).findAllSorted("createdAt", Sort.DESCENDING);
+ // specify an adapter (see also next example)
+ mAdapter = new FeedListViewAdapter(feedData, getContext());
+ mRecyclerView.setAdapter(mAdapter);
+ }
- // initialize views
- mContent = view.findViewById(R.id.feed_content);
+ public void loadNextDataFromApi(int offset, int totalItems) {
+ // Send an API request to retrieve appropriate paginated data
+ String token = authHelper.getAccessToken();
+ offset = totalItems / 10;
+ MainActivity.userFeedController.getUserFeed(token, getContext(), offset + 1);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
}
@Override
diff --git a/app/src/main/java/io/devsummit/android/Fragments/TicketFragment.java b/app/src/main/java/io/devsummit/android/Fragments/TicketFragment.java
index fb79ab1..55115f8 100644
--- a/app/src/main/java/io/devsummit/android/Fragments/TicketFragment.java
+++ b/app/src/main/java/io/devsummit/android/Fragments/TicketFragment.java
@@ -11,10 +11,12 @@
import android.view.ViewGroup;
import android.widget.ImageButton;
+import java.util.List;
+
+import io.devsummit.android.Activities.MainActivity;
import io.devsummit.android.Activities.OrderedTicketActivity;
-import io.devsummit.android.Controllers.UserTicketController;
import io.devsummit.android.Helpers.UserAuthenticationHelper;
-import io.devsummit.android.Models.UserTicketModel;
+import io.devsummit.android.Models.userticket.Datum;
import io.devsummit.android.R;
import io.devsummit.android.ViewAdapters.TicketListViewAdapter;
@@ -23,85 +25,39 @@
*/
public class TicketFragment extends Fragment implements View.OnClickListener {
- private static final String USER_TICKETS = "user_ticket_model";
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
- private View mContent;
- private UserTicketController userTicketController;
private UserAuthenticationHelper authHelper;
- private UserTicketModel mUserTicketModel;
private ImageButton myOrders;
- public static Fragment newInstance(UserTicketModel userTicketModel) {
- Fragment frag = new TicketFragment();
-
- Bundle bundle = new Bundle();
- bundle.putSerializable(USER_TICKETS, userTicketModel);
- frag.setArguments(bundle);
- return frag;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
-
- mUserTicketModel = (UserTicketModel) getArguments().getSerializable(
- USER_TICKETS);
+ authHelper = new UserAuthenticationHelper(getContext());
+ String token = authHelper.getAccessToken();
+ MainActivity.userTicketController.getUserTickets(token);
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.ticket_fragment, container, false);
- authHelper = new UserAuthenticationHelper(getActivity());
-
- if (mUserTicketModel.getData().size() > 0) {
- mRecyclerView = (RecyclerView) layout.findViewById(R.id.user_ticket_recycler_view);
-
- // use this setting to improve performance if you know that changes
- // in content do not change the layout size of the RecyclerView
- // mRecyclerView.setHasFixedSize(true);
+ mRecyclerView = layout.findViewById(R.id.user_ticket_recycler_view);
- // use a linear layout manager
- mLayoutManager = new LinearLayoutManager(getContext());
- mRecyclerView.setLayoutManager(mLayoutManager);
-
- // get ticket data
- // specify an adapter (see also next example)
- mAdapter = new TicketListViewAdapter(mUserTicketModel.getData());
- mRecyclerView.setAdapter(mAdapter);
- }
+ // use a linear layout manager
+ mLayoutManager = new LinearLayoutManager(getContext());
+ mRecyclerView.setLayoutManager(mLayoutManager);
- myOrders = (ImageButton) layout.findViewById(R.id.button_my_order);
+ myOrders = layout.findViewById(R.id.button_my_order);
myOrders.setOnClickListener(this);
- mRecyclerView = (RecyclerView) layout.findViewById(R.id.user_ticket_recycler_view);
-
- // use this setting to improve performance if you know that changes
- // in content do not change the layout size of the RecyclerView
- // mRecyclerView.setHasFixedSize(true);
-
return layout;
}
- @Override
- public void onResume() {
- super.onResume();
-
- // use a linear layout manager
- mLayoutManager = new LinearLayoutManager(getContext());
- mRecyclerView.setLayoutManager(mLayoutManager);
-
- // specify an adapter (see also next example)
- mAdapter = new TicketListViewAdapter(mUserTicketModel.getData());
- mRecyclerView.setAdapter(mAdapter);
- }
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
- // initialize views
- mContent = view.findViewById(R.id.ticket_content);
}
@Override
@@ -113,4 +69,10 @@ public void onClick(View view) {
Intent intent = new Intent(getActivity(), OrderedTicketActivity.class);
startActivity(intent);
}
+
+ public void attachItemToAdapter(List userTickets){
+ // specify an adapter (see also next example)
+ mAdapter = new TicketListViewAdapter(userTickets);
+ mRecyclerView.setAdapter(mAdapter);
+ }
}
diff --git a/app/src/main/java/io/devsummit/android/Helpers/EndlessRecyclerViewScrollListener.java b/app/src/main/java/io/devsummit/android/Helpers/EndlessRecyclerViewScrollListener.java
new file mode 100644
index 0000000..d67e05f
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Helpers/EndlessRecyclerViewScrollListener.java
@@ -0,0 +1,109 @@
+package io.devsummit.android.Helpers;
+
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+
+/**
+ * Created by wlisrausr on 09/10/17.
+ */
+
+public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
+ // The minimum amount of items to have below your current scroll position
+ // before loading more.
+ private int visibleThreshold = 5;
+ // The current offset index of data you have loaded
+ private int currentPage = 0;
+ // The total number of items in the dataset after the last load
+ private int previousTotalItemCount = 0;
+ // True if we are still waiting for the last set of data to load.
+ private boolean loading = true;
+ // Sets the starting page index
+ private int startingPageIndex = 0;
+
+ RecyclerView.LayoutManager mLayoutManager;
+
+ public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
+ this.mLayoutManager = layoutManager;
+ }
+
+ public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
+ this.mLayoutManager = layoutManager;
+ visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
+ }
+
+ public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
+ this.mLayoutManager = layoutManager;
+ visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
+ }
+
+ public int getLastVisibleItem(int[] lastVisibleItemPositions) {
+ int maxSize = 0;
+ for (int i = 0; i < lastVisibleItemPositions.length; i++) {
+ if (i == 0) {
+ maxSize = lastVisibleItemPositions[i];
+ }
+ else if (lastVisibleItemPositions[i] > maxSize) {
+ maxSize = lastVisibleItemPositions[i];
+ }
+ }
+ return maxSize;
+ }
+
+ // This happens many times a second during a scroll, so be wary of the code you place here.
+ // We are given a few useful parameters to help us work out if we need to load some more data,
+ // but first we check if we are waiting for the previous load to finish.
+ @Override
+ public void onScrolled(RecyclerView view, int dx, int dy) {
+ int lastVisibleItemPosition = 0;
+ int totalItemCount = mLayoutManager.getItemCount();
+
+ if (mLayoutManager instanceof StaggeredGridLayoutManager) {
+ int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
+ // get maximum element within the list
+ lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
+ } else if (mLayoutManager instanceof GridLayoutManager) {
+ lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
+ } else if (mLayoutManager instanceof LinearLayoutManager) {
+ lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
+ }
+
+ // If the total item count is zero and the previous isn't, assume the
+ // list is invalidated and should be reset back to initial state
+ if (totalItemCount < previousTotalItemCount) {
+ this.currentPage = this.startingPageIndex;
+ this.previousTotalItemCount = totalItemCount;
+ if (totalItemCount == 0) {
+ this.loading = true;
+ }
+ }
+ // If it’s still loading, we check to see if the dataset count has
+ // changed, if so we conclude it has finished loading and update the current page
+ // number and total item count.
+ if (loading && (totalItemCount > previousTotalItemCount)) {
+ loading = false;
+ previousTotalItemCount = totalItemCount;
+ }
+
+ // If it isn’t currently loading, we check to see if we have breached
+ // the visibleThreshold and need to reload more data.
+ // If we do need to reload some more data, we execute onLoadMore to fetch the data.
+ // threshold should reflect how many total columns there are too
+ if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
+ currentPage++;
+ onLoadMore(currentPage, totalItemCount, view);
+ loading = true;
+ }
+ }
+
+ // Call this method whenever performing new searches
+ public void resetState() {
+ this.currentPage = this.startingPageIndex;
+ this.previousTotalItemCount = 0;
+ this.loading = true;
+ }
+
+ // Defines the process for actually loading more data based on page
+ public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);
+}
diff --git a/app/src/main/java/io/devsummit/android/Helpers/InetConnectionHelper.java b/app/src/main/java/io/devsummit/android/Helpers/InetConnectionHelper.java
new file mode 100644
index 0000000..2b9373a
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Helpers/InetConnectionHelper.java
@@ -0,0 +1,19 @@
+package io.devsummit.android.Helpers;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+/**
+ * Created by wlisrausr on 07/10/17.
+ */
+
+public class InetConnectionHelper {
+ public static boolean isNetworkAvailable(Context context) {
+ ConnectivityManager connectivityManager
+ = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+
+ return activeNetworkInfo != null && activeNetworkInfo.isConnected();
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/Helpers/RealmHelper.java b/app/src/main/java/io/devsummit/android/Helpers/RealmHelper.java
new file mode 100644
index 0000000..0739863
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Helpers/RealmHelper.java
@@ -0,0 +1,24 @@
+package io.devsummit.android.Helpers;
+
+import io.realm.Realm;
+import io.realm.RealmModel;
+
+/**
+ * Created by ganesh on 06/10/17.
+ */
+
+public class RealmHelper {
+ public void receiveData(Object responseData) {
+ Realm realm = Realm.getDefaultInstance();
+
+ try {
+ realm.beginTransaction();
+ realm.copyToRealmOrUpdate((RealmModel) responseData);
+ realm.commitTransaction();
+ realm.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ realm.cancelTransaction();
+ }
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/Helpers/TextHelper.java b/app/src/main/java/io/devsummit/android/Helpers/TextHelper.java
new file mode 100644
index 0000000..b0817ae
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Helpers/TextHelper.java
@@ -0,0 +1,38 @@
+package io.devsummit.android.Helpers;
+
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by wlisrausr on 04/10/17.
+ */
+
+public class TextHelper {
+ public static String capitalizeFirstLetter(String input) {
+ return input.substring(0, 1).toUpperCase() + input.substring(1);
+ }
+
+ public static String toRupiahFormat(Number nominal) {
+ NumberFormat format = NumberFormat.getInstance();
+
+ return "Rp " + format.format(nominal);
+ }
+
+ public static String dateFormat(String inputDate) {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+ Date formattedDate = null;
+
+ try {
+ formattedDate = format.parse(inputDate);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ format = new SimpleDateFormat("MMM dd, yyyy (hh:mm)");
+ String outputDate = format.format(formattedDate);
+
+ return outputDate;
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/Models/UserFeedModel.java b/app/src/main/java/io/devsummit/android/Models/UserFeedModel.java
new file mode 100644
index 0000000..b284721
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Models/UserFeedModel.java
@@ -0,0 +1,63 @@
+package io.devsummit.android.Models;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+import java.util.List;
+
+import io.devsummit.android.Models.basemodel.Included;
+import io.devsummit.android.Models.basemodel.Meta;
+import io.devsummit.android.Models.userfeed.FeedData;
+import io.devsummit.android.Models.userfeed.Links;
+
+/**
+ * Created by wlisrausr on 04/10/17.
+ */
+
+public class UserFeedModel implements Serializable {
+ @SerializedName("data")
+ @Expose
+ private List data = null;
+ @SerializedName("included")
+ @Expose
+ private Included included;
+ @SerializedName("links")
+ @Expose
+ private Links links;
+ @SerializedName("meta")
+ @Expose
+ private Meta meta;
+
+ public List getData() {
+ return data;
+ }
+
+ public void setData(List data) {
+ this.data = data;
+ }
+
+ public Included getIncluded() {
+ return included;
+ }
+
+ public void setIncluded(Included included) {
+ this.included = included;
+ }
+
+ public Links getLinks() {
+ return links;
+ }
+
+ public void setLinks(Links links) {
+ this.links = links;
+ }
+
+ public Meta getMeta() {
+ return meta;
+ }
+
+ public void setMeta(Meta meta) {
+ this.meta = meta;
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/Models/userfeed/FeedData.java b/app/src/main/java/io/devsummit/android/Models/userfeed/FeedData.java
new file mode 100644
index 0000000..83dca5e
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Models/userfeed/FeedData.java
@@ -0,0 +1,124 @@
+package io.devsummit.android.Models.userfeed;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+import io.realm.RealmObject;
+import io.realm.annotations.PrimaryKey;
+
+public class FeedData extends RealmObject implements Serializable {
+
+ @SerializedName("attachment")
+ @Expose
+ private String attachment;
+ @SerializedName("created_at")
+ @Expose
+ private String createdAt;
+ @SerializedName("id")
+ @Expose
+ @PrimaryKey
+ private Integer id;
+ @SerializedName("message")
+ @Expose
+ private String message;
+ @SerializedName("redirect_url")
+ @Expose
+ private String redirectUrl;
+ @SerializedName("sponsor_id")
+ @Expose
+ private Integer sponsorId;
+ @SerializedName("type")
+ @Expose
+ private String type;
+ @SerializedName("updated_at")
+ @Expose
+ private String updatedAt;
+ @SerializedName("user")
+ @Expose
+ private User user;
+ @SerializedName("user_id")
+ @Expose
+ private Integer userId;
+
+ public String getAttachment() {
+ return attachment;
+ }
+
+ public void setAttachment(String attachment) {
+ this.attachment = attachment;
+ }
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getRedirectUrl() {
+ return redirectUrl;
+ }
+
+ public void setRedirectUrl(String redirectUrl) {
+ this.redirectUrl = redirectUrl;
+ }
+
+ public Integer getSponsorId() {
+ return sponsorId;
+ }
+
+ public void setSponsorId(Integer sponsorId) {
+ this.sponsorId = sponsorId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+
+ public Integer getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Integer userId) {
+ this.userId = userId;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/devsummit/android/Models/userfeed/Links.java b/app/src/main/java/io/devsummit/android/Models/userfeed/Links.java
new file mode 100644
index 0000000..8e70d42
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Models/userfeed/Links.java
@@ -0,0 +1,52 @@
+package io.devsummit.android.Models.userfeed;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class Links {
+
+ @SerializedName("curr")
+ @Expose
+ private String curr;
+ @SerializedName("next")
+ @Expose
+ private String next;
+ @SerializedName("prev")
+ @Expose
+ private String prev;
+ @SerializedName("total_items")
+ @Expose
+ private Integer totalItems;
+
+ public String getCurr() {
+ return curr;
+ }
+
+ public void setCurr(String curr) {
+ this.curr = curr;
+ }
+
+ public String getNext() {
+ return next;
+ }
+
+ public void setNext(String next) {
+ this.next = next;
+ }
+
+ public String getPrev() {
+ return prev;
+ }
+
+ public void setPrev(String prev) {
+ this.prev = prev;
+ }
+
+ public Integer getTotalItems() {
+ return totalItems;
+ }
+
+ public void setTotalItems(Integer totalItems) {
+ this.totalItems = totalItems;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/devsummit/android/Models/userfeed/Photo.java b/app/src/main/java/io/devsummit/android/Models/userfeed/Photo.java
new file mode 100644
index 0000000..76f6717
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Models/userfeed/Photo.java
@@ -0,0 +1,69 @@
+package io.devsummit.android.Models.userfeed;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+import io.realm.RealmObject;
+import io.realm.annotations.PrimaryKey;
+
+public class Photo extends RealmObject implements Serializable {
+
+ @SerializedName("created_at")
+ @Expose
+ private String createdAt;
+ @SerializedName("id")
+ @Expose
+ @PrimaryKey
+ private Integer id;
+ @SerializedName("updated_at")
+ @Expose
+ private String updatedAt;
+ @SerializedName("url")
+ @Expose
+ private String url;
+ @SerializedName("user_id")
+ @Expose
+ private Integer userId;
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public Integer getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Integer userId) {
+ this.userId = userId;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/devsummit/android/Models/userfeed/User.java b/app/src/main/java/io/devsummit/android/Models/userfeed/User.java
new file mode 100644
index 0000000..c15bb89
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/Models/userfeed/User.java
@@ -0,0 +1,159 @@
+package io.devsummit.android.Models.userfeed;
+
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+import java.io.Serializable;
+
+import io.realm.RealmList;
+import io.realm.RealmObject;
+import io.realm.annotations.PrimaryKey;
+
+public class User extends RealmObject implements Serializable {
+
+ @SerializedName("created_at")
+ @Expose
+ private String createdAt;
+ @SerializedName("email")
+ @Expose
+ private String email;
+ @SerializedName("fcmtoken")
+ @Expose
+ private String fcmtoken;
+ @SerializedName("first_name")
+ @Expose
+ private String firstName;
+ @SerializedName("id")
+ @Expose
+ @PrimaryKey
+ private Integer id;
+ @SerializedName("last_name")
+ @Expose
+ private String lastName;
+ @SerializedName("photos")
+ @Expose
+ private RealmList photos = null;
+ @SerializedName("points")
+ @Expose
+ private Integer points;
+ @SerializedName("referer")
+ @Expose
+ private String referer;
+ @SerializedName("role_id")
+ @Expose
+ private Integer roleId;
+ @SerializedName("social_id")
+ @Expose
+ private String socialId;
+ @SerializedName("updated_at")
+ @Expose
+ private String updatedAt;
+ @SerializedName("username")
+ @Expose
+ private String username;
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(String createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getFcmtoken() {
+ return fcmtoken;
+ }
+
+ public void setFcmtoken(String fcmtoken) {
+ this.fcmtoken = fcmtoken;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public RealmList getPhotos() {
+ return photos;
+ }
+
+ public void setPhotos(RealmList photos) {
+ this.photos = photos;
+ }
+
+ public Integer getPoints() {
+ return points;
+ }
+
+ public void setPoints(Integer points) {
+ this.points = points;
+ }
+
+ public String getReferer() {
+ return referer;
+ }
+
+ public void setReferer(String referer) {
+ this.referer = referer;
+ }
+
+ public Integer getRoleId() {
+ return roleId;
+ }
+
+ public void setRoleId(Integer roleId) {
+ this.roleId = roleId;
+ }
+
+ public String getSocialId() {
+ return socialId;
+ }
+
+ public void setSocialId(String socialId) {
+ this.socialId = socialId;
+ }
+
+ public String getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(String updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/devsummit/android/Remote/APIService.java b/app/src/main/java/io/devsummit/android/Remote/APIService.java
index 2829e1e..3060d93 100644
--- a/app/src/main/java/io/devsummit/android/Remote/APIService.java
+++ b/app/src/main/java/io/devsummit/android/Remote/APIService.java
@@ -4,6 +4,7 @@
import io.devsummit.android.Models.NotificationModel;
import io.devsummit.android.Models.OrderedTicketModel;
import io.devsummit.android.Models.RegisterModel;
+import io.devsummit.android.Models.UserFeedModel;
import io.devsummit.android.Models.UserTicketModel;
import io.devsummit.android.Models.authmodel.RefreshTokenModel;
import io.devsummit.android.Models.login.Credentials;
@@ -16,6 +17,7 @@
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
+import retrofit2.http.Query;
import retrofit2.http.Url;
/**
@@ -49,6 +51,9 @@ public interface APIService {
@Headers("Content-Type: application/json")
Call fetchNotification(@Header("Authorization") String token, @Url String url);
+ @GET("api/v1/feeds")
+ Call fetchUserFeed(@Header("Authorization") String token, @Query("page") int page);
+
@POST("auth/refreshtoken")
@Headers("Content-Type:application/json")
Call refreshToken(@Body String refresh_token);
diff --git a/app/src/main/java/io/devsummit/android/ViewAdapters/FeedListViewAdapter.java b/app/src/main/java/io/devsummit/android/ViewAdapters/FeedListViewAdapter.java
new file mode 100644
index 0000000..dcecff8
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/ViewAdapters/FeedListViewAdapter.java
@@ -0,0 +1,105 @@
+package io.devsummit.android.ViewAdapters;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.squareup.picasso.Picasso;
+
+import java.util.List;
+
+import de.hdodenhof.circleimageview.CircleImageView;
+import io.devsummit.android.Helpers.TextHelper;
+import io.devsummit.android.Models.userfeed.FeedData;
+import io.devsummit.android.R;
+
+/**
+ * Created by wlisrausr on 04/10/17.
+ */
+
+public class FeedListViewAdapter extends RecyclerView.Adapter {
+ private List mDataset;
+ private Context context;
+
+ // Provide a suitable constructor (depends on the kind of dataset)
+ public FeedListViewAdapter(List myDataset, Context context) {
+ mDataset = myDataset;
+ this.context = context;
+ }
+
+ @Override
+ public FeedListViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
+ // TODO: inflate your view and create viewholder, most likely looks like this though
+ View v = LayoutInflater.from(viewGroup.getContext()).inflate(
+ R.layout.user_feed_row,
+ viewGroup,
+ false);
+
+ FeedListViewHolder vh = new FeedListViewHolder(v);
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(final FeedListViewHolder viewHolder, int i) {
+ // TODO: all your bind operations
+ viewHolder.firstName.setText(TextHelper.capitalizeFirstLetter(
+ mDataset.get(i).getUser().getFirstName().toString()
+ ));
+ viewHolder.lastName.setText(TextHelper.capitalizeFirstLetter(
+ mDataset.get(i).getUser().getLastName().toString()
+ ));
+ viewHolder.createdAt.setText(TextHelper.dateFormat(mDataset.get(i).getCreatedAt().toString()));
+ viewHolder.feedMessage.setText(mDataset.get(i).getMessage().toString());
+
+ Object attachmentUrl = mDataset.get(i).getAttachment();
+ List imgProfileUrl = mDataset.get(i).getUser().getPhotos();
+
+ viewHolder.feedAttachment.setVisibility(View.GONE);
+
+ if (attachmentUrl != null) {
+ viewHolder.feedAttachment.setVisibility(View.VISIBLE);
+
+ Picasso.with(context)
+ .load(mDataset.get(i).getAttachment().toString())
+ .into(viewHolder.feedAttachment);
+ }
+
+ if (imgProfileUrl.size() > 0) {
+ Picasso.with(context)
+ .load(mDataset.get(i).getUser().getPhotos().get(0).getUrl().toString())
+ .placeholder(R.drawable.empty_profile_grey)
+ .into(viewHolder.imageProfile);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ // TODO: return total item count of your views
+ return mDataset.size();
+ }
+
+ public static class FeedListViewHolder extends RecyclerView.ViewHolder {
+ // TODO: whatever views you need to bind
+ public TextView feedMessage;
+ public TextView firstName;
+ public TextView lastName;
+ public TextView createdAt;
+ public ImageView feedAttachment;
+ public CircleImageView imageProfile;
+
+ public FeedListViewHolder(View v) {
+ super(v); // done this way instead of view tagging
+
+ feedMessage = (TextView) v.findViewById(R.id.feedMessage);
+ firstName = (TextView) v.findViewById(R.id.firstNameText);
+ lastName = (TextView) v.findViewById(R.id.lastNameText);
+ createdAt = (TextView) v.findViewById(R.id.createdAtText);
+ feedAttachment = (ImageView) v.findViewById(R.id.feedAttachment);
+ imageProfile = (CircleImageView) v.findViewById(R.id.imageProfile);
+ }
+ }
+}
diff --git a/app/src/main/java/io/devsummit/android/ViewAdapters/MainViewPagerAdapter.java b/app/src/main/java/io/devsummit/android/ViewAdapters/MainViewPagerAdapter.java
new file mode 100644
index 0000000..91efaad
--- /dev/null
+++ b/app/src/main/java/io/devsummit/android/ViewAdapters/MainViewPagerAdapter.java
@@ -0,0 +1,34 @@
+package io.devsummit.android.ViewAdapters;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by wlisrausr on 09/10/17.
+ */
+
+public class MainViewPagerAdapter extends FragmentPagerAdapter {
+ private final List mFragmentList = new ArrayList<>();
+
+ public MainViewPagerAdapter(FragmentManager manager) {
+ super(manager);
+ }
+ @Override
+ public Fragment getItem(int position) {
+ return mFragmentList.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return mFragmentList.size();
+ }
+
+ public void addFragment(Fragment fragment) {
+ mFragmentList.add(fragment);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/devsummit/android/ViewAdapters/OrderedTicketListViewAdapter.java b/app/src/main/java/io/devsummit/android/ViewAdapters/OrderedTicketListViewAdapter.java
index 11dd0b0..262b50d 100644
--- a/app/src/main/java/io/devsummit/android/ViewAdapters/OrderedTicketListViewAdapter.java
+++ b/app/src/main/java/io/devsummit/android/ViewAdapters/OrderedTicketListViewAdapter.java
@@ -7,13 +7,10 @@
import android.widget.LinearLayout;
import android.widget.TextView;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.List;
import io.devsummit.android.Helpers.OrderStatusHelper;
+import io.devsummit.android.Helpers.TextHelper;
import io.devsummit.android.Models.orderedtickets.Datum;
import io.devsummit.android.R;
@@ -30,28 +27,6 @@ public OrderedTicketListViewAdapter(List myDataset) {
mDataset = myDataset;
}
- public String toRupiahFormat(Number nominal) {
- NumberFormat format = NumberFormat.getInstance();
-
- return "Rp " + format.format(nominal);
- }
-
- public String dateFormat(String inputDate) {
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
- Date formattedDate = null;
-
- try {
- formattedDate = format.parse(inputDate);
- } catch (ParseException e) {
- e.printStackTrace();
- }
-
- format = new SimpleDateFormat("MMM dd, yyyy (hh:mm)");
- String outputDate = format.format(formattedDate);
-
- return outputDate;
- }
-
@Override
public OrderedTicketListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// TODO: inflate your view and create viewholder, most likely looks like this though
@@ -75,8 +50,8 @@ public void onBindViewHolder(OrderedTicketListViewHolder holder, int position) {
// TODO: all your bind operations
holder.orderId.setText(mDataset.get(position).getId().toString());
- holder.orderDate.setText(dateFormat(mDataset.get(position).getCreatedAt().toString()));
- holder.orderAmount.setText(toRupiahFormat(mDataset.get(position).getAmount()));
+ holder.orderDate.setText(TextHelper.dateFormat(mDataset.get(position).getCreatedAt().toString()));
+ holder.orderAmount.setText(TextHelper.toRupiahFormat(mDataset.get(position).getAmount()));
holder.orderStatus.setText(orderStatus);
}
diff --git a/app/src/main/res/drawable/empty_profile_grey.jpg b/app/src/main/res/drawable/empty_profile_grey.jpg
new file mode 100644
index 0000000..8830fbc
Binary files /dev/null and b/app/src/main/res/drawable/empty_profile_grey.jpg differ
diff --git a/app/src/main/res/drawable/feed_attachment.xml b/app/src/main/res/drawable/feed_attachment.xml
new file mode 100644
index 0000000..75a1494
--- /dev/null
+++ b/app/src/main/res/drawable/feed_attachment.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_border_color_black_24dp.xml b/app/src/main/res/drawable/ic_border_color_black_24dp.xml
new file mode 100644
index 0000000..1889bdf
--- /dev/null
+++ b/app/src/main/res/drawable/ic_border_color_black_24dp.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_report_black_16dp.xml b/app/src/main/res/drawable/ic_report_black_16dp.xml
new file mode 100644
index 0000000..f6fb68f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_report_black_16dp.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_share_black_16dp.xml b/app/src/main/res/drawable/ic_share_black_16dp.xml
new file mode 100644
index 0000000..bcc5725
--- /dev/null
+++ b/app/src/main/res/drawable/ic_share_black_16dp.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d906496..7412f87 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -13,13 +13,13 @@
android:layout_height="match_parent"
android:background="@drawable/background_3x"
android:layout_weight="1">
-
-
+ android:layout_above="@+id/bottom_navigation"
+ android:layout_alignParentTop="true"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
-
+
+
+ android:layout_marginTop="8dp"
+ android:scrollbars="vertical" />
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_feed_row.xml b/app/src/main/res/layout/user_feed_row.xml
new file mode 100644
index 0000000..d13d316
--- /dev/null
+++ b/app/src/main/res/layout/user_feed_row.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/user_ticket_row.xml b/app/src/main/res/layout/user_ticket_row.xml
index ac0a52d..c7a3867 100644
--- a/app/src/main/res/layout/user_ticket_row.xml
+++ b/app/src/main/res/layout/user_ticket_row.xml
@@ -2,7 +2,8 @@
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="8dp">
diff --git a/app/src/main/res/menu/navigation.xml b/app/src/main/res/menu/navigation.xml
index fd5417e..01bcd5f 100644
--- a/app/src/main/res/menu/navigation.xml
+++ b/app/src/main/res/menu/navigation.xml
@@ -1,15 +1,15 @@