diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b81339e..5ef568b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,6 +45,11 @@ android:screenOrientation="portrait" android:theme="@style/AppTheme" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" /> + diff --git a/app/src/main/java/ro/code4/monitorizarevot/OnboardingActivity.java b/app/src/main/java/ro/code4/monitorizarevot/OnboardingActivity.java new file mode 100644 index 0000000..94cc49c --- /dev/null +++ b/app/src/main/java/ro/code4/monitorizarevot/OnboardingActivity.java @@ -0,0 +1,135 @@ +package ro.code4.monitorizarevot; + +import android.arch.lifecycle.ViewModelProviders; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.view.ViewPager; +import android.view.View; +import android.widget.Button; + +import java.util.ArrayList; +import java.util.List; + +import ro.code4.monitorizarevot.adapter.OnboardingAdapter; +import ro.code4.monitorizarevot.db.Preferences; +import ro.code4.monitorizarevot.net.model.OnboardingItem; +import ro.code4.monitorizarevot.observable.ObservableListener; +import ro.code4.monitorizarevot.viewmodel.OnboardingViewModel; + +import ro.code4.monitorizarevot.R; + +public class OnboardingActivity extends BaseActivity { + private Button buttonPrevious, buttonNext; + + private List items; + + private ViewPager onboardingViewPager; + private int currentPosition; + + // TODO get onboarding items dynamically + private List getOnboardingItems() { + List items = new ArrayList<>(); + + OnboardingItem item1 = new OnboardingItem(1, getString(R.string.onboarding_title_1), getString(R.string.onboarding_description_1), R.drawable.ic_onboarding_building); + items.add(item1); + + OnboardingItem item2 = new OnboardingItem(2, getString(R.string.onboarding_title_2), getString(R.string.onboarding_description_2), R.drawable.ic_onboarding_form); + items.add(item2); + + OnboardingItem item3 = new OnboardingItem(3, getString(R.string.onboarding_title_3), getString(R.string.onboarding_description_3), R.drawable.ic_onboarding_note); + items.add(item3); + + return items; + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_onboarding); + + items = getOnboardingItems(); + + onboardingViewPager = findViewById(R.id.onboarding_viewpager); + buttonNext = findViewById(R.id.btn_next); + buttonPrevious = findViewById(R.id.btn_previous); + + OnboardingAdapter onboardingAdapter = new OnboardingAdapter(this, items); + onboardingViewPager.setAdapter(onboardingAdapter); + onboardingViewPager.addOnPageChangeListener(onPageChangeListener); + + buttonPrevious.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onboardingViewPager.setCurrentItem(currentPosition - 1); + } + }); + + buttonNext.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (currentPosition == items.size() - 1) { + goToLogin(); + } else { + onboardingViewPager.setCurrentItem(currentPosition + 1); + } + } + }); + + Preferences.hasSeenOnboarding().startRequest(new PreferencesSubscriber()); + } + + @Override + protected void setupViewModel() { + viewModel = ViewModelProviders.of(this, factory).get(OnboardingViewModel.class); + } + + private class PreferencesSubscriber extends ObservableListener { + + @Override + public void onNext(Boolean hasSeenOnboarding) { + super.onNext(hasSeenOnboarding); + if (hasSeenOnboarding) { + goToLogin(); + } + } + + @Override + public void onSuccess() { + + } + } + + ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + currentPosition = position; + + if (position == 0) { + buttonPrevious.setVisibility(View.INVISIBLE); + } else if (position == items.size() - 1) { + buttonNext.setText(getString(R.string.onboarding_continue)); + } else { + buttonPrevious.setVisibility(View.VISIBLE); + + buttonNext.setText(getString(R.string.onboarding_next)); + } + } + + @Override + public void onPageScrollStateChanged(int state) { + + } + }; + + private void goToLogin() { + Preferences.saveSeenOnboarding(true); + startActivity(new Intent(OnboardingActivity.this, LoginActivity.class)); + finish(); + } +} diff --git a/app/src/main/java/ro/code4/monitorizarevot/StartActivity.java b/app/src/main/java/ro/code4/monitorizarevot/StartActivity.java index a58068f..22a016c 100644 --- a/app/src/main/java/ro/code4/monitorizarevot/StartActivity.java +++ b/app/src/main/java/ro/code4/monitorizarevot/StartActivity.java @@ -29,7 +29,7 @@ private class PreferencesSubscriber extends ObservableListener { public void onNext(Boolean hasCredentials) { super.onNext(hasCredentials); startActivity(new Intent(StartActivity.this, - hasCredentials ? ToolbarActivity.class : LoginActivity.class)); + hasCredentials ? ToolbarActivity.class : OnboardingActivity.class)); } @Override diff --git a/app/src/main/java/ro/code4/monitorizarevot/adapter/OnboardingAdapter.java b/app/src/main/java/ro/code4/monitorizarevot/adapter/OnboardingAdapter.java new file mode 100644 index 0000000..24f6aa9 --- /dev/null +++ b/app/src/main/java/ro/code4/monitorizarevot/adapter/OnboardingAdapter.java @@ -0,0 +1,62 @@ +package ro.code4.monitorizarevot.adapter; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.constraint.ConstraintLayout; +import android.support.v4.view.PagerAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import java.util.List; +import ro.code4.monitorizarevot.net.model.OnboardingItem; + +import ro.code4.monitorizarevot.R; + +public class OnboardingAdapter extends PagerAdapter { + private Context context; + private List items; + + public OnboardingAdapter(Context context, List items) { + this.context = context; + this.items = items; + } + + @Override + public int getCount() { + return items.size(); + } + + @Override + public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { + return view == object; + } + + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + View view = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)) + .inflate(R.layout.item_onboarding_page, container, false); + + OnboardingItem item = items.get(position); + + TextView onboardingTitle = view.findViewById(R.id.onboarding_title); + ImageView onboardingIcon = view.findViewById(R.id.onboarding_icon); + TextView onboardingDescription = view.findViewById(R.id.onboarding_description); + + onboardingTitle.setText(item.getTitle()); + onboardingIcon.setImageResource(item.getImageResource()); + onboardingDescription.setText(item.getDescription()); + + container.addView(view); + + return view; + } + + @Override + public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { + container.removeView((ConstraintLayout) object); + } +} diff --git a/app/src/main/java/ro/code4/monitorizarevot/dagger/ActivityBindingModule.java b/app/src/main/java/ro/code4/monitorizarevot/dagger/ActivityBindingModule.java index 84c915d..649c35e 100644 --- a/app/src/main/java/ro/code4/monitorizarevot/dagger/ActivityBindingModule.java +++ b/app/src/main/java/ro/code4/monitorizarevot/dagger/ActivityBindingModule.java @@ -3,12 +3,16 @@ import dagger.Module; import dagger.android.ContributesAndroidInjector; import ro.code4.monitorizarevot.LoginActivity; +import ro.code4.monitorizarevot.OnboardingActivity; import ro.code4.monitorizarevot.StartActivity; import ro.code4.monitorizarevot.ToolbarActivity; @Module(includes = {ViewModelModule.class}) public abstract class ActivityBindingModule { + @ContributesAndroidInjector + abstract OnboardingActivity activityOnboarding(); + @ContributesAndroidInjector abstract StartActivity activityStart(); diff --git a/app/src/main/java/ro/code4/monitorizarevot/dagger/ViewModelModule.java b/app/src/main/java/ro/code4/monitorizarevot/dagger/ViewModelModule.java index 5b29450..912663d 100644 --- a/app/src/main/java/ro/code4/monitorizarevot/dagger/ViewModelModule.java +++ b/app/src/main/java/ro/code4/monitorizarevot/dagger/ViewModelModule.java @@ -14,6 +14,11 @@ public abstract class ViewModelModule { @Binds abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory); + @Binds + @IntoMap + @ViewModelKey(OnboardingViewModel.class) + abstract ViewModel bindOnboardingViewModel(OnboardingViewModel viewModel); + @Binds @IntoMap @ViewModelKey(StartViewModel.class) diff --git a/app/src/main/java/ro/code4/monitorizarevot/db/Preferences.java b/app/src/main/java/ro/code4/monitorizarevot/db/Preferences.java index ec876a7..8c5752b 100644 --- a/app/src/main/java/ro/code4/monitorizarevot/db/Preferences.java +++ b/app/src/main/java/ro/code4/monitorizarevot/db/Preferences.java @@ -10,6 +10,7 @@ public class Preferences { private static final String PREFS_BRANCH_NUMBER = "PREFS_BRANCH_NUMBER"; private static final String PREFS_USERNAME = "PREFS_USERNAME"; private static final String PREFS_TOKEN = "PREFS_TOKEN"; + private static final String PREFS_ONBOARDING = "PREFS_ONBOARDING"; public static void clear() { Prefs.clear(); @@ -55,6 +56,10 @@ public static boolean hasBranch() { return getCountyCode() != null && getBranchNumber() != -1; } + public static void saveSeenOnboarding(boolean hasSeenOnboarding) { + Prefs.putBoolean(PREFS_ONBOARDING, hasSeenOnboarding); + } + public static ObservableRequest isAlreadyLoggedIn() { return new ObservableRequest<>(new ObservableRequest.OnRequested() { @Override @@ -64,4 +69,14 @@ public void onRequest(Subscriber subscriber) { } }); } + + public static ObservableRequest hasSeenOnboarding() { + return new ObservableRequest<>(new ObservableRequest.OnRequested() { + @Override + public void onRequest(Subscriber subscriber) { + subscriber.onNext(Prefs.getBoolean(PREFS_ONBOARDING, false)); + subscriber.onCompleted(); + } + }); + } } diff --git a/app/src/main/java/ro/code4/monitorizarevot/net/model/OnboardingItem.java b/app/src/main/java/ro/code4/monitorizarevot/net/model/OnboardingItem.java new file mode 100644 index 0000000..4fa69b1 --- /dev/null +++ b/app/src/main/java/ro/code4/monitorizarevot/net/model/OnboardingItem.java @@ -0,0 +1,31 @@ +package ro.code4.monitorizarevot.net.model; + +public class OnboardingItem { + private Integer id; + private String title; + private String description; + private int imageResource; + + public OnboardingItem(Integer id, String title, String description, int imageResource) { + this.id = id; + this.title = title; + this.description = description; + this.imageResource = imageResource; + } + + public Integer getId() { + return id; + } + + public String getTitle() { + return title; + } + + public String getDescription() { + return description; + } + + public int getImageResource() { + return imageResource; + } +} diff --git a/app/src/main/java/ro/code4/monitorizarevot/viewmodel/OnboardingViewModel.java b/app/src/main/java/ro/code4/monitorizarevot/viewmodel/OnboardingViewModel.java new file mode 100644 index 0000000..45f03c2 --- /dev/null +++ b/app/src/main/java/ro/code4/monitorizarevot/viewmodel/OnboardingViewModel.java @@ -0,0 +1,16 @@ +package ro.code4.monitorizarevot.viewmodel; + +import javax.inject.Inject; + +import ro.code4.monitorizarevot.domain.usecase.UseCaseFactory; +import ro.code4.monitorizarevot.presentation.LoadingMessageFactory; +import ro.code4.monitorizarevot.presentation.MessageFactory; + +public class OnboardingViewModel extends BaseViewModel { + + @Inject + public OnboardingViewModel(UseCaseFactory useCaseFactory, LoadingMessageFactory loadingMessageFactory, + MessageFactory messageFactory) { + super(useCaseFactory, loadingMessageFactory, messageFactory); + } +} diff --git a/app/src/main/res/drawable-xhdpi/ic_onboarding_building.png b/app/src/main/res/drawable-xhdpi/ic_onboarding_building.png new file mode 100755 index 0000000..6247f8f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_onboarding_building.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_onboarding_form.png b/app/src/main/res/drawable-xhdpi/ic_onboarding_form.png new file mode 100755 index 0000000..dbfcbf5 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_onboarding_form.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_onboarding_note.png b/app/src/main/res/drawable-xhdpi/ic_onboarding_note.png new file mode 100755 index 0000000..d89548e Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_onboarding_note.png differ diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml new file mode 100644 index 0000000..af75935 --- /dev/null +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -0,0 +1,43 @@ + + + + + +