Merge branch 'develop' into feature/code-publish

This commit is contained in:
Kuba Szczodrzyński 2021-03-31 09:38:31 +02:00
commit 2a3b1422ef
112 changed files with 565 additions and 4820 deletions

View File

@ -140,22 +140,20 @@ dependencies {
implementation "eu.szkolny:nachos:0e5dfcaceb" implementation "eu.szkolny:nachos:0e5dfcaceb"
implementation "eu.szkolny.selective-dao:annotation:27f8f3f194" implementation "eu.szkolny.selective-dao:annotation:27f8f3f194"
implementation "eu.szkolny:ssl-provider:1.0.0" 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:numberslidingpicker:2921225f76"
implementation "pl.szczodrzynski:recyclertablayout:700f980584" implementation "pl.szczodrzynski:recyclertablayout:700f980584"
implementation "pl.szczodrzynski:tachyon:551943a6b5" implementation "pl.szczodrzynski:tachyon:551943a6b5"
kapt "eu.szkolny.selective-dao:codegen:27f8f3f194" kapt "eu.szkolny.selective-dao:codegen:27f8f3f194"
// Iconics & related // Iconics & related
implementation "com.mikepenz:iconics-core:5.2.8" implementation "com.mikepenz:iconics-core:5.3.0-b01"
implementation "com.mikepenz:iconics-views:5.2.8" implementation "com.mikepenz:iconics-views:5.3.0-b01"
implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar" implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar"
implementation "eu.szkolny:szkolny-font:1.3" implementation "eu.szkolny:szkolny-font:1.3"
// Other dependencies // Other dependencies
implementation "cat.ereza:customactivityoncrash:2.3.0" 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.applandeo:material-calendar-view:1.5.0"
implementation "com.daimajia.swipelayout:library:1.2.0@aar" implementation "com.daimajia.swipelayout:library:1.2.0@aar"
implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2" implementation "com.github.antonKozyriatskyi:CircularProgressIndicator:1.2.2"
@ -169,7 +167,6 @@ dependencies {
implementation "com.jaredrummler:colorpicker:1.1.0" implementation "com.jaredrummler:colorpicker:1.1.0"
implementation "com.qifan.powerpermission:powerpermission-coroutines:1.3.0" implementation "com.qifan.powerpermission:powerpermission-coroutines:1.3.0"
implementation "com.qifan.powerpermission:powerpermission: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 "com.yuyh.json:jsonviewer:1.0.6"
implementation "io.coil-kt:coil:1.1.1" implementation "io.coil-kt:coil:1.1.1"
implementation "me.dm7.barcodescanner:zxing:1.9.8" implementation "me.dm7.barcodescanner:zxing:1.9.8"

View File

@ -123,9 +123,6 @@
android:configChanges="orientation|screenSize|keyboardHidden" android:configChanges="orientation|screenSize|keyboardHidden"
android:process=":error_activity" android:process=":error_activity"
android:theme="@style/DeadTheme" /> android:theme="@style/DeadTheme" />
<activity android:name=".ui.modules.base.CrashGtfoActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:theme="@style/DeadTheme" />
<activity android:name=".ui.modules.intro.ChangelogIntroActivity" <activity android:name=".ui.modules.intro.ChangelogIntroActivity"
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name" android:label="@string/app_name"
@ -180,13 +177,6 @@
____) | __/ | \ V /| | (_| __/\__ \ ____) | __/ | \ V /| | (_| __/\__ \
|_____/ \___|_| \_/ |_|\___\___||___/ |_____/ \___|_| \_/ |_|\___\___||___/
--> -->
<!--<service android:name=".sync.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>-->
<service android:name=".data.api.ApiService" /> <service android:name=".data.api.ApiService" />
<service android:name=".data.firebase.MyFirebaseService" <service android:name=".data.firebase.MyFirebaseService"
android:exported="false"> android:exported="false">

View File

@ -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-----

View File

@ -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.api.szkolny.interceptor.Signing
import pl.szczodrzynski.edziennik.data.db.AppDb import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Profile 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.network.cookie.DumbCookieJar
import pl.szczodrzynski.edziennik.sync.SyncWorker import pl.szczodrzynski.edziennik.sync.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateWorker import pl.szczodrzynski.edziennik.sync.UpdateWorker
@ -89,7 +88,6 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.build() .build()
val permissionChecker by lazy { PermissionChecker(this) } val permissionChecker by lazy { PermissionChecker(this) }
val networkUtils by lazy { NetworkUtils(this) }
val gson by lazy { Gson() } val gson by lazy { Gson() }
/* _ _ _______ _______ _____ /* _ _ _______ _______ _____
@ -166,6 +164,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.errorActivity(CrashActivity::class.java) .errorActivity(CrashActivity::class.java)
.apply() .apply()
Iconics.init(applicationContext) Iconics.init(applicationContext)
Iconics.respectFontBoundsDefault = true
// initialize companion object values // initialize companion object values
App.db = AppDb(this) App.db = AppDb(this)

View File

@ -37,6 +37,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.* import com.google.gson.*
import com.google.gson.JsonArray import com.google.gson.JsonArray
@ -1279,3 +1280,10 @@ fun Context.getSyncInterval(interval: Int): String {
"" ""
return hoursText?.plus(" $minutesText") ?: minutesText return hoursText?.plus(" $minutesText") ?: minutesText
} }
fun Profile.getSchoolYearConstrains(): CalendarConstraints {
return CalendarConstraints.Builder()
.setStart(dateSemester1Start.inMillisUtc)
.setEnd(dateYearEnd.inMillisUtc)
.build()
}

View File

@ -1,5 +0,0 @@
package pl.szczodrzynski.edziennik;
import androidx.core.content.FileProvider;
public class GenericFileProvider extends FileProvider {}

View File

@ -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.ErrorDetailsDialog
import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment 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.GradesListFragment
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
@ -128,7 +127,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
const val DRAWER_ITEM_DEBUG = 102 const val DRAWER_ITEM_DEBUG = 102
const val TARGET_GRADES_EDITOR = 501 const val TARGET_GRADES_EDITOR = 501
const val TARGET_HELP = 502
const val TARGET_FEEDBACK = 120 const val TARGET_FEEDBACK = 120
const val TARGET_MESSAGES_DETAILS = 503 const val TARGET_MESSAGES_DETAILS = 503
const val TARGET_MESSAGES_COMPOSE = 504 const val TARGET_MESSAGES_COMPOSE = 504
@ -226,7 +224,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
// other target items, not directly navigated // other target items, not directly navigated
list += NavTarget(TARGET_GRADES_EDITOR, R.string.menu_grades_editor, GradesEditorFragment::class) 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_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_DETAILS, R.string.menu_message, MessageFragment::class).withPopTo(DRAWER_ITEM_MESSAGES)
list += NavTarget(TARGET_MESSAGES_COMPOSE, R.string.menu_message_compose, MessagesComposeFragment::class) 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) .content(R.string.rate_snackbar_text)
.icon(IconicsDrawable(this).apply { .icon(IconicsDrawable(this).apply {
icon = CommunityMaterial.Icon3.cmd_star_outline icon = CommunityMaterial.Icon3.cmd_star_outline
sizeDp = 20 sizeDp = 24
colorInt = Themes.getPrimaryTextColor(this@MainActivity) colorInt = Themes.getPrimaryTextColor(this@MainActivity)
}) })
.positiveText(R.string.rate_snackbar_positive) .positiveText(R.string.rate_snackbar_positive)

View File

@ -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)")
}
}

View File

@ -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<Profile> 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
}
}*/
}
}

View File

@ -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());
}
}
}
};
}*/
}

View File

@ -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.
* <p/>
* 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<String> 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);
}
}
}

View File

@ -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
}

View File

@ -5,12 +5,11 @@
package pl.szczodrzynski.edziennik.ui.dialogs.home package pl.szczodrzynski.edziennik.ui.dialogs.home
import android.text.InputType import android.text.InputType
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity 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.R
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.ui.dialogs.input
class StudentNumberDialog( class StudentNumberDialog(
val activity: AppCompatActivity, val activity: AppCompatActivity,
@ -22,25 +21,27 @@ class StudentNumberDialog(
private const val TAG = "StudentNumberDialog" private const val TAG = "StudentNumberDialog"
} }
private lateinit var dialog: AlertDialog
init { run { init { run {
if (activity.isFinishing) if (activity.isFinishing)
return@run return@run
onShowListener?.invoke(TAG) onShowListener?.invoke(TAG)
MaterialDialog.Builder(activity) MaterialAlertDialogBuilder(activity)
.title(R.string.card_lucky_number_set_title) .setTitle(R.string.card_lucky_number_set_title)
.content(R.string.card_lucky_number_set_text) .input(
.inputType(InputType.TYPE_CLASS_NUMBER) message = activity.getString(R.string.card_lucky_number_set_text),
.input(null, if (profile.studentNumber == -1) "" else profile.studentNumber.toString()) { _: MaterialDialog?, input: CharSequence -> type = InputType.TYPE_CLASS_NUMBER,
try { hint = null,
profile.studentNumber = input.toString().toInt() value = if (profile.studentNumber == -1) null else profile.studentNumber.toString(),
} catch (e: Exception) { positiveButton = R.string.ok,
Toast.makeText(activity, R.string.incorrect_format, Toast.LENGTH_SHORT).show() positiveListener = { _, input ->
profile.studentNumber = input.toIntOrNull() ?: -1
true
} }
} )
.dismissListener { .setNegativeButton(R.string.cancel, null)
.setOnDismissListener {
onDismissListener?.invoke(TAG) onDismissListener?.invoke(TAG)
}.show() }
.show()
}} }}
} }

View File

