Skip to content

Commit 31895aa

Browse files
committed
implemented onboarding
1 parent e70e262 commit 31895aa

28 files changed

+690
-157
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.nmc.android.onboarding
2+
3+
import androidx.test.espresso.Espresso.*
4+
import androidx.test.espresso.action.ViewActions.swipeLeft
5+
import androidx.test.espresso.action.ViewActions.swipeRight
6+
import androidx.test.espresso.assertion.ViewAssertions.matches
7+
import androidx.test.espresso.matcher.ViewMatchers.isClickable
8+
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
9+
import androidx.test.espresso.matcher.ViewMatchers.withId
10+
import androidx.test.ext.junit.rules.ActivityScenarioRule
11+
import androidx.test.ext.junit.runners.AndroidJUnit4
12+
import com.nextcloud.client.onboarding.FirstRunActivity
13+
import com.owncloud.android.AbstractIT
14+
import com.owncloud.android.R
15+
import org.junit.Rule
16+
import org.junit.Test
17+
import org.junit.runner.RunWith
18+
19+
@RunWith(AndroidJUnit4::class)
20+
class OnBoardingIT : AbstractIT() {
21+
22+
@get:Rule
23+
var activityRule = ActivityScenarioRule(FirstRunActivity::class.java)
24+
25+
@Test
26+
fun runAllOnboardingTests() {
27+
verifyUIElements()
28+
29+
shortSleep()
30+
31+
verifyOnBoardingSwipe()
32+
}
33+
34+
private fun verifyUIElements() {
35+
onView(withId(R.id.contentPanel)).check(matches(isCompletelyDisplayed()))
36+
onView(withId(R.id.progressIndicator)).check(matches(isCompletelyDisplayed()))
37+
onView(withId(R.id.login)).check(matches(isCompletelyDisplayed()))
38+
onView(withId(R.id.login)).check(matches(isClickable()))
39+
}
40+
41+
private fun verifyOnBoardingSwipe() {
42+
onView(withId(R.id.contentPanel)).perform(swipeLeft())
43+
onView(withId(R.id.contentPanel)).perform(swipeLeft())
44+
onView(withId(R.id.contentPanel)).perform(swipeLeft())
45+
46+
onView(withId(R.id.contentPanel)).perform(swipeRight())
47+
onView(withId(R.id.contentPanel)).perform(swipeRight())
48+
}
49+
}

app/src/main/java/com/nextcloud/client/onboarding/FirstRunActivity.java

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,32 @@
2626

2727
import android.accounts.Account;
2828
import android.accounts.AccountManager;
29+
import android.annotation.SuppressLint;
2930
import android.content.Intent;
31+
import android.content.pm.ActivityInfo;
3032
import android.content.res.Configuration;
31-
import android.net.Uri;
3233
import android.os.Bundle;
33-
import android.view.View;
3434
import android.view.ViewGroup;
35-
import android.widget.LinearLayout;
3635

3736
import com.nextcloud.android.common.ui.theme.utils.ColorRole;
3837
import com.nextcloud.client.account.UserAccountManager;
3938
import com.nextcloud.client.appinfo.AppInfo;
4039
import com.nextcloud.client.di.Injectable;
4140
import com.nextcloud.client.preferences.AppPreferences;
41+
import com.nmc.android.helper.OnBoardingUtils;
42+
import com.nmc.android.helper.OnBoardingPagerAdapter;
4243
import com.owncloud.android.BuildConfig;
4344
import com.owncloud.android.R;
4445
import com.owncloud.android.authentication.AuthenticatorActivity;
4546
import com.owncloud.android.databinding.FirstRunActivityBinding;
46-
import com.owncloud.android.features.FeatureItem;
4747
import com.owncloud.android.ui.activity.BaseActivity;
4848
import com.owncloud.android.ui.activity.FileDisplayActivity;
49-
import com.owncloud.android.ui.adapter.FeaturesViewAdapter;
5049
import com.owncloud.android.utils.DisplayUtils;
5150
import com.owncloud.android.utils.theme.ViewThemeUtils;
5251

5352
import javax.inject.Inject;
5453

54+
import androidx.annotation.NonNull;
5555
import androidx.viewpager.widget.ViewPager;
5656

