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

View File

@ -123,9 +123,6 @@
android:configChanges="orientation|screenSize|keyboardHidden"
android:process=":error_activity"
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"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
@ -180,13 +177,6 @@
____) | __/ | \ 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.firebase.MyFirebaseService"
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.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.network.NetworkUtils
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
import pl.szczodrzynski.edziennik.sync.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateWorker
@ -89,7 +88,6 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.build()
val permissionChecker by lazy { PermissionChecker(this) }
val networkUtils by lazy { NetworkUtils(this) }
val gson by lazy { Gson() }
/* _ _ _______ _______ _____
@ -166,6 +164,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.errorActivity(CrashActivity::class.java)
.apply()
Iconics.init(applicationContext)
Iconics.respectFontBoundsDefault = true
// initialize companion object values
App.db = AppDb(this)

View File

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

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

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

View File

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

View File

@ -14,7 +14,7 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import org.greenrobot.eventbus.EventBus;
@ -120,7 +120,7 @@ public class AnnouncementsFragment extends Fragment {
return;
}*/
AnnouncementsAdapter announcementsAdapter = new AnnouncementsAdapter(activity, announcements, (v, announcement) -> {
if (announcement.getText() == null || (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.getSeen() && app.getNetworkUtils().isOnline())) {
if (announcement.getText() == null || (app.getProfile().getLoginStoreType() == LOGIN_TYPE_LIBRUS && !announcement.getSeen())) {
EdziennikTask.Companion.announcementGet(App.Companion.getProfileId(), announcement).enqueue(requireContext());
} else {
showAnnouncementDetailsDialog(announcement);
@ -161,12 +161,12 @@ public class AnnouncementsFragment extends Fragment {
}
private void showAnnouncementDetailsDialog(AnnouncementFull announcement) {
MaterialDialog dialog = new MaterialDialog.Builder(activity)
.title(announcement.getSubject())
.customView(R.layout.dialog_announcement, true)
.positiveText(R.string.ok)
DialogAnnouncementBinding b = DialogAnnouncementBinding.inflate(LayoutInflater.from(activity), null, false);
new MaterialAlertDialogBuilder(activity)
.setTitle(announcement.getSubject())
.setView(b.getRoot())
.setPositiveButton(R.string.ok, null)
.show();
DialogAnnouncementBinding b = DialogAnnouncementBinding.bind(dialog.getCustomView());
b.text.setText(announcement.getTeacherName() +"\n\n"+ (announcement.getStartDate() != null ? announcement.getStartDate().getFormattedString() : "-") + (announcement.getEndDate() != null ? " do " + announcement.getEndDate().getFormattedString() : "")+"\n\n" +announcement.getText());
if (!announcement.getSeen() && app.getProfile().getLoginStoreType() != LOGIN_TYPE_LIBRUS) {
announcement.setSeen(true);

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 androidx.appcompat.app.AppCompatActivity
import cat.ereza.customactivityoncrash.CustomActivityOnCrash
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.BuildConfig
@ -69,47 +69,31 @@ class CrashActivity : AppCompatActivity(), CoroutineScope {
val restartButton = findViewById<Button>(R.id.crash_restart_btn)
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)
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 {
api.runCatching({
withContext(Dispatchers.Default) {
errorReport(listOf(getReportableError(intent)))
}
}, {
Toast.makeText(app, getString(R.string.crash_report_cannot_send) + it, Toast.LENGTH_LONG).show()
}) ?: return@launch
launch {
api.runCatching({
withContext(Dispatchers.Default) {
errorReport(listOf(getReportableError(intent)))
}
}, {
Toast.makeText(app, getString(R.string.crash_report_cannot_send) + it, Toast.LENGTH_LONG).show()
}) ?: return@launch
Toast.makeText(app, getString(R.string.crash_report_sent), Toast.LENGTH_SHORT).show()
reportButton.isEnabled = false
reportButton.setTextColor(resources.getColor(android.R.color.darker_gray))
}
Toast.makeText(app, getString(R.string.crash_report_sent), Toast.LENGTH_SHORT).show()
reportButton.isEnabled = false
reportButton.setTextColor(resources.getColor(android.R.color.darker_gray))
}
}
val moreInfoButton = findViewById<Button>(R.id.crash_details_btn)
moreInfoButton.setOnClickListener { v: View? ->
MaterialDialog.Builder(this@CrashActivity)
.title(R.string.crash_details)
.content(Html.fromHtml(getErrorString(intent, false)))
.typeface(null, "RobotoMono-Regular.ttf")
.positiveText(R.string.close)
.neutralText(R.string.copy_to_clipboard)
.onNeutral { _, _ -> copyErrorToClipboard() }
.show()
moreInfoButton.setOnClickListener {
MaterialAlertDialogBuilder(this, R.style.AppTheme_MaterialAlertDialogMonospace)
.setTitle(R.string.crash_details)
.setMessage(Html.fromHtml(getErrorString(intent, false)))
.setPositiveButton(R.string.close, null)
.setNeutralButton(R.string.copy_to_clipboard) { _, _ -> copyErrorToClipboard() }
.show()
}
val errorInformation = CustomActivityOnCrash.getAllErrorDetailsFromIntent(this@CrashActivity, intent)

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.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.gson.Gson;
import com.yuyh.jsonviewer.library.JsonRecyclerView;
@ -211,10 +211,10 @@ public class DebugFragment extends Fragment {
mRecyclerView.bindJson(result);
}
catch (Exception e) {
new MaterialDialog.Builder(getActivity())
.title("Result")
.content(result)
.positiveText(R.string.ok)
new MaterialAlertDialogBuilder(getActivity(), R.style.AppTheme_MaterialAlertDialogMonospace)
.setTitle("Result")
.setMessage(result)
.setPositiveButton(R.string.ok, null)
.show();
}
mRecyclerView.setTextSize(20);

View File

@ -10,7 +10,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -18,6 +18,7 @@ import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.models.ApiError
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.utils.SimpleDividerItemDecoration
import kotlin.coroutines.CoroutineContext
@ -87,51 +88,55 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
else -> objVal.toString()
}
MaterialDialog.Builder(activity)
.input("value", value, false) { _, input ->
val input = input.toString()
when (parent) {
is JsonObject -> {
val v = objVal as JsonPrimitive
when {
v.isString -> (parent as JsonObject)[objName] = input
v.isNumber -> (parent as JsonObject)[objName] = input.toLong()
v.isBoolean -> (parent as JsonObject)[objName] = input.toBoolean()
MaterialAlertDialogBuilder(activity)
.setTitle(item.key)
.input(
hint = "value",
value = value,
positiveButton = R.string.ok,
positiveListener = { _, input ->
when (parent) {
is JsonObject -> {
val v = objVal as JsonPrimitive
when {
v.isString -> (parent as JsonObject)[objName] = input
v.isNumber -> (parent as JsonObject)[objName] = input.toLong()
v.isBoolean -> (parent as JsonObject)[objName] = input.toBoolean()
}
}
is JsonArray -> {
}
is HashMap<*, *> -> app.config.set(objName, input)
else -> {
val field = parent::class.java.getDeclaredField(objName)
field.isAccessible = true
val newVal = when (objVal) {
is Int -> input.toInt()
is Boolean -> input.toBoolean()
is Float -> input.toFloat()
is Char -> input.toCharArray()[0]
is String -> input
is Long -> input.toLong()
is Double -> input.toDouble()
else -> input
}
field.set(parent, newVal)
}
}
is JsonArray -> {
when (item.key.substringBefore(":")) {
"App.profile" -> app.profileSave()
"App.profile.studentData" -> app.profileSave()
"App.profile.loginStore" -> app.db.loginStoreDao().add(loginStore)
}
is HashMap<*, *> -> app.config.set(objName, input)
else -> {
val field = parent::class.java.getDeclaredField(objName)
field.isAccessible = true
val newVal = when (objVal) {
is Int -> input.toInt()
is Boolean -> input.toBoolean()
is Float -> input.toFloat()
is Char -> input.toCharArray()[0]
is String -> input
is Long -> input.toLong()
is Double -> input.toDouble()
else -> input
}
field.set(parent, newVal)
}
showJson()
return@input true
}
when (item.key.substringBefore(":")) {
"App.profile" -> app.profileSave()
"App.profile.studentData" -> app.profileSave()
"App.profile.loginStore" -> app.db.loginStoreDao().add(loginStore)
}
showJson()
}
.title(item.key)
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
)
.setNegativeButton(R.string.cancel, null)
.show()
}
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.lifecycle.Observer
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.data.db.entity.Grade
import pl.szczodrzynski.edziennik.databinding.FragmentGradesEditorBinding
import pl.szczodrzynski.edziennik.ui.dialogs.input
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_SEM
@ -72,12 +73,11 @@ class GradesEditorFragment : Fragment() {
semester = arguments.getInt("semester", 1)
if (subjectId == -1L) {
MaterialDialog.Builder(activity)
.title(R.string.error_occured)
.content(R.string.error_no_subject_id)
.positiveText(R.string.ok)
.onPositive { _, _ -> activity.navigateUp() }
.show()
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.error_occured)
.setMessage(R.string.error_no_subject_id)
.setPositiveButton(R.string.ok) { _, _ -> activity.navigateUp() }
.show()
return
}
@ -193,12 +193,11 @@ class GradesEditorFragment : Fragment() {
app.db.subjectDao().getById(App.profileId, subjectId).observe(this, Observer { subject ->
if (subject == null || subject.id == -1L) {
MaterialDialog.Builder(activity)
.title(R.string.error_occured)
.content(R.string.error_no_subject_id)
.positiveText(R.string.ok)
.onPositive { _, _ -> activity.navigateUp() }
.show()
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.error_occured)
.setMessage(R.string.error_no_subject_id)
.setPositiveButton(R.string.ok) { _, _ -> activity.navigateUp() }
.show()
return@Observer
}
@ -329,21 +328,24 @@ class GradesEditorFragment : Fragment() {
popup.setOnMenuItemClickListener { item ->
if (item.itemId == 100) {
MaterialDialog.Builder(v.context)
.title(R.string.grades_editor_add_grade_title)
.content(R.string.grades_editor_add_grade_weight)
.inputType(InputType.TYPE_NUMBER_FLAG_SIGNED)
.input(null, null) { _, input ->
MaterialAlertDialogBuilder(v.context)
.setTitle(R.string.grades_editor_add_grade_title)
.input(
message = v.context.getString(R.string.grades_editor_add_grade_weight),
type = InputType.TYPE_NUMBER_FLAG_SIGNED,
positiveButton = R.string.ok,
positiveListener = { _, input ->
try {
editorGrade.weight = input.toString().toFloat()
editorGrade.weight = input.toFloat()
callback()
} catch (e: Exception) {
e.printStackTrace()
}
true
}
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.show()
)
.setNegativeButton(R.string.cancel, null)
.show()
} else {
editorGrade.weight = item.itemId.toFloat()
callback()

View File

@ -90,21 +90,21 @@ class HomeTimetableCard(
b.settings.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon.cmd_cog_outline).apply {
colorAttr(activity, R.attr.colorIcon)
sizeDp = 20
sizeDp = 24
}
)
b.bellSync.setImageDrawable(
IconicsDrawable(activity, SzkolnyFont.Icon.szf_alarm_bell_outline).apply {
colorAttr(activity, R.attr.colorIcon)
sizeDp = 20
sizeDp = 24
}
)
b.showCounter.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon2.cmd_fullscreen).apply {
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 com.google.android.material.textfield.TextInputLayout
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -100,7 +99,6 @@ class LoginFormFragment : Fragment(), CoroutineScope {
b.textLayout.startIconDrawable = IconicsDrawable(activity).apply {
icon = credential.icon
sizeDp = 24
paddingDp = 2
colorAttr(activity, R.attr.colorOnBackground)
}

View File

@ -67,7 +67,7 @@ class MessageFragment : Fragment(), CoroutineScope {
b.closeButton.setImageDrawable(
IconicsDrawable(activity, CommunityMaterial.Icon3.cmd_window_close).apply {
colorAttr(activity, android.R.attr.textColorSecondary)
sizeDp = 12
sizeDp = 16
}
)
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
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.databinding.FragmentProfileManagerBinding
import pl.szczodrzynski.edziennik.utils.Themes
@ -26,8 +25,6 @@ class ProfileManagerFragment : Fragment() {
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 = FragmentProfileManagerBinding.inflate(inflater)
b.refreshLayout.setParent(activity.swipeRefreshLayout)

View File

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

View File

@ -25,7 +25,7 @@ class SettingsUtil(
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 {
icon = this@asDrawable
sizeDp = size
@ -66,7 +66,7 @@ class SettingsUtil(
val moreItem = MaterialAboutActionItem.Builder()
.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()
moreItem.setOnClickAction {

View File

@ -16,8 +16,8 @@ import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.google.android.material.datepicker.MaterialDatePicker
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import eu.szkolny.font.SzkolnyFont
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App
@ -25,7 +25,7 @@ import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
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.timetable.GenerateBlockTimetableDialog
import pl.szczodrzynski.edziennik.utils.models.Date
@ -167,19 +167,23 @@ class TimetableFragment : Fragment(), CoroutineScope {
BottomSheetPrimaryItem(true)
.withTitle(R.string.timetable_select_day)
.withIcon(SzkolnyFont.Icon.szf_calendar_today_outline)
.withOnClickListener(View.OnClickListener {
.withOnClickListener { _ ->
activity.bottomSheet.close()
val date = Date.getToday()
DatePickerDialog
.newInstance({ _, year, monthOfYear, dayOfMonth ->
val dateSelected = Date(year, monthOfYear, dayOfMonth)
b.tabLayout.setCurrentItem(items.indexOfFirst { it == dateSelected }, true)
}, date.year, date.month, date.day)
.apply {
accentColor = R.attr.colorPrimary.resolveAttr(this@TimetableFragment.activity)
show(this@TimetableFragment.activity.supportFragmentManager, "DatePickerDialog")
val date = pageSelection ?: Date.getToday()
MaterialDatePicker.Builder.datePicker()
.setSelection(date.inMillisUtc)
.setCalendarConstraints(app.profile.getSchoolYearConstrains())
.build()
.apply {
addOnPositiveButtonClickListener { millis ->
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)
.withTitle(R.string.menu_add_event)
.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.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.utils.paddingDp
import com.mikepenz.iconics.utils.sizeDp
import eu.szkolny.font.SzkolnyFont
import kotlinx.coroutines.CoroutineScope
@ -85,12 +84,11 @@ class AttachmentAdapter(
icon = attachmentIcon
colorAttr(context, R.attr.colorOnSurface)
sizeDp = 24
paddingDp = 2
}
b.chip.closeIcon = IconicsDrawable(context).apply {
icon = CommunityMaterial.Icon.cmd_check
colorAttr(context, R.attr.colorOnSurface)
sizeDp = 18
sizeDp = 24
}
b.chip.isCloseIconVisible = item.isDownloaded && !item.isDownloading

View File

@ -10,14 +10,13 @@ import android.util.AttributeSet
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import com.google.android.material.datepicker.MaterialDatePicker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.observeOnce
import pl.szczodrzynski.edziennik.resolveAttr
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week
@ -179,17 +178,17 @@ class DateDropdown : TextInputDropDown {
fun pickerDialog() {
val date = getSelected() as? Date ?: Date.getToday()
DatePickerDialog
.newInstance({ _, year, monthOfYear, dayOfMonth ->
val dateSelected = Date(year, monthOfYear+1, dayOfMonth)
MaterialDatePicker.Builder.datePicker()
.setSelection(date.inMillisUtc)
.build()
.apply {
addOnPositiveButtonClickListener { millis ->
val dateSelected = Date.fromMillisUtc(millis)
selectDate(dateSelected)
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) {

View File

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

View File

@ -8,7 +8,8 @@ import android.content.Context
import android.content.ContextWrapper
import android.util.AttributeSet
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.withContext
import pl.szczodrzynski.edziennik.*
@ -177,17 +178,19 @@ class TimeDropdown : TextInputDropDown {
fun pickerDialog() {
val time = (getSelected() as? Pair<*, *>)?.first as? Time ?: Time.getNow()
TimePickerDialog
.newInstance({ _, hourOfDay, minute, second ->
val timeSelected = Time(hourOfDay, minute, second)
MaterialTimePicker.Builder()
.setTimeFormat(TimeFormat.CLOCK_24H)
.setHour(time.hour)
.setMinute(time.minute)
.build()
.also { dialog ->
dialog.addOnPositiveButtonClickListener {
val timeSelected = Time(dialog.hour, dialog.minute, 0)
selectTime(timeSelected)
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) {

View File

@ -8,17 +8,18 @@ import android.app.Activity;
import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.graphics.Color;
import android.database.DataSetObserver;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SeekBar;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.simplelist.MaterialSimpleListAdapter;
import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.gson.JsonObject;
import java.util.List;
@ -27,6 +28,7 @@ import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
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.notifications.WidgetNotificationsProvider;
import pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider;
@ -96,45 +98,84 @@ public class WidgetConfigActivity extends Activity {
}
private void selectProfile() {
MaterialSimpleListAdapter adapter =
new MaterialSimpleListAdapter((dialog, index1, item) -> {
profileId = (int) item.getId();
profileName = item.toString();
if (profileList.size() > 1 && widgetType != WIDGET_LUCKY_NUMBER) {
profileList.add(
new Profile(-1,
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();
});
for (Profile profile : profileList) {
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)
.id(-1)
.content(R.string.widget_config_all_profiles)
.backgroundColor(Color.WHITE)
.build());
}
new MaterialDialog.Builder(this)
.title(R.string.choose_profile)
.adapter(adapter, null)
.dismissListener(dialog -> finish())
return b.getRoot();
}
};
new MaterialAlertDialogBuilder(this)
.setTitle(R.string.choose_profile)
.setAdapter(adapter, null)
.setOnDismissListener(dialog -> finish())
.show();
}
private void configure() {
MaterialDialog dialog = new MaterialDialog.Builder(this)
.title(R.string.widget_config_activity_customize)
.customView(R.layout.dialog_widget_config, true)
.dismissListener(dialog1 -> finish())
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.onPositive(((dialog1, which) -> {
b = DialogWidgetConfigBinding.inflate(getLayoutInflater(), null, false);
new MaterialAlertDialogBuilder(this)
.setTitle(R.string.widget_config_activity_customize)
.setView(b.getRoot())
.setOnDismissListener(dialog -> finish())
.setPositiveButton(R.string.ok, ((dialog, which) -> {
WidgetConfig config = new WidgetConfig(profileId, bigStyle, darkTheme, opacity);
JsonObject configs = app.getConfig().getWidgetConfigs();
configs.add(Integer.toString(mAppWidgetId), app.getGson().toJsonTree(config));
@ -165,10 +206,9 @@ public class WidgetConfigActivity extends Activity {
setResult(RESULT_OK, resultValue);
finish();
}))
.setNegativeButton(R.string.cancel, null)
.show();
b = DialogWidgetConfigBinding.bind(dialog.getCustomView());
b.setProfileName(profileName);
WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);

View File

@ -32,7 +32,7 @@ class WidgetNotificationsProvider : AppWidgetProvider() {
for (appWidgetId in appWidgetIds) {
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) {
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() {
return new IconicsDrawable(context).apply((drawable) -> {
IconicsConvertersKt.setColorRes(drawable, R.color.md_red_500);
IconicsConvertersKt.setSizeDp(drawable, 10);
IconicsConvertersKt.setSizeDp(drawable, 14);
IconicsDrawableExtensionsKt.icon(drawable, CommunityMaterial.Icon2.cmd_home);
return Unit.INSTANCE;
}).toBitmap();

View File

@ -119,7 +119,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
R.id.widgetTimetableRefresh,
IconicsDrawable(context, CommunityMaterial.Icon3.cmd_refresh).apply {
colorInt = Color.WHITE
sizeDp = if (config.bigStyle) 24 else 16
sizeDp = if (config.bigStyle) 28 else 20
}.toBitmap()
)
@ -127,7 +127,7 @@ class WidgetTimetableProvider : AppWidgetProvider() {
R.id.widgetTimetableSync,
IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline).apply {
colorInt = Color.WHITE
sizeDp = if (config.bigStyle) 24 else 16
sizeDp = if (config.bigStyle) 28 else 20
}.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.util.AttributeSet
import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.drawable.DrawableCompat
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 {
constructor(context: Context) : super(context) {
@ -32,11 +34,12 @@ open class TextInputDropDown : TextInputEditText {
}
open fun create(context: Context) {
val drawable = context.resources.getDrawable(R.drawable.dropdown_arrow)
val wrappedDrawable = DrawableCompat.wrap(drawable)
DrawableCompat.setTint(wrappedDrawable, Themes.getPrimaryTextColor(context))
val drawable = IconicsDrawable(context, CommunityMaterial.Icon.cmd_chevron_down).apply {
colorInt = Themes.getPrimaryTextColor(context)
sizeDp = 24
}
setCompoundDrawablesWithIntrinsicBounds(null, null, wrappedDrawable, null)
setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null)
isFocusableInTouchMode = false
isCursorVisible = 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));
}
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) {
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();
}
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() {
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: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>
<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"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down"
app:iiv_size="18dp"
app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" />
</LinearLayout>

View File

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

View File

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

View File

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

View File

@ -178,27 +178,27 @@
<ImageView
android:id="@+id/settings"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="10dp"
android:padding="12dp"
android:visibility="gone"
tools:src="@sample/settings" />
<ImageView
android:id="@+id/bellSync"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="10dp"
android:padding="12dp"
tools:src="@sample/settings" />
<ImageView
android:id="@+id/showCounter"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?selectableItemBackgroundBorderless"
android:padding="10dp"
android:padding="12dp"
tools:src="@sample/settings" />
</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"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:autoLink="web|email"
android:textColor="?android:textColorPrimary"
android:textIsSelectable="true"
android:textSize="16sp" />
</LinearLayout>
</layout>
</ScrollView>

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"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-help-circle-outline"
app:iiv_size="16dp"
app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_help" />
</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_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_color="?android:textColorSecondary"
app:iiv_end_checked_size="16dp"/>
app:iiv_end_checked_size="24dp"/>
<LinearLayout
android:id="@+id/moreLayout"

View File

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

View File

@ -2,122 +2,129 @@
<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">
<data>
<import type="android.view.View" />
<variable
name="profileName"
type="String" />
</data>
<LinearLayout
android:orientation="vertical"
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}"
android:text="@string/dialog_widget_config_profile" />
android:padding="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{profileName}"
android:textIsSelectable="true"
android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}"
tools:text="Władca Androida" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:text="@string/dialog_widget_timetable_config_theme" />
<RadioGroup
android:id="@+id/theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/themeLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:text="@string/theme_light" />
<RadioButton
android:id="@+id/themeDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/theme_dark" />
</RadioGroup>
<CheckBox
android:id="@+id/bigStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/dialog_widget_timetable_config_big_style" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:text="@string/dialog_widget_timetable_config_opacity" />
<SeekBar
android:id="@+id/opacity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="100" />
<TextView
android:id="@+id/opacityText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textIsSelectable="true"
android:gravity="end"
tools:text="100%" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/wallpaper"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="center"
app:layout_constraintBottom_toBottomOf="@+id/widgetPreview"
app:layout_constraintEnd_toEndOf="@+id/widgetPreview"
app:layout_constraintStart_toStartOf="@+id/widgetPreview"
app:layout_constraintTop_toTopOf="@+id/widgetPreview"
tools:srcCompat="@tools:sample/backgrounds/scenic[4]"
tools:visibility="visible" />
<ImageView
android:id="@+id/widgetPreview"
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="32dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/widget_timetable_preview" />
android:textAppearance="@style/NavView.TextView.Helper"
android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}"
android:text="@string/dialog_widget_config_profile" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:text="@{profileName}"
android:textIsSelectable="true"
android:visibility="@{profileName == null ? View.GONE : View.VISIBLE}"
tools:text="Władca Androida" />
</LinearLayout>
</layout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:text="@string/dialog_widget_timetable_config_theme" />
<RadioGroup
android:id="@+id/theme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/themeLight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:text="@string/theme_light" />
<RadioButton
android:id="@+id/themeDark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/theme_dark" />
</RadioGroup>
<CheckBox
android:id="@+id/bigStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/dialog_widget_timetable_config_big_style" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textAppearance="@style/NavView.TextView.Helper"
android:text="@string/dialog_widget_timetable_config_opacity" />
<SeekBar
android:id="@+id/opacity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="100" />
<TextView
android:id="@+id/opacityText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="0dp"
android:textIsSelectable="true"
android:gravity="end"
tools:text="100%" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/wallpaper"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="center"
app:layout_constraintBottom_toBottomOf="@+id/widgetPreview"
app:layout_constraintEnd_toEndOf="@+id/widgetPreview"
app:layout_constraintStart_toStartOf="@+id/widgetPreview"
app:layout_constraintTop_toTopOf="@+id/widgetPreview"
tools:srcCompat="@tools:sample/backgrounds/scenic[4]"
tools:visibility="visible" />
<ImageView
android:id="@+id/widgetPreview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="32dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/widget_timetable_preview" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</ScrollView>
</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"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-chevron-down"
app:iiv_size="16dp"
app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_more" />
<TextView
@ -85,7 +85,7 @@
android:scaleType="centerInside"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-playlist-edit"
app:iiv_size="16dp"
app:iiv_size="24dp"
tools:src="@android:drawable/ic_menu_edit" />
</LinearLayout>
</layout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -60,6 +60,6 @@
android:background="?selectableItemBackgroundBorderless"
app:iiv_color="?colorOnBackground"
app:iiv_icon="cmd-image-search-outline"
app:iiv_size="36dp" />
app:iiv_size="40dp" />
</LinearLayout>
</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:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-reply-outline"
tools:srcCompat="@android:drawable/ic_menu_revert" />
@ -234,7 +233,6 @@
android:id="@+id/forwardIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:padding="4dp"
app:iiv_color="?android:textColorSecondary"
app:iiv_icon="cmd-arrow-right"
tools:srcCompat="@android:drawable/ic_media_ff" />
@ -265,7 +263,6 @@
<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-outline"
tools:srcCompat="@android:drawable/ic_menu_delete" />
@ -295,7 +292,6 @@
<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-download-outline"
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