Skip to content

Commit ea80a42

Browse files
committed
Completes issues #3 and implements issue #11
1 parent 1a5cb09 commit ea80a42

File tree

5 files changed

+252
-25
lines changed

5 files changed

+252
-25
lines changed

res/layout/stats.xml

+6
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@
103103
android:layout_width="wrap_content"
104104
android:layout_height="wrap_content" />
105105
</LinearLayout>
106+
107+
<TextView
108+
android:id="@+id/tag_eta_shortest"
109+
style="@style/Estimates"
110+
android:layout_width="match_parent"
111+
android:layout_height="wrap_content"/>
106112
</LinearLayout>
107113

108114
<com.wanikani.androidnotifier.graph.HistogramChart

res/values/strings.xml

+4
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@
222222
<string name="tag_eta_next_future">Next level in:</string>
223223
<string name="tag_eta_next_past">Next level:</string>
224224
<string name="tag_eta_l50">Level 50 on:</string>
225+
<string name="fmt_eta_shortest">You can levelup %s</string>
226+
<string name="tag_eta_today">today</string>
227+
<string name="tag_eta_tomorrow">tomorrow</string>
228+
<string name="tag_eta_in">in %d days</string>
225229

226230
<string name="fmt_eta_next_future">%s</string>
227231
<string name="fmt_eta_next_past">%s ago</string>

src/com/wanikani/androidnotifier/DashboardData.java

+50-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
import android.graphics.Bitmap;
77
import android.os.Bundle;
88

9+
import com.wanikani.wklib.ItemLibrary;
10+
import com.wanikani.wklib.Kanji;
911
import com.wanikani.wklib.LevelProgression;
12+
import com.wanikani.wklib.Radical;
1013
import com.wanikani.wklib.SRSDistribution;
1114
import com.wanikani.wklib.StudyQueue;
1215
import com.wanikani.wklib.UserInformation;
@@ -78,6 +81,15 @@ public static class OptionalData {
7881
/** Critical items status */
7982
public DashboardData.OptionalDataStatus ciStatus;
8083

84+
/** Current level radicals */
85+
public ItemLibrary<Radical> tlradicals;
86+
87+
/** Current level kanji */
88+
public ItemLibrary<Kanji> tlkanji;
89+
90+
/** Current level status */
91+
public DashboardData.OptionalDataStatus tlStatus;
92+
8193
/**
8294
* Constructor. Input parameters may be null.
8395
* In order to provide consistent behaviour:
@@ -95,10 +107,13 @@ public static class OptionalData {
95107
* @param lpStatus level progression status
96108
* @param criticalItems number of critical items
97109
* @param ciStatus critical items status
110+
* @param tlradicals current level radicals
111+
* @param tlkanji current level kanji
98112
*/
99113
public OptionalData (SRSDistribution srs, DashboardData.OptionalDataStatus srsStatus,
100114
LevelProgression lp, DashboardData.OptionalDataStatus lpStatus,
101-
int criticalItems, DashboardData.OptionalDataStatus ciStatus)
115+
int criticalItems, DashboardData.OptionalDataStatus ciStatus,
116+
ItemLibrary<Radical> tlradicals, ItemLibrary<Kanji> tlkanji)
102117
{
103118
this.srs = srs;
104119
this.lp = lp;
@@ -107,6 +122,9 @@ public OptionalData (SRSDistribution srs, DashboardData.OptionalDataStatus srsSt
107122
this.srsStatus = srsStatus;
108123
this.lpStatus = lpStatus;
109124
this.ciStatus = ciStatus;
125+
126+
this.tlradicals = tlradicals;
127+
this.tlkanji = tlkanji;
110128
}
111129

112130
/**
@@ -118,6 +136,7 @@ public OptionalData ()
118136
srsStatus = DashboardData.OptionalDataStatus.RETRIEVING;
119137
lpStatus = DashboardData.OptionalDataStatus.RETRIEVING;
120138
ciStatus = DashboardData.OptionalDataStatus.RETRIEVING;
139+
tlStatus = DashboardData.OptionalDataStatus.RETRIEVING;
121140
}
122141

123142
/**
@@ -144,6 +163,13 @@ private void merge (DashboardData.OptionalData od)
144163
criticalItems = od.criticalItems;
145164
ciStatus = od.ciStatus;
146165
}
166+
167+
if (tlStatus != DashboardData.OptionalDataStatus.RETRIEVED &&
168+
od.tlStatus == DashboardData.OptionalDataStatus.RETRIEVED) {
169+
tlradicals = od.tlradicals;
170+
tlkanji = od.tlkanji;
171+
tlStatus = od.tlStatus;
172+
}
147173
}
148174

149175
/**
@@ -153,7 +179,9 @@ private void merge (DashboardData.OptionalData od)
153179
public boolean isIncomplete ()
154180
{
155181
return lpStatus != DashboardData.OptionalDataStatus.RETRIEVED ||
156-
srsStatus != DashboardData.OptionalDataStatus.RETRIEVED;
182+
srsStatus != DashboardData.OptionalDataStatus.RETRIEVED ||
183+
ciStatus != DashboardData.OptionalDataStatus.RETRIEVED ||
184+
tlStatus != DashboardData.OptionalDataStatus.RETRIEVED;
157185
}
158186
};
159187

@@ -198,6 +226,9 @@ public boolean isIncomplete ()
198226

199227
private static final String KEY_CRITICAL_ITEMS = PREFIX + "critical_items";
200228

229+
private static final String KEY_CURRENT_LEVEL_RADICALS = PREFIX + "current_level_radicals";
230+
private static final String KEY_CURRENT_LEVEL_KANJI = PREFIX + "current_level_kanji";
231+
201232
public int lessonsAvailable;
202233

203234
public int reviewsAvailable;
@@ -356,6 +387,11 @@ public void serialize (Bundle bundle)
356387
if (od.ciStatus == OptionalDataStatus.RETRIEVED)
357388
bundle.putInt (KEY_CRITICAL_ITEMS, od.criticalItems);
358389

390+
if (od.lpStatus == OptionalDataStatus.RETRIEVED) {
391+
bundle.putSerializable (KEY_CURRENT_LEVEL_RADICALS, od.tlradicals);
392+
bundle.putSerializable (KEY_CURRENT_LEVEL_KANJI, od.tlkanji);
393+
}
394+
359395
if (e != null)
360396
bundle.putSerializable (KEY_EXCEPTION, e);
361397
}
@@ -433,6 +469,18 @@ private void deserialize (Bundle bundle)
433469
od.criticalItems = 0;
434470
}
435471

472+
if (bundle.containsKey (KEY_CURRENT_LEVEL_RADICALS)) {
473+
od.tlStatus = OptionalDataStatus.RETRIEVED;
474+
od.tlradicals = (ItemLibrary<Radical>) bundle.getSerializable (KEY_CURRENT_LEVEL_RADICALS);
475+
od.tlkanji = (ItemLibrary<Kanji>) bundle.getSerializable (KEY_CURRENT_LEVEL_KANJI);
476+
} else {
477+
/* RETRIEVING is correct, because this is what DashboardActivity
478+
* will do right after calling this method */
479+
od.tlStatus = OptionalDataStatus.RETRIEVING;
480+
od.tlradicals = null;
481+
od.tlkanji = null;
482+
}
483+
436484
if (bundle.containsKey (KEY_EXCEPTION))
437485
e = (IOException) bundle.getSerializable (KEY_EXCEPTION);
438486
else