5757
/**
@@ -72,21 +72,25 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
7272

7373
private FirstRunActivityBinding binding;
7474
private ViewThemeUtils defaultViewThemeUtils;
75+
private int selectedPosition = 0;
7576

77+
@SuppressLint("SourceLockedOrientationActivity")
7678
@Override
7779
protected void onCreate(Bundle savedInstanceState) {
7880
enableAccountHandling = false;
7981

8082
super.onCreate(savedInstanceState);
8183
defaultViewThemeUtils = viewThemeUtilsFactory.withPrimaryAsBackground();
8284
defaultViewThemeUtils.platform.themeStatusBar(this, ColorRole.PRIMARY);
83-
this.binding = FirstRunActivityBinding.inflate(getLayoutInflater());
84-
setContentView(binding.getRoot());
85-
86-
boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
8785

88-
setSlideshowSize(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
86+
//if device is not tablet then we have to lock it to Portrait mode
87+
//as we don't have images for that
88+
if (!com.nmc.android.utils.DisplayUtils.isTablet()) {
89+
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
90+
}
8991

92+
this.binding = FirstRunActivityBinding.inflate(getLayoutInflater());
93+
setContentView(binding.getRoot());
9094

9195
defaultViewThemeUtils.material.colorMaterialButtonFilledOnPrimary(binding.login);
9296
binding.login.setOnClickListener(v -> {
@@ -95,69 +99,52 @@ protected void onCreate(Bundle savedInstanceState) {
9599
authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, false);
96100
startActivityForResult(authenticatorActivityIntent, FIRST_RUN_RESULT_CODE);
97101
} else {
102+
preferences.setOnBoardingComplete(true);
98103
finish();
99104
}
100105
});
101106

102-
103-
defaultViewThemeUtils.material.colorMaterialButtonOutlinedOnPrimary(binding.signup);
104-
binding.signup.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
105-
binding.signup.setOnClickListener(v -> {
106-
Intent authenticatorActivityIntent = new Intent(this, AuthenticatorActivity.class);
107-
authenticatorActivityIntent.putExtra(AuthenticatorActivity.EXTRA_USE_PROVIDER_AS_WEBLOGIN, true);
108-
109-
if (getIntent().getBooleanExtra(EXTRA_ALLOW_CLOSE, false)) {
110-
startActivityForResult(authenticatorActivityIntent, FIRST_RUN_RESULT_CODE);
111-
} else {
112-
authenticatorActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
113-
startActivity(authenticatorActivityIntent);
114-
}
115-
});
116-
117-
defaultViewThemeUtils.platform.colorTextView(binding.hostOwnServer, ColorRole.ON_PRIMARY);
118-
binding.hostOwnServer.setVisibility(isProviderOrOwnInstallationVisible ? View.VISIBLE : View.GONE);
119-
120-
if (!isProviderOrOwnInstallationVisible) {
121-
binding.hostOwnServer.setOnClickListener(v -> onHostYourOwnServerClick());
122-
}
123-
124-
125107
// Sometimes, accounts are not deleted when you uninstall the application so we'll do it now
126108
if (onboarding.isFirstRun()) {
127109
userAccountManager.removeAllAccounts();
128110
}
129111

130-
FeaturesViewAdapter featuresViewAdapter = new FeaturesViewAdapter(getSupportFragmentManager(), getFirstRun());
131-
binding.progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
132-
binding.contentPanel.setAdapter(featuresViewAdapter);
112+
updateLoginButtonMargin();
113+
updateOnBoardingPager(selectedPosition);
133114

134115
binding.contentPanel.addOnPageChangeListener(this);
135116
}
136117

137-
private void setSlideshowSize(boolean isLandscape) {
138-
boolean isProviderOrOwnInstallationVisible = getResources().getBoolean(R.bool.show_provider_or_own_installation);
139-
140-
LinearLayout.LayoutParams layoutParams;
141-
142-
binding.buttonLayout.setOrientation(isLandscape ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
118+
private void updateOnBoardingPager(int selectedPosition) {
119+
OnBoardingPagerAdapter featuresViewAdapter = new OnBoardingPagerAdapter(this, OnBoardingUtils.Companion.getOnBoardingItems());
120+
binding.progressIndicator.setNumberOfSteps(featuresViewAdapter.getCount());
121+
binding.contentPanel.setAdapter(featuresViewAdapter);
122+
binding.contentPanel.setCurrentItem(selectedPosition);
123+
}
143124

144-
if (isProviderOrOwnInstallationVisible) {
145-
layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
125+
private void updateLoginButtonMargin() {
126+
if (com.nmc.android.utils.DisplayUtils.isLandscapeOrientation()) {
127+
if (binding.login.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
128+
((ViewGroup.MarginLayoutParams) binding.login.getLayoutParams()).setMargins(
129+
0, 0, 0, getResources().getDimensionPixelOffset(
130+
R.dimen.login_btn_bottom_margin_land));
131+
binding.login.requestLayout();
132+
}
146133
} else {
147-
layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, DisplayUtils.convertDpToPixel(isLandscape ? 100f : 150f, this));
134+
if (binding.login.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
135+
((ViewGroup.MarginLayoutParams) binding.login.getLayoutParams()).setMargins(
136+
0, 0, 0, getResources().getDimensionPixelOffset(
137+
R.dimen.login_btn_bottom_margin));
138+
binding.login.requestLayout();
139+
}
148140
}
149-
150-
binding.bottomLayout.setLayoutParams(layoutParams);
151141
}
152142

153143
@Override
154-
public void onConfigurationChanged(Configuration newConfig) {
144+
public void onConfigurationChanged(@NonNull Configuration newConfig) {
155145
super.onConfigurationChanged(newConfig);
156-
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
157-
setSlideshowSize(true);
158-
} else {
159-
setSlideshowSize(false);
160-
}
146+
updateLoginButtonMargin();
147+
updateOnBoardingPager(selectedPosition);
161148
}
162149

163150
@Override
@@ -167,11 +154,7 @@ public void onBackPressed() {
167154
if (getIntent().getBooleanExtra(EXTRA_ALLOW_CLOSE, false)) {
168155
super.onBackPressed();
169156
} else {
170-
Intent intent = new Intent(getApplicationContext(), AuthenticatorActivity.class);
171-
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
172-
intent.putExtra(EXTRA_EXIT, true);
173-
startActivity(intent);
174-
finish();
157+
finishAffinity();
175158
}
176159
}
177160

@@ -193,19 +176,18 @@ public void onPageScrolled(int position, float positionOffset, int positionOffse
193176

194177
@Override
195178
public void onPageSelected(int position) {
196-
binding.progressIndicator.animateToStep(position + 1);
179+
//-1 to position because this position doesn't start from 0
180+
selectedPosition = position - 1;
181+
182+
//pass directly the position here because this position will doesn't start from 0
183+
binding.progressIndicator.animateToStep(position);
197184
}
198185

199186
@Override
200187
public void onPageScrollStateChanged(int state) {
201188
// unused but to be implemented due to abstract parent
202189
}
203190

204-
public void onHostYourOwnServerClick() {
205-
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.url_server_install)));
206-
DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_browser_available);
207-
}
208-
209191
@Override
210192
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
211193
super.onActivityResult(requestCode, resultCode, data);
@@ -230,13 +212,4 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
230212
finish();
231213
}
232214
}
233-
234-
235-
public static FeatureItem[] getFirstRun() {
236-
return new FeatureItem[]{
237-
new FeatureItem(R.drawable.logo, R.string.first_run_1_text, R.string.empty, true, false),
238-
new FeatureItem(R.drawable.first_run_files, R.string.first_run_2_text, R.string.empty, true, false),
239-
new FeatureItem(R.drawable.first_run_groupware, R.string.first_run_3_text, R.string.empty, true, false),
240-
new FeatureItem(R.drawable.first_run_talk, R.string.first_run_4_text, R.string.empty, true, false)};
241-
}
242215
}

app/src/main/java/com/nextcloud/client/onboarding/OnboardingServiceImpl.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ internal class OnboardingServiceImpl constructor(
7272
}
7373

7474
override fun launchFirstRunIfNeeded(activity: Activity): Boolean {
75-
val isProviderOrOwnInstallationVisible = resources.getBoolean(R.bool.show_provider_or_own_installation)
76-
val canLaunch = isProviderOrOwnInstallationVisible && isFirstRun && activity is AuthenticatorActivity
75+
val canLaunch = !preferences.onBoardingComplete && activity is AuthenticatorActivity
7776
if (canLaunch) {
7877
val intent = Intent(activity, FirstRunActivity::class.java)
7978
activity.startActivityForResult(intent, AuthenticatorActivity.REQUEST_CODE_FIRST_RUN)

app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ default void onDarkThemeModeChanged(DarkMode mode) {
372372

373373
void setCalendarLastBackup(long timestamp);
374374

375+
void setOnBoardingComplete(boolean isCompleted);
376+
377+
boolean getOnBoardingComplete();
378+
375379
void setPdfZoomTipShownCount(int count);
376380

377381
int getPdfZoomTipShownCount();

app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public final class AppPreferencesImpl implements AppPreferences {
8585
private static final String PREF__FOLDER_SORT_ORDER = "folder_sort_order";
8686
private static final String PREF__FOLDER_LAYOUT = "folder_layout";
8787

88+
private static final String PREF__ON_BOARDING_COMPLETE = "on_boarding_complete";
89+
8890
private static final String PREF__LOCK_TIMESTAMP = "lock_timestamp";
8991
private static final String PREF__SHOW_MEDIA_SCAN_NOTIFICATIONS = "show_media_scan_notifications";
9092
private static final String PREF__LOCK = SettingsActivity.PREFERENCE_LOCK;
@@ -691,6 +693,16 @@ public void setCalendarLastBackup(long timestamp) {
691693
preferences.edit().putLong(PREF__CALENDAR_LAST_BACKUP, timestamp).apply();
692694
}
693695

696+
@Override
697+
public void setOnBoardingComplete(boolean isCompleted) {
698+
preferences.edit().putBoolean(PREF__ON_BOARDING_COMPLETE, isCompleted).apply();
699+
}
700+
701+
@Override
702+
public boolean getOnBoardingComplete() {
703+
return preferences.getBoolean(PREF__ON_BOARDING_COMPLETE, false);
704+
}
705+
694706
@Override
695707
public void setPdfZoomTipShownCount(int count) {
696708
preferences.edit().putInt(PREF__PDF_ZOOM_TIP_SHOWN, count).apply();

0 commit comments

Comments
 (0)