diff --git a/Afw/src/main/java/yuku/afw/storage/Preferences.java b/Afw/src/main/java/yuku/afw/storage/Preferences.java index b3ad65e0c..445ea2bc1 100644 --- a/Afw/src/main/java/yuku/afw/storage/Preferences.java +++ b/Afw/src/main/java/yuku/afw/storage/Preferences.java @@ -6,6 +6,7 @@ import android.os.Build; import android.os.SystemClock; import android.preference.PreferenceManager; +import android.support.annotation.BoolRes; import android.support.annotation.IntegerRes; import android.support.annotation.StringRes; import android.util.Log; @@ -194,7 +195,18 @@ public static int getInt(@StringRes final int keyStringResId, @IntegerRes final return (int) value; } } - + + public static boolean getBoolean(@StringRes final int keyStringResId, @BoolRes final int defaultIntResId) { + final Resources r = App.context.getResources(); + final String key = r.getString(keyStringResId); + final Object value = get(key); + if (value == null) { + return r.getBoolean(defaultIntResId); + } else { + return (boolean) value; + } + } + @TargetApi(9) private synchronized static void commitIfNotHeld() { if (held > 0) { // don't do anything now diff --git a/Alkitab/build.gradle b/Alkitab/build.gradle index 1e53f0341..21f167d06 100644 --- a/Alkitab/build.gradle +++ b/Alkitab/build.gradle @@ -17,8 +17,8 @@ android { applicationId 'yuku.alkitab.debug' minSdkVersion 14 targetSdkVersion 22 - versionCode 14000231 - versionName '4.2.1' + versionCode 14000240 + versionName '4.3.0-beta0' } buildTypes { release { diff --git a/Alkitab/src/main/java/yuku/alkitab/base/App.java b/Alkitab/src/main/java/yuku/alkitab/base/App.java index 9d51b17e3..2ced07b2b 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/App.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/App.java @@ -15,7 +15,9 @@ import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import yuku.afw.storage.Preferences; +import yuku.alkitab.base.model.SyncShadow; import yuku.alkitab.base.model.VersionImpl; +import yuku.alkitab.base.storage.Prefkey; import yuku.alkitab.base.sync.Gcm; import yuku.alkitab.base.sync.Sync; import yuku.alkitab.debug.R; @@ -128,6 +130,11 @@ public synchronized static void staticInit() { // make sure launcher do not open other variants of the app Launcher.setAppPackageName(context.getPackageName()); + + // sync on app start, if we are logged in + if (Preferences.contains(Prefkey.sync_simpleToken)) { + Sync.notifySyncNeeded(SyncShadow.ALL_SYNC_SET_NAMES); + } } private static void forceOverflowMenu() { diff --git a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java index 771394972..8a5a70015 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/IsiActivity.java @@ -556,13 +556,6 @@ public void onReceive(final Context context, final Intent intent) { App.getLbm().registerReceiver(reloadAttributeMapReceiver, new IntentFilter(ACTION_ATTRIBUTE_MAP_CHANGED)); - // sync on app start, if we are logged in - if (Preferences.contains(Prefkey.sync_simpleToken)) { - for (final String syncSetName : SyncShadow.ALL_SYNC_SET_NAMES) { - Sync.notifySyncNeeded(syncSetName); - } - } - if (!U.equals(getPackageName(), "yuku.alkitab") /* prevent self-import */ && !U.equals(getPackageName(), "yuku.alkitab.kjv") /* prevent self-import */ && Preferences.getInt(Prefkey.stop_import_yuku_alkitab_backups, 0) == 0 diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java index 5a1bddc6b..98c965311 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/MarkersActivity.java @@ -212,14 +212,14 @@ public void onReceive(final Context context, final Intent intent) { if (marker_count == 0) { // no markers, just delete straight away - S.getDb().deleteLabelById(label._id); + S.getDb().deleteLabelAndMarker_LabelsByLabelId(label._id); adapter.reload(); } else { new AlertDialogWrapper.Builder(this) .setMessage(getString(R.string.are_you_sure_you_want_to_delete_the_label_label, label.title, marker_count)) .setNegativeButton(R.string.cancel, null) .setPositiveButton(R.string.delete, (dialog, which) -> { - S.getDb().deleteLabelById(label._id); + S.getDb().deleteLabelAndMarker_LabelsByLabelId(label._id); adapter.reload(); }) .show(); diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/NoteActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/NoteActivity.java index d74857894..6fabf1023 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/ac/NoteActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/NoteActivity.java @@ -205,6 +205,10 @@ public void onNoMoreDetected() { return false; }); tCaptionReadOnly.setOnClickListener(v -> { + if (!Preferences.getBoolean(R.string.pref_tapToEditNote_key, R.bool.pref_tapToEditNote_default)) { + return; + } + if (!justClickedLink) { setEditingMode(true); } else { diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/ReadingPlanActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/ReadingPlanActivity.java index e78c2dceb..9809f2655 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/ac/ReadingPlanActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/ReadingPlanActivity.java @@ -691,6 +691,21 @@ public String getReadingDateHeader(final int dayNumber) { return getString(R.string.rp_dayHeader, (dayNumber + 1), Sqlitil.toLocaleDateMedium(calendar.getTime())); } + void one_reading_longClick(final int day, final int sequence) { + new MaterialDialog.Builder(this) + .content(R.string.rp_mark_as_read_up_to) + .positiveText(R.string.ok) + .negativeText(R.string.cancel) + .callback(new MaterialDialog.ButtonCallback() { + @Override + public void onPositive(final MaterialDialog dialog) { + ReadingPlanManager.markAsReadUpTo(readingPlan.info.name, readingPlan.dailyVerses, day, sequence); + reload(); + } + }) + .show(); + } + class ReadingPlanAdapter extends EasyAdapter { private int[] todayReadings; @@ -795,14 +810,14 @@ public void bindView(final View res, final int position, final ViewGroup parent) } else if (itemViewType == 2) { final LinearLayout layout = V.get(res, R.id.llOneDayReadingPlan); - final int currentViewTypePosition = position - todayReadings.length / 2 - 1; + final int day = position - todayReadings.length / 2 - 1; //Text title TextView tTitle = V.get(res, android.R.id.text1); - tTitle.setText(getReadingDateHeader(currentViewTypePosition)); + tTitle.setText(getReadingDateHeader(day)); //Text reading - int[] ariRanges = readingPlan.dailyVerses[currentViewTypePosition]; + int[] ariRanges = readingPlan.dailyVerses[day]; final int checkbox_count = ariRanges.length / 2; { // remove extra checkboxes @@ -816,14 +831,14 @@ public void bindView(final View res, final int position, final ViewGroup parent) } final boolean[] readMarks = new boolean[checkbox_count]; - ReadingPlanManager.writeReadMarksByDay(readingCodes, readMarks, currentViewTypePosition); + ReadingPlanManager.writeReadMarksByDay(readingCodes, readMarks, day); for (int i = 0; i < checkbox_count; i++) { final int sequence = i; CheckBox checkBox = (CheckBox) layout.findViewWithTag(i); if (checkBox == null) { - checkBox = (CheckBox) getLayoutInflater().inflate(R.layout.item_reading_plan_one_day_checkbox, layout, false); + checkBox = (CheckBox) getLayoutInflater().inflate(R.layout.item_reading_plan_one_reading_checkbox, layout, false); checkBox.setTag(i); layout.addView(checkBox); } @@ -832,10 +847,14 @@ public void bindView(final View res, final int position, final ViewGroup parent) checkBox.setChecked(readMarks[sequence]); checkBox.setText(S.activeVersion.referenceRange(ariRanges[sequence * 2], ariRanges[sequence * 2 + 1])); checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> { - ReadingPlanManager.updateReadingPlanProgress(readingPlan.info.name, currentViewTypePosition, sequence, isChecked); + ReadingPlanManager.updateReadingPlanProgress(readingPlan.info.name, day, sequence, isChecked); loadReadingPlanProgress(); load(); }); + checkBox.setOnLongClickListener(v -> { + one_reading_longClick(day, sequence); + return true; + }); } } } diff --git a/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSyncDebugActivity.java b/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSyncDebugActivity.java index 7d394c738..4a9baefef 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSyncDebugActivity.java +++ b/Alkitab/src/main/java/yuku/alkitab/base/ac/SecretSyncDebugActivity.java @@ -1,13 +1,19 @@ package yuku.alkitab.base.ac; +import android.annotation.SuppressLint; import android.content.Intent; import android.os.Bundle; -import android.util.Pair; +import android.os.Handler; +import android.os.SystemClock; import android.view.View; +import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.EditText; -import android.widget.TextView; +import android.widget.Spinner; +import android.widget.Toast; import com.afollestad.materialdialogs.AlertDialogWrapper; +import com.afollestad.materialdialogs.MaterialDialog; +import com.google.gson.reflect.TypeToken; import com.squareup.okhttp.Call; import com.squareup.okhttp.Callback; import com.squareup.okhttp.FormEncodingBuilder; @@ -24,28 +30,36 @@ import yuku.alkitab.base.model.SyncShadow; import yuku.alkitab.base.storage.Prefkey; import yuku.alkitab.base.sync.Sync; +import yuku.alkitab.base.sync.Sync_History; import yuku.alkitab.base.sync.Sync_Mabel; +import yuku.alkitab.base.sync.Sync_Pins; +import yuku.alkitab.base.sync.Sync_Rp; import yuku.alkitab.base.util.Highlights; +import yuku.alkitab.debug.BuildConfig; import yuku.alkitab.debug.R; import yuku.alkitab.model.Label; import yuku.alkitab.model.Marker; import yuku.alkitab.model.Marker_Label; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; public class SecretSyncDebugActivity extends BaseActivity { public static final String TAG = SecretSyncDebugActivity.class.getSimpleName(); EditText tServer; - TextView tUser; EditText tUserEmail; CheckBox cMakeDirtyMarker; CheckBox cMakeDirtyLabel; CheckBox cMakeDirtyMarker_Label; + Spinner cbSyncSetName; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,7 +67,6 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_secret_sync_debug); tServer = V.get(this, R.id.tServer); - tUser = V.get(this, R.id.tUser); tUserEmail = V.get(this, R.id.tUserEmail); cMakeDirtyMarker = V.get(this, R.id.cMakeDirtyMarker); cMakeDirtyLabel = V.get(this, R.id.cMakeDirtyLabel); @@ -86,16 +99,20 @@ protected void onCreate(Bundle savedInstanceState) { V.get(this, R.id.bMabelClientState).setOnClickListener(bMabelClientState_click); V.get(this, R.id.bGenerateDummies).setOnClickListener(bGenerateDummies_click); V.get(this, R.id.bGenerateDummies2).setOnClickListener(bGenerateDummies2_click); + V.get(this, R.id.bMabelMonkey).setOnClickListener(bMabelMonkey_click); V.get(this, R.id.bLogout).setOnClickListener(bLogout_click); V.get(this, R.id.bSync).setOnClickListener(bSync_click); - displayUser(); + cbSyncSetName = V.get(this, R.id.cbSyncSetName); + cbSyncSetName.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, SyncShadow.ALL_SYNC_SET_NAMES)); + + V.get(this, R.id.bCheckHash).setOnClickListener(bCheckHash_click); } View.OnClickListener bMabelClientState_click = v -> { final StringBuilder sb = new StringBuilder(); - final Pair>> pair = Sync_Mabel.getClientStateAndCurrentEntities(); - final Sync_Mabel.ClientState clientState = pair.first; + final Sync.GetClientStateResult pair = Sync_Mabel.getClientStateAndCurrentEntities(); + final Sync.ClientState clientState = pair.clientState; sb.append("Base revno: ").append(clientState.base_revno).append('\n'); sb.append("Delta operations (size " + clientState.delta.operations.size() + "):\n"); @@ -160,6 +177,145 @@ int rand(int n) { .show(); }; + static MonkeyThread monkey; + Handler toastHandler = new Handler(); + + class MonkeyThread extends Thread { + final AtomicBoolean stopRequested = new AtomicBoolean(); + + final Toast toast; + + @SuppressLint("ShowToast") + MonkeyThread() { + toast = Toast.makeText(SecretSyncDebugActivity.this, "none", Toast.LENGTH_SHORT); + } + + void toast(String msg) { + toastHandler.post(() -> { + toast.setText(msg); + toast.show(); + }); + } + + @Override + public void run() { + while (!stopRequested.get()) { + toast("preparing"); + SystemClock.sleep(5000); + + { + int nlabel = rand(5); + toast("creating " + nlabel + " labels"); + for (int i = 0; i < nlabel; i++) { + S.getDb().insertLabel(randomString("monkey L " + i + " ", 1, 3, 8), U.encodeLabelBackgroundColor(rand(0xffffff))); + } + } + + if (stopRequested.get()) return; + toast("waiting for 10 secs"); + SystemClock.sleep(10000); + + final List