From 3dabb1147354c9f508826cf2fa5d7139c15c5e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Tue, 20 Mar 2018 23:10:20 +0100 Subject: [PATCH 01/12] [API] Add error messages to exceptions (#71) --- .../java/io/github/wulkanowy/api/Client.java | 18 +++++++++++------- .../api/NotLoggedInErrorException.java | 4 ++++ .../github/wulkanowy/api/StudentAndParent.java | 4 ++-- .../java/io/github/wulkanowy/api/Vulcan.java | 2 +- .../github/wulkanowy/api/VulcanException.java | 4 ++++ .../wulkanowy/api/VulcanOfflineException.java | 4 ++++ .../api/login/AccountPermissionException.java | 4 ++++ .../api/login/BadCredentialsException.java | 4 ++++ .../io/github/wulkanowy/api/login/Login.java | 10 ++++++---- .../api/login/LoginErrorException.java | 6 +++++- .../api/messages/BadRequestException.java | 4 ++++ .../wulkanowy/api/messages/Messages.java | 8 ++++---- .../data/db/resources/AppResources.java | 3 --- app/src/main/res/values-pl/strings.xml | 1 - app/src/main/res/values/strings.xml | 1 - 15 files changed, 53 insertions(+), 24 deletions(-) diff --git a/api/src/main/java/io/github/wulkanowy/api/Client.java b/api/src/main/java/io/github/wulkanowy/api/Client.java index 16b7982c..c3abb2ee 100644 --- a/api/src/main/java/io/github/wulkanowy/api/Client.java +++ b/api/src/main/java/io/github/wulkanowy/api/Client.java @@ -108,7 +108,11 @@ public class Client { this.cookies.addItems(response.cookies()); - return checkForErrors(response.parse()); + Document doc = checkForErrors(response.parse()); + + lastSuccessRequest = new Date(); + + return doc; } public Document postPageByUrl(String url, String[][] params) throws IOException, VulcanException { @@ -165,16 +169,16 @@ public class Client { } Document checkForErrors(Document doc) throws VulcanException { - if ("Przerwa techniczna".equals(doc.select("title").text())) { - throw new VulcanOfflineException(); + String title = doc.select("title").text(); + if ("Przerwa techniczna".equals(title)) { + throw new VulcanOfflineException(title); } - if ("Zaloguj się".equals(doc.select(".loginButton").text())) { - throw new NotLoggedInErrorException(); + String singIn = doc.select(".loginButton").text(); + if ("Zaloguj się".equals(singIn)) { + throw new NotLoggedInErrorException(singIn); } - lastSuccessRequest = new Date(); - return doc; } } diff --git a/api/src/main/java/io/github/wulkanowy/api/NotLoggedInErrorException.java b/api/src/main/java/io/github/wulkanowy/api/NotLoggedInErrorException.java index 86372266..179fc8cc 100644 --- a/api/src/main/java/io/github/wulkanowy/api/NotLoggedInErrorException.java +++ b/api/src/main/java/io/github/wulkanowy/api/NotLoggedInErrorException.java @@ -1,4 +1,8 @@ package io.github.wulkanowy.api; public class NotLoggedInErrorException extends VulcanException { + + public NotLoggedInErrorException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/StudentAndParent.java b/api/src/main/java/io/github/wulkanowy/api/StudentAndParent.java index c014e96c..8f67da39 100644 --- a/api/src/main/java/io/github/wulkanowy/api/StudentAndParent.java +++ b/api/src/main/java/io/github/wulkanowy/api/StudentAndParent.java @@ -48,7 +48,7 @@ public class StudentAndParent implements SnP { Element studentTileLink = startPage.select(".panel.linkownia.pracownik.klient > a").first(); if (null == studentTileLink) { - throw new NotLoggedInErrorException(); + throw new NotLoggedInErrorException("You are probably not logged in. Force login"); } String snpPageUrl = studentTileLink.attr("href"); @@ -62,7 +62,7 @@ public class StudentAndParent implements SnP { String[] path = snpPageUrl.split(client.getHost())[1].split("/"); if (5 != path.length) { - throw new NotLoggedInErrorException(); + throw new NotLoggedInErrorException("You are probably not logged in"); } return path[2]; diff --git a/api/src/main/java/io/github/wulkanowy/api/Vulcan.java b/api/src/main/java/io/github/wulkanowy/api/Vulcan.java index c16ef088..75b939dd 100644 --- a/api/src/main/java/io/github/wulkanowy/api/Vulcan.java +++ b/api/src/main/java/io/github/wulkanowy/api/Vulcan.java @@ -32,7 +32,7 @@ public class Vulcan { public Client getClient() throws NotLoggedInErrorException { if (null == client) { - throw new NotLoggedInErrorException(); + throw new NotLoggedInErrorException("Use setCredentials() method first"); } return client; diff --git a/api/src/main/java/io/github/wulkanowy/api/VulcanException.java b/api/src/main/java/io/github/wulkanowy/api/VulcanException.java index 0e7ed243..723cab91 100644 --- a/api/src/main/java/io/github/wulkanowy/api/VulcanException.java +++ b/api/src/main/java/io/github/wulkanowy/api/VulcanException.java @@ -1,4 +1,8 @@ package io.github.wulkanowy.api; public abstract class VulcanException extends Exception { + + protected VulcanException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/VulcanOfflineException.java b/api/src/main/java/io/github/wulkanowy/api/VulcanOfflineException.java index 497fba94..24ab48e6 100644 --- a/api/src/main/java/io/github/wulkanowy/api/VulcanOfflineException.java +++ b/api/src/main/java/io/github/wulkanowy/api/VulcanOfflineException.java @@ -1,4 +1,8 @@ package io.github.wulkanowy.api; public class VulcanOfflineException extends VulcanException { + + VulcanOfflineException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/login/AccountPermissionException.java b/api/src/main/java/io/github/wulkanowy/api/login/AccountPermissionException.java index 99feb86f..de3901ff 100644 --- a/api/src/main/java/io/github/wulkanowy/api/login/AccountPermissionException.java +++ b/api/src/main/java/io/github/wulkanowy/api/login/AccountPermissionException.java @@ -3,4 +3,8 @@ package io.github.wulkanowy.api.login; import io.github.wulkanowy.api.VulcanException; public class AccountPermissionException extends VulcanException { + + AccountPermissionException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/login/BadCredentialsException.java b/api/src/main/java/io/github/wulkanowy/api/login/BadCredentialsException.java index 1ac37f9c..13efd4a1 100644 --- a/api/src/main/java/io/github/wulkanowy/api/login/BadCredentialsException.java +++ b/api/src/main/java/io/github/wulkanowy/api/login/BadCredentialsException.java @@ -3,4 +3,8 @@ package io.github.wulkanowy.api.login; import io.github.wulkanowy.api.VulcanException; public class BadCredentialsException extends VulcanException { + + BadCredentialsException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/login/Login.java b/api/src/main/java/io/github/wulkanowy/api/login/Login.java index 7f88037d..e7aecec0 100644 --- a/api/src/main/java/io/github/wulkanowy/api/login/Login.java +++ b/api/src/main/java/io/github/wulkanowy/api/login/Login.java @@ -2,6 +2,7 @@ package io.github.wulkanowy.api.login; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; import org.jsoup.parser.Parser; import org.jsoup.select.Elements; @@ -42,8 +43,9 @@ public class Login { {"Password", password} }); - if (null != html.select(".ErrorMessage").first()) { - throw new BadCredentialsException(); + Element errorMessage = html.select(".ErrorMessage").first(); + if (null != errorMessage) { + throw new BadCredentialsException(errorMessage.text()); } return html.select("input[name=wresult]").attr("value"); @@ -59,11 +61,11 @@ public class Login { }).select("title").text(); if ("Logowanie".equals(title)) { - throw new AccountPermissionException(); + throw new AccountPermissionException("No account access. Try another symbol"); } if (!"Uonet+".equals(title)) { - throw new LoginErrorException(); + throw new LoginErrorException("Could not log in, unknown error"); } return this.symbol; diff --git a/api/src/main/java/io/github/wulkanowy/api/login/LoginErrorException.java b/api/src/main/java/io/github/wulkanowy/api/login/LoginErrorException.java index e264dc67..be7439df 100644 --- a/api/src/main/java/io/github/wulkanowy/api/login/LoginErrorException.java +++ b/api/src/main/java/io/github/wulkanowy/api/login/LoginErrorException.java @@ -2,5 +2,9 @@ package io.github.wulkanowy.api.login; import io.github.wulkanowy.api.NotLoggedInErrorException; -public class LoginErrorException extends NotLoggedInErrorException { +class LoginErrorException extends NotLoggedInErrorException { + + LoginErrorException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/messages/BadRequestException.java b/api/src/main/java/io/github/wulkanowy/api/messages/BadRequestException.java index ed407b4d..14dca67b 100644 --- a/api/src/main/java/io/github/wulkanowy/api/messages/BadRequestException.java +++ b/api/src/main/java/io/github/wulkanowy/api/messages/BadRequestException.java @@ -3,4 +3,8 @@ package io.github.wulkanowy.api.messages; import io.github.wulkanowy.api.VulcanException; class BadRequestException extends VulcanException { + + BadRequestException(String message) { + super(message); + } } diff --git a/api/src/main/java/io/github/wulkanowy/api/messages/Messages.java b/api/src/main/java/io/github/wulkanowy/api/messages/Messages.java index eb5f8bba..ec2a3fba 100644 --- a/api/src/main/java/io/github/wulkanowy/api/messages/Messages.java +++ b/api/src/main/java/io/github/wulkanowy/api/messages/Messages.java @@ -59,10 +59,10 @@ public class Messages { messages = new Gson().fromJson(res, MessagesContainer.class).data; } catch (JsonParseException e) { if (res.contains(ERROR_TITLE)) { - throw new BadRequestException(); + throw new BadRequestException(ERROR_TITLE); } - throw new NotLoggedInErrorException(); + throw new NotLoggedInErrorException("You are probably not logged in"); } return messages; @@ -80,10 +80,10 @@ public class Messages { message = new Gson().fromJson(res, MessageContainer.class).data; } catch (JsonParseException e) { if (res.contains(ERROR_TITLE)) { - throw new BadRequestException(); + throw new BadRequestException(ERROR_TITLE); } - throw new NotLoggedInErrorException(); + throw new NotLoggedInErrorException("You are probably not logged in. Force login"); } return message; diff --git a/app/src/main/java/io/github/wulkanowy/data/db/resources/AppResources.java b/app/src/main/java/io/github/wulkanowy/data/db/resources/AppResources.java index 349ac177..c35f44c7 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/resources/AppResources.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/resources/AppResources.java @@ -12,7 +12,6 @@ import javax.inject.Singleton; import io.github.wulkanowy.R; import io.github.wulkanowy.api.NotLoggedInErrorException; -import io.github.wulkanowy.api.VulcanOfflineException; import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson; import io.github.wulkanowy.di.annotations.ApplicationContext; import io.github.wulkanowy.utils.AppConstant; @@ -51,8 +50,6 @@ public class AppResources implements ResourcesContract { return resources.getString(R.string.generic_timeout_error); } else if (exception instanceof NotLoggedInErrorException || exception instanceof IOException) { return resources.getString(R.string.login_denied_text); - } else if (exception instanceof VulcanOfflineException) { - return resources.getString(R.string.error_host_offline); } else { return exception.getMessage(); } diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 9642a53d..244f39e8 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -39,7 +39,6 @@ Brak ocen Brak połączenia z internetem - Przerwa techniczna. Spróbuj ponownie później Szyfrowanie nie powiodło się. Automatyczne logowanie zostało wyłączone Wersja %1$s "Podczas odświeżania zawartości wystąpił błąd. " diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 315fee4f..b4b6c0c0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -73,7 +73,6 @@ Average: %1$.2f No average No lesson in this week - Technical break Room %s From 8431661d5473b519182400ed2d2648938a3b80fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Thu, 22 Mar 2018 22:42:08 +0100 Subject: [PATCH 02/12] Fix resuming states in fragments (#72) * Downgrade sdk version * Update dependencies * Fix infinite loading on restore states * Fix crash when loading loaded fragments --- api/build.gradle | 10 +-- app/build.gradle | 61 +++++++++---------- .../main/attendance/AttendanceContract.java | 10 +-- .../main/attendance/AttendanceFragment.java | 38 +++++------- .../main/attendance/AttendanceHeaderItem.java | 6 +- .../main/attendance/AttendancePresenter.java | 24 ++++---- .../ui/main/attendance/AttendanceSubItem.java | 8 ++- .../attendance/AttendanceTabContract.java | 4 +- .../attendance/AttendanceTabFragment.java | 38 +++--------- .../attendance/AttendanceTabPresenter.java | 20 +++--- .../ui/main/timetable/TimetableContract.java | 10 +-- .../ui/main/timetable/TimetableFragment.java | 38 +++++------- .../main/timetable/TimetableHeaderItem.java | 6 +- .../ui/main/timetable/TimetablePresenter.java | 25 ++++---- .../ui/main/timetable/TimetableSubItem.java | 8 ++- .../main/timetable/TimetableTabContract.java | 4 +- .../main/timetable/TimetableTabFragment.java | 38 +++--------- .../main/timetable/TimetableTabPresenter.java | 20 +++--- build.gradle | 28 ++++++++- 19 files changed, 173 insertions(+), 223 deletions(-) diff --git a/api/build.gradle b/api/build.gradle index ebaca4c8..001d2579 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -28,12 +28,12 @@ jacocoTestReport { } dependencies { - implementation 'org.jsoup:jsoup:1.10.3' - implementation 'org.apache.commons:commons-lang3:3.7' - implementation 'com.google.code.gson:gson:2.8.2' + implementation "org.jsoup:jsoup:$jsoup" + implementation "org.apache.commons:commons-lang3:$apacheLang" + implementation "com.google.code.gson:gson:$gson" - testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.13.0' + testImplementation "junit:junit:$junit" + testImplementation "org.mockito:mockito-core:$mockito" } version = PUBLISH_VERSION diff --git a/app/build.gradle b/app/build.gradle index 055fb302..6b63b2d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -21,13 +21,13 @@ apply from: '../jacoco.gradle' apply from: '../android-sonarqube.gradle' android { - compileSdkVersion 27 - buildToolsVersion "27.0.3" + compileSdkVersion 26 + buildToolsVersion "26.0.3" defaultConfig { applicationId "io.github.wulkanowy" testApplicationId "io.github.tests.wulkanowy" minSdkVersion 15 - targetSdkVersion 27 + targetSdkVersion 26 versionCode 4 versionName "0.2.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -68,42 +68,39 @@ greendao { dependencies { implementation project(':api') - implementation 'com.android.support:appcompat-v7:27.1.0' - implementation 'com.android.support:design:27.1.0' - implementation 'com.android.support:support-v4:27.1.0' - implementation 'com.android.support:recyclerview-v7:27.1.0' - implementation 'com.android.support:cardview-v7:27.1.0' - implementation 'com.android.support:customtabs:27.1.0' - implementation 'com.firebase:firebase-jobdispatcher:0.8.5' - implementation 'org.apache.commons:commons-lang3:3.7' - implementation 'eu.davidea:flexible-adapter:5.0.0-rc4' - implementation 'eu.davidea:flexible-adapter-ui:1.0.0-b1' - implementation 'org.apache.commons:commons-collections4:4.1' - implementation 'org.greenrobot:greendao:3.2.2' - implementation 'com.github.yuweiguocn:GreenDaoUpgradeHelper:v2.0.2' - implementation 'com.jakewharton:butterknife:8.8.1' - implementation 'joda-time:joda-time:2.9.9' - implementation 'com.google.dagger:dagger-android:2.14.1' - implementation 'com.google.dagger:dagger-android-support:2.14.1' - implementation 'com.aurelhubert:ahbottomnavigation:2.1.0' + implementation "com.android.support:support-v4:$supportVersion" + implementation "com.android.support:design:$supportVersion" + implementation "com.android.support:cardview-v7:$supportVersion" + implementation "com.android.support:customtabs:$supportVersion" + implementation "com.firebase:firebase-jobdispatcher:$firebaseJob" + implementation "org.apache.commons:commons-lang3:$apacheLang" + implementation "org.apache.commons:commons-collections4:$apacheCollections" + implementation "eu.davidea:flexible-adapter:$flexibleAdapter" + implementation "eu.davidea:flexible-adapter-ui:$flexibleUi" + implementation "org.greenrobot:greendao:$greenDao" + implementation "com.github.yuweiguocn:GreenDaoUpgradeHelper:$greenDaoHelper" + implementation "com.jakewharton:butterknife:$butterknife" + implementation "joda-time:joda-time:$jodaTime" + implementation "com.google.dagger:dagger-android-support:$dagger2" + implementation "com.aurelhubert:ahbottomnavigation:$ahbottom" - implementation('com.crashlytics.sdk.android:crashlytics:2.8.0@aar') { + implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsSdk@aar") { transitive = true } - implementation('com.crashlytics.sdk.android:answers:1.4.1@aar') { + implementation("com.crashlytics.sdk.android:answers:$crashlyticsAnswers@aar") { transitive = true } - annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1' - annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1' - annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' + annotationProcessor "com.google.dagger:dagger-android-processor:$dagger2" + annotationProcessor "com.google.dagger:dagger-compiler:$dagger2" + annotationProcessor "com.jakewharton:butterknife-compiler:$butterknife" - debugImplementation 'com.amitshekhar.android:debug-db:1.0.1' - debugImplementation 'net.zetetic:android-database-sqlcipher:3.5.9' + debugImplementation "com.amitshekhar.android:debug-db:$debugDb" + debugImplementation "net.zetetic:android-database-sqlcipher:$sqlcipher" - testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.13.0' + testImplementation "junit:junit:$junit" + testImplementation "org.mockito:mockito-core:$mockito" - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'org.mockito:mockito-android:2.13.0' + androidTestImplementation "com.android.support.test:runner:$testRunner" + androidTestImplementation "org.mockito:mockito-android:$mockito" } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceContract.java index f8d3b302..545e300e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceContract.java @@ -17,20 +17,16 @@ public interface AttendanceContract { void setAdapterWithTabLayout(); - void setChildFragmentSelected(int position, boolean selected); - boolean isMenuVisible(); } @PerActivity interface Presenter extends BaseContract.Presenter { - void onFragmentVisible(boolean isVisible); - - void onTabSelected(int position); - - void onTabUnselected(int position); + void onFragmentActivated(boolean isVisible); void onStart(View view, OnFragmentIsReadyListener listener); + + void setRestoredPosition(int position); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceFragment.java index 82bb2520..4dd179b1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceFragment.java @@ -20,7 +20,9 @@ import io.github.wulkanowy.ui.base.BaseFragment; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.ui.main.TabsData; -public class AttendanceFragment extends BaseFragment implements AttendanceContract.View, TabLayout.OnTabSelectedListener { +public class AttendanceFragment extends BaseFragment implements AttendanceContract.View { + + private static final String CURRENT_ITEM_KEY = "CurrentItem"; @BindView(R.id.attendance_fragment_viewpager) ViewPager viewPager; @@ -45,6 +47,10 @@ public class AttendanceFragment extends BaseFragment implements AttendanceContra component.inject(this); setButterKnife(ButterKnife.bind(this, view)); presenter.onStart(this, (OnFragmentIsReadyListener) getActivity()); + + if (savedInstanceState != null) { + presenter.setRestoredPosition(savedInstanceState.getInt(CURRENT_ITEM_KEY)); + } } return view; @@ -54,25 +60,10 @@ public class AttendanceFragment extends BaseFragment implements AttendanceContra public void setMenuVisibility(boolean menuVisible) { super.setMenuVisibility(menuVisible); if (presenter != null) { - presenter.onFragmentVisible(menuVisible); + presenter.onFragmentActivated(menuVisible); } } - @Override - public void onTabSelected(TabLayout.Tab tab) { - presenter.onTabSelected(tab.getPosition()); - } - - @Override - public void onTabUnselected(TabLayout.Tab tab) { - presenter.onTabUnselected(tab.getPosition()); - } - - @Override - public void onTabReselected(TabLayout.Tab tab) { - //do nothing - } - @Override public void setTabDataToAdapter(TabsData tabsData) { pagerAdapter.setTabsData(tabsData); @@ -81,14 +72,7 @@ public class AttendanceFragment extends BaseFragment implements AttendanceContra @Override public void setAdapterWithTabLayout() { viewPager.setAdapter(pagerAdapter); - tabLayout.setupWithViewPager(viewPager); - tabLayout.addOnTabSelectedListener(this); - } - - @Override - public void setChildFragmentSelected(int position, boolean selected) { - ((AttendanceTabFragment) pagerAdapter.getItem(position)).setSelected(selected); } @Override @@ -109,6 +93,12 @@ public class AttendanceFragment extends BaseFragment implements AttendanceContra } } + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putInt(CURRENT_ITEM_KEY, viewPager.getCurrentItem()); + super.onSaveInstanceState(outState); + } + @Override public void onDestroyView() { presenter.onDestroy(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceHeaderItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceHeaderItem.java index 306065ee..a055156d 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceHeaderItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceHeaderItem.java @@ -19,6 +19,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem; +import eu.davidea.flexibleadapter.items.IFlexible; import eu.davidea.viewholders.ExpandableViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.Day; @@ -58,12 +59,13 @@ public class AttendanceHeaderItem } @Override - public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) { return new HeaderViewHolder(view, adapter); } @Override - public void bindViewHolder(FlexibleAdapter adapter, HeaderViewHolder holder, int position, List payloads) { + public void bindViewHolder(FlexibleAdapter adapter, HeaderViewHolder holder, + int position, List payloads) { holder.onBind(day, getSubItems()); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendancePresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendancePresenter.java index 73dd44ca..bad68e16 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendancePresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendancePresenter.java @@ -24,7 +24,7 @@ public class AttendancePresenter extends BasePresenter private OnFragmentIsReadyListener listener; - private int positionToScroll; + private int positionToScroll = 0; private boolean isFirstSight = false; @@ -45,7 +45,10 @@ public class AttendancePresenter extends BasePresenter if (dates.isEmpty()) { dates = TimeUtils.getMondaysFromCurrentSchoolYear(); } - positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); + + if (positionToScroll == 0) { + positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); + } if (!isFirstSight) { isFirstSight = true; @@ -57,22 +60,12 @@ public class AttendancePresenter extends BasePresenter } @Override - public void onFragmentVisible(boolean isVisible) { + public void onFragmentActivated(boolean isVisible) { if (isVisible) { getView().setActivityTitle(); } } - @Override - public void onTabSelected(int position) { - getView().setChildFragmentSelected(position, true); - } - - @Override - public void onTabUnselected(int position) { - getView().setChildFragmentSelected(position, false); - } - @Override public void onDoInBackgroundLoading() throws Exception { for (String date : dates) { @@ -97,6 +90,11 @@ public class AttendancePresenter extends BasePresenter } } + @Override + public void setRestoredPosition(int position) { + this.positionToScroll = position; + } + @Override public void onDestroy() { isFirstSight = false; diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceSubItem.java index 6da35555..8249a513 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceSubItem.java @@ -16,6 +16,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.items.AbstractSectionableItem; +import eu.davidea.flexibleadapter.items.IFlexible; import eu.davidea.viewholders.FlexibleViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.AttendanceLesson; @@ -60,12 +61,13 @@ class AttendanceSubItem } @Override - public AttendanceSubItem.SubItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { - return new AttendanceSubItem.SubItemViewHolder(view, adapter); + public SubItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + return new SubItemViewHolder(view, adapter); } @Override - public void bindViewHolder(FlexibleAdapter adapter, AttendanceSubItem.SubItemViewHolder holder, int position, List payloads) { + public void bindViewHolder(FlexibleAdapter adapter, SubItemViewHolder holder, + int position, List payloads) { holder.onBind(lesson); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabContract.java index 1bac005d..dcb16bf8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabContract.java @@ -21,12 +21,10 @@ public interface AttendanceTabContract { interface Presenter extends BaseContract.Presenter { - void onFragmentSelected(boolean isSelected); + void onFragmentActivated(boolean isSelected); void setArgumentDate(String date); - void onStart(AttendanceTabContract.View view, boolean isPrimary); - void onRefresh(); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabFragment.java index 90313daa..b635da2b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabFragment.java @@ -27,12 +27,6 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab private static final String ARGUMENT_KEY = "date"; - private static final String SAVED_KEY = "isSelected"; - - private boolean isPrimary = false; - - private boolean isSelected = false; - @BindView(R.id.attendance_tab_fragment_recycler) RecyclerView recyclerView; @@ -51,6 +45,8 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab @Inject FlexibleAdapter adapter; + private boolean isFragmentVisible = false; + public static AttendanceTabFragment newInstance(String date) { AttendanceTabFragment fragmentTab = new AttendanceTabFragment(); @@ -61,15 +57,6 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab return fragmentTab; } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (savedInstanceState != null) { - isSelected = savedInstanceState.getBoolean(SAVED_KEY, isSelected); - } - } - @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -84,7 +71,8 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab presenter.setArgumentDate(getArguments().getString(ARGUMENT_KEY)); } - presenter.onStart(this, isPrimary); + presenter.onStart(this); + presenter.onFragmentActivated(isFragmentVisible); } return view; } @@ -111,10 +99,9 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab @Override public void setMenuVisibility(boolean menuVisible) { super.setMenuVisibility(menuVisible); - if (presenter != null && getView() != null) { - presenter.onFragmentSelected(isSelected); - } else if (isSelected) { - isPrimary = true; + isFragmentVisible = menuVisible; + if (presenter != null) { + presenter.onFragmentActivated(menuVisible); } } @@ -143,10 +130,6 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab noItemView.setVisibility(show ? View.VISIBLE : View.INVISIBLE); } - public void setSelected(boolean selected) { - isSelected = selected; - } - @Override public void onError(String message) { if (getActivity() != null) { @@ -155,15 +138,8 @@ public class AttendanceTabFragment extends BaseFragment implements AttendanceTab } } - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putBoolean(SAVED_KEY, isSelected); - super.onSaveInstanceState(outState); - } - @Override public void onDestroyView() { - isPrimary = false; presenter.onDestroy(); super.onDestroyView(); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabPresenter.java index 48aff81c..1db29cb1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/attendance/AttendanceTabPresenter.java @@ -33,21 +33,22 @@ public class AttendanceTabPresenter extends BasePresenter { - void onFragmentVisible(boolean isVisible); - - void onTabSelected(int position); - - void onTabUnselected(int position); + void onFragmentActivated(boolean isVisible); void onStart(View view, OnFragmentIsReadyListener listener); + + void setRestoredPosition(int position); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java index 8bef4fb2..2df28df2 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java @@ -20,7 +20,9 @@ import io.github.wulkanowy.ui.base.BaseFragment; import io.github.wulkanowy.ui.main.OnFragmentIsReadyListener; import io.github.wulkanowy.ui.main.TabsData; -public class TimetableFragment extends BaseFragment implements TimetableContract.View, TabLayout.OnTabSelectedListener { +public class TimetableFragment extends BaseFragment implements TimetableContract.View { + + private static final String CURRENT_ITEM_KEY = "CurrentItem"; @BindView(R.id.timetable_fragment_viewpager) ViewPager viewPager; @@ -44,6 +46,10 @@ public class TimetableFragment extends BaseFragment implements TimetableContract component.inject(this); setButterKnife(ButterKnife.bind(this, view)); presenter.onStart(this, (OnFragmentIsReadyListener) getActivity()); + + if (savedInstanceState != null) { + presenter.setRestoredPosition(savedInstanceState.getInt(CURRENT_ITEM_KEY)); + } } return view; } @@ -52,25 +58,10 @@ public class TimetableFragment extends BaseFragment implements TimetableContract public void setMenuVisibility(boolean menuVisible) { super.setMenuVisibility(menuVisible); if (presenter != null) { - presenter.onFragmentVisible(menuVisible); + presenter.onFragmentActivated(menuVisible); } } - @Override - public void onTabSelected(TabLayout.Tab tab) { - presenter.onTabSelected(tab.getPosition()); - } - - @Override - public void onTabUnselected(TabLayout.Tab tab) { - presenter.onTabUnselected(tab.getPosition()); - } - - @Override - public void onTabReselected(TabLayout.Tab tab) { - //do nothing - } - @Override public void setTabDataToAdapter(TabsData tabsData) { pagerAdapter.setTabsData(tabsData); @@ -79,14 +70,7 @@ public class TimetableFragment extends BaseFragment implements TimetableContract @Override public void setAdapterWithTabLayout() { viewPager.setAdapter(pagerAdapter); - tabLayout.setupWithViewPager(viewPager); - tabLayout.addOnTabSelectedListener(this); - } - - @Override - public void setChildFragmentSelected(int position, boolean selected) { - ((TimetableTabFragment) pagerAdapter.getItem(position)).setSelected(selected); } @Override @@ -107,6 +91,12 @@ public class TimetableFragment extends BaseFragment implements TimetableContract } } + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putInt(CURRENT_ITEM_KEY, viewPager.getCurrentItem()); + super.onSaveInstanceState(outState); + } + @Override public void onDestroyView() { presenter.onDestroy(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableHeaderItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableHeaderItem.java index d704e8a3..c904d931 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableHeaderItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableHeaderItem.java @@ -19,6 +19,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.items.AbstractExpandableHeaderItem; +import eu.davidea.flexibleadapter.items.IFlexible; import eu.davidea.viewholders.ExpandableViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.Day; @@ -58,12 +59,13 @@ public class TimetableHeaderItem } @Override - public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + public HeaderViewHolder createViewHolder(View view, FlexibleAdapter adapter) { return new HeaderViewHolder(view, adapter); } @Override - public void bindViewHolder(FlexibleAdapter adapter, HeaderViewHolder holder, int position, List payloads) { + public void bindViewHolder(FlexibleAdapter adapter, HeaderViewHolder holder, + int position, List payloads) { holder.onBind(day, getSubItems()); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetablePresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetablePresenter.java index e816a190..080ec90b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetablePresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetablePresenter.java @@ -24,7 +24,7 @@ public class TimetablePresenter extends BasePresenter private OnFragmentIsReadyListener listener; - private int positionToScroll; + private int positionToScroll = 0; private boolean isFirstSight = false; @@ -45,7 +45,10 @@ public class TimetablePresenter extends BasePresenter if (dates.isEmpty()) { dates = TimeUtils.getMondaysFromCurrentSchoolYear(); } - positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); + + if (positionToScroll == 0) { + positionToScroll = dates.indexOf(TimeUtils.getDateOfCurrentMonday(true)); + } if (!isFirstSight) { isFirstSight = true; @@ -57,22 +60,12 @@ public class TimetablePresenter extends BasePresenter } @Override - public void onFragmentVisible(boolean isVisible) { + public void onFragmentActivated(boolean isVisible) { if (isVisible) { getView().setActivityTitle(); } } - @Override - public void onTabSelected(int position) { - getView().setChildFragmentSelected(position, true); - } - - @Override - public void onTabUnselected(int position) { - getView().setChildFragmentSelected(position, false); - } - @Override public void onDoInBackgroundLoading() throws Exception { for (String date : dates) { @@ -84,7 +77,6 @@ public class TimetablePresenter extends BasePresenter @Override public void onCanceledLoadingAsync() { //do nothing - } @Override @@ -97,6 +89,11 @@ public class TimetablePresenter extends BasePresenter } } + @Override + public void setRestoredPosition(int position) { + this.positionToScroll = position; + } + @Override public void onDestroy() { isFirstSight = false; diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java index ca82f783..3d85772a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableSubItem.java @@ -17,6 +17,7 @@ import butterknife.BindView; import butterknife.ButterKnife; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.items.AbstractSectionableItem; +import eu.davidea.flexibleadapter.items.IFlexible; import eu.davidea.viewholders.FlexibleViewHolder; import io.github.wulkanowy.R; import io.github.wulkanowy.data.db.dao.entities.TimetableLesson; @@ -27,7 +28,7 @@ public class TimetableSubItem private TimetableLesson lesson; - public TimetableSubItem(TimetableHeaderItem header, TimetableLesson lesson) { + TimetableSubItem(TimetableHeaderItem header, TimetableLesson lesson) { super(header); this.lesson = lesson; } @@ -62,12 +63,13 @@ public class TimetableSubItem } @Override - public SubItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { + public SubItemViewHolder createViewHolder(View view, FlexibleAdapter adapter) { return new SubItemViewHolder(view, adapter); } @Override - public void bindViewHolder(FlexibleAdapter adapter, SubItemViewHolder holder, int position, List payloads) { + public void bindViewHolder(FlexibleAdapter adapter, SubItemViewHolder holder, + int position, List payloads) { holder.onBind(lesson); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabContract.java index d17e6e55..0d6bdf2a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabContract.java @@ -23,12 +23,10 @@ public interface TimetableTabContract { interface Presenter extends BaseContract.Presenter { - void onFragmentSelected(boolean isSelected); + void onFragmentActivated(boolean isSelected); void setArgumentDate(String date); - void onStart(View view, boolean isPrimary); - void onRefresh(); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabFragment.java index 65841247..9cbca045 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabFragment.java @@ -28,12 +28,6 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo private static final String ARGUMENT_KEY = "date"; - private static final String SAVED_KEY = "isSelected"; - - private boolean isPrimary = false; - - private boolean isSelected = false; - @BindView(R.id.timetable_tab_fragment_recycler) RecyclerView recyclerView; @@ -55,6 +49,8 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo @Inject FlexibleAdapter adapter; + private boolean isFragmentVisible = false; + public static TimetableTabFragment newInstance(String date) { TimetableTabFragment fragmentTab = new TimetableTabFragment(); @@ -65,14 +61,6 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo return fragmentTab; } - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - if (savedInstanceState != null) { - isSelected = savedInstanceState.getBoolean(SAVED_KEY, isSelected); - } - } - @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { @@ -86,8 +74,8 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo if (getArguments() != null) { presenter.setArgumentDate(getArguments().getString(ARGUMENT_KEY)); } - - presenter.onStart(this, isPrimary); + presenter.onStart(this); + presenter.onFragmentActivated(isFragmentVisible); } return view; } @@ -114,10 +102,9 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo @Override public void setMenuVisibility(boolean menuVisible) { super.setMenuVisibility(menuVisible); - if (presenter != null && getView() != null) { - presenter.onFragmentSelected(isSelected); - } else if (isSelected) { - isPrimary = true; + isFragmentVisible = menuVisible; + if (presenter != null) { + presenter.onFragmentActivated(menuVisible); } } @@ -151,10 +138,6 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo noItemView.setVisibility(show ? View.VISIBLE : View.INVISIBLE); } - public void setSelected(boolean selected) { - isSelected = selected; - } - @Override public void onError(String message) { if (getActivity() != null) { @@ -163,15 +146,8 @@ public class TimetableTabFragment extends BaseFragment implements TimetableTabCo } } - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putBoolean(SAVED_KEY, isSelected); - super.onSaveInstanceState(outState); - } - @Override public void onDestroyView() { - isPrimary = false; presenter.onDestroy(); super.onDestroyView(); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabPresenter.java index 20d0b965..dcfe2612 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableTabPresenter.java @@ -36,21 +36,22 @@ public class TimetableTabPresenter extends BasePresenter Date: Thu, 22 Mar 2018 22:54:11 +0100 Subject: [PATCH 03/12] Version 0.2.2 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6b63b2d3..252021af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,8 +28,8 @@ android { testApplicationId "io.github.tests.wulkanowy" minSdkVersion 15 targetSdkVersion 26 - versionCode 4 - versionName "0.2.1" + versionCode 5 + versionName "0.2.2" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true manifestPlaceholders = [ From 5c9f10fa508c11d38665c27080bb8673cf75164d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Tue, 3 Apr 2018 16:10:56 +0200 Subject: [PATCH 04/12] Update gradle to 4.4 (#75) --- .gitignore | 2 ++ app/build.gradle | 2 +- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- jacoco.gradle | 6 +++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 3b524b65..eec8adbe 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,8 @@ local.properties .idea/tasks.xml .idea/vcs.xml .idea/workspace.xml +.idea/caches/ +.idea/codeStyles/ *.iml # OS-specific files diff --git a/app/build.gradle b/app/build.gradle index 252021af..ac4485f5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ apply from: '../android-sonarqube.gradle' android { compileSdkVersion 26 - buildToolsVersion "26.0.3" + buildToolsVersion '27.0.3' defaultConfig { applicationId "io.github.wulkanowy" testApplicationId "io.github.tests.wulkanowy" diff --git a/build.gradle b/build.gradle index 28748fc0..f0827365 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' + classpath 'com.android.tools.build:gradle:3.1.0' classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.1" classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 28bd184f..8a440624 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Oct 27 17:19:04 CEST 2017 +#Tue Mar 27 02:10:44 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/jacoco.gradle b/jacoco.gradle index 47a077ca..84a0ce97 100644 --- a/jacoco.gradle +++ b/jacoco.gradle @@ -1,7 +1,11 @@ apply plugin: "jacoco" jacoco { - toolVersion "0.7.4.201502262128" + toolVersion "0.8.1" +} + +tasks.withType(Test) { + jacoco.includeNoLocationClasses = true } // run ./gradlew clean createDebugCoverageReport jacocoTestReport From c72e7748e28ebd8112ed92b4bba07e84573a8be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Thu, 5 Apr 2018 21:56:08 +0200 Subject: [PATCH 05/12] Migrate to ThreeTenABP (#77) --- app/build.gradle | 2 +- .../io/github/wulkanowy/WulkanowyApp.java | 3 ++ .../io/github/wulkanowy/utils/TimeUtils.java | 34 +++++++++---------- build.gradle | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ac4485f5..eb8b9422 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,9 +80,9 @@ dependencies { implementation "org.greenrobot:greendao:$greenDao" implementation "com.github.yuweiguocn:GreenDaoUpgradeHelper:$greenDaoHelper" implementation "com.jakewharton:butterknife:$butterknife" - implementation "joda-time:joda-time:$jodaTime" implementation "com.google.dagger:dagger-android-support:$dagger2" implementation "com.aurelhubert:ahbottomnavigation:$ahbottom" + implementation "com.jakewharton.threetenabp:threetenabp:$threeTenABP" implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsSdk@aar") { transitive = true diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java index 8e5318e1..ab94afa6 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java @@ -4,6 +4,7 @@ import android.app.Application; import com.crashlytics.android.Crashlytics; import com.crashlytics.android.core.CrashlyticsCore; +import com.jakewharton.threetenabp.AndroidThreeTen; import org.greenrobot.greendao.query.QueryBuilder; @@ -28,6 +29,8 @@ public class WulkanowyApp extends Application { @Override public void onCreate() { super.onCreate(); + AndroidThreeTen.init(this); + applicationComponent = DaggerApplicationComponent .builder() .applicationModule(new ApplicationModule(this)) diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeUtils.java b/app/src/main/java/io/github/wulkanowy/utils/TimeUtils.java index 717ed42a..a7162d15 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimeUtils.java +++ b/app/src/main/java/io/github/wulkanowy/utils/TimeUtils.java @@ -1,8 +1,8 @@ package io.github.wulkanowy.utils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.LocalDate; +import org.threeten.bp.DayOfWeek; +import org.threeten.bp.LocalDate; +import org.threeten.bp.format.DateTimeFormatter; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -13,14 +13,14 @@ import java.util.List; import java.util.Locale; import java.util.TimeZone; -import static io.github.wulkanowy.utils.AppConstant.DATE_PATTERN; - public final class TimeUtils { private static final long TICKS_AT_EPOCH = 621355968000000000L; private static final long TICKS_PER_MILLISECOND = 10000; + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(AppConstant.DATE_PATTERN); + private TimeUtils() { throw new IllegalStateException("Utility class"); } @@ -33,7 +33,7 @@ public final class TimeUtils { } public static long getNetTicks(String dateString) throws ParseException { - return getNetTicks(dateString, DATE_PATTERN); + return getNetTicks(dateString, AppConstant.DATE_PATTERN); } public static long getNetTicks(String dateString, String dateFormat) throws ParseException { @@ -49,12 +49,12 @@ public final class TimeUtils { } public static List getMondaysFromCurrentSchoolYear() { - LocalDate startDate = new LocalDate(getCurrentSchoolYear(), 9, 1); - LocalDate endDate = new LocalDate(getCurrentSchoolYear() + 1, 8, 31); + LocalDate startDate = LocalDate.of(getCurrentSchoolYear(), 9, 1); + LocalDate endDate = LocalDate.of(getCurrentSchoolYear() + 1, 8, 31); List dateList = new ArrayList<>(); - LocalDate thisMonday = startDate.withDayOfWeek(DateTimeConstants.MONDAY); + LocalDate thisMonday = startDate.with(DayOfWeek.MONDAY); if (startDate.isAfter(thisMonday)) { startDate = thisMonday.plusWeeks(1); @@ -63,27 +63,27 @@ public final class TimeUtils { } while (startDate.isBefore(endDate)) { - dateList.add(startDate.toString(DATE_PATTERN)); + dateList.add(startDate.format(formatter)); startDate = startDate.plusWeeks(1); } return dateList; } public static int getCurrentSchoolYear() { - DateTime dateTime = new DateTime(); - return dateTime.getMonthOfYear() <= 8 ? dateTime.getYear() - 1 : dateTime.getYear(); + LocalDate localDate = LocalDate.now(); + return localDate.getMonthValue() <= 8 ? localDate.getYear() - 1 : localDate.getYear(); } public static String getDateOfCurrentMonday(boolean normalize) { - DateTime currentDate = new DateTime(); + LocalDate currentDate = LocalDate.now(); - if (currentDate.getDayOfWeek() == DateTimeConstants.SATURDAY && normalize) { + if (currentDate.getDayOfWeek() == DayOfWeek.SATURDAY && normalize) { currentDate = currentDate.plusDays(2); - } else if (currentDate.getDayOfWeek() == DateTimeConstants.SUNDAY && normalize) { + } else if (currentDate.getDayOfWeek() == DayOfWeek.SUNDAY && normalize) { currentDate = currentDate.plusDays(1); } else { - currentDate = currentDate.withDayOfWeek(DateTimeConstants.MONDAY); + currentDate = currentDate.with(DayOfWeek.MONDAY); } - return currentDate.toString(DATE_PATTERN); + return currentDate.format(formatter); } } diff --git a/build.gradle b/build.gradle index f0827365..b6ada2fb 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ ext { greenDao = "3.2.2" greenDaoHelper = "v2.0.2" butterknife = "8.8.1" - jodaTime = "2.9.9" + threeTenABP = "1.0.5" dagger2 = "2.15" ahbottom = "2.1.0" jsoup = "1.10.3" From cb6afb137f344e07cbf92885b2aeeeefc9a2ecca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Sun, 8 Apr 2018 15:54:46 +0200 Subject: [PATCH 06/12] Hide actionbar during login (#79) --- .../io/github/wulkanowy/ui/login/LoginActivity.java | 13 +++++++++++++ .../io/github/wulkanowy/ui/login/LoginContract.java | 2 ++ .../github/wulkanowy/ui/login/LoginPresenter.java | 8 +++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/github/wulkanowy/ui/login/LoginActivity.java b/app/src/main/java/io/github/wulkanowy/ui/login/LoginActivity.java index 95c5548b..9d6e8b12 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/login/LoginActivity.java +++ b/app/src/main/java/io/github/wulkanowy/ui/login/LoginActivity.java @@ -7,6 +7,7 @@ import android.content.Intent; import android.os.Bundle; import android.support.design.widget.Snackbar; import android.support.design.widget.TextInputLayout; +import android.support.v7.app.ActionBar; import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; @@ -209,6 +210,18 @@ public class LoginActivity extends BaseActivity implements LoginContract.View { }); } + @Override + public void showActionBar(boolean show) { + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + if (show) { + actionBar.show(); + } else { + actionBar.hide(); + } + } + } + @Override public void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/login/LoginContract.java b/app/src/main/java/io/github/wulkanowy/ui/login/LoginContract.java index debfbbde..570e1b26 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/login/LoginContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/login/LoginContract.java @@ -33,6 +33,8 @@ public interface LoginContract { void hideSoftInput(); + void showActionBar(boolean show); + } @PerActivity diff --git a/app/src/main/java/io/github/wulkanowy/ui/login/LoginPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/login/LoginPresenter.java index 2b6d173d..b547f3f6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/login/LoginPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/login/LoginPresenter.java @@ -55,6 +55,7 @@ public class LoginPresenter extends BasePresenter @Override public void onStartAsync() { if (isViewAttached()) { + getView().showActionBar(false); getView().showLoginProgress(true); } } @@ -84,24 +85,25 @@ public class LoginPresenter extends BasePresenter public void onEndAsync(boolean success, Exception exception) { if (success) { getView().openMainActivity(); + return; } else if (exception instanceof BadCredentialsException) { getView().setErrorPassIncorrect(); getView().showSoftInput(); - getView().showLoginProgress(false); } else if (exception instanceof AccountPermissionException) { getView().setErrorSymbolRequired(); getView().showSoftInput(); - getView().showLoginProgress(false); } else { getView().onError(getRepository().getErrorLoginMessage(exception)); - getView().showLoginProgress(false); } + getView().showActionBar(true); + getView().showLoginProgress(false); } @Override public void onCanceledAsync() { if (isViewAttached()) { + getView().showActionBar(true); getView().showLoginProgress(false); } } From 0aa8c5605dff068550e7124c0bfbe1409292c9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Sun, 8 Apr 2018 16:15:05 +0200 Subject: [PATCH 07/12] Add setttings (#74) --- app/build.gradle | 1 + .../io/github/wulkanowy/data/Repository.java | 25 +++++++ .../wulkanowy/data/RepositoryContract.java | 10 +++ .../wulkanowy/data/db/shared/SharedPref.java | 38 ++++++++-- .../data/db/shared/SharedPrefContract.java | 10 +++ .../io/github/wulkanowy/services/SyncJob.java | 23 +++--- .../wulkanowy/ui/main/MainActivity.java | 56 ++++++--------- .../wulkanowy/ui/main/MainContract.java | 6 ++ .../wulkanowy/ui/main/MainPresenter.java | 17 ++++- .../ui/main/settings/SettingsFragment.java | 70 +++++++++++++++++++ .../ui/main/timetable/TimetableFragment.java | 2 +- .../wulkanowy/ui/splash/SplashActivity.java | 4 +- .../wulkanowy/ui/splash/SplashContract.java | 2 +- .../wulkanowy/ui/splash/SplashPresenter.java | 5 +- .../main/res/values-pl/prefernces_array.xml | 12 ++++ app/src/main/res/values-pl/strings.xml | 11 ++- app/src/main/res/values/prefernces_array.xml | 33 +++++++++ app/src/main/res/values/strings.xml | 11 ++- app/src/main/res/values/styles.xml | 1 + app/src/main/res/xml/preferences.xml | 38 ++++++++++ 20 files changed, 318 insertions(+), 57 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/ui/main/settings/SettingsFragment.java create mode 100644 app/src/main/res/values-pl/prefernces_array.xml create mode 100644 app/src/main/res/values/prefernces_array.xml create mode 100644 app/src/main/res/xml/preferences.xml diff --git a/app/build.gradle b/app/build.gradle index eb8b9422..d0344eda 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,6 +72,7 @@ dependencies { implementation "com.android.support:design:$supportVersion" implementation "com.android.support:cardview-v7:$supportVersion" implementation "com.android.support:customtabs:$supportVersion" + implementation "com.android.support:preference-v14:$supportVersion" implementation "com.firebase:firebase-jobdispatcher:$firebaseJob" implementation "org.apache.commons:commons-lang3:$apacheLang" implementation "org.apache.commons:commons-collections4:$apacheCollections" diff --git a/app/src/main/java/io/github/wulkanowy/data/Repository.java b/app/src/main/java/io/github/wulkanowy/data/Repository.java index d25be8b5..7b6caa8a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/Repository.java +++ b/app/src/main/java/io/github/wulkanowy/data/Repository.java @@ -68,6 +68,31 @@ public class Repository implements RepositoryContract { return sharedPref.getCurrentUserId(); } + @Override + public int getStartupTab() { + return sharedPref.getStartupTab(); + } + + @Override + public int getServicesInterval() { + return sharedPref.getServicesInterval(); + } + + @Override + public boolean isServicesEnable() { + return sharedPref.isServicesEnable(); + } + + @Override + public boolean isNotifyEnable() { + return sharedPref.isNotifyEnable(); + } + + @Override + public boolean isMobileDisable() { + return sharedPref.isMobileDisable(); + } + @Override public String[] getSymbolsKeysArray() { return resources.getSymbolsKeysArray(); diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryContract.java b/app/src/main/java/io/github/wulkanowy/data/RepositoryContract.java index f06c4762..55287263 100644 --- a/app/src/main/java/io/github/wulkanowy/data/RepositoryContract.java +++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryContract.java @@ -21,6 +21,16 @@ public interface RepositoryContract extends ResourcesContract, AccountSyncContra long getCurrentUserId(); + int getStartupTab(); + + boolean isServicesEnable(); + + boolean isNotifyEnable(); + + int getServicesInterval(); + + boolean isMobileDisable(); + void syncGrades() throws VulcanException, IOException, ParseException; void syncSubjects() throws VulcanException, IOException, ParseException; diff --git a/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPref.java b/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPref.java index ba437f88..6034c99c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPref.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPref.java @@ -2,32 +2,62 @@ package io.github.wulkanowy.data.db.shared; import android.content.Context; import android.content.SharedPreferences; +import android.preference.PreferenceManager; import javax.inject.Inject; import javax.inject.Singleton; import io.github.wulkanowy.di.annotations.ApplicationContext; import io.github.wulkanowy.di.annotations.SharedPreferencesInfo; +import io.github.wulkanowy.ui.main.settings.SettingsFragment; @Singleton public class SharedPref implements SharedPrefContract { private static final String SHARED_KEY_USER_ID = "USER_ID"; - private final SharedPreferences sharedPreferences; + private final SharedPreferences appSharedPref; + + private final SharedPreferences settingsSharedPref; @Inject SharedPref(@ApplicationContext Context context, @SharedPreferencesInfo String sharedName) { - sharedPreferences = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE); + appSharedPref = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE); + settingsSharedPref = PreferenceManager.getDefaultSharedPreferences(context); } @Override public long getCurrentUserId() { - return sharedPreferences.getLong(SHARED_KEY_USER_ID, 0); + return appSharedPref.getLong(SHARED_KEY_USER_ID, 0); } @Override public void setCurrentUserId(long userId) { - sharedPreferences.edit().putLong(SHARED_KEY_USER_ID, userId).apply(); + appSharedPref.edit().putLong(SHARED_KEY_USER_ID, userId).apply(); + } + + @Override + public int getStartupTab() { + return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_START_TAB, "2")); + } + + @Override + public int getServicesInterval() { + return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_SERVICES_INTERVAL, "60")); + } + + @Override + public boolean isServicesEnable() { + return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_ENABLE, true); + } + + @Override + public boolean isNotifyEnable() { + return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_NOTIFY_ENABLE, true); + } + + @Override + public boolean isMobileDisable() { + return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_MOBILE_DISABLED, false); } } diff --git a/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPrefContract.java b/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPrefContract.java index 7f540acf..b00d9e4c 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPrefContract.java +++ b/app/src/main/java/io/github/wulkanowy/data/db/shared/SharedPrefContract.java @@ -5,4 +5,14 @@ public interface SharedPrefContract { long getCurrentUserId(); void setCurrentUserId(long userId); + + int getStartupTab(); + + int getServicesInterval(); + + boolean isMobileDisable(); + + boolean isServicesEnable(); + + boolean isNotifyEnable(); } diff --git a/app/src/main/java/io/github/wulkanowy/services/SyncJob.java b/app/src/main/java/io/github/wulkanowy/services/SyncJob.java index e7b0908f..cefc8207 100644 --- a/app/src/main/java/io/github/wulkanowy/services/SyncJob.java +++ b/app/src/main/java/io/github/wulkanowy/services/SyncJob.java @@ -14,6 +14,7 @@ import com.firebase.jobdispatcher.RetryStrategy; import com.firebase.jobdispatcher.SimpleJobService; import com.firebase.jobdispatcher.Trigger; +import java.util.ArrayList; import java.util.List; import javax.inject.Inject; @@ -27,32 +28,34 @@ import io.github.wulkanowy.utils.LogUtils; public class SyncJob extends SimpleJobService { - private static final int DEFAULT_INTERVAL_START = 60 * 50; - - private static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + (60 * 40); - public static final String EXTRA_INTENT_KEY = "cardId"; - private List gradeList; + public static final String JOB_TAG = "SyncJob"; + + private List gradeList = new ArrayList<>(); @Inject RepositoryContract repository; - public static void start(Context context) { + public static void start(Context context, int interval, boolean useOnlyWifi) { FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context)); dispatcher.mustSchedule(dispatcher.newJobBuilder() .setLifetime(Lifetime.FOREVER) .setService(SyncJob.class) - .setTag("SyncJob") + .setTag(JOB_TAG) .setRecurring(true) - .setTrigger(Trigger.executionWindow(DEFAULT_INTERVAL_START, DEFAULT_INTERVAL_END)) - .setConstraints(Constraint.ON_ANY_NETWORK) + .setTrigger(Trigger.executionWindow(interval * 60, (interval + 10) * 60)) + .setConstraints(useOnlyWifi ? Constraint.ON_UNMETERED_NETWORK : Constraint.ON_ANY_NETWORK) .setReplaceCurrent(false) .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) .build()); } + public static void stop(Context context) { + new FirebaseJobDispatcher(new GooglePlayDriver(context)).cancel(JOB_TAG); + } + @Override public void onCreate() { super.onCreate(); @@ -67,7 +70,7 @@ public class SyncJob extends SimpleJobService { gradeList = repository.getNewGrades(); - if (!gradeList.isEmpty()) { + if (!gradeList.isEmpty() && repository.isNotifyEnable()) { showNotification(); } return JobService.RESULT_SUCCESS; diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/MainActivity.java b/app/src/main/java/io/github/wulkanowy/ui/main/MainActivity.java index cc9b1dc8..3656e167 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/MainActivity.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/MainActivity.java @@ -21,13 +21,12 @@ import io.github.wulkanowy.ui.base.BaseActivity; import io.github.wulkanowy.ui.main.attendance.AttendanceFragment; import io.github.wulkanowy.ui.main.dashboard.DashboardFragment; import io.github.wulkanowy.ui.main.grades.GradesFragment; +import io.github.wulkanowy.ui.main.settings.SettingsFragment; import io.github.wulkanowy.ui.main.timetable.TimetableFragment; public class MainActivity extends BaseActivity implements MainContract.View, AHBottomNavigation.OnTabSelectedListener, OnFragmentIsReadyListener { - private int initTabPosition = 0; - @BindView(R.id.main_activity_nav) AHBottomNavigation bottomNavigation; @@ -52,15 +51,10 @@ public class MainActivity extends BaseActivity implements MainContract.View, super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - initTabPosition = getIntent().getIntExtra(SyncJob.EXTRA_INTENT_KEY, initTabPosition); - getActivityComponent().inject(this); setButterKnife(ButterKnife.bind(this)); - presenter.onStart(this); - - initiationViewPager(); - initiationBottomNav(); + presenter.onStart(this, getIntent().getIntExtra(SyncJob.EXTRA_INTENT_KEY, -1)); } @Override @@ -102,48 +96,44 @@ public class MainActivity extends BaseActivity implements MainContract.View, presenter.onFragmentIsReady(); } - private void initiationBottomNav() { - bottomNavigation.addItem(new AHBottomNavigationItem( - getString(R.string.grades_text), - getResources().getDrawable(R.drawable.ic_menu_grade_26dp) - )); - bottomNavigation.addItem(new AHBottomNavigationItem( - getString(R.string.attendance_text), - getResources().getDrawable(R.drawable.ic_menu_attendance_24dp) - )); - bottomNavigation.addItem(new AHBottomNavigationItem( - getString(R.string.dashboard_text), - getResources().getDrawable(R.drawable.ic_menu_dashboard_24dp) - )); - bottomNavigation.addItem(new AHBottomNavigationItem( - getString(R.string.lessonplan_text), - getResources().getDrawable(R.drawable.ic_menu_timetable_24dp) - )); - bottomNavigation.addItem(new AHBottomNavigationItem( - getString(R.string.settings_text), - getResources().getDrawable(R.drawable.ic_menu_other_24dp) - )); + @Override + public void initiationBottomNav(int tabPosition) { + bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.grades_text), + R.drawable.ic_menu_grade_26dp)); + + bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.attendance_text), + R.drawable.ic_menu_attendance_24dp)); + + bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.dashboard_text), + R.drawable.ic_menu_dashboard_24dp)); + + bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.timetable_text), + R.drawable.ic_menu_timetable_24dp)); + + bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.settings_text), + R.drawable.ic_menu_other_24dp)); bottomNavigation.setAccentColor(getResources().getColor(R.color.colorPrimary)); bottomNavigation.setInactiveColor(Color.BLACK); bottomNavigation.setBackgroundColor(getResources().getColor(R.color.colorBackgroundBottomNav)); bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW); bottomNavigation.setOnTabSelectedListener(this); - bottomNavigation.setCurrentItem(initTabPosition); + bottomNavigation.setCurrentItem(tabPosition); bottomNavigation.setBehaviorTranslationEnabled(false); } - private void initiationViewPager() { + @Override + public void initiationViewPager(int tabPosition) { pagerAdapter.addFragment(new GradesFragment()); pagerAdapter.addFragment(new AttendanceFragment()); pagerAdapter.addFragment(new DashboardFragment()); pagerAdapter.addFragment(new TimetableFragment()); - pagerAdapter.addFragment(new DashboardFragment()); + pagerAdapter.addFragment(new SettingsFragment()); viewPager.setPagingEnabled(false); viewPager.setAdapter(pagerAdapter); viewPager.setOffscreenPageLimit(4); - viewPager.setCurrentItem(initTabPosition, false); + viewPager.setCurrentItem(tabPosition, false); } @Override diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/MainContract.java b/app/src/main/java/io/github/wulkanowy/ui/main/MainContract.java index cb1d5d7c..d4d8156b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/MainContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/MainContract.java @@ -14,11 +14,17 @@ public interface MainContract { void showActionBar(); void hideActionBar(); + + void initiationViewPager(int tabPosition); + + void initiationBottomNav(int tabPosition); } @PerActivity interface Presenter extends BaseContract.Presenter { + void onStart(View view, int tabPositionIntent); + void onTabSelected(int position, boolean wasSelected); void onFragmentIsReady(); diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/MainPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/main/MainPresenter.java index 149e49e2..6a727b7a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/MainPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/MainPresenter.java @@ -17,10 +17,21 @@ public class MainPresenter extends BasePresenter } @Override - public void onStart(MainContract.View view) { + public void onStart(MainContract.View view, int tabPositionIntent) { super.onStart(view); getView().showProgressBar(true); getView().hideActionBar(); + + int tabPosition; + + if (tabPositionIntent != -1) { + tabPosition = tabPositionIntent; + } else { + tabPosition = getRepository().getStartupTab(); + } + + getView().initiationBottomNav(tabPosition); + getView().initiationViewPager(tabPosition); } @Override @@ -32,11 +43,11 @@ public class MainPresenter extends BasePresenter @Override public void onFragmentIsReady() { - if (fragmentCount < 5) { + if (fragmentCount < 4) { fragmentCount++; } - if (fragmentCount == 5) { + if (fragmentCount == 4) { getView().showActionBar(); getView().showProgressBar(false); } diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/settings/SettingsFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/settings/SettingsFragment.java new file mode 100644 index 00000000..d1483123 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/main/settings/SettingsFragment.java @@ -0,0 +1,70 @@ +package io.github.wulkanowy.ui.main.settings; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v7.preference.PreferenceFragmentCompat; + +import io.github.wulkanowy.R; +import io.github.wulkanowy.services.SyncJob; + +public class SettingsFragment extends PreferenceFragmentCompat + implements SharedPreferences.OnSharedPreferenceChangeListener { + + public static final String SHARED_KEY_START_TAB = "startup_tab"; + + public static final String SHARED_KEY_SERVICES_ENABLE = "services_enable"; + + public static final String SHARED_KEY_NOTIFY_ENABLE = "notify_enable"; + + public static final String SHARED_KEY_SERVICES_INTERVAL = "services_interval"; + + public static final String SHARED_KEY_SERVICES_MOBILE_DISABLED = "services_disable_mobile"; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + addPreferencesFromResource(R.xml.preferences); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(SHARED_KEY_SERVICES_ENABLE) || key.equals(SHARED_KEY_SERVICES_INTERVAL) + || key.equals(SHARED_KEY_SERVICES_MOBILE_DISABLED)) { + launchServices(sharedPreferences.getBoolean(SHARED_KEY_SERVICES_ENABLE, true), + sharedPreferences); + } + } + + private void launchServices(boolean start, SharedPreferences sharedPref) { + if (start) { + int newInterval = Integer.parseInt(sharedPref.getString(SHARED_KEY_SERVICES_INTERVAL, "60")); + boolean useOnlyWifi = sharedPref.getBoolean(SHARED_KEY_SERVICES_MOBILE_DISABLED, false); + + SyncJob.stop(getContext()); + SyncJob.start(getContext(), newInterval, useOnlyWifi); + } else { + SyncJob.stop(getContext()); + } + } + + @Override + public void setMenuVisibility(boolean menuVisible) { + super.setMenuVisibility(menuVisible); + if (menuVisible) { + getActivity().setTitle(R.string.settings_text); + } + } + + @Override + public void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onPause() { + super.onPause(); + getPreferenceScreen().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java index 2df28df2..5d9d96bf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java +++ b/app/src/main/java/io/github/wulkanowy/ui/main/timetable/TimetableFragment.java @@ -80,7 +80,7 @@ public class TimetableFragment extends BaseFragment implements TimetableContract @Override public void setActivityTitle() { - setTitle(getString(R.string.lessonplan_text)); + setTitle(getString(R.string.timetable_text)); } @Override diff --git a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashActivity.java b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashActivity.java index c9f98d5e..3eb3fdfe 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashActivity.java +++ b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashActivity.java @@ -44,7 +44,7 @@ public class SplashActivity extends BaseActivity implements SplashContract.View } @Override - public void startSyncService() { - SyncJob.start(getApplicationContext()); + public void startSyncService(int interval, boolean useOnlyWifi) { + SyncJob.start(getApplicationContext(), interval, useOnlyWifi); } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashContract.java b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashContract.java index a69deb03..515c842f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashContract.java +++ b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashContract.java @@ -12,7 +12,7 @@ public interface SplashContract { void openMainActivity(); - void startSyncService(); + void startSyncService(int interval, boolean useOnlyWifi); } @PerActivity diff --git a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashPresenter.java b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashPresenter.java index c3d81215..165fc4ff 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/splash/SplashPresenter.java +++ b/app/src/main/java/io/github/wulkanowy/ui/splash/SplashPresenter.java @@ -18,7 +18,10 @@ public class SplashPresenter extends BasePresenter @Override public void onStart(@NonNull SplashContract.View activity) { super.onStart(activity); - getView().startSyncService(); + if (getRepository().isServicesEnable()) { + getView().startSyncService(getRepository().getServicesInterval(), + getRepository().isMobileDisable()); + } if (getRepository().getCurrentUserId() == 0) { getView().openLoginActivity(); diff --git a/app/src/main/res/values-pl/prefernces_array.xml b/app/src/main/res/values-pl/prefernces_array.xml new file mode 100644 index 00000000..4e66a373 --- /dev/null +++ b/app/src/main/res/values-pl/prefernces_array.xml @@ -0,0 +1,12 @@ + + + + 10 minut + 30 minut + 1 godzinę + 2 godziny + 6 godzin + 12 godzin + 24 godzin + + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 244f39e8..da84ba42 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -33,7 +33,7 @@ Dashboard Oceny Frekwencja - Plan lekcji + Plan lekcji Ustawienia Ta część aplikacji jest w budowie Brak ocen @@ -113,4 +113,13 @@ %1$d nieobecności %1$d nieobecności + + Widok + Domyślny widok + Powiadomienia + Pokazuj powiadomienia + Usługi + Włącz odświeżanie danych w tle + Interwał między odświeżaniem danych + Synchronizacja tylko przez WiFi diff --git a/app/src/main/res/values/prefernces_array.xml b/app/src/main/res/values/prefernces_array.xml new file mode 100644 index 00000000..8bf159f3 --- /dev/null +++ b/app/src/main/res/values/prefernces_array.xml @@ -0,0 +1,33 @@ + + + + @string/grades_text + @string/attendance_text + @string/dashboard_text + @string/timetable_text + + + 0 + 1 + 2 + 3 + + + 10 minutes + 30 minutes + 1 hour + 2 hours + 6 hours + 12 hours + 24 hours + + + 10 + 30 + 60 + 120 + 360 + 720 + 1440 + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b4b6c0c0..0c039698 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,7 +33,7 @@ Dashboard Grades Attendance - Timetable + Timetable Settings This section of app is under construction. No grades @@ -109,4 +109,13 @@ %1$d absences %1$d absences + + Default view after startup + View + Notifications + Show the notifications + Services + Enable background data refreshing + Interval between data refreshing + Synchronization via WiFi only diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ed5c249d..fff8e94c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -13,6 +13,7 @@ @android:color/primary_text_dark @android:color/primary_text_dark @android:color/white + @style/PreferenceThemeOverlay.v14.Material