@ -18,8 +18,8 @@ import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
@ -107,26 +107,28 @@ class GenerateBlockTimetableDialog(
.show() .show()
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick { dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick {
app.permissionManager.requestStoragePermission(activity, permissionMessage = R.string.permissions_generate_timetable) {
when (b.weekSelectionRadioGroup.checkedRadioButtonId) { when (b.weekSelectionRadioGroup.checkedRadioButtonId) {
R.id.withChangesCurrentWeekRadio -> generateBlockTimetable(weekCurrentStart, weekCurrentEnd) R.id.withChangesCurrentWeekRadio -> generateBlockTimetable(weekCurrentStart, weekCurrentEnd)
R.id.withChangesNextWeekRadio -> generateBlockTimetable(weekNextStart, weekNextEnd) R.id.withChangesNextWeekRadio -> generateBlockTimetable(weekNextStart, weekNextEnd)
R.id.forSelectedWeekRadio -> selectDate() R.id.forSelectedWeekRadio -> selectDate()
} }
} }
}
}} }}
private fun selectDate() { private fun selectDate() {
val date = Date.getToday() MaterialDatePicker.Builder.datePicker()
DatePickerDialog .setCalendarConstraints(app.profile.getSchoolYearConstrains())
.newInstance({ _, year, monthOfYear, dayOfMonth -> .build()
val dateSelected = Date(year, monthOfYear, dayOfMonth)
generateBlockTimetable(dateSelected.weekStart, dateSelected.weekEnd)
}, date.year, date.month, date.day)
.apply { .apply {
accentColor = R.attr.colorPrimary.resolveAttr(this@GenerateBlockTimetableDialog.activity) addOnPositiveButtonClickListener { millis ->
show(this@GenerateBlockTimetableDialog.activity.supportFragmentManager, "DatePickerDialog") val dateSelected = Date.fromMillisUtc(millis)
generateBlockTimetable(dateSelected.weekStart, dateSelected.weekEnd)
} }
} }
.show(activity.supportFragmentManager, TAG)
}
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) { fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) {

View File

@ -14,7 +14,7 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; 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 com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
@ -120,7 +120,7 @@ public class AnnouncementsFragment extends Fragment {
return; return;
}*/ }*/
AnnouncementsAdapter announcementsAdapter = new AnnouncementsAdapter(activity, announcements, (v, announcement) -> { 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()); EdziennikTask.Companion.announcementGet(App.Companion.getProfileId(), announcement).enqueue(requireContext());
} else { } else {
showAnnouncementDetailsDialog(announcement); showAnnouncementDetailsDialog(announcement);
@ -161,12 +161,12 @@ public class AnnouncementsFragment extends Fragment {
} }
private void showAnnouncementDetailsDialog(AnnouncementFull announcement) { private void showAnnouncementDetailsDialog(AnnouncementFull announcement) {
MaterialDialog dialog = new MaterialDialog.Builder(activity) DialogAnnouncementBinding b = DialogAnnouncementBinding.inflate(LayoutInflater.from(activity), null, false);
.title(announcement.getSubject()) new MaterialAlertDialogBuilder(activity)
.customView(R.layout.dialog_announcement, true) .setTitle(announcement.getSubject())
.positiveText(R.string.ok) .setView(b.getRoot())
.setPositiveButton(R.string.ok, null)
.show(); .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()); 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) { if (!announcement.getSeen() && app.getProfile().getLoginStoreType() != LOGIN_TYPE_LIBRUS) {
announcement.setSeen(true); announcement.setSeen(true);

View File

@ -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<int[]> subjectTotalCount;
private LongSparseArray<int[]> subjectAbsentCount;
private LongSparseArray<Float> subjectAttendancePercentage;
private List<AttendanceFull> 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<Subject> 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<AttendanceFull> 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)+"%";
};
}

View File

