From 82bbdea990386100396eedb0db402d7238ae9661 Mon Sep 17 00:00:00 2001 From: str4d Date: Thu, 19 Jun 2014 01:00:22 +0000 Subject: [PATCH] Introduction to Bote for new users --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 7 + .../i2p/bote/android/EmailListActivity.java | 54 ++++--- .../i2p/bote/android/intro/IntroActivity.java | 144 ++++++++++++++++++ .../res/drawable-hdpi/ic_navigation_back.png | Bin 0 -> 1331 bytes .../res/drawable-mdpi/ic_navigation_back.png | Bin 0 -> 1227 bytes .../res/drawable-xhdpi/ic_navigation_back.png | Bin 0 -> 1478 bytes app/src/main/res/layout/activity_intro.xml | 28 ++++ app/src/main/res/layout/fragment_intro_0.xml | 53 +++++++ app/src/main/res/layout/fragment_intro_1.xml | 40 +++++ app/src/main/res/layout/fragment_intro_2.xml | 40 +++++ app/src/main/res/layout/fragment_intro_3.xml | 40 +++++ app/src/main/res/layout/fragment_intro_4.xml | 49 ++++++ app/src/main/res/values/strings.xml | 16 +- 14 files changed, 453 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/i2p/bote/android/intro/IntroActivity.java create mode 100644 app/src/main/res/drawable-hdpi/ic_navigation_back.png create mode 100644 app/src/main/res/drawable-mdpi/ic_navigation_back.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_navigation_back.png create mode 100644 app/src/main/res/layout/activity_intro.xml create mode 100644 app/src/main/res/layout/fragment_intro_0.xml create mode 100644 app/src/main/res/layout/fragment_intro_1.xml create mode 100644 app/src/main/res/layout/fragment_intro_2.xml create mode 100644 app/src/main/res/layout/fragment_intro_3.xml create mode 100644 app/src/main/res/layout/fragment_intro_4.xml diff --git a/app/build.gradle b/app/build.gradle index ef1aaad..b239a69 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,4 +26,5 @@ dependencies { compile 'com.android.support:support-v4:19.+' compile 'com.android.support:appcompat-v7:19.+' compile 'com.github.chrisbanes.actionbarpulltorefresh:extra-abc:+' + compile 'com.mcxiaoke.viewpagerindicator:library:2.4.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e4b06b7..a8a68c9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,13 @@ + + + diff --git a/app/src/main/java/i2p/bote/android/EmailListActivity.java b/app/src/main/java/i2p/bote/android/EmailListActivity.java index 4d6a808..2900a37 100644 --- a/app/src/main/java/i2p/bote/android/EmailListActivity.java +++ b/app/src/main/java/i2p/bote/android/EmailListActivity.java @@ -1,23 +1,9 @@ package i2p.bote.android; -import net.i2p.android.router.service.IRouterState; -import i2p.bote.I2PBote; -import i2p.bote.android.addressbook.AddressBookActivity; -import i2p.bote.android.config.SettingsActivity; -import i2p.bote.android.service.BoteService; -import i2p.bote.android.service.Init; -import i2p.bote.android.service.Init.RouterChoice; -import i2p.bote.android.util.MoveToDialogFragment; -import i2p.bote.folder.EmailFolder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.preference.PreferenceManager; -import android.app.Activity; import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; import android.app.AlertDialog; import android.app.Dialog; -import android.app.ActivityManager.RunningServiceInfo; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; @@ -26,6 +12,10 @@ import android.content.ServiceConnection; import android.content.SharedPreferences; import android.content.res.Configuration; import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.preference.PreferenceManager; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.app.DialogFragment; import android.support.v4.view.GravityCompat; @@ -38,6 +28,19 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; + +import net.i2p.android.router.service.IRouterState; + +import i2p.bote.I2PBote; +import i2p.bote.android.addressbook.AddressBookActivity; +import i2p.bote.android.config.SettingsActivity; +import i2p.bote.android.intro.IntroActivity; +import i2p.bote.android.service.BoteService; +import i2p.bote.android.service.Init; +import i2p.bote.android.service.Init.RouterChoice; +import i2p.bote.android.util.MoveToDialogFragment; +import i2p.bote.folder.EmailFolder; public class EmailListActivity extends ActionBarActivity implements EmailListFragment.OnEmailSelectedListener, @@ -60,9 +63,11 @@ public class EmailListActivity extends ActionBarActivity implements private static final String SHARED_PREFS = "i2p.bote"; private static final String PREF_NAV_DRAWER_OPENED = "navDrawerOpened"; + private static final String PREF_FIRST_START = "firstStart"; private static final String ACTIVE_FOLDER = "activeFolder"; - private static final int REQUEST_START_I2P = 1; + private static final int RUN_SETUP_WIZARD = 1; + private static final int REQUEST_START_I2P = 2; @Override protected void onCreate(Bundle savedInstanceState) { @@ -206,6 +211,14 @@ public class EmailListActivity extends ActionBarActivity implements // Open nav drawer if the user has never opened it themselves if (!mSharedPrefs.getBoolean(PREF_NAV_DRAWER_OPENED, false)) mDrawerLayout.openDrawer(mDrawerOuter); + + // If first start, go to introduction and setup wizard + // TODO always show while testing, revert to preference when finished + if (true || mSharedPrefs.getBoolean(PREF_FIRST_START, true)) { + mSharedPrefs.edit().putBoolean(PREF_FIRST_START, false).apply(); + Intent i = new Intent(EmailListActivity.this, IntroActivity.class); + startActivityForResult(i, RUN_SETUP_WIZARD); + } } private class DrawerItemClickListener implements ListView.OnItemClickListener { @@ -353,8 +366,13 @@ public class EmailListActivity extends ActionBarActivity implements @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQUEST_START_I2P) { - if (resultCode == Activity.RESULT_OK) { + if (requestCode == RUN_SETUP_WIZARD) { + if (resultCode == RESULT_OK) { + // TODO remove (and implement a UI tutorial?) + Toast.makeText(this, "Setup wizard not yet implemented.", Toast.LENGTH_SHORT).show(); + } + } else if (requestCode == REQUEST_START_I2P) { + if (resultCode == RESULT_OK) { startBote(); } } else { diff --git a/app/src/main/java/i2p/bote/android/intro/IntroActivity.java b/app/src/main/java/i2p/bote/android/intro/IntroActivity.java new file mode 100644 index 0000000..e6debe2 --- /dev/null +++ b/app/src/main/java/i2p/bote/android/intro/IntroActivity.java @@ -0,0 +1,144 @@ +package i2p.bote.android.intro; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.ActionBarActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import com.viewpagerindicator.LinePageIndicator; + +import i2p.bote.android.R; + +public class IntroActivity extends ActionBarActivity { + + /** + * The {@link android.support.v4.view.PagerAdapter} that will provide + * fragments for each of the sections. We use a + * {@link FragmentPagerAdapter} derivative, which will keep every + * loaded fragment in memory. If this becomes too memory intensive, it + * may be best to switch to a + * {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + SectionsPagerAdapter mSectionsPagerAdapter; + + /** + * The {@link ViewPager} that will host the section contents. + */ + ViewPager mViewPager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_intro); + + // Take up the entire screen. + getSupportActionBar().hide(); + + // Create the sections adapter. + mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + + // Set up the ViewPager with the sections adapter. + mViewPager = (ViewPager) findViewById(R.id.pager); + mViewPager.setAdapter(mSectionsPagerAdapter); + + // Bind the page indicator to the pager. + LinePageIndicator pageIndicator = (LinePageIndicator)findViewById(R.id.page_indicator); + pageIndicator.setViewPager(mViewPager); + + findViewById(R.id.skip_intro).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + setResult(Activity.RESULT_CANCELED); + finish(); + } + }); + } + + + /** + * A {@link FragmentPagerAdapter} that returns a fragment corresponding to + * one of the intro sections. + */ + public class SectionsPagerAdapter extends FragmentPagerAdapter { + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class below). + return PlaceholderFragment.newInstance(position); + } + + @Override + public int getCount() { + return 5; + } + } + + /** + * A placeholder fragment containing a simple view. + */ + public static class PlaceholderFragment extends Fragment { + /** + * The fragment argument representing the section number for this + * fragment. + */ + private static final String ARG_SECTION_NUMBER = "section_number"; + + /** + * Returns a new instance of this fragment for the given section + * number. + */ + public static PlaceholderFragment newInstance(int sectionNumber) { + PlaceholderFragment fragment = new PlaceholderFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_SECTION_NUMBER, sectionNumber); + fragment.setArguments(args); + return fragment; + } + + public PlaceholderFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + switch (getArguments().getInt(ARG_SECTION_NUMBER)) { + case 1: + return inflater.inflate(R.layout.fragment_intro_1, container, false); + case 2: + return inflater.inflate(R.layout.fragment_intro_2, container, false); + case 3: + return inflater.inflate(R.layout.fragment_intro_3, container, false); + case 4: + View v4 = inflater.inflate(R.layout.fragment_intro_4, container, false); + Button b = (Button) v4.findViewById(R.id.start_setup_wizard); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + // TODO start setup wizard + getActivity().setResult(Activity.RESULT_OK); + getActivity().finish(); + } + }); + return v4; + default: + View v0 = inflater.inflate(R.layout.fragment_intro_0, container, false); + TextView tv = (TextView) v0.findViewById(R.id.intro_app_name); + tv.append("."); + return v0; + } + } + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_navigation_back.png b/app/src/main/res/drawable-hdpi/ic_navigation_back.png new file mode 100644 index 0000000000000000000000000000000000000000..837998f4abfca5099844e78e41ff82b914cab210 GIT binary patch literal 1331 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%qp275hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8hm3bwJ6}oxF$}kgLQj3#|G7CyF^YauyCMG83 zmzLNn0bL65LT&-v*t}wBFaZNhzap_f-%!s00+w{G(#^lGsVi#&B@r%*~QG%$-u?X(ACh=#L&{!#L3yw z&D7A`#K{n**Cju>G&eP`1g19yq1POzUQlAlEdbi=l3J8mmYU*Ll%J~r_Ow+dZnv1= zG!Lpb1-DyFaq86vIz}H9wMbD769T3m5EGtofgE_!Pt60S_ab1zKJm-JoPmLHsi%u$ zNX4x;GdFr2aS(Bxe0N30;-&IJIXSGlEN`!D4f!MfKQY%eQI|#f;H{+2-u(&5x{DSa zt6N(whC6h)22z4+%seE_&yVw?<*k7}B zx{_Yy&%AIT$D#Vo{uZ|&!4oZK_%r@+-)i)kv0jCt%IR7Cg8UWyd!5h6b{tsp({fw- zg$S+%*Hb^|GO`%oXLAVnypQ4F+20HsU;_^X{4nR~YOam#<@(eSz_L<;@B9+D*@dpWV0= zFIIf<=>c8$x&ztPTxnc;H}Id-{PJw}k@B3}jwu&+H@;)#cPkaDUhm{9uU1%It6rRnRPTc%-V*<5N%FQ%}BD*tlH@n%+m`(O)l61k1+0BC6qNTGlH@jmx zKbg64H~V4<2rJYQE3LK_A&9g>s8(MD6(1ZVVjn6+5wS0U`e4u!6se-dnKYaF;5smK z?>(IFJKwqIV_uq`n(XxT`3QpOOdk<)&I;VOZIAP{YPDaTWj`J-;2C`uS40yL30W^9 zkXFSK${|r+oc{ui5QKL?$ro@T^CU0nDlNJ>bX7GRG(n7vRSi*^Ll_iMNzr1|osT}H zfFj4Jrz06QW28`7IZ`vxOl>MJ)#fBlrp89WNR@X8RD?xPRZnUbUyV`Qyu7n_!wdzs zQ}A4jx+kiTnFcA{L?A-5L5UrPU^q;}Fw2Fx00^;=WnhS5qd~~>ktokXu=7w(HB+AD zbHc<_r6tebgVKiRm&>9US>tE?L!H4~vB$cU1nxsh!|Cc~#S3yYeB z(n5@KIA}$Yc{q_Af+-;pNwNZj45`-s~783dDcf~)qw#Gh-w|t%@PxHhr&*0#o{o`$K@mVn1WpCBL#y?!& z-#glVp{qo$4}f8^sDR_0w%qzy&xP})mTTSqtv#)M{$G|KX$|xix_rOA79a7{$6nna z1|Ki{{l-~gExdfbXM?zSbn3LX{2aF;w0-dX!}S+Dn-X}l#n!JJ^`sqf1k^TQjw?`O}Z9LT~U>+zQuW`h!?$sOAAMKwU6V}eWPTH4OUe3LL>6^Fy hTFR0gA9{(F4&q$`UlX^jxzuN literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_navigation_back.png b/app/src/main/res/drawable-xhdpi/ic_navigation_back.png new file mode 100644 index 0000000000000000000000000000000000000000..f420e43f1777fc1b9e346c9108510c44f4e28598 GIT binary patch literal 1478 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m{l@EB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%uvD1M9IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8E%gnI^o@*kfhu&1EAvVcD|GXUm0>2hq!uR^WfqiV=I1GZOiWD5 zFD$Tv3bSNU;+l1ennz|zM-B0$V)JVzP|XC=H|jx7ncO3BHWAB;NpiyW)Z+ZoqGVvir744~DzI`cN=+=uFAB-e&w+(vKt_H^esM;Afr4|esh**NZ(?$0 z9!LbN!`Ii!Gq1QLF)umQ)5TT^Xog;9W{Q=eo1v+tk%fz?lYxt&p{t>#iJ_&diIcOV zo2j9>iIX8ruSMv>2~2MaLa!@My`aR9TL84#CABECEH%ZgC_h&L>}jh^+-`Bg zX&zK>3U0SJvz`6Op8`{wLDo*G|{m~Y=}fA2WS7AWF4Q(J(6$$^1`fl+~hrGY_!p>|c= zdg*$-EZMJ3RhvwAxGkRebM6JfAC^}(CB3#{T+BDmvj3L**+r{X$Y0TXwVj9I%7gC# zmshB%7PKxqBDu;ohhZV}^X$&XGLO|OSj9OxWG(K$s@muEQ1#Wt>zWJZ&VMPjr>mB= zw9o2esoNdo^V`?qCXV!4YI$xN9`*|*7!s9)>3~T0?^ES-=tj4&Zobb0xlbIOom^_N(uA3jZJ1>^$(JHrq^DCq$GkkfFt=ZhK z@z49gx~t1pJMBLx(cpT8FH0-+gD1yYCY9Yxmb<+br|kKp_JHy0R72J;P8M+!G!4?K z1Z!Mng<7)uJ6N}H+;hJ3T>FqxMveFdfvVi*S%0LL=YFsc3>DxDkdHO&KJisI=z(@a zijZBPaOZhz6VogA<7V42pYUpm;x@BTNxX1%R;`dvPWYP130eEoX0uFY7n|m3P@9xI zokiL`EX;F5Xb+nQQv`!vW^Vq;;Nx5*Ikr75}rDDTFf*t i1|~#&YGnWAG+^k_eXaHOs9*;J5O})!xvX + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_intro_0.xml b/app/src/main/res/layout/fragment_intro_0.xml new file mode 100644 index 0000000..e3cbd75 --- /dev/null +++ b/app/src/main/res/layout/fragment_intro_0.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_intro_1.xml b/app/src/main/res/layout/fragment_intro_1.xml new file mode 100644 index 0000000..d7555aa --- /dev/null +++ b/app/src/main/res/layout/fragment_intro_1.xml @@ -0,0 +1,40 @@ + + + + + + + + diff --git a/app/src/main/res/layout/fragment_intro_2.xml b/app/src/main/res/layout/fragment_intro_2.xml new file mode 100644 index 0000000..68d7042 --- /dev/null +++ b/app/src/main/res/layout/fragment_intro_2.xml @@ -0,0 +1,40 @@ + + + + + + + + diff --git a/app/src/main/res/layout/fragment_intro_3.xml b/app/src/main/res/layout/fragment_intro_3.xml new file mode 100644 index 0000000..757d871 --- /dev/null +++ b/app/src/main/res/layout/fragment_intro_3.xml @@ -0,0 +1,40 @@ + + + + + + + + diff --git a/app/src/main/res/layout/fragment_intro_4.xml b/app/src/main/res/layout/fragment_intro_4.xml new file mode 100644 index 0000000..6ed512c --- /dev/null +++ b/app/src/main/res/layout/fragment_intro_4.xml @@ -0,0 +1,49 @@ + + + + + + + + +