src/com/wanikani/androidnotifier/MainActivity.java

+60-11
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import android.os.AsyncTask;
2323
import android.os.Bundle;
2424
import android.os.Looper;
25-
import android.preference.PreferenceManager;
2625
import android.support.v4.app.Fragment;
2726
import android.support.v4.app.FragmentActivity;
2827
import android.support.v4.app.FragmentManager;
@@ -34,12 +33,15 @@
3433
import android.view.View;
3534
import android.widget.TextView;
3635

36+
import com.wanikani.androidnotifier.Tab.RefreshType;
3737
import com.wanikani.wklib.AuthenticationException;
3838
import com.wanikani.wklib.Connection;
3939
import com.wanikani.wklib.Item;
4040
import com.wanikani.wklib.ItemLibrary;
4141
import com.wanikani.wklib.ItemsCache;
42+
import com.wanikani.wklib.Kanji;
4243
import com.wanikani.wklib.LevelProgression;
44+
import com.wanikani.wklib.Radical;
4345
import com.wanikani.wklib.SRSDistribution;
4446
import com.wanikani.wklib.SRSLevel;
4547
import com.wanikani.wklib.StudyQueue;
@@ -266,9 +268,21 @@ else if (action.equals (ACTION_REFRESH)) {
266268
*/
267269
private class RefreshTask extends AsyncTask<Connection, Void, DashboardData > {
268270

271+
/// The refresh type
272+
RefreshType rtype;
273+
269274
/// The default "turtle" avatar
270275
Bitmap defAvatar;
271276

277+
/**
278+
* Constructor.
279+
* @param rtype the type of refresh to be used
280+
*/
281+
public RefreshTask (RefreshType rtype)
282+
{
283+
this.rtype = rtype;
284+
}
285+
272286
/**
273287
* Called before starting the task, inside the activity thread.
274288
*/
@@ -333,7 +347,7 @@ protected void onPostExecute (DashboardData dd)
333347

334348
refreshComplete (dd, true);
335349

336-
new RefreshTaskPartII ().execute (conn);
350+
new RefreshTaskPartII (rtype, dd.level).execute (conn);
337351
} catch (AuthenticationException e) {
338352
error (R.string.status_msg_unauthorized);
339353
} catch (IOException e) {
@@ -348,7 +362,24 @@ protected void onPostExecute (DashboardData dd)
348362
* so it can be run after the splash screen disappears (and the startup is faster).
349363
*/
350364
private class RefreshTaskPartII extends AsyncTask<Connection, Void, DashboardData.OptionalData> {
351-
365+
366+
/// The refresh type
367+
RefreshType rtype;
368+
369+
/// User level
370+
int level;
371+
372+
/**
373+
* Constructor
374+
* @param rtype refresh type
375+
* @param level current user level
376+
*/
377+
public RefreshTaskPartII (RefreshType rtype, int level)
378+
{
379+
this.rtype = rtype;
380+
this.level = level;
381+
}
382+
352383
/**
353384
* Called before starting the task, inside the activity thread.
354385
*/
@@ -368,10 +399,12 @@ protected void onPreExecute ()
368399
@Override
369400
protected DashboardData.OptionalData doInBackground (Connection... conn)
370401
{
371-
DashboardData.OptionalDataStatus srsStatus, lpStatus, ciStatus;
402+
DashboardData.OptionalDataStatus srsStatus, lpStatus, ciStatus, tlStatus;
372403
SRSDistribution srs;
373404
LevelProgression lp;
374405
ItemLibrary<Item> critical;
406+
ItemLibrary<Radical> tlradicals;
407+
ItemLibrary<Kanji> tlkanji;
375408
int cis;
376409

377410
try {
@@ -399,8 +432,24 @@ protected DashboardData.OptionalData doInBackground (Connection... conn)
399432
cis = 0;
400433
}
401434

435+
if (rtype == RefreshType.FULL) {
436+
try {
437+
tlradicals = conn [0].getRadicals (MeterSpec.T.DASHBOARD_REFRESH.get (MainActivity.this), level);
438+
tlkanji = conn [0].getKanji (MeterSpec.T.DASHBOARD_REFRESH.get (MainActivity.this), level);
439+
tlStatus = DashboardData.OptionalDataStatus.RETRIEVED;
440+
} catch (IOException e) {
441+
tlStatus = DashboardData.OptionalDataStatus.FAILED;
442+
tlradicals = null;
443+
tlkanji = null;
444+
}
445+
} else {
446+
tlradicals = null;
447+
tlkanji = null; /* Failed is weak enough to make merge choose for the older status */
448+
tlStatus = DashboardData.OptionalDataStatus.FAILED;
449+
}
450+
402451
return new DashboardData.OptionalData (srs, srsStatus, lp, lpStatus,
403-
cis, ciStatus);
452+
cis, ciStatus, tlradicals, tlkanji);
404453
}
405454

406455
/**
@@ -729,9 +778,9 @@ public void onStart ()
729778
if (resumeRefresh)
730779
refresh (Tab.RefreshType.LIGHT);
731780
else if (ldd.isIncomplete ())
732-
refreshOptional ();
781+
refreshOptional (ldd.level);
733782
} else
734-
refresh (Tab.RefreshType.LIGHT);
783+
refresh (Tab.RefreshType.FULL);
735784
}
736785

737786
resumeRefresh = false;
@@ -914,19 +963,19 @@ private void refresh (Tab.RefreshType rtype)
914963

915964
pad.flush (rtype, pager.getCurrentItem ());
916965

917-
rtask = new RefreshTask ();
966+
rtask = new RefreshTask (rtype);
918967
rtask.execute (conn);
919968
}
920969

921970
/**
922-
* Called when optional data needs to be refreshed. This happen in
971+
* Called when optional data needs to be refreshed. This happens in
923972
* some strange situations, e.g. when the application is stopped before
924973
* optional data, and then is resumed from a bundle. I'm not even
925974
* sure it can happen, however...
926975
*/
927-
private void refreshOptional ()
976+
private void refreshOptional (int level)
928977
{
929-
new RefreshTaskPartII ().execute (conn);
978+
new RefreshTaskPartII (RefreshType.FULL, level).execute (conn);
930979
}
931980

932981
/**

0 commit comments

Comments
 (0)