@ -12,7 +12,7 @@ import android.widget.Button
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import cat.ereza.customactivityoncrash.CustomActivityOnCrash import cat.ereza.customactivityoncrash.CustomActivityOnCrash
import com.afollestad.materialdialogs.MaterialDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.* import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.BuildConfig
@ -69,21 +69,8 @@ class CrashActivity : AppCompatActivity(), CoroutineScope {
val restartButton = findViewById<Button>(R.id.crash_restart_btn) val restartButton = findViewById<Button>(R.id.crash_restart_btn)
restartButton.setOnClickListener { CustomActivityOnCrash.restartApplication(this@CrashActivity, config) } restartButton.setOnClickListener { CustomActivityOnCrash.restartApplication(this@CrashActivity, config) }
val devMessageButton = findViewById<Button>(R.id.crash_dev_message_btn)
devMessageButton.setOnClickListener {
val i = Intent(this@CrashActivity, CrashGtfoActivity::class.java)
startActivity(i)
}
val reportButton = findViewById<Button>(R.id.crash_report_btn) val reportButton = findViewById<Button>(R.id.crash_report_btn)
reportButton.setOnClickListener { reportButton.setOnClickListener {
if (!app.networkUtils.isOnline) {
MaterialDialog.Builder(this@CrashActivity)
.title(R.string.network_you_are_offline_title)
.content(R.string.network_you_are_offline_text)
.positiveText(R.string.ok)
.show()
} else {
launch { launch {
api.runCatching({ api.runCatching({
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
@ -98,17 +85,14 @@ class CrashActivity : AppCompatActivity(), CoroutineScope {
reportButton.setTextColor(resources.getColor(android.R.color.darker_gray)) reportButton.setTextColor(resources.getColor(android.R.color.darker_gray))
} }
} }
}
val moreInfoButton = findViewById<Button>(R.id.crash_details_btn) val moreInfoButton = findViewById<Button>(R.id.crash_details_btn)
moreInfoButton.setOnClickListener { v: View? -> moreInfoButton.setOnClickListener {
MaterialDialog.Builder(this@CrashActivity) MaterialAlertDialogBuilder(this, R.style.AppTheme_MaterialAlertDialogMonospace)
.title(R.string.crash_details) .setTitle(R.string.crash_details)
.content(Html.fromHtml(getErrorString(intent, false))) .setMessage(Html.fromHtml(getErrorString(intent, false)))
.typeface(null, "RobotoMono-Regular.ttf") .setPositiveButton(R.string.close, null)
.positiveText(R.string.close) .setNeutralButton(R.string.copy_to_clipboard) { _, _ -> copyErrorToClipboard() }
.neutralText(R.string.copy_to_clipboard)
.onNeutral { _, _ -> copyErrorToClipboard() }
.show() .show()
} }

View File

@ -1,20 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.base;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import pl.szczodrzynski.edziennik.R;
public class CrashGtfoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme((getApplication()
.getSharedPreferences(getString(R.string.preference_file_global), Context.MODE_PRIVATE)
.getBoolean("dark_theme", false) ? R.style.AppTheme_Dark : R.style.AppTheme));
setContentView(R.layout.activity_gtfo);
}
}

View File

@ -1,23 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.base
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import pl.szczodrzynski.edziennik.databinding.FragmentLoadingBinding
import pl.szczodrzynski.edziennik.utils.Themes
class LoadingFragment : Fragment() {
private lateinit var b: FragmentLoadingBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
if (context == null)
return null
context!!.theme.applyStyle(Themes.appTheme, true)
// activity, context and profile is valid
b = FragmentLoadingBinding.inflate(inflater)
return b.root
}
}

View File

@ -14,7 +14,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.afollestad.materialdialogs.MaterialDialog; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.yuyh.jsonviewer.library.JsonRecyclerView; import com.yuyh.jsonviewer.library.JsonRecyclerView;
@ -211,10 +211,10 @@ public class DebugFragment extends Fragment {
mRecyclerView.bindJson(result); mRecyclerView.bindJson(result);
} }
catch (Exception e) { catch (Exception e) {
new MaterialDialog.Builder(getActivity()) new MaterialAlertDialogBuilder(getActivity(), R.style.AppTheme_MaterialAlertDialogMonospace)
.title("Result") .setTitle("Result")
.content(result) .setMessage(result)
.positiveText(R.string.ok) .setPositiveButton(R.string.ok, null)
.show(); .show();
} }
mRecyclerView.setTextSize(20); mRecyclerView.setTextSize(20);

View File

@ -10,7 +10,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.* import com.google.gson.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -18,6 +18,7 @@ import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
import pl.szczodrzynski.edziennik.ui.dialogs.input
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -87,9 +88,13 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
else -> objVal.toString() else -> objVal.toString()
} }
MaterialDialog.Builder(activity) MaterialAlertDialogBuilder(activity)
.input("value", value, false) { _, input -> .setTitle(item.key)
val input = input.toString() .input(
hint = "value",
value = value,
positiveButton = R.string.ok,
positiveListener = { _, input ->
when (parent) { when (parent) {
is JsonObject -> { is JsonObject -> {
val v = objVal as JsonPrimitive val v = objVal as JsonPrimitive
@ -128,10 +133,10 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
showJson() showJson()
return@input true
} }
.title(item.key) )
.positiveText(R.string.ok) .setNegativeButton(R.string.cancel, null)
.negativeText(R.string.cancel)
.show() .show()
} }
catch (e: Exception) { catch (e: Exception) {

View File

@ -1,43 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.feedback
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.databinding.FragmentHelpBinding
import pl.szczodrzynski.edziennik.utils.Themes
class HelpFragment : Fragment() {
private lateinit var app: App
private lateinit var activity: MainActivity
private lateinit var b: FragmentHelpBinding
/*
private val navController: NavController by lazy { Navigation.findNavController(b.root) }
*/
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
if (context == null)
return null
app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = FragmentHelpBinding.inflate(inflater)
return b.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// TODO check if app, activity, b can be null
if (app.profile == null || !isAdded)
return
}
}

View File

@ -11,10 +11,11 @@ import androidx.appcompat.widget.PopupMenu
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Grade import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.databinding.FragmentGradesEditorBinding import pl.szczodrzynski.edziennik.databinding.FragmentGradesEditorBinding
import pl.szczodrzynski.edziennik.ui.dialogs.input
import pl.szczodrzynski.edziennik.utils.Colors import pl.szczodrzynski.edziennik.utils.Colors
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_AVG import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_AVG
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_SEM import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_SEM
@ -72,11 +73,10 @@ class GradesEditorFragment : Fragment() {
semester = arguments.getInt("semester", 1) semester = arguments.getInt("semester", 1)
if (subjectId == -1L) { if (subjectId == -1L) {
MaterialDialog.Builder(activity) MaterialAlertDialogBuilder(activity)
.title(R.string.error_occured) .setTitle(R.string.error_occured)
.content(R.string.error_no_subject_id) .setMessage(R.string.error_no_subject_id)
.positiveText(R.string.ok) .setPositiveButton(R.string.ok) { _, _ -> activity.navigateUp() }
.onPositive { _, _ -> activity.navigateUp() }
.show() .show()
return return
} }
@ -193,11 +193,10 @@ class GradesEditorFragment : Fragment() {
app.db.subjectDao().getById(App.profileId, subjectId).observe(this, Observer { subject -> app.db.subjectDao().getById(App.profileId, subjectId).observe(this, Observer { subject ->
if (subject == null || subject.id == -1L) { if (subject == null || subject.id == -1L) {
MaterialDialog.Builder(activity) MaterialAlertDialogBuilder(activity)
.title(R.string.error_occured) .setTitle(R.string.error_occured)
.content(R.string.error_no_subject_id) .setMessage(R.string.error_no_subject_id)
.positiveText(R.string.ok) .setPositiveButton(R.string.ok) { _, _ -> activity.navigateUp() }
.onPositive { _, _ -> activity.navigateUp() }
.show() .show()
return@Observer return@Observer
} }
@ -329,20 +328,23 @@ class GradesEditorFragment : Fragment() {
popup.setOnMenuItemClickListener { item -> popup.setOnMenuItemClickListener { item ->
if (item.itemId == 100) { if (item.itemId == 100) {
MaterialDialog.Builder(v.context) MaterialAlertDialogBuilder(v.context)
.title(R.string.grades_editor_add_grade_title) .setTitle(R.string.grades_editor_add_grade_title)
.content(R.string.grades_editor_add_grade_weight) .input(
.inputType(InputType.TYPE_NUMBER_FLAG_SIGNED) message = v.context.getString(R.string.grades_editor_add_grade_weight),
.input(null, null) { _, input -> type = InputType.TYPE_NUMBER_FLAG_SIGNED,
positiveButton = R.string.ok,
positiveListener = { _, input ->
try { try {
editorGrade.weight = input.toString().toFloat() editorGrade.weight = input.toFloat()
callback() callback()
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
true
} }
.positiveText(R.string.ok) )
.negativeText(R.string.cancel) .setNegativeButton(R.string.cancel, null)
.show() .show()
} else { } else {
editorGrade.weight = item.itemId.toFloat() editorGrade.weight = item.itemId.toFloat()

View File

@ -90,21 +90,21 @@ class HomeTimetableCard(
b.settings.setImageDrawable( b.settings.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon.cmd_cog_outline).apply { IconicsDrawable(activity, CommunityMaterial.Icon.cmd_cog_outline).apply {
colorAttr(activity, R.attr.colorIcon) colorAttr(activity, R.attr.colorIcon)
sizeDp = 20 sizeDp = 24
} }
) )
b.bellSync.setImageDrawable( b.bellSync.setImageDrawable(
IconicsDrawable(activity, SzkolnyFont.Icon.szf_alarm_bell_outline).apply { IconicsDrawable(activity, SzkolnyFont.Icon.szf_alarm_bell_outline).apply {
colorAttr(activity, R.attr.colorIcon) colorAttr(activity, R.attr.colorIcon)
sizeDp = 20 sizeDp = 24
} }
) )
b.showCounter.setImageDrawable( b.showCounter.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon2.cmd_fullscreen).apply { IconicsDrawable(activity, CommunityMaterial.Icon2.cmd_fullscreen).apply {
colorAttr(activity, R.attr.colorIcon) colorAttr(activity, R.attr.colorIcon)
sizeDp = 20 sizeDp = 24
} }
) )

View File

@ -1,120 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.homework;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.full.EventFull;
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog;
import pl.szczodrzynski.edziennik.utils.models.Date;
import static pl.szczodrzynski.edziennik.utils.Utils.bs;
public class HomeworkAdapter extends RecyclerView.Adapter<HomeworkAdapter.ViewHolder> {
private Context context;
private List<EventFull> homeworkList;
//getting the context and product list with constructor
public HomeworkAdapter(Context mCtx, List<EventFull> homeworkList) {
this.context = mCtx;
this.homeworkList = homeworkList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.row_homework_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
App app = (App) context.getApplicationContext();
EventFull homework = homeworkList.get(position);
int diffDays = Date.diffDays(homework.getDate(), Date.getToday());
holder.homeworkItemHomeworkDate.setText(app.getString(R.string.date_relative_format, homework.getDate().getFormattedString(), Date.dayDiffString(context, diffDays)));
holder.homeworkItemTopic.setText(homework.getTopic());
holder.homeworkItemSubjectTeacher.setText(context.getString(R.string.homework_subject_teacher_format, bs(homework.getSubjectLongName()), bs(homework.getTeacherName())));
holder.homeworkItemTeamDate.setText(context.getString(R.string.homework_team_date_format, bs(homework.getTeamName()), Date.fromMillis(homework.getAddedDate()).getFormattedStringShort()));
if (!homework.getSeen()) {
holder.homeworkItemTopic.setBackground(context.getResources().getDrawable(R.drawable.bg_rounded_8dp));
holder.homeworkItemTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
homework.setSeen(true);
AsyncTask.execute(() -> {
App.db.metadataDao().setSeen(App.Companion.getProfileId(), homework, true);
});
}
else {
holder.homeworkItemTopic.setBackground(null);
}
holder.homeworkItemEdit.setVisibility((homework.getAddedManually() ? View.VISIBLE : View.GONE));
holder.homeworkItemEdit.setOnClickListener(v -> {
new EventManualDialog(
(MainActivity) context,
homework.getProfileId(),
null,
null,
null,
null,
homework,
null,
null);
});
if (homework.getSharedBy() == null) {
holder.homeworkItemSharedBy.setVisibility(View.GONE);
}
else if (homework.getSharedByName() != null) {
holder.homeworkItemSharedBy.setText(app.getString(R.string.event_shared_by_format, (homework.getSharedBy().equals("self") ? app.getString(R.string.event_shared_by_self) : homework.getSharedByName())));
}
}
@Override
public int getItemCount() {
return homeworkList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
CardView homeworkItemCard;
TextView homeworkItemTopic;
TextView homeworkItemHomeworkDate;
TextView homeworkItemSharedBy;
TextView homeworkItemSubjectTeacher;
TextView homeworkItemTeamDate;
Button homeworkItemEdit;
ViewHolder(View itemView) {
super(itemView);
homeworkItemCard = itemView.findViewById(R.id.homeworkItemCard);
homeworkItemTopic = itemView.findViewById(R.id.homeworkItemTopic);
homeworkItemHomeworkDate = itemView.findViewById(R.id.homeworkItemHomeworkDate);
homeworkItemSharedBy = itemView.findViewById(R.id.homeworkItemSharedBy);
homeworkItemSubjectTeacher = itemView.findViewById(R.id.homeworkItemSubjectTeacher);
homeworkItemTeamDate = itemView.findViewById(R.id.homeworkItemTeamDate);
homeworkItemEdit = itemView.findViewById(R.id.homeworkItemEdit);
}
}
}

View File

@ -15,7 +15,6 @@ import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -100,7 +99,6 @@ class LoginFormFragment : Fragment(), CoroutineScope {
b.textLayout.startIconDrawable = IconicsDrawable(activity).apply { b.textLayout.startIconDrawable = IconicsDrawable(activity).apply {
icon = credential.icon icon = credential.icon
sizeDp = 24 sizeDp = 24
paddingDp = 2
colorAttr(activity, R.attr.colorOnBackground) colorAttr(activity, R.attr.colorOnBackground)
} }

View File

@ -67,7 +67,7 @@ class MessageFragment : Fragment(), CoroutineScope {
b.closeButton.setImageDrawable( b.closeButton.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon3.cmd_window_close).apply { IconicsDrawable(activity, CommunityMaterial.Icon3.cmd_window_close).apply {
colorAttr(activity, android.R.attr.textColorSecondary) colorAttr(activity, android.R.attr.textColorSecondary)
sizeDp = 12 sizeDp = 16
} }
) )
b.closeButton.setOnClickListener { activity.navigateUp() } b.closeButton.setOnClickListener { activity.navigateUp() }

View File

@ -1,295 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.messages;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.entity.Message;
import pl.szczodrzynski.edziennik.data.db.full.MessageFull;
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull;
import pl.szczodrzynski.edziennik.databinding.MessagesListBinding;
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment;
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration;
import pl.szczodrzynski.edziennik.utils.Themes;
import static androidx.recyclerview.widget.RecyclerView.NO_POSITION;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
import static pl.szczodrzynski.edziennik.utils.Utils.d;
public class MessagesListFragmentOld extends LazyFragment {
private App app = null;
private MainActivity activity = null;
private MessagesListBinding b = null;
private Rect viewRect = new Rect();
private MessagesAdapter messagesAdapter = null;
private ViewGroup viewParent = null;
static final Interpolator transitionInterpolator = new FastOutSlowInInterpolator();
static final long TRANSITION_DURATION = 300L;
static final String TAP_POSITION = "tap_position";
public static int[] tapPositions = {NO_POSITION, NO_POSITION};
public static int[] topPositions = {NO_POSITION, NO_POSITION};
public static int[] bottomPositions = {NO_POSITION, NO_POSITION};
private int messageType = Message.TYPE_RECEIVED;
@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.messages_list, container, false);
return b.getRoot();
}
@Override
public boolean onPageCreated() {
if (app == null || activity == null || b == null || !isAdded())
return false;
long messageId = -1;
if (getArguments() != null) {
messageId = getArguments().getLong("messageId", -1);
}
if (messageId != -1) {
Bundle args = new Bundle();
args.putLong("messageId", messageId);
getArguments().remove("messageId");
activity.loadTarget(MainActivity.TARGET_MESSAGES_DETAILS, args);
return false;
}
if (getArguments() != null) {
messageType = getArguments().getInt("messageType", Message.TYPE_RECEIVED);
}
/*b.refreshLayout.setOnRefreshListener(() -> {
activity.syncCurrentFeature(messageType, b.refreshLayout);
});*/
/*messagesAdapter = new MessagesAdapter(app, ((parent, view1, position, id) -> {
// TODO ANIMATION
tapPositions[messageType] = position;
topPositions[messageType] = ((LinearLayoutManager) b.emailList.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
bottomPositions[messageType] = ((LinearLayoutManager) b.emailList.getLayoutManager()).findLastCompletelyVisibleItemPosition();
*//*view1.getGlobalVisibleRect(viewRect);
((Transition) MessagesListFragment.this.getExitTransition()).setEpicenterCallback(new Transition.EpicenterCallback() {
@Override
public Rect onGetEpicenter(@NonNull Transition transition) {
return viewRect;
}
});*//*
Bundle args = new Bundle();
args.putLong("messageId", messagesAdapter.getMessageList().get(position).id);
activity.loadTarget(MainActivity.TARGET_MESSAGES_DETAILS, args);
// KOD W WERSJI 2.7
// TODO ANIMATION
*//*TransitionSet sharedElementTransition = new TransitionSet()
.addTransition(new Fade())
.addTransition(new ChangeBounds())
.addTransition(new ChangeTransform())
.addTransition(new ChangeImageTransform())
.setDuration(TRANSITION_DURATION)
.setInterpolator(transitionInterpolator);
MessagesDetailsFragment fragment = new MessagesDetailsFragment();
Bundle args = new Bundle();
args.putLong("messageId", messagesAdapter.messageList.get(position).id);
fragment.setArguments(args);
fragment.setSharedElementEnterTransition(sharedElementTransition);
fragment.setSharedElementReturnTransition(sharedElementTransition);*//*
// JAKIS STARSZY KOD
*//*Intent intent = new Intent(activity, MessagesDetailsActivity.class);
intent.putExtra("item_id", 1);
intent.putExtra("transition_name", ViewCompat.getTransitionName(view1));
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity,
view1,
getString(R.string.transition_name)
);
TransitionManager.beginDelayedTransition((ViewGroup) view1, sharedElementTransition);
setEnterTransition(sharedElementTransition);
setReturnTransition(sharedElementTransition);
setExitTransition(sharedElementTransition);
setSharedElementEnterTransition(sharedElementTransition);
setSharedElementReturnTransition(sharedElementTransition);
startActivity(intent, options.toBundle());*//*
*//*activity.getSupportFragmentManager()
.beginTransaction()
.setReorderingAllowed(true)
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.addSharedElement(view1, getString(R.string.transition_name))
.commit();*//*
}));*/
//tapPosition = savedInstanceState != null ? savedInstanceState.getInt(TAP_POSITION, tapPosition) : tapPosition;
// May not be the best place to postpone transition. Just an example to demo how reenter transition works.
// TODO ANIMATION
//postponeEnterTransition();
viewParent = (ViewGroup) getView().getParent();
b.emailList.setLayoutManager(new LinearLayoutManager(getView().getContext()));
b.emailList.addItemDecoration(new SimpleDividerItemDecoration(getView().getContext()));
b.emailList.setAdapter(messagesAdapter);
b.emailList.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
if (b.emailList.canScrollVertically(-1)) {
setSwipeToRefresh(false);
}
if (!b.emailList.canScrollVertically(-1) && newState == SCROLL_STATE_IDLE) {
setSwipeToRefresh(true);
}
}
});
if (messageType == Message.TYPE_RECEIVED) {
App.db.messageDao().getReceived(App.Companion.getProfileId()).observe(this, messageFulls -> {
createMessageList(messageFulls);
});
}
else if (messageType == Message.TYPE_DELETED) {
App.db.messageDao().getDeleted(App.Companion.getProfileId()).observe(this, messageFulls -> {
createMessageList(messageFulls);
});
}
else if (messageType == Message.TYPE_SENT) {
App.db.messageDao().getSent(App.Companion.getProfileId()).observe(this, messageFulls -> {
AsyncTask.execute(() -> {
List<MessageRecipientFull> messageRecipients = App.db.messageRecipientDao().getAll(App.Companion.getProfileId());
List<Long> messageIds = new ArrayList<>();
for (MessageFull messageFull: messageFulls) {
messageIds.add(messageFull.getId());
}
for (MessageRecipientFull messageRecipientFull: messageRecipients) {
if (messageRecipientFull.id == -1)
continue;
int index = -1;
int i = -1;
for (long id: messageIds) {
//index++;
i++;
if (id == messageRecipientFull.messageId) {
index = i;
break;
}
}
if (index >= 0) {
MessageFull messageFull = messageFulls.get(index);
if (messageFull != null) {
messageFull.addRecipient(messageRecipientFull);
}
}
}
activity.runOnUiThread(() -> {
createMessageList(messageFulls);
});
});
});
}
return true;
}
private void createMessageList(List<MessageFull> messageFulls) {
b.progressBar.setVisibility(View.GONE);
b.emailList.setVisibility(View.VISIBLE);
//messagesAdapter.setData(messageFulls);
LinearLayoutManager layoutManager = (LinearLayoutManager) b.emailList.getLayoutManager();
if (tapPositions[messageType] != NO_POSITION && layoutManager != null) {
//d("MessageList", "Scrolling");
if (topPositions[messageType] > layoutManager.findLastCompletelyVisibleItemPosition()) {
b.emailList.scrollToPosition(topPositions[messageType]);
}
else if (bottomPositions[messageType] < layoutManager.findFirstCompletelyVisibleItemPosition()) {
b.emailList.scrollToPosition(bottomPositions[messageType]);
}
else {
b.emailList.scrollToPosition(tapPositions[messageType]);
}
//tapPositions[messageType] = NO_POSITION;
//topPositions[messageType] = NO_POSITION;
//bottomPositions[messageType] = NO_POSITION;
}
// TODO ANIMATION
/*final ViewTreeObserver observer = viewParent.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
*//*viewParent.getViewTreeObserver().removeOnPreDrawListener(this);
if (getExitTransition() == null) {
setExitTransition(new SlideExplode().setDuration(TRANSITION_DURATION).setInterpolator(transitionInterpolator));
}
View view2 = layoutManager != null ? layoutManager.findViewByPosition(tapPosition) : null;
if (view2 != null) {
view2.getGlobalVisibleRect(viewRect);
((Transition) getExitTransition()).setEpicenterCallback(new Transition.EpicenterCallback() {
@Override
public Rect onGetEpicenter(@NonNull Transition transition) {
return viewRect;
}
});
}
d("MessagesList", "topPosition "+topPosition);
d("MessagesList", "tapPosition "+tapPosition);
d("MessagesList", "bottomPosition "+bottomPosition);*//*
startPostponedEnterTransition();
return true;
}
});*/
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
d("MessagesList", "onSaveInstanceState position "+tapPositions[messageType]);
outState.putInt(TAP_POSITION, tapPositions[messageType]);
}
}

View File

@ -1,12 +1,11 @@
package pl.szczodrzynski.edziennik.ui.modules.settings package pl.szczodrzynski.edziennik.ui.modules.settings
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.databinding.FragmentProfileManagerBinding import pl.szczodrzynski.edziennik.databinding.FragmentProfileManagerBinding
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
@ -26,8 +25,6 @@ class ProfileManagerFragment : Fragment() {
return null return null
app = activity.application as App app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true) context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid // activity, context and profile is valid
b = FragmentProfileManagerBinding.inflate(inflater) b = FragmentProfileManagerBinding.inflate(inflater)
b.refreshLayout.setParent(activity.swipeRefreshLayout) b.refreshLayout.setParent(activity.swipeRefreshLayout)

View File

@ -26,7 +26,7 @@ class SettingsLicenseActivity : MaterialAboutActivity() {
get() = IconicsDrawable(this).apply { get() = IconicsDrawable(this).apply {
icon = CommunityMaterial.Icon.cmd_book_outline icon = CommunityMaterial.Icon.cmd_book_outline
colorInt = foregroundColor colorInt = foregroundColor
sizeDp = 18 sizeDp = 24
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -308,14 +308,6 @@ class SettingsLicenseActivity : MaterialAboutActivity() {
"https://github.com/underwindfall/PowerPermission" "https://github.com/underwindfall/PowerPermission"
), ),
license(
"Material DateTime Picker",
"2015",
"Wouter Dullaert",
OpenSourceLicense.APACHE_2,
"https://github.com/wdullaer/MaterialDateTimePicker"
),
license( license(
"JsonViewer", "JsonViewer",
"2017", "2017",

View File

@ -25,7 +25,7 @@ class SettingsUtil(
fun refresh() = onRefresh() fun refresh() = onRefresh()
private fun IIcon.asDrawable(color: Int? = null, size: Int = 20) = private fun IIcon.asDrawable(color: Int? = null, size: Int = 24) =
IconicsDrawable(activity).apply { IconicsDrawable(activity).apply {
icon = this@asDrawable icon = this@asDrawable
sizeDp = size sizeDp = size
@ -66,7 +66,7 @@ class SettingsUtil(
val moreItem = MaterialAboutActionItem.Builder() val moreItem = MaterialAboutActionItem.Builder()
.text(R.string.settings_more_text) .text(R.string.settings_more_text)
.icon(CommunityMaterial.Icon.cmd_chevron_down.asDrawable(iconColor, size = 14)) .icon(CommunityMaterial.Icon.cmd_chevron_down.asDrawable(iconColor, size = 24))
.build() .build()
moreItem.setOnClickAction { moreItem.setOnClickAction {

View File

@ -16,8 +16,8 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.datepicker.MaterialDatePicker
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import eu.szkolny.font.SzkolnyFont import eu.szkolny.font.SzkolnyFont
import kotlinx.coroutines.* import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
@ -25,7 +25,7 @@ import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
import pl.szczodrzynski.edziennik.resolveAttr import pl.szczodrzynski.edziennik.getSchoolYearConstrains
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.ui.dialogs.timetable.GenerateBlockTimetableDialog import pl.szczodrzynski.edziennik.ui.dialogs.timetable.GenerateBlockTimetableDialog
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@ -167,19 +167,23 @@ class TimetableFragment : Fragment(), CoroutineScope {
BottomSheetPrimaryItem(true) BottomSheetPrimaryItem(true)
.withTitle(R.string.timetable_select_day) .withTitle(R.string.timetable_select_day)
.withIcon(SzkolnyFont.Icon.szf_calendar_today_outline) .withIcon(SzkolnyFont.Icon.szf_calendar_today_outline)
.withOnClickListener(View.OnClickListener { .withOnClickListener { _ ->
activity.bottomSheet.close() activity.bottomSheet.close()
val date = Date.getToday() val date = pageSelection ?: Date.getToday()
DatePickerDialog MaterialDatePicker.Builder.datePicker()
.newInstance({ _, year, monthOfYear, dayOfMonth -> .setSelection(date.inMillisUtc)
val dateSelected = Date(year, monthOfYear, dayOfMonth) .setCalendarConstraints(app.profile.getSchoolYearConstrains())
b.tabLayout.setCurrentItem(items.indexOfFirst { it == dateSelected }, true) .build()
}, date.year, date.month, date.day)
.apply { .apply {
accentColor = R.attr.colorPrimary.resolveAttr(this@TimetableFragment.activity) addOnPositiveButtonClickListener { millis ->
show(this@TimetableFragment.activity.supportFragmentManager, "DatePickerDialog") val dateSelected = Date.fromMillisUtc(millis)
val index = items.indexOfFirst { it == dateSelected }
if (index != -1)
b.tabLayout.setCurrentItem(index, true)
} }
}), }
.show(activity.supportFragmentManager, TAG)
},
BottomSheetPrimaryItem(true) BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_event) .withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc) .withDescription(R.string.menu_add_event_desc)

View File

@ -12,7 +12,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import eu.szkolny.font.SzkolnyFont import eu.szkolny.font.SzkolnyFont
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -85,12 +84,11 @@ class AttachmentAdapter(
icon = attachmentIcon icon = attachmentIcon
colorAttr(context, R.attr.colorOnSurface) colorAttr(context, R.attr.colorOnSurface)
sizeDp = 24 sizeDp = 24
paddingDp = 2
} }
b.chip.closeIcon = IconicsDrawable(context).apply { b.chip.closeIcon = IconicsDrawable(context).apply {
icon = CommunityMaterial.Icon.cmd_check icon = CommunityMaterial.Icon.cmd_check
colorAttr(context, R.attr.colorOnSurface) colorAttr(context, R.attr.colorOnSurface)
sizeDp = 18 sizeDp = 24
} }
b.chip.isCloseIconVisible = item.isDownloaded && !item.isDownloading b.chip.isCloseIconVisible = item.isDownloaded && !item.isDownloading

View File

@ -10,14 +10,13 @@ import android.util.AttributeSet
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.MaterialDatePicker
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.AppDb import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.full.LessonFull import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.observeOnce import pl.szczodrzynski.edziennik.observeOnce
import pl.szczodrzynski.edziennik.resolveAttr
import pl.szczodrzynski.edziennik.utils.TextInputDropDown import pl.szczodrzynski.edziennik.utils.TextInputDropDown
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
@ -179,18 +178,18 @@ class DateDropdown : TextInputDropDown {
fun pickerDialog() { fun pickerDialog() {
val date = getSelected() as? Date ?: Date.getToday() val date = getSelected() as? Date ?: Date.getToday()
DatePickerDialog MaterialDatePicker.Builder.datePicker()
.newInstance({ _, year, monthOfYear, dayOfMonth -> .setSelection(date.inMillisUtc)
val dateSelected = Date(year, monthOfYear+1, dayOfMonth) .build()
.apply {
addOnPositiveButtonClickListener { millis ->
val dateSelected = Date.fromMillisUtc(millis)
selectDate(dateSelected) selectDate(dateSelected)
onDateSelected?.invoke(dateSelected, null) onDateSelected?.invoke(dateSelected, null)
}, date.year, date.month-1, date.day)
.apply {
this@DateDropdown.activity ?: return@apply
accentColor = R.attr.colorPrimary.resolveAttr(this@DateDropdown.activity)
show(this@DateDropdown.activity!!.supportFragmentManager, "DatePickerDialog")
} }
} }
.show(activity!!.supportFragmentManager, "DateDropdown")
}
fun selectDate(date: Date) { fun selectDate(date: Date) {
if (select(date) == null) if (select(date) == null)

View File

@ -9,12 +9,13 @@ import android.content.ContextWrapper
import android.text.InputType import android.text.InputType
import android.util.AttributeSet import android.util.AttributeSet
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.crc16 import pl.szczodrzynski.edziennik.crc16
import pl.szczodrzynski.edziennik.data.db.AppDb import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.ui.dialogs.input
import pl.szczodrzynski.edziennik.utils.TextInputDropDown import pl.szczodrzynski.edziennik.utils.TextInputDropDown
class SubjectDropdown : TextInputDropDown { class SubjectDropdown : TextInputDropDown {
@ -105,18 +106,24 @@ class SubjectDropdown : TextInputDropDown {
fun customNameDialog() { fun customNameDialog() {
activity ?: return activity ?: return
MaterialDialog.Builder(activity!!) MaterialAlertDialogBuilder(activity!!)
.title("Własny przedmiot") .setTitle("Własny przedmiot")
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) .input(
.input("Nazwa", "") { _: MaterialDialog?, input: CharSequence -> hint = "Nazwa",
customSubjectName = input.toString() type = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE,
positiveButton = R.string.ok,
positiveListener = { _, input ->
customSubjectName = input
select(Item( select(Item(
-1L * customSubjectName.crc16(), -1L * customSubjectName.crc16(),
customSubjectName, customSubjectName,
tag = customSubjectName tag = customSubjectName
)) ))
onCustomSubjectSelected?.invoke(customSubjectName) onCustomSubjectSelected?.invoke(customSubjectName)
true
} }
)
.setNegativeButton(R.string.cancel, null)
.show() .show()
} }

View File

@ -8,7 +8,8 @@ import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.util.AttributeSet import android.util.AttributeSet
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.*
@ -177,18 +178,20 @@ class TimeDropdown : TextInputDropDown {
fun pickerDialog() { fun pickerDialog() {
val time = (getSelected() as? Pair<*, *>)?.first as? Time ?: Time.getNow() val time = (getSelected() as? Pair<*, *>)?.first as? Time ?: Time.getNow()
TimePickerDialog MaterialTimePicker.Builder()
.newInstance({ _, hourOfDay, minute, second -> .setTimeFormat(TimeFormat.CLOCK_24H)
val timeSelected = Time(hourOfDay, minute, second) .setHour(time.hour)
.setMinute(time.minute)
.build()
.also { dialog ->
dialog.addOnPositiveButtonClickListener {
val timeSelected = Time(dialog.hour, dialog.minute, 0)
selectTime(timeSelected) selectTime(timeSelected)
onTimeSelected?.invoke(timeSelected, null, null) onTimeSelected?.invoke(timeSelected, null, null)
}, time.hour, time.minute, 0, true)
.apply {
this@TimeDropdown.activity ?: return@apply
accentColor = R.attr.colorPrimary.resolveAttr(this@TimeDropdown.activity)
show(this@TimeDropdown.activity!!.supportFragmentManager, "TimePickerDialog")
} }
} }
.show(activity!!.supportFragmentManager, "TimeDropdown")
}
fun selectTime(time: Time) { fun selectTime(time: Time) {
if (select(time.value.toLong()) == null) if (select(time.value.toLong()) == null)

View File

@ -8,17 +8,18 @@ import android.app.Activity;
import android.app.WallpaperManager; import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.database.DataSetObserver;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SeekBar; import android.widget.SeekBar;
import com.afollestad.materialdialogs.MaterialDialog; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.afollestad.materialdialogs.simplelist.MaterialSimpleListAdapter;
import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import java.util.List; import java.util.List;
@ -27,6 +28,7 @@ import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.entity.Profile; import pl.szczodrzynski.edziennik.data.db.entity.Profile;
import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding; import pl.szczodrzynski.edziennik.databinding.DialogWidgetConfigBinding;
import pl.szczodrzynski.edziennik.databinding.WidgetProfileDialogItemBinding;
import pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider; import pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider;
import pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider; import pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider;
import pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider; import pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider;
@ -96,45 +98,84 @@ public class WidgetConfigActivity extends Activity {
} }
private void selectProfile() { private void selectProfile() {
MaterialSimpleListAdapter adapter = if (profileList.size() > 1 && widgetType != WIDGET_LUCKY_NUMBER) {
new MaterialSimpleListAdapter((dialog, index1, item) -> { profileList.add(
profileId = (int) item.getId(); new Profile(-1,
profileName = item.toString(); 0,
0,
getString(R.string.widget_config_all_profiles),
null,
"",
"",
null,
new JsonObject()
)
);
}
ListAdapter adapter = new ListAdapter() {
@Override public boolean areAllItemsEnabled() { return true; }
@Override public boolean isEnabled(int position) { return true; }
@Override public void registerDataSetObserver(DataSetObserver observer) { }
@Override public void unregisterDataSetObserver(DataSetObserver observer) { }
@Override public boolean hasStableIds() { return true; }
@Override public int getItemViewType(int position) { return 0; }
@Override public int getViewTypeCount() { return 1; }
@Override public boolean isEmpty() { return false; }
@Override public int getCount() { return profileList.size(); }
@Override public Object getItem(int position) { return profileList.get(position); }
@Override
public long getItemId(int position) {
return profileList.get(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
WidgetProfileDialogItemBinding b;
if (convertView == null) {
b = WidgetProfileDialogItemBinding.inflate(getLayoutInflater(), null, false);
}
else {
b = WidgetProfileDialogItemBinding.bind(convertView);
}
Profile profile = profileList.get(position);
b.name.setText(profile.getName());
b.subname.setText(profile.getSubname());
b.subname.setVisibility(profile.getSubname() == null ? View.GONE : View.VISIBLE);
b.image.setVisibility(profile.getId() == -1 ? View.GONE : View.VISIBLE);
if (profile.getId() == -1)
b.image.setImageDrawable(null);
else
b.image.setImageDrawable(profile.getImageDrawable(WidgetConfigActivity.this));
b.getRoot().setOnClickListener(v -> {
profileId = profile.getId();
profileName = profile.getName();
configure(); configure();
}); });
for (Profile profile : profileList) { return b.getRoot();
adapter.add(
new MaterialSimpleListItem.Builder(this)
.id(profile.getId())
.content(profile.getName())
.icon(profile.getImageDrawable(this))
.backgroundColor(Color.WHITE)
.build());
} }
if (profileList.size() > 1 && widgetType != WIDGET_LUCKY_NUMBER) { };
adapter.add(
new MaterialSimpleListItem.Builder(this) new MaterialAlertDialogBuilder(this)
.id(-1) .setTitle(R.string.choose_profile)
.content(R.string.widget_config_all_profiles) .setAdapter(adapter, null)
.backgroundColor(Color.WHITE) .setOnDismissListener(dialog -> finish())
.build());
}
new MaterialDialog.Builder(this)
.title(R.string.choose_profile)
.adapter(adapter, null)
.dismissListener(dialog -> finish())
.show(); .show();
} }
private void configure() { private void configure() {
MaterialDialog dialog = new MaterialDialog.Builder(this) b = DialogWidgetConfigBinding.inflate(getLayoutInflater(), null, false);
.title(R.string.widget_config_activity_customize)
.customView(R.layout.dialog_widget_config, true) new MaterialAlertDialogBuilder(this)
.dismissListener(dialog1 -> finish()) .setTitle(R.string.widget_config_activity_customize)
.positiveText(R.string.ok) .setView(b.getRoot())
.negativeText(R.string.cancel) .setOnDismissListener(dialog -> finish())
.onPositive(((dialog1, which) -> { .setPositiveButton(R.string.ok, ((dialog, which) -> {
WidgetConfig config = new WidgetConfig(profileId, bigStyle, darkTheme, opacity); WidgetConfig config = new WidgetConfig(profileId, bigStyle, darkTheme, opacity);
JsonObject configs = app.getConfig().getWidgetConfigs(); JsonObject configs = app.getConfig().getWidgetConfigs();
configs.add(Integer.toString(mAppWidgetId), app.getGson().toJsonTree(config)); configs.add(Integer.toString(mAppWidgetId), app.getGson().toJsonTree(config));
@ -165,10 +206,9 @@ public class WidgetConfigActivity extends Activity {
setResult(RESULT_OK, resultValue); setResult(RESULT_OK, resultValue);
finish(); finish();
})) }))
.setNegativeButton(R.string.cancel, null)
.show(); .show();
b = DialogWidgetConfigBinding.bind(dialog.getCustomView());
b.setProfileName(profileName); b.setProfileName(profileName);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);

View File

@ -32,7 +32,7 @@ class WidgetNotificationsProvider : AppWidgetProvider() {
for (appWidgetId in appWidgetIds) { for (appWidgetId in appWidgetIds) {
val config = widgetConfigs.getJsonObject(appWidgetId.toString())?.let { app.gson.fromJson(it, WidgetConfig::class.java) } ?: continue val config = widgetConfigs.getJsonObject(appWidgetId.toString())?.let { app.gson.fromJson(it, WidgetConfig::class.java) } ?: continue
val iconSize = if (config.bigStyle) 24 else 16 val iconSize = if (config.bigStyle) 28 else 20
val views: RemoteViews = if (config.bigStyle) { val views: RemoteViews = if (config.bigStyle) {
RemoteViews(app.packageName, if (config.darkTheme) R.layout.widget_notifications_dark_big else R.layout.widget_notifications_big) RemoteViews(app.packageName, if (config.darkTheme) R.layout.widget_notifications_dark_big else R.layout.widget_notifications_big)

View File

@ -130,7 +130,7 @@ public class WidgetTimetableFactory implements RemoteViewsService.RemoteViewsFac
private Bitmap homeIconBitmap() { private Bitmap homeIconBitmap() {
return new IconicsDrawable(context).apply((drawable) -> { return new IconicsDrawable(context).apply((drawable) -> {
IconicsConvertersKt.setColorRes(drawable, R.color.md_red_500); IconicsConvertersKt.setColorRes(drawable, R.color.md_red_500);
IconicsConvertersKt.setSizeDp(drawable, 10); IconicsConvertersKt.setSizeDp(drawable, 14);
IconicsDrawableExtensionsKt.icon(drawable, CommunityMaterial.Icon2.cmd_home); IconicsDrawableExtensionsKt.icon(drawable, CommunityMaterial.Icon2.cmd_home);
return Unit.INSTANCE; return Unit.INSTANCE;
}).toBitmap(); }).toBitmap();

View File

@ -119,7 +119,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
R.id.widgetTimetableRefresh, R.id.widgetTimetableRefresh,
IconicsDrawable(context, CommunityMaterial.Icon3.cmd_refresh).apply { IconicsDrawable(context, CommunityMaterial.Icon3.cmd_refresh).apply {
colorInt = Color.WHITE colorInt = Color.WHITE
sizeDp = if (config.bigStyle) 24 else 16 sizeDp = if (config.bigStyle) 28 else 20
}.toBitmap() }.toBitmap()
) )
@ -127,7 +127,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
R.id.widgetTimetableSync, R.id.widgetTimetableSync,
IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline).apply { IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline).apply {
colorInt = Color.WHITE colorInt = Color.WHITE
sizeDp = if (config.bigStyle) 24 else 16 sizeDp = if (config.bigStyle) 28 else 20
}.toBitmap() }.toBitmap()
) )

View File

@ -1,114 +0,0 @@
package pl.szczodrzynski.edziennik.utils;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
public class BadgeDrawable extends Drawable {
private float mTextSize;
private Paint mBadgePaint;
private Paint mTextPaint;
private Rect mTxtRect = new Rect();
private String mCount = "";
private boolean mTextEnabled = true;
private boolean mWillDraw = false;
public BadgeDrawable(Context context) {
mTextSize = dpToPx(context, 11); //text size
mBadgePaint = new Paint();
mBadgePaint.setColor(Color.RED);
mBadgePaint.setAntiAlias(true);
mBadgePaint.setStyle(Paint.Style.FILL);
mTextPaint = new Paint();
mTextPaint.setColor(Color.WHITE);
mTextPaint.setTypeface(Typeface.DEFAULT);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setAntiAlias(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
private float dpToPx(Context context, float value) {
Resources r = context.getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, r.getDisplayMetrics());
return px;
}
@Override
public void draw(Canvas canvas) {
if (!mWillDraw) {
return;
}
Rect bounds = getBounds();
float width = bounds.right - bounds.left;
float height = bounds.bottom - bounds.top;
// Position the badge in the top-right quadrant of the icon.
/*Using Math.max rather than Math.min */
// float radius = ((Math.max(width, height) / 2)) / 2;
float radius = width * 0.15f;
float centerX = (width - radius - 1) +10;
float centerY = radius -5;
if (mTextEnabled) {
if(mCount.length() <= 2){
// Draw badge circle.
canvas.drawCircle(centerX, centerY, radius+13, mBadgePaint);
}
else{
canvas.drawCircle(centerX, centerY, radius+16, mBadgePaint);
}
// Draw badge count text inside the circle.
mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect);
float textHeight = mTxtRect.bottom - mTxtRect.top;
float textY = centerY + (textHeight / 2f);
if (mCount.length() > 2)
canvas.drawText("99+", centerX, textY, mTextPaint);
else
canvas.drawText(mCount, centerX, textY, mTextPaint);
}
else {
canvas.drawCircle(centerX, centerY, radius+5, mBadgePaint);
}
}
/*
Sets the count (i.e notifications) to display.
*/
public void setCount(String count) {
mCount = count;
// Only draw a badge if there are notifications.
mWillDraw = !count.equalsIgnoreCase("0");
invalidateSelf();
}
@Override
public void setAlpha(int alpha) {
// do nothing
}
public void setTextEnabled(boolean mTextEnabled) {
this.mTextEnabled = mTextEnabled;
}
@Override
public void setColorFilter(ColorFilter cf) {
// do nothing
}
@Override
public int getOpacity() {
return PixelFormat.UNKNOWN;
}
}

View File

@ -1,51 +0,0 @@
package pl.szczodrzynski.edziennik.utils;
import android.text.Editable;
import android.text.Html;
import android.text.Spannable;
import android.text.style.StrikethroughSpan;
import org.xml.sax.XMLReader;
public class SpannableHtmlTagHandler implements Html.TagHandler {
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
if(tag.equalsIgnoreCase("strike") || tag.equals("s") || tag.equals("del")) {
processStrike(opening, output);
}
}
private void processStrike(boolean opening, Editable output) {
int len = output.length();
if(opening) {
output.setSpan(new StrikethroughSpan(), len, len, Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, StrikethroughSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
if (where != len) {
output.setSpan(new StrikethroughSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private Object getLast(Editable text, Class kind) {
Object[] objs = text.getSpans(0, text.length(), kind);
if (objs.length == 0) {
return null;
} else {
for(int i = objs.length;i>0;i--) {
if(text.getSpanFlags(objs[i-1]) == Spannable.SPAN_MARK_MARK) {
return objs[i-1];
}
}
return null;
}
}
}

View File

@ -3,9 +3,11 @@ package pl.szczodrzynski.edziennik.utils
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.drawable.DrawableCompat
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import pl.szczodrzynski.edziennik.R import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
open class TextInputDropDown : TextInputEditText { open class TextInputDropDown : TextInputEditText {
constructor(context: Context) : super(context) { constructor(context: Context) : super(context) {
@ -32,11 +34,12 @@ open class TextInputDropDown : TextInputEditText {
} }
open fun create(context: Context) { open fun create(context: Context) {
val drawable = context.resources.getDrawable(R.drawable.dropdown_arrow) val drawable = IconicsDrawable(context, CommunityMaterial.Icon.cmd_chevron_down).apply {
val wrappedDrawable = DrawableCompat.wrap(drawable) colorInt = Themes.getPrimaryTextColor(context)
DrawableCompat.setTint(wrappedDrawable, Themes.getPrimaryTextColor(context)) sizeDp = 24
}
setCompoundDrawablesWithIntrinsicBounds(null, null, wrappedDrawable, null) setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null)
isFocusableInTouchMode = false isFocusableInTouchMode = false
isCursorVisible = false isCursorVisible = false
isLongClickable = false isLongClickable = false

View File

@ -70,6 +70,13 @@ public class Date implements Comparable<Date> {
return new Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH)); return new Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
} }
public static Date fromMillisUtc(long millis) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(millis);
c.setTimeZone(TimeZone.getTimeZone("UTC"));
return new Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
}
public static Date fromCalendar(Calendar c) { public static Date fromCalendar(Calendar c) {
return new Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH)); return new Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DAY_OF_MONTH));
} }
@ -94,6 +101,14 @@ public class Date implements Comparable<Date> {
return c.getTimeInMillis(); return c.getTimeInMillis();
} }
public long getInMillisUtc() {
Calendar c = Calendar.getInstance();
c.set(year, month - 1, day, 0, 0, 0);
c.set(Calendar.MILLISECOND, 0);
c.setTimeZone(TimeZone.getTimeZone("UTC"));
return c.getTimeInMillis();
}
public long getInUnix() { public long getInUnix() {
return getInMillis() / 1000; return getInMillis() / 1000;
} }

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:shareInterpolator="@android:anim/decelerate_interpolator"
tools:keep="@anim/down_from_top">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="-100%" android:toYDelta="0%"
android:duration="200" />
</set>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2017 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"/>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2014 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.4"
android:controlY1="0"
android:controlX2="1"
android:controlY2="1"/>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2014 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.4"
android:controlY1="0"
android:controlX2="0.2"
android:controlY2="1"/>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/linear_interpolator.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<linearInterpolator />

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:interpolator="@android:anim/linear_interpolator" android:duration="1000" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"
tools:keep="@anim/sync_rotate" />

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:interpolator="@android:anim/linear_interpolator" android:duration="100" android:fromDegrees="0" android:toDegrees="180" android:pivotX="50%" android:pivotY="50%"
tools:keep="@anim/sync_rotate_0_180" />

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:interpolator="@android:anim/linear_interpolator" android:duration="100" android:fromDegrees="180" android:toDegrees="0" android:pivotX="50%" android:pivotY="50%"
tools:keep="@anim/sync_rotate_180_0" />

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:shareInterpolator="@android:anim/decelerate_interpolator"
tools:keep="@anim/up_from_bottom">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="100%" android:toYDelta="0%"
android:duration="200" />
</set>

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="2dp" />
<solid android:color="#DEDEDE" />
<size
android:width="32dp"
android:height="4dp" />
</shape>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 B

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/ic_main_icon"
android:drawable="@mipmap/ic_launcher_foreground"
android:gravity="center" />
<!-- set a place holder Drawable so android:drawable isn't null -->
<item android:id="@+id/ic_badge"
android:drawable="@mipmap/ic_launcher_foreground" />
</layer-list>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<accelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:factor="2.0" />

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2017 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.2"
android:controlY1="0"
android:controlX2="0"
android:controlY2="1"/>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:factor="2.0" />

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2010, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:factor="2.5" />

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2014 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0.4"
android:controlY1="0"
android:controlX2="0.2"
android:controlY2="1"/>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/anim/linear_interpolator.xml
**
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<linearInterpolator />

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2014 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:controlX1="0"
android:controlY1="0"
android:controlX2="0.2"
android:controlY2="1"/>

View File

@ -101,15 +101,6 @@
android:text="@string/crash_details" android:text="@string/crash_details"
android:textColor="@color/colorPrimary" /> android:textColor="@color/colorPrimary" />
<Button
android:id="@+id/crash_dev_message_btn"
style="?borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/crash_dev_message"
android:textColor="@color/colorPrimary"
android:visibility="gone"/>
</LinearLayout> </LinearLayout>
<ImageView <ImageView

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/gtfo"
android:contentDescription="TODO" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -57,7 +57,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -66,7 +66,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -66,7 +66,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -77,7 +77,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:background="@android:drawable/ic_menu_more" /> tools:background="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -178,27 +178,27 @@
<ImageView <ImageView
android:id="@+id/settings" android:id="@+id/settings"
android:layout_width="40dp" android:layout_width="48dp"
android:layout_height="40dp" android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
android:padding="10dp" android:padding="12dp"
android:visibility="gone" android:visibility="gone"
tools:src="@sample/settings" /> tools:src="@sample/settings" />
<ImageView <ImageView
android:id="@+id/bellSync" android:id="@+id/bellSync"
android:layout_width="40dp" android:layout_width="48dp"
android:layout_height="40dp" android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
android:padding="10dp" android:padding="12dp"
tools:src="@sample/settings" /> tools:src="@sample/settings" />
<ImageView <ImageView
android:id="@+id/showCounter" android:id="@+id/showCounter"
android:layout_width="40dp" android:layout_width="48dp"
android:layout_height="40dp" android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
android:padding="10dp" android:padding="12dp"
tools:src="@sample/settings" /> tools:src="@sample/settings" />
</LinearLayout> </LinearLayout>

View File

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="@+id/cardUpdate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardElevation="4dp"
app:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.mikepenz.iconics.view.IconicsTextView
android:id="@+id/cardUpdateIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:text="{cmd-cloud-download}"
android:textSize="20sp"
app:fontFamily="sans-serif-condensed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:fontFamily="sans-serif-medium"
android:text="@string/card_update_title"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="@+id/cardUpdateIcon"
app:layout_constraintStart_toEndOf="@+id/cardUpdateIcon"
app:layout_constraintTop_toTopOf="@+id/cardUpdateIcon" />
<TextView
android:id="@+id/cardUpdateText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="8dp"
android:text="@string/card_update_text_format"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/cardUpdateIcon" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:textColorSecondary" />
<Button
android:id="@+id/cardUpdateButton"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:gravity="center_vertical|start"
android:minWidth="0dp"
android:minHeight="0dp"
android:padding="@dimen/card_button_padding"
android:text="@string/card_update_button" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</layout>

View File

@ -1,61 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/chatContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.github.bassaer.chatmessageview.view.MessageView
android:id="@+id/messageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="@android:color/transparent"
android:listSelector="@android:color/transparent"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurface"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/optionButtonContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</FrameLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="3" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/sendButton"
style="@style/Base.Widget.AppCompat.Button.Borderless"
android:layout_width="@dimen/icon_normal"
android:layout_height="@dimen/icon_normal"
android:layout_gravity="center"
android:contentDescription="@string/send"
android:src="@drawable/ic_action_send" />
</LinearLayout>
</LinearLayout>

View File

@ -1,16 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"
android:layout_height="match_parent"> android:orientation="vertical"
android:padding="24dp">
<TextView <TextView
android:id="@+id/text" android:id="@+id/text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:autoLink="web|email" android:autoLink="web|email"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textIsSelectable="true" android:textIsSelectable="true"
android:textSize="16sp" /> android:textSize="16sp" />
</LinearLayout> </ScrollView>
</layout>

View File

@ -1,13 +0,0 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingHorizontal="16dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
</FrameLayout>

View File

@ -132,7 +132,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-help-circle-outline" app:iiv_icon="cmd-help-circle-outline"
app:iiv_size="16dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_help" /> tools:src="@android:drawable/ic_menu_help" />
</LinearLayout> </LinearLayout>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/detailsLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/lessonChangeContainer"
layout="@layout/row_lesson_change_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="5dp"
android:visibility="gone"
tools:visibility="visible" />
<include
android:id="@+id/teacherAbsenceContainer"
layout="@layout/row_teacher_absence_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginVertical="5dp"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/eventListLessonDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:orientation="vertical">
<TextView
android:id="@+id/eventListLessonDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="21 października 2018, 9:05" />
<TextView
android:id="@+id/eventListLessonChange"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="italic"
tools:text="Lekcja odwołana" />
<TextView
android:id="@+id/eventListTeacher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="italic"
tools:text="Jan Kowalski -> John Doe" />
<TextView
android:id="@+id/eventListClassroom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="italic"
tools:text="029 informatyczna -> 016 językowa" />
</LinearLayout>
<TextView
android:id="@+id/textNoEvents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="32dp"
android:text="@string/dialog_event_list_no_data"
android:textStyle="italic"
android:visibility="gone" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/eventListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:clipToPadding="false"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
tools:listitem="@layout/row_dialog_event_list_item" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</layout>

View File

@ -1,232 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_event_manual_date_header"
android:textAllCaps="true"
android:textColor="?attr/colorAccent"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/section_underline_height"
android:layout_marginTop="2dp"
android:background="?attr/colorAccent" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/registerEventManualDateLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_date"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/registerEventManualLessonLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/dialog_event_manual_lesson"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualLesson"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/registerEventManualTeamLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/dialog_event_manual_team"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualTeam"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/registerEventManualShare"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:text="@string/dialog_event_manual_share_enabled" />
<TextView
android:id="@+id/registerEventManualShareText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:text="@string/dialog_event_manual_share_first_notice"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_homework_manual_details_header"
android:textAllCaps="true"
android:textColor="?attr/colorAccent"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="@dimen/section_underline_height"
android:layout_marginTop="2dp"
android:background="?attr/colorAccent" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/registerEventManualTypeLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_type"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip" />
</com.google.android.material.textfield.TextInputLayout>
<LinearLayout
android:layout_width="0px"
android:layout_height="0px"
android:focusable="true"
android:focusableInTouchMode="true" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/registerEventManualTopicLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/dialog_event_manual_topic"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/registerEventManualTopic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textMultiLine|textPersonName"
android:maxLines="5"
android:singleLine="false" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/registerEventManualColorPreview"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.button.MaterialButton
android:id="@+id/registerEventManualColorChoose"
style="@style/Widget.MaterialComponents.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:text="@string/dialog_event_manual_change_color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/registerEventManualColorPreview"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_teacher"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualTeacher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip"
android:text="@string/dialog_event_manual_no_teacher" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/dialog_event_manual_subject"
app:errorEnabled="true"
app:hintAnimationEnabled="true"
app:hintEnabled="true">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/registerEventManualSubject"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="6.0dip"
android:paddingRight="6.0dip"
android:text="@string/dialog_event_manual_no_subject" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>

View File

@ -145,11 +145,11 @@
app:iiv_end_icon="cmd-chevron-down" app:iiv_end_icon="cmd-chevron-down"
app:iiv_end_color="?android:textColorSecondary" app:iiv_end_color="?android:textColorSecondary"
app:iiv_end_size="16dp" app:iiv_end_size="24dp"
app:iiv_end_checked_icon="cmd-chevron-up" app:iiv_end_checked_icon="cmd-chevron-up"
app:iiv_end_checked_color="?android:textColorSecondary" app:iiv_end_checked_color="?android:textColorSecondary"
app:iiv_end_checked_size="16dp"/> app:iiv_end_checked_size="24dp"/>
<LinearLayout <LinearLayout
android:id="@+id/moreLayout" android:id="@+id/moreLayout"

View File

@ -23,6 +23,7 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="false"
android:orientation="vertical" android:orientation="vertical"
android:paddingHorizontal="24dp" android:paddingHorizontal="24dp"
android:paddingTop="24dp"> android:paddingTop="24dp">
@ -30,7 +31,8 @@
<FrameLayout <FrameLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"> android:layout_gravity="center_horizontal"
android:clipChildren="false">
<com.mikepenz.materialdrawer.view.BezelImageView <com.mikepenz.materialdrawer.view.BezelImageView
android:id="@+id/image" android:id="@+id/image"
@ -56,12 +58,12 @@
app:iiv_padding="5dp" app:iiv_padding="5dp"
tools:background="@color/colorSurface_16dp" /> tools:background="@color/colorSurface_16dp" />
<View <FrameLayout
android:id="@+id/imageButton" android:id="@+id/imageButton"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:background="?selectableItemBackgroundBorderless" /> android:foreground="?selectableItemBackgroundBorderless" />
</FrameLayout> </FrameLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
@ -85,9 +87,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:text="@{profile.subname}"
android:textAppearance="@style/NavView.TextView.Subtitle" android:textAppearance="@style/NavView.TextView.Subtitle"
android:textColor="?android:textColorSecondary" android:textColor="?android:textColorSecondary"
android:text="@{profile.subname}"
tools:text="3b3t - 2020/2021" /> tools:text="3b3t - 2020/2021" />
<com.google.android.material.switchmaterial.SwitchMaterial <com.google.android.material.switchmaterial.SwitchMaterial
@ -95,8 +97,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/profile_config_sync_enabled" android:checked="@={profile.syncEnabled}"
android:checked="@={profile.syncEnabled}" /> android:text="@string/profile_config_sync_enabled" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/logoutButton" android:id="@+id/logoutButton"

View File

@ -2,21 +2,29 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="android.view.View" /> <import type="android.view.View" />
<variable <variable
name="profileName" name="profileName"
type="String" /> type="String" />
</data> </data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:padding="24dp">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper" android:textAppearance="@style/NavView.TextView.Helper"
android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}" android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}"
android:text="@string/dialog_widget_config_profile" /> android:text="@string/dialog_widget_config_profile" />
@ -116,8 +124,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/widget_timetable_preview" /> app:srcCompat="@drawable/widget_timetable_preview" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
</layout> </layout>

View File

@ -1,203 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_weight="2"
android:orientation="vertical">
<TextView
android:id="@+id/attendanceSummaryTitle"
style="@style/Widget.AppCompat.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="@string/attendances_summary_title_loading_format"
android:textSize="20sp" />
<TextView
android:id="@+id/attendanceSummarySubject"
style="@style/Widget.AppCompat.Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="@string/subject_filter_disabled"
android:textSize="20sp" />
<LinearLayout
android:id="@+id/presentCountContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attendances_present" />
<TextView
android:id="@+id/presentCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:textStyle="bold"
tools:text="0" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attendances_absent" />
<TextView
android:id="@+id/absentCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:textStyle="bold"
tools:text="0" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attendances_absent_unexcused" />
<TextView
android:id="@+id/absentUnexcusedCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:textStyle="bold"
tools:text="0" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attendances_belated" />
<TextView
android:id="@+id/belatedCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:textStyle="bold"
tools:text="0" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/attendances_releases" />
<TextView
android:id="@+id/releasedCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="5dp"
android:textStyle="bold"
tools:text="8" />
</LinearLayout>
</LinearLayout>
<antonkozyriatskyi.circularprogressindicator.CircularProgressIndicator
android:id="@+id/attendancePercentage"
android:layout_width="160dp"
android:layout_height="160dp"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
app:direction="clockwise"
app:drawDot="false"
app:progressBackgroundStrokeWidth="11dp"
app:progressStrokeWidth="12dp"
app:textSize="18sp" />
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/attendance_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
tools:listitem="@layout/row_attendance_item">
</androidx.recyclerview.widget.RecyclerView>
<LinearLayout
android:id="@+id/attendance_no_data"
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="match_parent"
android:layout_height="92dp"
app:iiv_icon="cmd-calendar-check"
app:iiv_color="?android:textColorPrimary"
app:iiv_size="92dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="@string/attendances_no_data"
android:textSize="18sp"
android:textStyle="italic" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
</layout>

View File

@ -1,48 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/gradesRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
<LinearLayout
android:id="@+id/gradesNoData"
android:layout_width="match_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="match_parent"
android:layout_height="92dp"
app:iiv_icon="szf-numeric-0-box-multiple-outline-off"
app:iiv_color="?android:textColorPrimary"
app:iiv_size="92dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="@string/grades_no_data"
android:textSize="18sp"
android:textStyle="italic" />
</LinearLayout>
</FrameLayout>
</layout>

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</LinearLayout>
</ScrollView>
</layout>

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorSurface_6dp"
app:tabIndicatorColor="?colorPrimary"
app:tabMode="auto"
app:tabSelectedTextColor="?colorPrimary"
app:tabTextColor="?android:textColorPrimary"/>
<pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</LinearLayout>
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
</layout>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/messagesWebView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
<ProgressBar
android:id="@+id/messagesWebProgressBar"
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/messagesWebError"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="18sp"
android:textStyle="italic"
android:visibility="gone"
tools:text="Błąd" />
</FrameLayout>
</layout>

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorSurface"
style="@style/Widget.MaterialComponents.AppBarLayout.Surface">
<com.google.android.material.tabs.TabLayout
android:id="@+id/result_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorSurface_6dp"
app:tabIndicatorColor="?colorPrimary"
app:tabMode="scrollable"
app:tabSelectedTextColor="?colorPrimary"
app:tabTextColor="?android:textColorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>
</layout>

View File

@ -1,94 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/timetableView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
<LinearLayout
android:id="@+id/timetableNoData"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="gone">
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="match_parent"
android:layout_height="92dp"
app:iiv_color="?android:textColorPrimary"
app:iiv_icon="cmd-timetable"
app:iiv_size="92dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:text="@string/timetable_no_data"
android:textSize="18sp"
android:textStyle="italic" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
android:orientation="vertical"
android:visibility="gone"
android:gravity="center"
tools:visibility="visible">
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_sunbed" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:fontFamily="sans-serif-light"
android:gravity="center"
android:text="Dzień wolny"
android:textSize="24sp" />
<TextView
android:id="@+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="16dp"
android:text="W tym dniu nie ma lekcji: \nFerie zimowe"
android:textSize="14sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
style="@style/Widget.MaterialComponents.Button"
android:layout_gravity="center"
android:text="Pokaż plan lekcji" />
</LinearLayout>
</FrameLayout>
</layout>

View File

@ -24,7 +24,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="16dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
<TextView <TextView
@ -85,7 +85,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-playlist-edit" app:iiv_icon="cmd-playlist-edit"
app:iiv_size="16dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_edit" /> tools:src="@android:drawable/ic_menu_edit" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@ -167,7 +167,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-help-circle-outline" app:iiv_icon="cmd-help-circle-outline"
app:iiv_size="16dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_help" /> tools:src="@android:drawable/ic_menu_help" />
<View <View

View File

@ -57,7 +57,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -47,7 +47,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>

View File

@ -42,7 +42,7 @@
android:scaleType="centerInside" android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down" app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp" app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" /> tools:src="@android:drawable/ic_menu_more" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@ -106,7 +106,7 @@
android:layout_height="24dp" android:layout_height="24dp"
app:iiv_color="?colorOnError" app:iiv_color="?colorOnError"
app:iiv_icon="cmd-alert-circle-outline" app:iiv_icon="cmd-alert-circle-outline"
app:iiv_size="20dp" /> app:iiv_size="24dp" />
<TextView <TextView
android:id="@+id/errorText" android:id="@+id/errorText"

View File

@ -60,6 +60,6 @@
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
app:iiv_color="?colorOnBackground" app:iiv_color="?colorOnBackground"
app:iiv_icon="cmd-image-search-outline" app:iiv_icon="cmd-image-search-outline"
app:iiv_size="36dp" /> app:iiv_size="40dp" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:ignore="PrivateResource"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:focusable="true"
android:gravity="start|center_vertical"
android:minHeight="@dimen/md_simpleitem_height"
android:orientation="horizontal"
android:paddingHorizontal="@dimen/md_dialog_frame_margin">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/md_simplelist_icon_margin"
android:layout_marginRight="@dimen/md_simplelist_icon_margin"
android:innerRadius="0dp"
android:padding="0dp"
app:cardCornerRadius="20dp"
app:cardElevation="4dp">
<ImageView
android:id="@android:id/icon"
android:layout_width="@dimen/md_simplelist_icon"
android:layout_height="@dimen/md_simplelist_icon"
android:layout_gravity="start|center_vertical"
android:background="@drawable/gray_circle"
android:scaleType="centerCrop"
tools:background="#f5f5f5"
tools:ignore="ContentDescription"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="@dimen/md_simplelist_textsize"
tools:text="Title" />
</LinearLayout>

View File

@ -204,7 +204,6 @@
android:id="@+id/replyIcon" android:id="@+id/replyIcon"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-reply-outline" app:iiv_icon="cmd-reply-outline"
tools:srcCompat="@android:drawable/ic_menu_revert" /> tools:srcCompat="@android:drawable/ic_menu_revert" />
@ -234,7 +233,6 @@
android:id="@+id/forwardIcon" android:id="@+id/forwardIcon"
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-arrow-right" app:iiv_icon="cmd-arrow-right"
tools:srcCompat="@android:drawable/ic_media_ff" /> tools:srcCompat="@android:drawable/ic_media_ff" />
@ -265,7 +263,6 @@
<com.mikepenz.iconics.view.IconicsImageView <com.mikepenz.iconics.view.IconicsImageView
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-delete-outline" app:iiv_icon="cmd-delete-outline"
tools:srcCompat="@android:drawable/ic_menu_delete" /> tools:srcCompat="@android:drawable/ic_menu_delete" />
@ -295,7 +292,6 @@
<com.mikepenz.iconics.view.IconicsImageView <com.mikepenz.iconics.view.IconicsImageView
android:layout_width="24dp" android:layout_width="24dp"
android:layout_height="24dp" android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary" app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-download-outline" app:iiv_icon="cmd-download-outline"
tools:srcCompat="@android:drawable/ic_menu_delete" /> tools:srcCompat="@android:drawable/ic_menu_delete" />

View File

@ -1,359 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transitionName="@string/transition_name">
<LinearLayout
android:id="@+id/messageToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:orientation="horizontal"
android:background="@color/colorSurface_6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageButton
android:id="@+id/messageClose"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="2dp"
android:background="?android:attr/actionBarItemBackground"
app:srcCompat="@android:drawable/ic_delete" />
<TextView
android:id="@+id/messageSubject"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:animateLayoutChanges="true"
android:background="?selectableItemBackground"
android:ellipsize="end"
android:maxLines="2"
android:padding="16dp"
android:textAppearance="@style/NavView.TextView.Title"
tools:ignore="HardcodedText"
tools:text="mobiDziennik - raport dzienny." />
</LinearLayout>
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@drawable/shadow_top"
app:layout_constraintTop_toBottomOf="@+id/messageToolbar"
tools:layout_editor_absoluteX="0dp" />
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ScrollView
android:id="@+id/messageContent"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<ImageView
android:id="@+id/messageProfileBackground"
android:layout_width="64dp"
android:layout_height="64dp"
android:padding="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bg_circle" />
<TextView
android:id="@+id/messageProfileName"
android:layout_width="64dp"
android:layout_height="64dp"
android:fontFamily="sans-serif"
android:gravity="center"
android:padding="12dp"
android:textColor="#ffffff"
android:textSize="20sp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="JP"
tools:visibility="visible" />
<ImageView
android:id="@+id/messageProfileImage"
android:layout_width="64dp"
android:layout_height="64dp"
android:padding="12dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars[0]" />
<TextView
android:id="@+id/messageSender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:ellipsize="end"
android:maxLines="3"
android:paddingHorizontal="8dp"
android:paddingTop="12dp"
android:textAppearance="@style/NavView.TextView.Subtitle"
app:layout_constraintEnd_toStartOf="@+id/messageDate"
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
app:layout_constraintTop_toTopOf="parent"
tools:text="Allegro - wysyłamy duużo wiadomości!!! Masz nowe oferty! Możesz kupić nowego laptopa! Ale super! Ehh, to jest nadawca a nie temat więc nwm czemu to tutaj wpisałem" />
<TextView
android:id="@+id/messageDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:textAppearance="@style/NavView.TextView.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="14:26" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/messageBody"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:autoLink="all"
android:minHeight="250dp"
android:paddingHorizontal="16dp"
android:textIsSelectable="true"
tools:text="To jest treść wiadomości.\n\nZazwyczaj ma wiele linijek.\n\nTak" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="?colorControlHighlight" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:text="Odbiorcy wiadomości:"
android:textAppearance="@style/NavView.TextView.Subtitle" />
<TextView
android:id="@+id/messageRecipients"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
tools:text=" - Jan Kowalski, przeczytano: nie\n - Adam Dodatkowy, przeczytano: 20 marca, 17:35" />
<TextView
android:id="@+id/messageAttachmentsTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:text="Załączniki:"
android:textAppearance="@style/NavView.TextView.Subtitle" />
<LinearLayout
android:id="@+id/messageAttachments"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingBottom="8dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible">
<com.google.android.material.chip.Chip
android:id="@+id/chip3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:text="Testowy plik.pdf"
android:visibility="visible"
app:chipBackgroundColor="@color/mtrl_chip_background_color"
app:chipIcon="@drawable/googleg_standard_color_18"
app:chipMinHeight="36dp"
app:chipSurfaceColor="@color/mtrl_chip_surface_color"
app:closeIcon="@drawable/ic_error_outline"
app:closeIconVisible="true" />
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyle"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center_vertical|end"
android:layout_marginHorizontal="8dp" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
tools:visibility="visible">
<com.google.android.material.chip.Chip
android:id="@+id/chip4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:text="Wyniki sprawdzianu z matematyki.pdf"
android:visibility="visible"
app:chipIcon="@drawable/googleg_standard_color_18"
app:chipMinHeight="36dp"
app:closeIcon="@drawable/background_transparent"
app:closeIconVisible="true"/>
<ProgressBar
android:id="@+id/progressBar3"
style="?android:attr/progressBarStyle"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center_vertical|end"
android:layout_marginHorizontal="8dp" />
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="8dp"
android:orientation="horizontal"
android:visibility="gone"
tools:visibility="visible">
<LinearLayout
android:id="@+id/messageReplyButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="4dp"
android:layout_weight="1"
android:background="@drawable/bg_rounded_ripple"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="4dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Odpowiedz"
android:textAppearance="@style/NavView.TextView.Small" />
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-reply"
tools:srcCompat="@android:drawable/ic_menu_revert" />
</LinearLayout>
<LinearLayout
android:id="@+id/messageForwardButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="4dp"
android:layout_weight="1"
android:background="@drawable/bg_rounded_ripple"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="4dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Przekaż dalej"
android:textAllCaps="false"
android:textAppearance="@style/NavView.TextView.Small" />
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-share"
tools:srcCompat="@android:drawable/ic_media_ff" />
</LinearLayout>
<LinearLayout
android:id="@+id/messageRemoveButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="4dp"
android:layout_weight="1"
android:background="@drawable/bg_rounded_ripple"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="4dp"
android:paddingVertical="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Usuń"
android:textAppearance="@style/NavView.TextView.Small" />
<com.mikepenz.iconics.view.IconicsImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-delete"
tools:srcCompat="@android:drawable/ic_menu_delete" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<ImageView
android:id="@+id/messageProfileBackground"
android:layout_width="72dp"
android:layout_height="72dp"
android:padding="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/bg_circle" />
<TextView
android:id="@+id/messageProfileName"
android:layout_width="72dp"
android:layout_height="72dp"
android:gravity="center"
android:padding="12dp"
android:textColor="#ffffff"
android:textSize="24sp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="JP"
tools:visibility="visible" />
<!--<ImageView
android:id="@+id/messageProfileImage"
android:layout_width="72dp"
android:layout_height="72dp"
android:padding="12dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars[13]" />-->
<com.mikepenz.iconics.view.IconicsImageView
android:id="@+id/messageAttachmentImage"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:adjustViewBounds="true"
android:paddingVertical="2dp"
android:scaleType="fitCenter"
app:iiv_icon="cmd-attachment"
app:iiv_color="?android:textColorSecondary"
app:layout_constraintBottom_toBottomOf="@+id/messageDate"
app:layout_constraintEnd_toStartOf="@+id/messageDate"
app:layout_constraintTop_toTopOf="@+id/messageDate"
tools:srcCompat="@tools:sample/avatars[4]" />
<TextView
android:id="@+id/messageSubject"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:singleLine="true"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
app:layout_constraintTop_toBottomOf="@+id/messageSender"
tools:text="Nowe oferty w Twoich obserwowanych wyszukiwaniach" />
<TextView
android:id="@+id/messageSender"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="4dp"
android:layout_marginRight="4dp"
android:ellipsize="end"
android:maxLines="2"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/messageAttachmentImage"
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
app:layout_constraintTop_toTopOf="parent"
tools:text="Allegro" />
<TextView
android:id="@+id/messageBody"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:layout_marginBottom="12dp"
android:singleLine="true"
android:textAppearance="@style/NavView.TextView.Helper"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/messageProfileBackground"
app:layout_constraintTop_toBottomOf="@+id/messageSubject"
tools:text="Znajdź produkty, których szukasz. Witaj Jan Kowalski (Client" />
<TextView
android:id="@+id/messageDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="02:00" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/emailList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:transitionGroup="false"
tools:listitem="@layout/messages_item"
tools:targetApi="lollipop" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</FrameLayout>
</layout>

View File

@ -1,93 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="8dp">
<TextView
android:id="@+id/attendanceType"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:background="@drawable/bg_rounded_8dp"
android:gravity="center"
android:textColor="@color/black"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="nb" />
<TextView
android:id="@+id/attendanceLessonTopic"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:ellipsize="marquee"
android:focusableInTouchMode="false"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintEnd_toStartOf="@+id/attendanceDate"
app:layout_constraintStart_toStartOf="@+id/attendanceSubject"
app:layout_constraintTop_toTopOf="parent"
tools:text="Podstawy języka C."
android:layout_marginRight="8dp" />
<TextView
android:id="@+id/attendanceSubject"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
app:layout_constraintEnd_toStartOf="@+id/attendanceDate"
app:layout_constraintStart_toEndOf="@+id/attendanceType"
app:layout_constraintTop_toBottomOf="@+id/attendanceLessonTopic"
tools:text="podstawy programowania" />
<TextView
android:id="@+id/attendanceTeacher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="8dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/NavView.TextView.Helper"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/attendanceDate"
app:layout_constraintStart_toEndOf="@+id/attendanceType"
app:layout_constraintTop_toBottomOf="@+id/attendanceSubject"
tools:text="Piotr Matematyczny" />
<TextView
android:id="@+id/attendanceTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="0dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:textAppearance="@style/NavView.TextView.Helper"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/attendanceLessonTopic"
tools:text="11:05" />
<TextView
android:id="@+id/attendanceDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
tools:text="19.11.2018"
android:textAppearance="@style/NavView.TextView.Helper"
app:layout_constraintBottom_toBottomOf="@+id/attendanceLessonTopic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/attendanceLessonTopic" />
</androidx.constraintlayout.widget.ConstraintLayout>

Some files were not shown because too many files have changed in this diff Show More