Skip to content

Commit

Permalink
Merge pull request #14 from naeemark/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
naeemark authored Nov 30, 2017
2 parents b4f5e94 + b9cbb4c commit 6ebc9d0
Show file tree
Hide file tree
Showing 36 changed files with 418 additions and 56 deletions.
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ A mocked application for Stream and Timeline.

### Application Flow ###

_to be provided later_
- A: User Clicks on App Icon for device
- B: Splash appear
- C: After splash delay, Login Screen Appears
- D: By Clicking login, it launches authentication screen for Twitter Kit
- E: On Successful login, you will see Timeline screen, with three tabs
- F: Actionbar button is there to switch the app language and logout

## How do I get set up? ##

Expand Down Expand Up @@ -50,11 +55,6 @@ Please sync and resolve dependencies
- [`SharedPreferences`](https://developer.android.com/reference/android/content/SharedPreferences.html) are used for local persistance of preferences _(if required)_


#### PoJo Converters: ####

- API-response DTOs are created by using [JSON2Schema](http://www.jsonschema2pojo.org/)


### Resources ###

- [Dagger-Rx-Database-MVP](https://github.com/filippella/Dagger-Rx-Database-MVP)
Expand Down Expand Up @@ -91,4 +91,22 @@ The project can be distributed using [Google Play Store](https://github.com/Trip

## Screenshots ##

_to be provided later_
![Screenshot](screenshots/0.png)
![Screenshot](screenshots/1.png)
![Screenshot](screenshots/2a.png)
![Screenshot](screenshots/2b.png)
![Screenshot](screenshots/2c.png)
![Screenshot](screenshots/2d.png)
![Screenshot](screenshots/3.png)
![Screenshot](screenshots/4a.png)
![Screenshot](screenshots/4b.png)
![Screenshot](screenshots/5a.png)
![Screenshot](screenshots/5b.png)
![Screenshot](screenshots/6a.png)
![Screenshot](screenshots/6b.png)
![Screenshot](screenshots/7a.png)
![Screenshot](screenshots/7b.png)
![Screenshot](screenshots/8a.png)
![Screenshot](screenshots/8b.png)
![Screenshot](screenshots/9a.png)
![Screenshot](screenshots/9b.png)
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.tline.android;


import android.support.test.espresso.ViewInteraction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

import com.tline.android.features.timeline.activity.view.impl.TimelineActivity;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class TimelineActivityTest {

@Rule
public ActivityTestRule<TimelineActivity> mActivityTestRule = new ActivityTestRule<>(TimelineActivity.class);


@Before
public void setUp() throws Exception {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Test
public void checkActionbarItemsVisiblility(){
ViewInteraction language = onView(withId(R.id.action_language));
ViewInteraction logout = onView(withId(R.id.action_logout)).perform();

language.check(matches(isDisplayed()));
logout.check(matches(isDisplayed()));
}

@Test
public void checkTimelineBottomTabVisiblility(){
ViewInteraction tab = onView(withId(R.id.action_timeline));

tab.check(matches(isDisplayed()));
}

@Test
public void checkAndroidDevBottomTabVisiblility(){
ViewInteraction tab = onView(withId(R.id.action_android_dev));

tab.check(matches(isDisplayed()));
}

@Test
public void checkOlxBottomTabVisiblility(){
ViewInteraction tab = onView(withId(R.id.action_olx_egypt));

tab.check(matches(isDisplayed()));
}

@Test
public void checkRecyclerViewVisibility(){

ViewInteraction scroll = onView(withId(R.id.recyclerView));

scroll.check(matches(isDisplayed()));
}

@Test
public void checkScrollViewHasAnyItem(){

ViewInteraction container = onView(withId(R.id.recyclerView));

container.check(matches(hasDescendant(withId(R.id.tvUserName))));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

public interface LoginPresenter extends BasePresenter<LoginView> {

void checkSession(TwitterSession activeSession);

void handleLoginSuccess(TwitterSession twitterSession);

void handleLoginFailure(TwitterException twitterException);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.tline.android.features.login.presenter.LoginPresenter;
import com.tline.android.features.login.view.LoginView;
import com.tline.android.features.login.interactor.LoginInteractor;
import com.twitter.sdk.android.core.TwitterCore;
import com.twitter.sdk.android.core.TwitterException;
import com.twitter.sdk.android.core.TwitterSession;

Expand All @@ -28,9 +29,20 @@ public LoginPresenterImpl(@NonNull LoginInteractor interactor) {
public void onStart(boolean viewCreated) {
super.onStart(viewCreated);

if (viewCreated){
assert mView != null;
mView.updateUi();
if (viewCreated) {
checkSession(TwitterCore.getInstance().getSessionManager().getActiveSession());
}
}

@Override
public void checkSession(TwitterSession activeSession) {

assert mView != null;
if (activeSession == null) {
mView.showLoginUi();
} else {
mView.updateUi(activeSession.getUserName());
mView.launchHomeActivity();
}
}

Expand All @@ -42,20 +54,18 @@ public void onStop() {

@Override
public void handleLoginSuccess(TwitterSession twitterSession) {
assert mView != null;
mView.launchHomeActivity();
// to persist session data
}

@Override
public void handleLoginFailure(TwitterException twitterException) {
assert mView != null;
mView.showLoginError(twitterException.getMessage());
// to work with Exception
}

@Override
public void logout() {
assert mView != null;
mView.logoutTwitter();
mView.updateUi();
mView.showLoginUi();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
@UiThread
public interface LoginView extends BaseView{

void updateUi();
void showLoginUi();

void updateUi(String userName);

void launchHomeActivity();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,15 @@ protected void onViewReady(Bundle savedInstanceState, Intent intent) {

setButtonListeners();

if (TwitterCore.getInstance().getSessionManager().getActiveSession() != null) {
launchHomeActivity();
}
}

private void setButtonListeners() {

mLoginButton.setCallback(new Callback<TwitterSession>() {
@Override
public void success(Result<TwitterSession> result) {
Timber.i(result.data.getUserName());
assert mPresenter != null;
mPresenter.handleLoginSuccess(result.data);
launchHomeActivity();
}

Expand All @@ -101,8 +99,8 @@ public void failure(TwitterException exception) {
mLogoutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
logoutTwitter();
updateUi();
assert mPresenter != null;
mPresenter.logout();
}
});
}
Expand All @@ -116,21 +114,21 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}

@Override
public void updateUi() {

TwitterSession activeSession = TwitterCore.getInstance().getSessionManager().getActiveSession();
public void showLoginUi() {
mLogoutButton.setVisibility(View.GONE);
mLoginButton.setVisibility(View.VISIBLE);
mUserDpImageView.setImageResource(R.drawable.ic_launcher_round_web);
}

if (activeSession == null) {
mLogoutButton.setVisibility(View.GONE);
mLoginButton.setVisibility(View.VISIBLE);
mUserDpImageView.setImageResource(R.drawable.ic_launcher_round_web);
} else {
/**
* In-case we need to show Logout button
*/
@Override
public void updateUi(String userName) {

mUserNameTextView.setText(getString(R.string.prompt_welcome_prefix, activeSession.getUserName()));
//ImageUtils.loadImage(this, mUserDpImageView, appUser.getPhotoUrl());
mLogoutButton.setVisibility(View.VISIBLE);
mLoginButton.setVisibility(View.GONE);
}
mUserNameTextView.setText(getString(R.string.prompt_welcome_prefix, userName));
mLogoutButton.setVisibility(View.VISIBLE);
mLoginButton.setVisibility(View.GONE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.tline.android.features.timeline.activity.view.impl;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
Expand All @@ -19,6 +20,7 @@
import com.tline.android.features.timeline.activity.presenter.TimelinePresenter;
import com.tline.android.features.timeline.fragment.view.impl.TweetsFragment;
import com.tline.android.features.timeline.activity.view.TimelineView;
import com.tline.android.utils.DialogUtils;
import com.twitter.sdk.android.core.TwitterCore;

import javax.inject.Inject;
Expand Down Expand Up @@ -72,12 +74,6 @@ protected void onViewReady(Bundle savedInstanceState, Intent intent) {

}

@Override
protected void onStart() {
super.onStart();
// mPresenter.start();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
Expand All @@ -91,7 +87,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
assert mPresenter != null;
switch (id) {
case R.id.action_logout:
mPresenter.logout();
showLogoutDialog();
return true;
case R.id.action_language:
mPresenter.switchAppLocale(this);
Expand Down Expand Up @@ -166,4 +162,15 @@ private void replaceFragment(Fragment targetFragment) {
ft.replace(R.id.container, targetFragment, targetFragment.getTag());
ft.commit();
}

private void showLogoutDialog() {
DialogUtils.showLogoutDialog(this, getString(R.string.message_logout), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
assert mPresenter != null;
mPresenter.logout();
dialog.dismiss();
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@
import com.tline.android.app.interactor.BaseInteractor;
import com.tline.android.features.timeline.fragment.presenter.TweetsPresenter;
import com.tline.android.features.timeline.fragment.presenter.impl.TweetsPresenterImpl;
import com.twitter.sdk.android.core.models.Tweet;

import java.util.List;

public interface TweetsInteractor extends BaseInteractor {

boolean isNetworkConnected();

void fetchTweets(String twitterHandle, TweetsPresenter.OnFetchDataListener listener);
void fetchTweets(String twitterHandle, OnFetchDataListener listener);

String getErrorString();


interface OnFetchDataListener {

void onStart();

void onSuccess(List<Tweet> tweets);

void onFailure(String message);

void onComplete();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public boolean isNetworkConnected() {
}

@Override
public void fetchTweets(String twitterHandle, final TweetsPresenter.OnFetchDataListener listener) {
public void fetchTweets(String twitterHandle, final OnFetchDataListener listener) {

listener.onStart();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
package com.tline.android.features.timeline.fragment.presenter;

import com.tline.android.app.presenter.BasePresenter;
import com.tline.android.features.timeline.fragment.interactor.TweetsInteractor;
import com.tline.android.features.timeline.fragment.view.TweetsView;
import com.twitter.sdk.android.core.models.Tweet;

import java.util.List;

public interface TweetsPresenter extends BasePresenter<TweetsView> {
public interface TweetsPresenter extends BasePresenter<TweetsView>, TweetsInteractor.OnFetchDataListener {

interface OnFetchDataListener {

void onStart();

void onSuccess(List<Tweet> tweets);

void onFailure(String message);

void onComplete();
}


}
Loading

0 comments on commit 6ebc9d0

Please sign in to comment.