Skip to content

Commit 5a1278d

Browse files
committed
Added data export, about page and bug fixes
Added about page with useful links Added feature to export dream journal entries and completed questionnaires to HTML, Markdown, Print (PDF) Added placeholder prompts when selecting a placeholder Various bug fixes and smaller improvements
1 parent efe8d52 commit 5a1278d

File tree

87 files changed

+2658
-1952
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+2658
-1952
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,7 @@ lint/tmp/
8181
*.hprof
8282

8383
# Other
84-
values-classic/
84+
values-classic/
85+
86+
app/release/
87+
app/release/output-metadata.json

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ android {
4141
}
4242

4343
dependencies {
44+
implementation(libs.markdown)
4445
implementation(libs.androidx.core.ktx)
4546
implementation(libs.androidx.datastore.preferences)
4647
implementation(libs.androidx.datastore.preferences.rxjava3)

app/src/main/AndroidManifest.xml

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools">
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
44

5-
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
5+
<!-- Required for audio recordings in dream journal -->
66
<uses-permission android:name="android.permission.RECORD_AUDIO" />
7-
<uses-permission android:name="android.permission.VIBRATE" />
8-
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
9-
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
7+
8+
<!-- Required for app lock feature -->
9+
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
10+
11+
<!-- Required for notification feature -->
1012
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
13+
14+
<!-- Required for alarm feature -->
1115
<uses-permission android:name="android.permission.WAKE_LOCK" />
12-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
16+
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
17+
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
18+
<uses-permission android:name="android.permission.VIBRATE" />
19+
<uses-permission android:name="android.permission.FLASHLIGHT" />
1320
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1421
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
22+
23+
<!-- Required for rescheduling alarms and notifications after phone reboot -->
1524
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
16-
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
1725

18-
<permission
19-
android:name="android.permission.FLASHLIGHT"
20-
android:permissionGroup="android.permission-group.HARDWARE_CONTROLS"
21-
android:protectionLevel="normal"
22-
tools:node="remove" />
26+
<!-- Required for getting this apps usage stats before packageSelf(...) existed -->
27+
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" android:maxSdkVersion="27" />
2328

2429
<application
2530
android:allowBackup="true"
@@ -29,6 +34,9 @@
2934
android:roundIcon="@mipmap/ic_launcher_pure_round"
3035
android:supportsRtl="true"
3136
android:theme="@style/Theme.LucidSourceKit.Default">
37+
<activity
38+
android:name=".main.about.AboutActivity"
39+
android:exported="false" />
3240
<activity
3341
android:name=".main.questionnaire.CompletedQuestionnaireViewerActivity"
3442
android:exported="false" />

app/src/main/java/com/bitflaker/lucidsourcekit/MainActivity.java

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import androidx.biometric.BiometricManager;
2020
import androidx.biometric.BiometricPrompt;
2121
import androidx.core.content.ContextCompat;
22+
import androidx.core.content.res.ResourcesCompat;
23+
import androidx.recyclerview.widget.GridLayoutManager;
2224

2325
import com.bitflaker.lucidsourcekit.data.datastore.DataStoreKeys;
2426
import com.bitflaker.lucidsourcekit.data.datastore.DataStoreManager;
@@ -47,6 +49,8 @@
4749
import com.bitflaker.lucidsourcekit.databinding.ActivityMainBinding;
4850
import com.bitflaker.lucidsourcekit.main.MainViewer;
4951
import com.bitflaker.lucidsourcekit.main.alarms.AlarmHandler;
52+
import com.bitflaker.lucidsourcekit.main.notification.visual.KeypadAdapter;
53+
import com.bitflaker.lucidsourcekit.main.notification.visual.KeypadButtonModel;
5054
import com.bitflaker.lucidsourcekit.setup.SetupViewer;
5155
import com.bitflaker.lucidsourcekit.utils.Crypt;
5256
import com.bitflaker.lucidsourcekit.utils.Tools;
@@ -56,14 +60,17 @@
5660

5761
import java.io.File;
5862
import java.util.ArrayList;
63+
import java.util.Arrays;
5964
import java.util.Calendar;
6065
import java.util.GregorianCalendar;
6166
import java.util.List;
6267
import java.util.TimeZone;
6368
import java.util.concurrent.Executor;
6469
import java.util.concurrent.TimeUnit;
70+
import java.util.stream.Collectors;
6571

6672
import io.reactivex.rxjava3.core.Maybe;
73+
import kotlin.Unit;
6774

6875
public class MainActivity extends AppCompatActivity {
6976
private final char[] pinLayout = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', '0', '<' };
@@ -75,6 +82,11 @@ public class MainActivity extends AppCompatActivity {
7582

7683
@Override
7784
protected void onCreate(Bundle savedInstanceState) {
85+
DataStoreManager.initialize(this);
86+
DataStoreMigrator.migrateSharedPreferencesToDataStore(this);
87+
DataStoreMigrator.migrateSetupFinishedToDataStore(this);
88+
Tools.loadLanguage(this);
89+
7890
// TODO: remove enforce dark mode
7991
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
8092
int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
@@ -91,19 +103,11 @@ protected void onCreate(Bundle savedInstanceState) {
91103
super.onCreate(savedInstanceState);
92104
binding = ActivityMainBinding.inflate(getLayoutInflater());
93105
setContentView(binding.getRoot());
94-
95-
DataStoreManager.initialize(this);
96-
DataStoreMigrator.migrateSharedPreferencesToDataStore(this);
97-
DataStoreMigrator.migrateSetupFinishedToDataStore(this);
98-
99-
Tools.loadLanguage(MainActivity.this);
100106
Tools.makeStatusBarTransparent(MainActivity.this);
101107

102108
binding.btnFingerprintUnlock.setOnClickListener(e -> startBiometricAuthentication());
103109
pinButtonSize = getResources().getBoolean(R.bool.is_h720dp) ? 68 : 54;
104110

105-
// TODO: set language of controls
106-
107111
Calendar cldrStored = new GregorianCalendar(TimeZone.getDefault());
108112
Calendar cldrNow = new GregorianCalendar(TimeZone.getDefault());
109113
cldrNow.setTime(Calendar.getInstance().getTime());
@@ -340,38 +344,34 @@ public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationRes
340344
private void setupPinAuthentication() {
341345
binding.llPwAuthContainer.setVisibility(View.GONE);
342346
binding.llPinAuthContainer.setVisibility(View.VISIBLE);
343-
for (int y = 0; y < 4; y++) {
344-
FlexboxLayout hFlxBx = new FlexboxLayout(this);
345-
hFlxBx.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
346-
hFlxBx.setJustifyContent(JustifyContent.SPACE_AROUND);
347-
for (int x = 0; x < 3; x++) {
348-
hFlxBx.addView(generatePinButton(y*3+x));
349-
}
350-
binding.llPinLayout.addView(hFlxBx);
351-
}
352-
}
353347

354-
private View generatePinButton(int pos) {
355-
MaterialButton pinButton = new MaterialButton(this);
356-
char currentType = pinLayout[pos];
357-
LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
358-
pinButton.setLayoutParams(lParams);
359-
pinButton.setMinimumHeight(Tools.dpToPx(this, pinButtonSize));
360-
pinButton.setMinimumWidth(Tools.dpToPx(this, pinButtonSize));
361-
pinButton.setMinHeight(Tools.dpToPx(this, pinButtonSize));
362-
pinButton.setMinWidth(Tools.dpToPx(this, pinButtonSize));
363-
pinButton.setHeight(Tools.dpToPx(this, pinButtonSize));
364-
pinButton.setWidth(Tools.dpToPx(this, pinButtonSize));
365-
pinButton.setPadding(0,0,0,0);
366-
pinButton.setTextColor(Tools.getAttrColor(R.attr.primaryTextColor, getTheme()));
367-
pinButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
368-
pinButton.setBackgroundResource(R.drawable.ripple_round_clear);
369-
if (Character.isDigit(currentType)) {
370-
pinButton.setText(Character.toString(currentType));
371-
int buttonVal = Integer.parseInt(Character.toString(currentType));
372-
pinButton.setOnClickListener(e -> {
348+
// Generate the keypad
349+
List<KeypadButtonModel> buttons = Arrays.stream(new Character[] {
350+
'1', '2', '3',
351+
'4', '5', '6',
352+
'7', '8', '9',
353+
null, '0', '#'
354+
}).map(c -> new KeypadButtonModel(c, null)).collect(Collectors.toList());
355+
356+
// Set the icon for delete
357+
buttons.get(buttons.size() - 1).setButtonIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.rounded_backspace_24, getTheme()));
358+
359+
// Configure keypad adapter
360+
KeypadAdapter keypadAdapter = new KeypadAdapter(this, buttons);
361+
binding.rcvKeypad.setAdapter(keypadAdapter);
362+
binding.rcvKeypad.setLayoutManager(new GridLayoutManager(this, 3));
363+
keypadAdapter.setOnButtonClick(value -> {
364+
if (value == '#') {
365+
if (enteredPin.length() > 0) {
366+
enteredPin.deleteCharAt(enteredPin.length() - 1);
367+
StringBuilder pinText = new StringBuilder();
368+
for(int i = 0; i < enteredPin.length(); i++) { pinText.append("\u2022"); }
369+
binding.txtEnteredPin.setText(pinText.toString());
370+
}
371+
}
372+
else {
373373
binding.txtEnteredPin.setText(binding.txtEnteredPin.getText() + "•");
374-
enteredPin.append(buttonVal);
374+
enteredPin.append(value);
375375
new Thread(() -> {
376376
boolean success = isPinSuccess();
377377
if(success || enteredPin.length() > 7){
@@ -388,22 +388,9 @@ private View generatePinButton(int pos) {
388388
});
389389
}
390390
}).start();
391-
});
392-
return pinButton;
393-
}
394-
else if (currentType == '<') {
395-
pinButton.setText("⌫");
396-
pinButton.setOnClickListener(e -> {
397-
if(enteredPin.length() > 0) {
398-
enteredPin.deleteCharAt(enteredPin.length()-1);
399-
StringBuilder pinText = new StringBuilder();
400-
for(int i = 0; i < enteredPin.length(); i++) { pinText.append("\u2022"); }
401-
binding.txtEnteredPin.setText(pinText.toString());
402-
}
403-
});
404-
return pinButton;
405-
}
406-
return generateSpace();
391+
}
392+
return Unit.INSTANCE;
393+
});
407394
}
408395

409396
private void startLoadingAnimation() {

app/src/main/java/com/bitflaker/lucidsourcekit/data/datastore/DataStoreKeys.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ public class DataStoreKeys {
4848
public static final Preferences.Key<byte[]> NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_DIGITS = PreferencesKeys.byteArrayKey("NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_DIGITS");
4949
public static final Preferences.Key<Long> NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_TIME = PreferencesKeys.longKey("NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_TIME");
5050

51+
// Usage stats
52+
public static final Preferences.Key<Integer> USAGE_STATS_PERMISSION_DISMISSED = PreferencesKeys.intKey("USAGE_STATS_PERMISSION_DISMISSED");
53+
5154
// Default settings values
5255
public static final HashMap<Preferences.Key<?>, Object> DEFAULT_VALUES = new HashMap<>() {{
5356
this.put(LANGUAGE, "en");
@@ -79,5 +82,6 @@ public class DataStoreKeys {
7982
this.put(NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_DIGITS, new byte[0]);
8083
this.put(NOTIFICATION_RC_REMINDER_FULL_SCREEN_CONFIRM_TIME, 0L);
8184
this.put(APP_SETUP_FINISHED, false);
85+
this.put(USAGE_STATS_PERMISSION_DISMISSED, 0);
8286
}};
8387
}

0 commit comments

Comments
 (0)