diff --git a/app/build.gradle b/app/build.gradle
index c9602d71..1e02f040 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -140,22 +140,20 @@ dependencies {
implementation "eu.szkolny:nachos:0e5dfcaceb"
implementation "eu.szkolny.selective-dao:annotation:27f8f3f194"
implementation "eu.szkolny:ssl-provider:1.0.0"
- implementation "pl.szczodrzynski:navlib:0.7.2"
+ implementation "pl.szczodrzynski:navlib:0.8.0"
implementation "pl.szczodrzynski:numberslidingpicker:2921225f76"
implementation "pl.szczodrzynski:recyclertablayout:700f980584"
implementation "pl.szczodrzynski:tachyon:551943a6b5"
kapt "eu.szkolny.selective-dao:codegen:27f8f3f194"
// Iconics & related
- implementation "com.mikepenz:iconics-core:5.2.8"
- implementation "com.mikepenz:iconics-views:5.2.8"
+ implementation "com.mikepenz:iconics-core:5.3.0-b01"
+ implementation "com.mikepenz:iconics-views:5.3.0-b01"
implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar"
implementation "eu.szkolny:szkolny-font:1.3"
// Other dependencies
implementation "cat.ereza:customactivityoncrash:2.3.0"
- implementation "com.afollestad.material-dialogs:commons:0.9.6.0"
- implementation "com.afollestad.material-dialogs:core:0.9.6.0"
implementation "com.applandeo:material-calendar-view:1.5.0"
implementation "com.daimajia.swipelayout:library:1.2.0@aar"
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2"
@@ -169,7 +167,6 @@ dependencies {
implementation "com.jaredrummler:colorpicker:1.1.0"
implementation "com.qifan.powerpermission:powerpermission-coroutines:1.3.0"
implementation "com.qifan.powerpermission:powerpermission:1.3.0"
- implementation "com.wdullaer:materialdatetimepicker:4.2.3"
implementation "com.yuyh.json:jsonviewer:1.0.6"
implementation "io.coil-kt:coil:1.1.1"
implementation "me.dm7.barcodescanner:zxing:1.9.8"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bf1d5732..5f295533 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -123,9 +123,6 @@
android:configChanges="orientation|screenSize|keyboardHidden"
android:process=":error_activity"
android:theme="@style/DeadTheme" />
-
-
diff --git a/app/src/main/assets/certificate.cer b/app/src/main/assets/certificate.cer
deleted file mode 100644
index 0002462c..00000000
--- a/app/src/main/assets/certificate.cer
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
-SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
-GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
-q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
-SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
-Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
-a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
-/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
-AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
-CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
-bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
-c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
-VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
-ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
-MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
-Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
-AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
-uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
-wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
-X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
-PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
-KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
------END CERTIFICATE-----
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt
index e8aa4cd2..a9186d94 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt
@@ -38,7 +38,6 @@ import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.network.NetworkUtils
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
import pl.szczodrzynski.edziennik.sync.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateWorker
@@ -89,7 +88,6 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.build()
val permissionChecker by lazy { PermissionChecker(this) }
- val networkUtils by lazy { NetworkUtils(this) }
val gson by lazy { Gson() }
/* _ _ _______ _______ _____
@@ -166,6 +164,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.errorActivity(CrashActivity::class.java)
.apply()
Iconics.init(applicationContext)
+ Iconics.respectFontBoundsDefault = true
// initialize companion object values
App.db = AppDb(this)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
index 350bf67c..a07634a1 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
@@ -37,6 +37,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.viewpager.widget.ViewPager
import com.google.android.material.button.MaterialButton
+import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.*
import com.google.gson.JsonArray
@@ -1279,3 +1280,10 @@ fun Context.getSyncInterval(interval: Int): String {
""
return hoursText?.plus(" $minutesText") ?: minutesText
}
+
+fun Profile.getSchoolYearConstrains(): CalendarConstraints {
+ return CalendarConstraints.Builder()
+ .setStart(dateSemester1Start.inMillisUtc)
+ .setEnd(dateYearEnd.inMillisUtc)
+ .build()
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/GenericFileProvider.java b/app/src/main/java/pl/szczodrzynski/edziennik/GenericFileProvider.java
deleted file mode 100644
index 69aef167..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/GenericFileProvider.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package pl.szczodrzynski.edziennik;
-
-import androidx.core.content.FileProvider;
-
-public class GenericFileProvider extends FileProvider {}
\ No newline at end of file
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
index b7b2d6f2..8dd83bf2 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
@@ -68,7 +68,6 @@ import pl.szczodrzynski.edziennik.ui.modules.debug.LabFragment
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorDetailsDialog
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
-import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesListFragment
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
@@ -128,7 +127,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
const val DRAWER_ITEM_DEBUG = 102
const val TARGET_GRADES_EDITOR = 501
- const val TARGET_HELP = 502
const val TARGET_FEEDBACK = 120
const val TARGET_MESSAGES_DETAILS = 503
const val TARGET_MESSAGES_COMPOSE = 504
@@ -226,7 +224,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
// other target items, not directly navigated
list += NavTarget(TARGET_GRADES_EDITOR, R.string.menu_grades_editor, GradesEditorFragment::class)
- list += NavTarget(TARGET_HELP, R.string.menu_help, HelpFragment::class)
list += NavTarget(TARGET_FEEDBACK, R.string.menu_feedback, FeedbackFragment::class)
list += NavTarget(TARGET_MESSAGES_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class)
@@ -497,7 +494,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
.content(R.string.rate_snackbar_text)
.icon(IconicsDrawable(this).apply {
icon = CommunityMaterial.Icon3.cmd_star_outline
- sizeDp = 20
+ sizeDp = 24
colorInt = Themes.getPrimaryTextColor(this@MainActivity)
})
.positiveText(R.string.rate_snackbar_positive)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseBroadcastReceiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseBroadcastReceiver.kt
deleted file mode 100644
index 25c2de48..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseBroadcastReceiver.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) Kuba Szczodrzyński 2020-1-11.
- */
-
-package pl.szczodrzynski.edziennik.data.firebase
-
-import android.content.Context
-import android.content.Intent
-import android.util.Log
-import androidx.legacy.content.WakefulBroadcastReceiver
-import com.google.gson.JsonObject
-
-class FirebaseBroadcastReceiver : WakefulBroadcastReceiver() {
- companion object {
- private const val TAG = "FirebaseBroadcast"
- }
-
- override fun onReceive(context: Context, intent: Intent) {
- val extras = intent.extras
- val json = JsonObject()
- extras?.keySet()?.forEach { key ->
- extras.get(key)?.let {
- when (it) {
- is String -> json.addProperty(key, it)
- is Int -> json.addProperty(key, it)
- is Long -> json.addProperty(key, it)
- is Float -> json.addProperty(key, it)
- is Boolean -> json.addProperty(key, it)
- else -> json.addProperty(key, it.toString())
- }
- }
- }
- Log.d(TAG, "Intent(action=${intent?.action}, extras=$json)")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/MyFirebaseMessagingService.java b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/MyFirebaseMessagingService.java
deleted file mode 100644
index 34e341ed..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/MyFirebaseMessagingService.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) Kuba Szczodrzyński 2020-1-11.
- */
-
-package pl.szczodrzynski.edziennik.data.firebase;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-
-import com.google.firebase.messaging.FirebaseMessagingService;
-import com.google.firebase.messaging.RemoteMessage;
-
-import java.util.List;
-
-import pl.szczodrzynski.edziennik.App;
-import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask;
-import pl.szczodrzynski.edziennik.data.db.entity.LoginStore;
-import pl.szczodrzynski.edziennik.data.db.entity.Profile;
-
-import static pl.szczodrzynski.edziennik.utils.Utils.d;
-import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
-
-public class MyFirebaseMessagingService extends FirebaseMessagingService {
- private static final String TAG = "FirebaseMessaging";
-
- @Override
- public void onNewToken(String s) {
- super.onNewToken(s);
-
- /* Log.d(TAG, "New token: "+s);
- App app = (App)getApplicationContext();
- if (app.config.getSync().getTokenApp() == null || !app.config.getSync().getTokenApp().equals(s)) {
- app.config.getSync().setTokenApp(s);
- }*/
- }
-
- @Override
- public void onMessageReceived(RemoteMessage remoteMessage) {
- /*App app = ((App) getApplicationContext());
- // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
-
- String from = remoteMessage.getFrom();
- if (from != null) {
- switch (from) {
- case "640759989760":
- app.debugLog("Firebase got push from App "+remoteMessage.getData().toString());
- //processAppPush
- processAppPush(app, remoteMessage);
- break;
- case "747285019373":
- app.debugLog("Firebase got push from Mobidziennik "+remoteMessage.getData().toString());
- processMobidziennikPush(app, remoteMessage);
- break;
- case "513056078587":
- app.debugLog("Firebase got push from Librus "+remoteMessage.getData().toString());
- processLibrusPush(app, remoteMessage);
- break;
- case "987828170337":
- app.debugLog("Firebase got push from Vulcan "+remoteMessage.getData().toString());
- processVulcanPush(app, remoteMessage);
- break;
- }
- }*/
- }
-
- private void processMobidziennikPush(App app, RemoteMessage remoteMessage) {
- SharedPreferences sharedPreferences = getSharedPreferences("pushtest_mobidziennik", Context.MODE_PRIVATE);
- sharedPreferences.edit().putString(Long.toString(System.currentTimeMillis()), remoteMessage.getData().toString()+"\n"+remoteMessage.toString()+"\n"+remoteMessage.getMessageType()).apply();
- String studentIdStr = remoteMessage.getData().get("id_ucznia");
- if (studentIdStr != null) {
- int studentId = strToInt(studentIdStr);
- AsyncTask.execute(() -> {
- List profileList = app.db.profileDao().getAllNow();
-
- Profile profile = null;
-
- for (Profile profileFull: profileList) {
- if (profileFull.getLoginStoreType() == LoginStore.LOGIN_TYPE_MOBIDZIENNIK
- && studentId == profileFull.getStudentData("studentId", -1)) {
- profile = profileFull;
- break;
- }
- }
-
- if (profile != null) {
- if (remoteMessage.getData().get("id_wiadomosci") != null) {
-
- d(TAG, "Syncing profile " + profile.getId());
- EdziennikTask.Companion.syncProfile(profile.getId(), null, null, null).enqueue(app);
- } else {
- /*app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
- .withProfileData(profile.id, profile.name)
- .withTitle(remoteMessage.getData().get("title"))
- .withType(Notification.TYPE_SERVER_MESSAGE)
- .withFragmentRedirect(MainActivity.DRAWER_ITEM_HOME)
- );
- app.notifier.postAll(profile);
- app.saveConfig("notifications");*/
- d(TAG, "Syncing profile " + profile.getId());
- EdziennikTask.Companion.syncProfile(profile.getId(), null, null, null).enqueue(app);
- }
- }
- });
- }
- }
-
- private void processLibrusPush(App app, RemoteMessage remoteMessage) {
- SharedPreferences sharedPreferences = getSharedPreferences("pushtest_librus", Context.MODE_PRIVATE);
- sharedPreferences.edit().putString(Long.toString(System.currentTimeMillis()), remoteMessage.getData().toString()+"\n"+remoteMessage.toString()+"\n"+remoteMessage.getMessageType()).apply();
- }
-
- private void processVulcanPush(App app, RemoteMessage remoteMessage) {
- SharedPreferences sharedPreferences = getSharedPreferences("pushtest_vulcan", Context.MODE_PRIVATE);
- sharedPreferences.edit().putString(Long.toString(System.currentTimeMillis()), remoteMessage.getData().toString()+"\n"+remoteMessage.toString()+"\n"+remoteMessage.getMessageType()).apply();
- }
-
- private void processAppPush(App app, RemoteMessage remoteMessage) {
- // Check if message contains a data payload.
- /*String type = remoteMessage.getData().get("type");
- if (remoteMessage.getData().size() > 0
- && type != null) {
- //Log.d(TAG, "Message data payload: " + remoteMessage.sync());
- switch (type) {
- case "app_update":
- int versionCode = Integer.parseInt(remoteMessage.getData().get("update_version_code"));
- if (BuildConfig.VERSION_CODE < versionCode) {
- String updateVersion = remoteMessage.getData().get("update_version");
- String updateUrl = remoteMessage.getData().get("update_url");
- String updateFilename = remoteMessage.getData().get("update_filename");
- boolean updateMandatory = Boolean.parseBoolean(remoteMessage.getData().get("update_mandatory"));
- boolean updateDirect = Boolean.parseBoolean(remoteMessage.getData().get("update_direct"));
-
- if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals(updateVersion)) {
- app.appConfig.updateVersion = updateVersion;
- app.appConfig.updateUrl = updateUrl;
- app.appConfig.updateFilename = updateFilename;
- app.appConfig.updateMandatory = updateMandatory;
- app.appConfig.updateDirect = updateDirect;
- app.saveConfig("updateVersion", "updateUrl", "updateFilename", "updateMandatory");
- }
- if (!remoteMessage.getData().containsKey("update_silent")) {
- app.notifier.notificationUpdatesShow(
- updateVersion,
- updateUrl,
- updateFilename,
- updateDirect);
- }
- } else {
- if (app.appConfig.updateVersion == null || !app.appConfig.updateVersion.equals("")) {
- app.appConfig.updateVersion = "";
- app.appConfig.updateMandatory = false;
- app.saveConfig("updateVersion", "updateMandatory");
- }
- app.notifier.notificationUpdatesHide();
- }
- break;
- case "message":
- app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
- .withTitle(remoteMessage.getData().get("title"))
- .withType(pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_SERVER_MESSAGE)
- .withFragmentRedirect(MainActivity.DRAWER_ITEM_NOTIFICATIONS)
- );
- app.notifier.postAll();
- app.saveConfig("notifications");
- break;
- case "feedback_message_from_dev":
- AsyncTask.execute(() -> {
- FeedbackMessage feedbackMessage = new FeedbackMessage(true, remoteMessage.getData().get("message"));
- if (feedbackMessage.text.startsWith("test")) {
- // todo
- }
- else {
- feedbackMessage.sentTime = Long.parseLong(remoteMessage.getData().get("sent_time"));
- if (feedbackMessage.text.startsWith("devmode")) {
- app.config.setDevModePassword(feedbackMessage.text.replace("devmode", ""));
- app.checkDevModePassword();
- feedbackMessage.text = "devmode "+(App.devMode ? "allowed" : "disallowed");
- }
- Intent intent = new Intent("pl.szczodrzynski.edziennik.ui.modules.base.FeedbackActivity");
- intent.putExtra("type", "user_chat");
- intent.putExtra("message", app.gson.toJson(feedbackMessage));
- app.sendBroadcast(intent);
- app.db.feedbackMessageDao().add(feedbackMessage);
-
- app.notifier.add(new Notification(app.getContext(), feedbackMessage.text)
- .withTitle(remoteMessage.getData().get("title"))
- .withType(pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_FEEDBACK_MESSAGE)
- .withFragmentRedirect(MainActivity.TARGET_FEEDBACK)
- );
- app.notifier.postAll();
- app.saveConfig("notifications");
- }
- });
- break;
- case "feedback_message_from_user":
- AsyncTask.execute(() -> {
- FeedbackMessage feedbackMessage = new FeedbackMessage(true, remoteMessage.getData().get("message"));
- feedbackMessage.fromUser = remoteMessage.getData().get("from_user");
- feedbackMessage.fromUserName = remoteMessage.getData().get("from_user_name");
- feedbackMessage.sentTime = Long.parseLong(remoteMessage.getData().get("sent_time"));
- Intent intent = new Intent("pl.szczodrzynski.edziennik.ui.modules.base.FeedbackActivity");
- intent.putExtra("type", "user_chat");
- intent.putExtra("message", app.gson.toJson(feedbackMessage));
- app.sendBroadcast(intent);
- app.db.feedbackMessageDao().add(feedbackMessage);
- });
- app.notifier.add(new Notification(app.getContext(), remoteMessage.getData().get("message"))
- .withTitle(remoteMessage.getData().get("title"))
- .withType(pl.szczodrzynski.edziennik.data.db.entity.Notification.TYPE_FEEDBACK_MESSAGE)
- .withFragmentRedirect(MainActivity.TARGET_FEEDBACK)
- );
- app.notifier.postAll();
- app.saveConfig("notifications");
- break;
- case "ping":
- // just a ping
- break
- }
- }*/
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/network/NetworkUtils.java b/app/src/main/java/pl/szczodrzynski/edziennik/network/NetworkUtils.java
deleted file mode 100644
index dac636c6..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/network/NetworkUtils.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package pl.szczodrzynski.edziennik.network;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.Build;
-
-import pl.szczodrzynski.edziennik.App;
-
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
-import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
-
-public class NetworkUtils {
- private App app;
-
- public NetworkUtils(App _app)
- {
- this.app = _app;
- }
-
- public boolean isOnline() {
- assert app != null;
- ConnectivityManager cm =
- (ConnectivityManager) app.getSystemService(Context.CONNECTIVITY_SERVICE);
- assert cm != null;
- NetworkInfo netInfo = cm.getActiveNetworkInfo();
- return netInfo != null && netInfo.isConnectedOrConnecting();
- }
-
- public int checkBackgroundDataRestricted() {
-
- ConnectivityManager connMgr = (ConnectivityManager) app.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- assert connMgr != null;
- switch (connMgr.getRestrictBackgroundStatus()) {
- case RESTRICT_BACKGROUND_STATUS_ENABLED:
- return 2;
-
- case RESTRICT_BACKGROUND_STATUS_WHITELISTED:
- return 1;
-
- case RESTRICT_BACKGROUND_STATUS_DISABLED:
- return 0;
- }
- }
- else
- {
- return 0;
- }
- return 0;
- }
-
- /*public void setSelfSignedSSL(Context mContext, @Nullable String instanceName){
- try {
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- // cert file stored in \app\src\main\assets
- Log.d("ION", "certificate: before");
- AssetManager am = mContext.getAssets();
- InputStream caInput = new BufferedInputStream(am.open("certificate.cer"));
- Log.d("ION", "certificate: after");
-
- Certificate ca = cf.generateCertificate(caInput);
- caInput.close();
-
- KeyStore keyStore = KeyStore.getInstance("BKS");
- keyStore.load(null, null);
- keyStore.setCertificateEntry("ca", ca);
-
- String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
- tmf.init(keyStore);
-
- TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, wrappedTrustManagers, null);
-
- AsyncSSLSocketMiddleware sslMiddleWare;
- if(TextUtils.isEmpty(instanceName)){
- sslMiddleWare = Ion.getDefault(mContext).getHttpClient().getSSLSocketMiddleware();
- }else {
- sslMiddleWare = Ion
- .getInstance(mContext, instanceName)
- .getHttpClient().getSSLSocketMiddleware();
- }
- sslMiddleWare.setTrustManagers(wrappedTrustManagers);
- sslMiddleWare.setHostnameVerifier(getHostnameVerifier());
- sslMiddleWare.setSSLContext(sslContext);
- }catch (Exception e){
- e.printStackTrace();
- }
- }
-
- private HostnameVerifier getHostnameVerifier() {
- return new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- return true;
- // or the following:
- // HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
- // return hv.verify("www.yourserver.com", session);
- }
- };
- }
-
- public TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
- final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
- return new TrustManager[]{
- new X509TrustManager() {
- public X509Certificate[] getAcceptedIssuers() {
- return originalTrustManager.getAcceptedIssuers();
- }
-
- public void checkClientTrusted(X509Certificate[] certs, String authType) {
- try {
- if (certs != null && certs.length > 0){
- certs[0].checkValidity();
- } else {
- originalTrustManager.checkClientTrusted(certs, authType);
- }
- } catch (CertificateException e) {
- Log.w("checkClientTrusted", e.toString());
- }
- }
-
- public void checkServerTrusted(X509Certificate[] certs, String authType) {
- try {
- if (certs != null && certs.length > 0){
- certs[0].checkValidity();
- } else {
- originalTrustManager.checkServerTrusted(certs, authType);
- }
- } catch (CertificateException e) {
- Log.w("checkServerTrusted", e.toString());
- }
- }
- }
- };
- }*/
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/network/TLSSocketFactory.java b/app/src/main/java/pl/szczodrzynski/edziennik/network/TLSSocketFactory.java
deleted file mode 100644
index 7cae49a2..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/network/TLSSocketFactory.java
+++ /dev/null
@@ -1,421 +0,0 @@
-package pl.szczodrzynski.edziennik.network;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.net.ssl.HandshakeCompletedListener;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * Enables TLS v1.2 when creating SSLSockets.
- *
- * For some reason, android supports TLS v1.2 from API 16, but enables it by
- * default only from API 20.
- * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
- * @see SSLSocketFactory
- */
-public class TLSSocketFactory extends SSLSocketFactory {
- private static final String[] TLS_V12 = {"TLSv1.2"};
- private static final String[] TLS_V11_V12 = {"TLSv1.1", "TLSv1.2"};
- private static final String[] TLS_V10_V11_V12 = {"TLSv1", "TLSv1.1", "TLSv1.2"};
-
- private final SSLSocketFactory delegate;
-
- public TLSSocketFactory(SSLSocketFactory base) {
- this.delegate = base;
- }
-
- @Override
- public String[] getDefaultCipherSuites() {
- return delegate.getDefaultCipherSuites();
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
-
- @Override
- public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
- return patch(delegate.createSocket(s, host, port, autoClose));
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
- return patch(delegate.createSocket(host, port));
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
- return patch(delegate.createSocket(host, port, localHost, localPort));
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return patch(delegate.createSocket(host, port));
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
- return patch(delegate.createSocket(address, port, localAddress, localPort));
- }
-
- private Socket patch(Socket socket) {
- if (socket instanceof SSLSocket) {
- ((SSLSocket) socket).setEnabledProtocols(TLS_V10_V11_V12);
- //socket = new NoSSLv3SSLSocket((SSLSocket) socket);
- }
- return socket;
- }
-
-
- public class DelegateSSLSocket extends SSLSocket {
-
- protected final SSLSocket delegate;
-
- DelegateSSLSocket(SSLSocket delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public String[] getSupportedCipherSuites() {
- return delegate.getSupportedCipherSuites();
- }
-
- @Override
- public String[] getEnabledCipherSuites() {
- return delegate.getEnabledCipherSuites();
- }
-
- @Override
- public void setEnabledCipherSuites(String[] suites) {
- delegate.setEnabledCipherSuites(suites);
- }
-
- @Override
- public String[] getSupportedProtocols() {
- return delegate.getSupportedProtocols();
- }
-
- @Override
- public String[] getEnabledProtocols() {
- return delegate.getEnabledProtocols();
- }
-
- @Override
- public void setEnabledProtocols(String[] protocols) {
- delegate.setEnabledProtocols(protocols);
- }
-
- @Override
- public SSLSession getSession() {
- return delegate.getSession();
- }
-
- @Override
- public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {
- delegate.addHandshakeCompletedListener(listener);
- }
-
- @Override
- public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {
- delegate.removeHandshakeCompletedListener(listener);
- }
-
- @Override
- public void startHandshake() throws IOException {
- delegate.startHandshake();
- }
-
- @Override
- public void setUseClientMode(boolean mode) {
- delegate.setUseClientMode(mode);
- }
-
- @Override
- public boolean getUseClientMode() {
- return delegate.getUseClientMode();
- }
-
- @Override
- public void setNeedClientAuth(boolean need) {
- delegate.setNeedClientAuth(need);
- }
-
- @Override
- public void setWantClientAuth(boolean want) {
- delegate.setWantClientAuth(want);
- }
-
- @Override
- public boolean getNeedClientAuth() {
- return delegate.getNeedClientAuth();
- }
-
- @Override
- public boolean getWantClientAuth() {
- return delegate.getWantClientAuth();
- }
-
- @Override
- public void setEnableSessionCreation(boolean flag) {
- delegate.setEnableSessionCreation(flag);
- }
-
- @Override
- public boolean getEnableSessionCreation() {
- return delegate.getEnableSessionCreation();
- }
-
- @Override
- public void bind(SocketAddress localAddr) throws IOException {
- delegate.bind(localAddr);
- }
-
- @Override
- public synchronized void close() throws IOException {
- delegate.close();
- }
-
- @Override
- public void connect(SocketAddress remoteAddr) throws IOException {
- delegate.connect(remoteAddr);
- }
-
- @Override
- public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
- delegate.connect(remoteAddr, timeout);
- }
-
- @Override
- public SocketChannel getChannel() {
- return delegate.getChannel();
- }
-
- @Override
- public InetAddress getInetAddress() {
- return delegate.getInetAddress();
- }
-
- @Override
- public InputStream getInputStream() throws IOException {
- return delegate.getInputStream();
- }
-
- @Override
- public boolean getKeepAlive() throws SocketException {
- return delegate.getKeepAlive();
- }
-
- @Override
- public InetAddress getLocalAddress() {
- return delegate.getLocalAddress();
- }
-
- @Override
- public int getLocalPort() {
- return delegate.getLocalPort();
- }
-
- @Override
- public SocketAddress getLocalSocketAddress() {
- return delegate.getLocalSocketAddress();
- }
-
- @Override
- public boolean getOOBInline() throws SocketException {
- return delegate.getOOBInline();
- }
-
- @Override
- public OutputStream getOutputStream() throws IOException {
- return delegate.getOutputStream();
- }
-
- @Override
- public int getPort() {
- return delegate.getPort();
- }
-
- @Override
- public synchronized int getReceiveBufferSize() throws SocketException {
- return delegate.getReceiveBufferSize();
- }
-
- @Override
- public SocketAddress getRemoteSocketAddress() {
- return delegate.getRemoteSocketAddress();
- }
-
- @Override
- public boolean getReuseAddress() throws SocketException {
- return delegate.getReuseAddress();
- }
-
- @Override
- public synchronized int getSendBufferSize() throws SocketException {
- return delegate.getSendBufferSize();
- }
-
- @Override
- public int getSoLinger() throws SocketException {
- return delegate.getSoLinger();
- }
-
- @Override
- public synchronized int getSoTimeout() throws SocketException {
- return delegate.getSoTimeout();
- }
-
- @Override
- public boolean getTcpNoDelay() throws SocketException {
- return delegate.getTcpNoDelay();
- }
-
- @Override
- public int getTrafficClass() throws SocketException {
- return delegate.getTrafficClass();
- }
-
- @Override
- public boolean isBound() {
- return delegate.isBound();
- }
-
- @Override
- public boolean isClosed() {
- return delegate.isClosed();
- }
-
- @Override
- public boolean isConnected() {
- return delegate.isConnected();
- }
-
- @Override
- public boolean isInputShutdown() {
- return delegate.isInputShutdown();
- }
-
- @Override
- public boolean isOutputShutdown() {
- return delegate.isOutputShutdown();
- }
-
- @Override
- public void sendUrgentData(int value) throws IOException {
- delegate.sendUrgentData(value);
- }
-
- @Override
- public void setKeepAlive(boolean keepAlive) throws SocketException {
- delegate.setKeepAlive(keepAlive);
- }
-
- @Override
- public void setOOBInline(boolean oobinline) throws SocketException {
- delegate.setOOBInline(oobinline);
- }
-
- @Override
- public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
- delegate.setPerformancePreferences(connectionTime, latency, bandwidth);
- }
-
- @Override
- public synchronized void setReceiveBufferSize(int size) throws SocketException {
- delegate.setReceiveBufferSize(size);
- }
-
- @Override
- public void setReuseAddress(boolean reuse) throws SocketException {
- delegate.setReuseAddress(reuse);
- }
-
- @Override
- public synchronized void setSendBufferSize(int size) throws SocketException {
- delegate.setSendBufferSize(size);
- }
-
- @Override
- public void setSoLinger(boolean on, int timeout) throws SocketException {
- delegate.setSoLinger(on, timeout);
- }
-
- @Override
- public synchronized void setSoTimeout(int timeout) throws SocketException {
- delegate.setSoTimeout(timeout);
- }
-
- @Override
- public void setTcpNoDelay(boolean on) throws SocketException {
- delegate.setTcpNoDelay(on);
- }
-
- @Override
- public void setTrafficClass(int value) throws SocketException {
- delegate.setTrafficClass(value);
- }
-
- @Override
- public void shutdownInput() throws IOException {
- delegate.shutdownInput();
- }
-
- @Override
- public void shutdownOutput() throws IOException {
- delegate.shutdownOutput();
- }
-
- @Override
- public String toString() {
- return delegate.toString();
- }
-
- @Override
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
- }
-
- private class NoSSLv3SSLSocket extends DelegateSSLSocket {
-
- private NoSSLv3SSLSocket(SSLSocket delegate) {
- super(delegate);
-
- }
-
- @Override
- public void setEnabledProtocols(String[] protocols) {
- if (protocols != null && protocols.length == 1 && "SSLv3".equals(protocols[0])) {
-
- List enabledProtocols = new ArrayList<>(Arrays.asList(delegate.getEnabledProtocols()));
- if (enabledProtocols.size() > 1) {
- if (enabledProtocols.remove("SSLv3")) {
- System.out.println("Removed SSLv3 from enabled protocols");
- }
- else {
- System.out.println("SSLv3 was not an enabled protocol");
- }
- } else {
- System.out.println("SSL stuck with protocol available for " + String.valueOf(enabledProtocols));
- }
- protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);
- }
-
- super.setEnabledProtocols(protocols);
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/DialogExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/DialogExtensions.kt
new file mode 100644
index 00000000..5bf46d16
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/DialogExtensions.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-3-30.
+ */
+
+package pl.szczodrzynski.edziennik.ui.dialogs
+
+import android.text.InputType
+import android.view.LayoutInflater
+import androidx.core.view.isVisible
+import androidx.core.widget.addTextChangedListener
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.textfield.TextInputEditText
+import pl.szczodrzynski.edziennik.databinding.DialogEditTextBinding
+import pl.szczodrzynski.edziennik.isNotNullNorBlank
+
+fun MaterialAlertDialogBuilder.input(
+ message: CharSequence? = null,
+ type: Int = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_MULTI_LINE,
+ hint: CharSequence? = null,
+ value: CharSequence? = null,
+ changeListener: ((editText: TextInputEditText, input: String) -> Boolean)? = null,
+ positiveButton: Int? = null,
+ positiveListener: ((editText: TextInputEditText, input: String) -> Boolean)? = null
+): MaterialAlertDialogBuilder {
+ val b = DialogEditTextBinding.inflate(LayoutInflater.from(context), null, false)
+ b.title.text = message
+ b.title.isVisible = message.isNotNullNorBlank()
+ b.text1.hint = hint
+ b.text1.inputType = type
+ b.text1.setText(value)
+ b.text1.addTextChangedListener { text ->
+ if (changeListener?.invoke(b.text1, text?.toString() ?: "") != false)
+ b.text1.error = null
+ }
+ if (positiveButton != null) {
+ setPositiveButton(positiveButton) { dialog, _ ->
+ if (positiveListener?.invoke(b.text1, b.text1.text?.toString() ?: "") != false)
+ dialog.dismiss()
+ }
+ }
+ setView(b.root)
+
+ return this
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/home/StudentNumberDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/home/StudentNumberDialog.kt
index 265bd17b..3f3f8176 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/home/StudentNumberDialog.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/home/StudentNumberDialog.kt
@@ -5,12 +5,11 @@
package pl.szczodrzynski.edziennik.ui.dialogs.home
import android.text.InputType
-import android.widget.Toast
-import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
-import com.afollestad.materialdialogs.MaterialDialog
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ui.dialogs.input
class StudentNumberDialog(
val activity: AppCompatActivity,
@@ -22,25 +21,27 @@ class StudentNumberDialog(
private const val TAG = "StudentNumberDialog"
}
- private lateinit var dialog: AlertDialog
-
init { run {
if (activity.isFinishing)
return@run
onShowListener?.invoke(TAG)
- MaterialDialog.Builder(activity)
- .title(R.string.card_lucky_number_set_title)
- .content(R.string.card_lucky_number_set_text)
- .inputType(InputType.TYPE_CLASS_NUMBER)
- .input(null, if (profile.studentNumber == -1) "" else profile.studentNumber.toString()) { _: MaterialDialog?, input: CharSequence ->
- try {
- profile.studentNumber = input.toString().toInt()
- } catch (e: Exception) {
- Toast.makeText(activity, R.string.incorrect_format, Toast.LENGTH_SHORT).show()
- }
+ MaterialAlertDialogBuilder(activity)
+ .setTitle(R.string.card_lucky_number_set_title)
+ .input(
+ message = activity.getString(R.string.card_lucky_number_set_text),
+ type = InputType.TYPE_CLASS_NUMBER,
+ hint = null,
+ value = if (profile.studentNumber == -1) null else profile.studentNumber.toString(),
+ positiveButton = R.string.ok,
+ positiveListener = { _, input ->
+ profile.studentNumber = input.toIntOrNull() ?: -1
+ true
}
- .dismissListener {
- onDismissListener?.invoke(TAG)
- }.show()
+ )
+ .setNegativeButton(R.string.cancel, null)
+ .setOnDismissListener {
+ onDismissListener?.invoke(TAG)
+ }
+ .show()
}}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/GenerateBlockTimetableDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/GenerateBlockTimetableDialog.kt
index aefd16f9..c93d5a6e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/GenerateBlockTimetableDialog.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/timetable/GenerateBlockTimetableDialog.kt
@@ -18,8 +18,8 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.content.FileProvider
+import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -107,25 +107,27 @@ class GenerateBlockTimetableDialog(
.show()
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick {
- when (b.weekSelectionRadioGroup.checkedRadioButtonId) {
- R.id.withChangesCurrentWeekRadio -> generateBlockTimetable(weekCurrentStart, weekCurrentEnd)
- R.id.withChangesNextWeekRadio -> generateBlockTimetable(weekNextStart, weekNextEnd)
- R.id.forSelectedWeekRadio -> selectDate()
+ app.permissionManager.requestStoragePermission(activity, permissionMessage = R.string.permissions_generate_timetable) {
+ when (b.weekSelectionRadioGroup.checkedRadioButtonId) {
+ R.id.withChangesCurrentWeekRadio -> generateBlockTimetable(weekCurrentStart, weekCurrentEnd)
+ R.id.withChangesNextWeekRadio -> generateBlockTimetable(weekNextStart, weekNextEnd)
+ R.id.forSelectedWeekRadio -> selectDate()
+ }
}
}
}}
private fun selectDate() {
- val date = Date.getToday()
- DatePickerDialog
- .newInstance({ _, year, monthOfYear, dayOfMonth ->
- val dateSelected = Date(year, monthOfYear, dayOfMonth)
+ MaterialDatePicker.Builder.datePicker()
+ .setCalendarConstraints(app.profile.getSchoolYearConstrains())
+ .build()
+ .apply {
+ addOnPositiveButtonClickListener { millis ->
+ val dateSelected = Date.fromMillisUtc(millis)
generateBlockTimetable(dateSelected.weekStart, dateSelected.weekEnd)
- }, date.year, date.month, date.day)
- .apply {
- accentColor = R.attr.colorPrimary.resolveAttr(this@GenerateBlockTimetableDialog.activity)
- show(this@GenerateBlockTimetableDialog.activity.supportFragmentManager, "DatePickerDialog")
}
+ }
+ .show(activity.supportFragmentManager, TAG)
}
@Subscribe(threadMode = ThreadMode.MAIN)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/announcements/AnnouncementsFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/announcements/AnnouncementsFragment.java
index 9529f268..d8cdbc2c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/announcements/AnnouncementsFragment.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/announcements/AnnouncementsFragment.java
@@ -14,7 +14,7 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.afollestad.materialdialogs.MaterialDialog;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import org.greenrobot.eventbus.EventBus;
@@ -120,7 +120,7 @@ public class AnnouncementsFragment extends Fragment {
return;
}*/
AnnouncementsAdapter announcementsAdapter = new AnnouncementsAdapter(activity, announcements, (v, announcement) -> {
- if (announcement.getText() == null || (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.getSeen() && app.getNetworkUtils().isOnline())) {
+ if (announcement.getText() == null || (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.getSeen())) {
EdziennikTask.Companion.announcementGet(App.Companion.getProfileId(), announcement).enqueue(requireContext());
} else {
showAnnouncementDetailsDialog(announcement);
@@ -161,12 +161,12 @@ public class AnnouncementsFragment extends Fragment {
}
private void showAnnouncementDetailsDialog(AnnouncementFull announcement) {
- MaterialDialog dialog = new MaterialDialog.Builder(activity)
- .title(announcement.getSubject())
- .customView(R.layout.dialog_announcement, true)
- .positiveText(R.string.ok)
+ DialogAnnouncementBinding b = DialogAnnouncementBinding.inflate(LayoutInflater.from(activity), null, false);
+ new MaterialAlertDialogBuilder(activity)
+ .setTitle(announcement.getSubject())
+ .setView(b.getRoot())
+ .setPositiveButton(R.string.ok, null)
.show();
- DialogAnnouncementBinding b = DialogAnnouncementBinding.bind(dialog.getCustomView());
b.text.setText(announcement.getTeacherName() +"\n\n"+ (announcement.getStartDate() != null ? announcement.getStartDate().getFormattedString() : "-") + (announcement.getEndDate() != null ? " do " + announcement.getEndDate().getFormattedString() : "")+"\n\n" +announcement.getText());
if (!announcement.getSeen() && app.getProfile().getLoginStoreType() != LOGIN_TYPE_LIBRUS) {
announcement.setSeen(true);
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/attendance/AttendanceFragment_.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/attendance/AttendanceFragment_.java
deleted file mode 100644
index c46b3e09..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/attendance/AttendanceFragment_.java
+++ /dev/null
@@ -1,361 +0,0 @@
-package pl.szczodrzynski.edziennik.ui.modules.attendance;
-
-import android.graphics.Color;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.LongSparseArray;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.PopupMenu;
-import androidx.core.graphics.ColorUtils;
-import androidx.databinding.DataBindingUtil;
-import androidx.fragment.app.Fragment;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
-
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import antonkozyriatskyi.circularprogressindicator.CircularProgressIndicator;
-import pl.szczodrzynski.edziennik.App;
-import pl.szczodrzynski.edziennik.MainActivity;
-import pl.szczodrzynski.edziennik.R;
-import pl.szczodrzynski.edziennik.data.db.entity.Subject;
-import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
-import pl.szczodrzynski.edziennik.databinding.FragmentAttendanceBinding;
-import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration;
-import pl.szczodrzynski.edziennik.utils.Themes;
-import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem;
-
-import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_ABSENT;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_ABSENT_EXCUSED;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_BELATED;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_BELATED_EXCUSED;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_PRESENT;
-import static pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_RELEASED;
-import static pl.szczodrzynski.edziennik.data.db.entity.LoginStore.LOGIN_TYPE_VULCAN;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
-
-public class AttendanceFragment_ extends Fragment {
-
- private App app = null;
- private MainActivity activity = null;
- private FragmentAttendanceBinding b = null;
-
- private int displayMode = MODE_YEAR;
- private static final int MODE_YEAR = 0;
- private static final int MODE_SEMESTER_1 = 1;
- private static final int MODE_SEMESTER_2 = 2;
- private long subjectIdFilter = -1;
- private LongSparseArray subjectTotalCount;
- private LongSparseArray subjectAbsentCount;
- private LongSparseArray subjectAttendancePercentage;
-
- private List attendanceList = null;
-
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- activity = (MainActivity) getActivity();
- if (getActivity() == null || getContext() == null)
- return null;
- app = (App) activity.getApplication();
- getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
- // activity, context and profile is valid
- b = DataBindingUtil.inflate(inflater, R.layout.fragment_attendance, container, false);
- b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
- return b.getRoot();
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- if (app == null || activity == null || b == null || !isAdded())
- return;
-
- activity.getBottomSheet().prependItems(
- new BottomSheetPrimaryItem(true)
- .withTitle(R.string.menu_mark_as_read)
- .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
- .withOnClickListener(v3 -> {
- activity.getBottomSheet().close();
- AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_ATTENDANCE, true));
- Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
- })
- );
-
- /*b.refreshLayout.setOnRefreshListener(() -> {
- activity.syncCurrentFeature(MainActivity.DRAWER_ITEM_ATTENDANCE, b.refreshLayout);
- });*/
-
- b.attendancePercentage.setProgressTextAdapter(PERCENTAGE_ADAPTER);
- b.attendancePercentage.setMaxProgress(100.0f);
-
- b.attendanceSummaryTitle.setOnClickListener((v -> {
- PopupMenu popupMenu = new PopupMenu(activity, b.attendanceSummaryTitle, Gravity.END);
- popupMenu.getMenu().add(0, 0, 0, R.string.summary_mode_year);
- popupMenu.getMenu().add(0, 1, 1, R.string.summary_mode_semester_1);
- popupMenu.getMenu().add(0, 2, 2, R.string.summary_mode_semester_2);
- popupMenu.setOnMenuItemClickListener((item -> {
- displayMode = item.getItemId();
- updateList();
- return true;
- }));
- popupMenu.show();
- }));
-
- /*if (app.profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK) {
- long attendanceLastSync = app.profile.getStudentData("attendanceLastSync", (long)0);
- if (attendanceLastSync == 0) {
- attendanceLastSync = app.profile.getSemesterStart(1).getInMillis();
- }
- Date lastSyncDate = Date.fromMillis(attendanceLastSync);
- if (lastSyncDate.getValue() < Week.getWeekStart().getValue()) {
- CafeBar.builder(activity)
- .to(activity.getNavView().getCoordinator())
- .content(R.string.sync_old_data_info)
- .icon(new IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_download_outline).size(IconicsSize.dp(20)).color(IconicsColor.colorInt(Themes.INSTANCE.getPrimaryTextColor(activity))))
- .positiveText(R.string.refresh)
- .positiveColor(0xff4caf50)
- .negativeText(R.string.ok)
- .negativeColor(0x66ffffff)
- .onPositive((cafeBar -> {
- if (!activity.getSwipeRefreshLayout().isRefreshing()) {
- cafeBar.dismiss();
- activity.syncCurrentFeature();
- }
- else {
- Toast.makeText(app, R.string.please_wait, Toast.LENGTH_SHORT).show();
- }
- }))
- .onNegative(CafeBar::dismiss)
- .autoDismiss(false)
- .swipeToDismiss(true)
- .floating(true)
- .show();
- }
- }*/
-
- b.attendanceSummarySubject.setOnClickListener((v -> {
- AsyncTask.execute(() -> {
- List subjectList = App.db.subjectDao().getAllNow(App.Companion.getProfileId());
- PopupMenu popupMenu = new PopupMenu(activity, b.attendanceSummarySubject, Gravity.END);
- popupMenu.getMenu().add(0, -1, 0, R.string.subject_filter_disabled);
- int index = 0;
- DecimalFormat format = new DecimalFormat("0.00");
- for (Subject subject: subjectList) {
- int total = subjectTotalCount.get(subject.id, new int[3])[displayMode];
- int absent = subjectAbsentCount.get(subject.id, new int[3])[displayMode];
- if (total == 0)
- continue;
- int present = total - absent;
- float percentage = (float)present / (float)total * 100.0f;
- String percentageStr = format.format(percentage);
- popupMenu.getMenu().add(0, (int)subject.id, index++, getString(R.string.subject_filter_format, subject.longName, percentageStr));
- }
- popupMenu.setOnMenuItemClickListener((item -> {
- subjectIdFilter = item.getItemId();
- b.attendanceSummarySubject.setText(item.getTitle().toString().replaceAll("\\s-\\s[0-9]{1,2}\\.[0-9]{1,2}%", ""));
- updateList();
- return true;
- }));
- new Handler(activity.getMainLooper()).post(popupMenu::show);
- });
-
- }));
-
- LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
-
- b.attendanceView.setHasFixedSize(true);
- b.attendanceView.setLayoutManager(linearLayoutManager);
- b.attendanceView.addItemDecoration(new SimpleDividerItemDecoration(getContext()));
-
- b.attendanceView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
- if (recyclerView.canScrollVertically(-1)) {
- b.refreshLayout.setEnabled(false);
- }
- if (!recyclerView.canScrollVertically(-1) && newState == SCROLL_STATE_IDLE) {
- b.refreshLayout.setEnabled(true);
- }
- }
- });
-
- App.db.attendanceDao().getAll(App.Companion.getProfileId()).observe(this, attendance -> {
- if (app == null || activity == null || b == null || !isAdded())
- return;
-
- if (attendance == null) {
- b.attendanceView.setVisibility(View.GONE);
- b.attendanceNoData.setVisibility(View.VISIBLE);
- return;
- }
-
- attendanceList = attendance;
-
- countSubjectStats();
-
- updateList();
- });
- }
-
- private void countSubjectStats() {
- subjectTotalCount = new LongSparseArray<>();
- subjectAbsentCount = new LongSparseArray<>();
- for (AttendanceFull attendance: attendanceList) {
- if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_VULCAN && attendance.getBaseType() == TYPE_RELEASED)
- continue;
- int[] subjectTotal = subjectTotalCount.get(attendance.getSubjectId(), new int[3]);
- int[] subjectAbsent = subjectAbsentCount.get(attendance.getSubjectId(), new int[3]);
-
- subjectTotal[0]++;
- subjectTotal[attendance.getSemester()]++;
-
- if (attendance.getBaseType() == TYPE_ABSENT || attendance.getBaseType() == TYPE_ABSENT_EXCUSED) {
- subjectAbsent[0]++;
- subjectAbsent[attendance.getSemester()]++;
- }
-
- subjectTotalCount.put(attendance.getSubjectId(), subjectTotal);
- subjectAbsentCount.put(attendance.getSubjectId(), subjectAbsent);
- }
- }
-
- private void updateList() {
- if (app == null || activity == null || b == null || !isAdded())
- return;
-
- int presentCount = 0;
- int absentCount = 0;
- int absentUnexcusedCount = 0;
- int belatedCount = 0;
- int releasedCount = 0;
-
- List filteredList = new ArrayList<>();
- for (AttendanceFull attendance: attendanceList) {
- if (displayMode != MODE_YEAR && attendance.getSemester() != displayMode)
- continue;
- if (subjectIdFilter != -1 && attendance.getSubjectId() != subjectIdFilter)
- continue;
- if (attendance.getBaseType() != TYPE_PRESENT)
- filteredList.add(attendance);
- switch (attendance.getBaseType()) {
- case TYPE_PRESENT:
- presentCount++;
- break;
- case TYPE_ABSENT:
- absentCount++;
- absentUnexcusedCount++;
- break;
- case TYPE_ABSENT_EXCUSED:
- absentCount++;
- break;
- case TYPE_BELATED_EXCUSED:
- case TYPE_BELATED:
- belatedCount++;
- break;
- case TYPE_RELEASED:
- releasedCount++;
- break;
- }
- }
- if (filteredList.size() > 0) {
- AttendanceAdapter adapter;
- b.attendanceView.setVisibility(View.VISIBLE);
- b.attendanceNoData.setVisibility(View.GONE);
- if ((adapter = (AttendanceAdapter) b.attendanceView.getAdapter()) != null) {
- //adapter.setItems(filteredList);
- adapter.notifyDataSetChanged();
- }
- else {
- //adapter = new AttendanceAdapter(activity, true, null);
- //adapter.setItems(filteredList);
- b.attendanceView.setAdapter(adapter);
- }
- }
- else {
- b.attendanceView.setVisibility(View.GONE);
- b.attendanceNoData.setVisibility(View.VISIBLE);
- }
-
- // SUMMARY
- if (displayMode == MODE_YEAR) {
- b.attendanceSummaryTitle.setText(getString(R.string.attendance_summary_title_year));
- }
- else {
- b.attendanceSummaryTitle.setText(getString(R.string.attendance_summary_title_semester_format, displayMode));
- }
- b.presentCountContainer.setVisibility(presentCount == 0 ? View.GONE : View.VISIBLE);
- b.presentCount.setText(String.format(Locale.getDefault(), "%d", presentCount));
- b.absentCount.setText(String.format(Locale.getDefault(), "%d", absentCount));
- b.absentUnexcusedCount.setText(String.format(Locale.getDefault(), "%d", absentUnexcusedCount));
- b.belatedCount.setText(String.format(Locale.getDefault(), "%d", belatedCount));
- b.releasedCount.setText(String.format(Locale.getDefault(), "%d", releasedCount));
- if (absentUnexcusedCount >= 5) {
- b.absentUnexcusedCount.setTextColor(Color.RED);
- }
- else {
- b.absentUnexcusedCount.setTextColor(Themes.INSTANCE.getPrimaryTextColor(activity));
- }
-
- float attendancePercentage;
-
- // in Mobidziennik there are no TYPE_PRESENT records so we cannot calculate the percentage
- if (app.getProfile().getLoginStoreType() == LOGIN_TYPE_VULCAN) {
- float allCount = presentCount + absentCount + belatedCount; // do not count releases
- float present = allCount - absentCount;
- attendancePercentage = present / allCount * 100.0f;
- }
- else {
- float allCount = presentCount + absentCount + belatedCount + releasedCount;
- float present = allCount - absentCount;
- attendancePercentage = present / allCount * 100.0f;
- }
- // if it's still 0%, hide the indicator
- if (attendancePercentage <= 0.0f) {
- b.attendancePercentage.setVisibility(View.GONE);
- return;
- }
- animatePercentageIndicator(attendancePercentage);
- }
-
- private void animatePercentageIndicator(float percentage) {
- Animation a = new Animation() {
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- float progress = percentage *interpolatedTime;
- if (interpolatedTime == 1.0f) {
- progress = percentage;
- }
- int color = ColorUtils.blendARGB(Color.RED, Color.GREEN, progress/100.0f);
- b.attendancePercentage.setTextColor(color);
- b.attendancePercentage.setProgressColor(color);
- b.attendancePercentage.setCurrentProgress(progress);
- }
- public boolean willChangeBounds() {
- return true;
- }
- };
- a.setDuration(1300);
- a.setInterpolator(new AccelerateDecelerateInterpolator());
- b.attendancePercentage.postDelayed(() -> b.attendancePercentage.startAnimation(a), 500);
- }
-
- private static final CircularProgressIndicator.ProgressTextAdapter PERCENTAGE_ADAPTER = value -> {
- DecimalFormat df = new DecimalFormat("0.##");
- return df.format(value)+"%";
- };
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/CrashActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/CrashActivity.kt
index bf8eab06..0b39b913 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/CrashActivity.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/base/CrashActivity.kt
@@ -12,7 +12,7 @@ import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import cat.ereza.customactivityoncrash.CustomActivityOnCrash
-import com.afollestad.materialdialogs.MaterialDialog
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.BuildConfig
@@ -69,47 +69,31 @@ class CrashActivity : AppCompatActivity(), CoroutineScope {
val restartButton = findViewById