Compare commits

...

9 Commits
0.6.4 ... 0.6.6

38 changed files with 102 additions and 95 deletions

View File

@ -159,7 +159,7 @@ jobs:
openssl aes-256-cbc -d -in ./app/upload-key-encrypted.jks -k $ENCRYPT_KEY >> ./app/upload-key.jks
- run:
name: Publish release
command: ./gradlew publishRelease --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
command: ./gradlew publish --no-daemon --stacktrace --console=plain -PenableCrashlytics -PdisablePreDex
workflows:
version: 2

View File

@ -11,6 +11,10 @@ cache:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
#branches:
# only:
# - master
android:
licenses:
- android-sdk-preview-license-.+
@ -56,7 +60,7 @@ script:
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
./gradlew publishRelease -PenableCrashlytics --stacktrace;
./gradlew publish -PenableCrashlytics --stacktrace;
fi
after_success:

View File

@ -11,24 +11,16 @@ android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
playAccountConfigs {
defaultAccountConfig {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL")
pk12File = file('key.p12')
}
}
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15
targetSdkVersion 28
versionCode 23
versionName "0.6.4"
versionCode 25
versionName "0.6.6"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
playAccountConfig = playAccountConfigs.defaultAccountConfig
manifestPlaceholders = [
fabric_api_key: System.getenv("FABRIC_API_KEY") ?: "null",
crashlytics_enabled: project.hasProperty("enableCrashlytics")
@ -48,7 +40,6 @@ android {
release {
buildConfigField "boolean", "CRASHLYTICS_ENABLED", "true"
minifyEnabled true
useProguard false
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
@ -73,14 +64,16 @@ androidExtensions {
}
play {
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
serviceAccountCredentials = file('key.p12')
defaultToAppBundles = true
track = 'alpha'
uploadImages = false
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation('io.github.wulkanowy:api:0.6.4') { exclude module: "threetenbp" }
implementation('io.github.wulkanowy:api:0.6.6') { exclude module: "threetenbp" }
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.appcompat:appcompat:1.0.2"

View File

@ -5,6 +5,7 @@
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-dontobfuscate
-allowaccessmodification
-repackageclasses ''
-verbose
@ -13,7 +14,6 @@
#Config for anallitycs
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
-keep class com.crashlytics.** {*;}
-keep public class * extends java.lang.Exception
-dontwarn com.crashlytics.**

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.local.StudentLocal
import io.github.wulkanowy.data.repositories.remote.StudentRemote
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
@ -41,7 +42,9 @@ class StudentRepository @Inject constructor(
}
fun getCurrentStudent(decryptPass: Boolean = true): Single<Student> {
return local.getCurrentStudent(decryptPass).toSingle()
return local.getCurrentStudent(decryptPass)
.switchIfEmpty(Maybe.error(NoSuchElementException("No current student")))
.toSingle()
}
fun saveStudent(student: Student): Single<Long> {

View File

@ -80,21 +80,24 @@ class SyncWorker : SimpleJobService() {
val end = LocalDate.now().friday
if (start.isHolidays) return RESULT_FAIL_NORETRY
if (!student.isStudentSaved) return RESULT_FAIL_RETRY
var error: Throwable? = null
val notify = prefRepository.isNotificationsEnable
disposable.add(student.getCurrentStudent()
.flatMap { semester.getCurrentSemester(it, true).map { semester -> semester to it } }
.flatMapPublisher {
Single.merge(
listOf(
gradesDetails.getGrades(it.first, true, true),
gradesDetails.getGrades(it.first, true, notify),
gradesSummary.getGradesSummary(it.first, true),
attendance.getAttendance(it.first, start, end, true),
exam.getExams(it.first, start, end, true),
timetable.getTimetable(it.first, start, end, true),
message.getMessages(it.second, RECEIVED, true, true),
note.getNotes(it.first, true, true),
message.getMessages(it.second, RECEIVED, true, notify),
note.getNotes(it.first, true, notify),
homework.getHomework(it.first, LocalDate.now(), true),
homework.getHomework(it.first, LocalDate.now().plusDays(1), true)
)
@ -103,7 +106,7 @@ class SyncWorker : SimpleJobService() {
.subscribe({}, { error = it }))
return if (null === error) {
if (prefRepository.isNotificationsEnable) sendNotifications()
if (notify) sendNotifications()
Timber.d("Synchronization successful")
RESULT_SUCCESS
} else {

View File

@ -0,0 +1,36 @@
package io.github.wulkanowy.ui.base
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
class BaseFragmentPagerAdapter(private val fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {
private val pages = mutableMapOf<Fragment, String?>()
private var containerId = 0
fun getFragmentInstance(position: Int): Fragment? {
return fragmentManager.findFragmentByTag("android:switcher:$containerId:$position")
}
fun addFragments(fragments: List<Fragment>) {
fragments.forEach { pages[it] = null }
}
fun addFragmentsWithTitle(pages: Map<Fragment, String>) {
this.pages.putAll(pages)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
containerId = container.id
return super.instantiateItem(container, position)
}
override fun getItem(position: Int) = pages.keys.elementAt(position)
override fun getCount() = pages.size
override fun getPageTitle(position: Int) = pages.values.elementAt(position)
}

View File

@ -1,32 +0,0 @@
package io.github.wulkanowy.ui.base
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter
class BasePagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
val fragments = mutableMapOf<String?, Fragment>()
val registeredFragments = mutableMapOf<Int, Fragment>()
override fun getItem(position: Int) = fragments.values.elementAt(position)
override fun getCount() = fragments.size
override fun getPageTitle(position: Int): CharSequence? {
return fragments.keys.elementAtOrNull(position)
}
override fun instantiateItem(container: ViewGroup, position: Int): Any {
return super.instantiateItem(container, position).also {
registeredFragments[position] = it as Fragment
}
}
override fun destroyItem(container: ViewGroup, position: Int, fragment: Any) {
registeredFragments.remove(position)
super.destroyItem(container, position, fragment)
}
}

View File

@ -11,7 +11,7 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.base.session.BaseSessionFragment
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
@ -26,7 +26,7 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
lateinit var presenter: GradePresenter
@Inject
lateinit var pagerAdapter: BasePagerAdapter
lateinit var pagerAdapter: BaseFragmentPagerAdapter
companion object {
private const val SAVED_SEMESTER_KEY = "CURRENT_SEMESTER"
@ -59,10 +59,11 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
}
override fun initView() {
pagerAdapter.fragments.putAll(mapOf(
getString(R.string.all_details) to GradeDetailsFragment.newInstance(),
getString(R.string.grade_menu_summary) to GradeSummaryFragment.newInstance()
pagerAdapter.addFragmentsWithTitle(mapOf(
GradeDetailsFragment.newInstance() to getString(R.string.all_details),
GradeSummaryFragment.newInstance() to getString(R.string.grade_menu_summary)
))
gradeViewPager.run {
adapter = pagerAdapter
setOnSelectPageListener { presenter.onPageSelected(it) }
@ -117,15 +118,15 @@ class GradeFragment : BaseSessionFragment(), GradeView, MainView.MainChildView,
}
override fun notifyChildLoadData(index: Int, semesterId: Int, forceRefresh: Boolean) {
(childFragmentManager.fragments[index] as GradeView.GradeChildView).onParentLoadData(semesterId, forceRefresh)
(pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentLoadData(semesterId, forceRefresh)
}
override fun notifyChildParentReselected(index: Int) {
(pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentReselected()
(pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentReselected()
}
override fun notifyChildSemesterChange(index: Int) {
(pagerAdapter.registeredFragments[index] as? GradeView.GradeChildView)?.onParentChangeSemester()
(pagerAdapter.getFragmentInstance(index) as? GradeView.GradeChildView)?.onParentChangeSemester()
}
override fun onSaveInstanceState(outState: Bundle) {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerChildFragment
import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.grade.details.GradeDetailsFragment
import io.github.wulkanowy.ui.modules.grade.summary.GradeSummaryFragment
@ -18,7 +18,7 @@ abstract class GradeModule {
@JvmStatic
@PerFragment
@Provides
fun provideGradePagerAdapter(fragment: GradeFragment) = BasePagerAdapter(fragment.childFragmentManager)
fun provideGradeAdapter(fragment: GradeFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
}
@PerChildFragment

View File

@ -5,7 +5,7 @@ import android.content.Intent
import android.os.Bundle
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
import io.github.wulkanowy.utils.setOnSelectPageListener
@ -18,7 +18,7 @@ class LoginActivity : BaseActivity(), LoginView {
lateinit var presenter: LoginPresenter
@Inject
lateinit var loginAdapter: BasePagerAdapter
lateinit var loginAdapter: BaseFragmentPagerAdapter
companion object {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
@ -36,9 +36,9 @@ class LoginActivity : BaseActivity(), LoginView {
}
override fun initAdapter() {
loginAdapter.fragments.putAll(mapOf(
"1" to LoginFormFragment.newInstance(),
"2" to LoginOptionsFragment.newInstance()
loginAdapter.addFragments(listOf(
LoginFormFragment.newInstance(),
LoginOptionsFragment.newInstance()
))
loginViewpager.run {
@ -52,7 +52,7 @@ class LoginActivity : BaseActivity(), LoginView {
}
override fun notifyOptionsViewLoadData() {
(supportFragmentManager.fragments[1] as? LoginOptionsFragment)?.onParentLoadData()
(loginAdapter.getFragmentInstance(1) as? LoginOptionsFragment)?.onParentLoadData()
}
fun onChildFragmentSwitchOptions() {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerActivity
import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.options.LoginOptionsFragment
@ -18,7 +18,7 @@ internal abstract class LoginModule {
@JvmStatic
@PerActivity
@Provides
fun provideLoginAdapter(activity: LoginActivity) = BasePagerAdapter(activity.supportFragmentManager)
fun provideLoginAdapter(activity: LoginActivity) = BaseFragmentPagerAdapter(activity.supportFragmentManager)
}
@PerFragment

View File

@ -11,7 +11,7 @@ import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.RE
import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.SENT
import io.github.wulkanowy.data.repositories.MessagesRepository.MessageFolder.TRASHED
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
import io.github.wulkanowy.utils.setOnSelectPageListener
@ -24,7 +24,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
lateinit var presenter: MessagePresenter
@Inject
lateinit var pagerAdapter: BasePagerAdapter
lateinit var pagerAdapter: BaseFragmentPagerAdapter
companion object {
fun newInstance() = MessageFragment()
@ -46,11 +46,12 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
}
override fun initView() {
pagerAdapter.fragments.putAll(mapOf(
getString(R.string.message_inbox) to MessageTabFragment.newInstance(RECEIVED),
getString(R.string.message_sent) to MessageTabFragment.newInstance(SENT),
getString(R.string.message_trash) to MessageTabFragment.newInstance(TRASHED)
pagerAdapter.addFragmentsWithTitle(mapOf(
MessageTabFragment.newInstance(RECEIVED) to getString(R.string.message_inbox),
MessageTabFragment.newInstance(SENT) to getString(R.string.message_sent),
MessageTabFragment.newInstance(TRASHED) to getString(R.string.message_trash)
))
messageViewPager.run {
adapter = pagerAdapter
offscreenPageLimit = 2
@ -73,7 +74,7 @@ class MessageFragment : BaseFragment(), MessageView, MainView.TitledView {
}
override fun notifyChildLoadData(index: Int, forceRefresh: Boolean) {
(childFragmentManager.fragments[index] as MessageView.MessageChildView).onParentLoadData(forceRefresh)
(pagerAdapter.getFragmentInstance(index) as? MessageView.MessageChildView)?.onParentLoadData(forceRefresh)
}
override fun onDestroyView() {

View File

@ -5,7 +5,7 @@ import dagger.Provides
import dagger.android.ContributesAndroidInjector
import io.github.wulkanowy.di.scopes.PerChildFragment
import io.github.wulkanowy.di.scopes.PerFragment
import io.github.wulkanowy.ui.base.BasePagerAdapter
import io.github.wulkanowy.ui.base.BaseFragmentPagerAdapter
import io.github.wulkanowy.ui.modules.message.tab.MessageTabFragment
@Module
@ -17,7 +17,7 @@ abstract class MessageModule {
@JvmStatic
@PerFragment
@Provides
fun provideGradePagerAdapter(fragment: MessageFragment) = BasePagerAdapter(fragment.childFragmentManager)
fun provideMessageAdapter(fragment: MessageFragment) = BaseFragmentPagerAdapter(fragment.childFragmentManager)
}
@PerChildFragment

View File

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

View File

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,10 +0,0 @@
Wersja 0.6.4
- naprawiono problemy ze stabilnością podczas logowania na urządzeniach marki Meizu
- naprawiono problemy ze stabilnością w uwagach
- naprawiono błąd pobierania podglądu wiadomości, gdy otworzono aplikację z powiadomienia
- zoptymalizowano pobieranie wiadomości wysłanych
- poprawiono wyświetlanie odbiorców wiadomości wysłanych
- naprawiono problem z liczeniem średniej z ocen zawierających minus
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases/tag/0.6.4

View File

@ -0,0 +1,7 @@
Wersja 0.6.6
- poprawiono problemy ze stabilnością w widoku ocen i wiadomości
- naprawiono wyświetlanie powiadomień po ich ponownym włączeniu po długim czasie
- ograniczono ilość zbędnych informacji na widżecie planu lekcji
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases/tag/0.6.6

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z" />
android:pathData="M21,17V8H7V17H21M21,3A2,2 0,0 1,23 5V17A2,2 0,0 1,21 19H7C5.89,19 5,18.1 5,17V5A2,2 0,0 1,7 3H8V1H10V3H18V1H20V3H21M3,21H17V23H3C1.89,23 1,22.1 1,21V9H3V21M19,15H15V11H19V15Z" />
</vector>

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.11'
ext.kotlin_version = '1.3.20'
repositories {
mavenCentral()
google()
@ -12,7 +12,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.google.gms:google-services:4.2.0'
classpath "io.fabric.tools:gradle:1.27.0"
classpath "com.github.triplet.gradle:play-publisher:1.2.2"
classpath "com.github.triplet.gradle:play-publisher:2.1.0"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7"
classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'
}

View File

@ -11,6 +11,7 @@
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
android.enableR8=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.