mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-14 06:30:18 +02:00
Compare commits
14 Commits
v4.0-beta.
...
v4.0-rc.2
Author | SHA1 | Date | |
---|---|---|---|
30b6ac2a06 | |||
a7fa7cb5e4 | |||
f3e87f9016 | |||
a983af6c28 | |||
114c841f0c | |||
e271048577 | |||
b8c5925e82 | |||
9bda6c8869 | |||
d1608d308c | |||
b8e1e1d33a | |||
8099a037e7 | |||
af23c932a6 | |||
4edabbb186 | |||
37a5bea79b |
@ -128,6 +128,7 @@ dependencies {
|
||||
implementation "com.mikepenz:iconics-core:${versions.iconics}"
|
||||
implementation "com.mikepenz:iconics-views:${versions.iconics}"
|
||||
implementation "com.mikepenz:community-material-typeface:${versions.font_cmd}@aar"
|
||||
implementation "com.mikepenz:materialize:1.2.1"
|
||||
|
||||
implementation "com.github.kuba2k2:NavLib:${versions.navlib}"
|
||||
|
||||
|
@ -31,6 +31,12 @@
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||
|
||||
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
|
||||
-keepclassmembernames class androidx.appcompat.view.menu.StandardMenuPopup { private *; }
|
||||
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }
|
||||
|
||||
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
||||
|
||||
-keep class .R
|
||||
-keep class **.R$* {
|
||||
<fields>;
|
||||
|
@ -1,12 +1,13 @@
|
||||
<h3>Wersja 4.0-beta.14, 2020-03-24</h3>
|
||||
<h3>Wersja 4.0-rc.2, 2020-03-26</h3>
|
||||
<ul>
|
||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkość oraz poprawność pobieranych danych.</li>
|
||||
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkość oraz poprawność pobieranych danych</li>
|
||||
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
||||
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
||||
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
||||
<li>Nowe <b>Oceny</b> - z możliwością zmiany wartości plusów oraz minusów oraz wyłączenia niektórych ocen ze średniej</li>
|
||||
<li>Opcja wyłączenia wybranych powiadomień z aplikacji</li>
|
||||
<li>Znaczki nieprzeczytanych informacji na obrazkach profili.</li>
|
||||
<br>
|
||||
<br>
|
||||
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
||||
@ -21,18 +22,8 @@
|
||||
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
||||
<li>Usunąłem denerwujący brak zaznaczenia w lewym menu</li>
|
||||
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
||||
<li><strike>Występują natomiast nowe błędy, dlatego proszę o ich zgłaszanie :)</strike></li>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<b>Uwaga.</b> Ponieważ to wersja <i>beta</i>, niektóre funkcje mogą nie działać prawidłowo.<br>
|
||||
Staramy się usuwać takie przypadki, jednak na chwilę obecną mogą występować błędy w:
|
||||
<ul>
|
||||
<li>Wysyłanie wiadomości może nie działać w pełni prawidłowo - proszę o zgłaszanie wszystkich błędów na naszym serwerze Discord</li>
|
||||
</ul>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Dzięki za korzystanie ze Szkolnego!<br>
|
||||
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
/*secret password - removed for source code publication*/
|
||||
static toys AES_IV[16] = {
|
||||
0xc4, 0x97, 0xfb, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
0x30, 0xfe, 0xe2, 0x8d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||
|
||||
|
@ -28,9 +28,6 @@ import com.hypertrack.hyperlog.HyperLog
|
||||
import com.mikepenz.iconics.Iconics
|
||||
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||
import im.wangchao.mhttp.MHttp
|
||||
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar
|
||||
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache
|
||||
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor
|
||||
import kotlinx.coroutines.*
|
||||
import me.leolin.shortcutbadger.ShortcutBadger
|
||||
import okhttp3.OkHttpClient
|
||||
@ -41,6 +38,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.network.NetworkUtils
|
||||
import pl.szczodrzynski.edziennik.network.cookie.DumbCookieJar
|
||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||
@ -125,7 +123,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
.followSslRedirects(false)
|
||||
.build()
|
||||
}
|
||||
val cookieJar by lazy { PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(this)) }
|
||||
val cookieJar by lazy { DumbCookieJar(this) }
|
||||
|
||||
/* _____ _ _
|
||||
/ ____(_) | |
|
||||
|
@ -31,8 +31,8 @@ import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
import com.mikepenz.materialdrawer.model.utils.withIsHiddenInMiniDrawer
|
||||
import kotlinx.coroutines.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
@ -90,7 +90,6 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
import pl.szczodrzynski.navlib.drawer.items.withAppTitle
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
@ -361,7 +360,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
false
|
||||
}
|
||||
drawerProfileLongClickListener = { _, profile, _, view ->
|
||||
if (profile is ProfileDrawerItem) {
|
||||
if (view != null && profile is ProfileDrawerItem) {
|
||||
showProfileContextMenu(profile, view)
|
||||
true
|
||||
}
|
||||
@ -915,7 +914,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
bottomSheet.removeAllContextual()
|
||||
bottomSheet.toggleGroupEnabled = false
|
||||
drawer.close()
|
||||
drawer.setSelection(target.id, fireOnClick = false)
|
||||
if (drawer.getSelection() != target.id)
|
||||
drawer.setSelection(target.id, fireOnClick = false)
|
||||
navView.toolbar.setTitle(target.title ?: target.name)
|
||||
navView.bottomBar.fabEnable = false
|
||||
navView.bottomBar.fabExtended = false
|
||||
@ -1063,7 +1063,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
val item = DrawerPrimaryItem()
|
||||
.withIdentifier(target.id.toLong())
|
||||
.withName(target.name)
|
||||
.withHiddenInMiniDrawer(!app.config.ui.miniMenuButtons.contains(target.id))
|
||||
.withIsHiddenInMiniDrawer(!app.config.ui.miniMenuButtons.contains(target.id))
|
||||
.also { if (target.description != null) it.withDescription(target.description!!) }
|
||||
.also { if (target.icon != null) it.withIcon(target.icon!!) }
|
||||
.also { if (target.title != null) it.withAppTitle(getString(target.title!!)) }
|
||||
@ -1127,7 +1127,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
drawer.addProfileSettings(*drawerProfiles.toTypedArray())
|
||||
}
|
||||
|
||||
private fun showProfileContextMenu(profile: IProfile<*>, view: View) {
|
||||
private fun showProfileContextMenu(profile: IProfile, view: View) {
|
||||
val profileId = profile.identifier.toInt()
|
||||
val popupMenu = PopupMenu(this, view)
|
||||
popupMenu.menu.add(0, 1, 1, R.string.profile_menu_open_settings)
|
||||
@ -1140,7 +1140,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
}
|
||||
loadTarget(DRAWER_ITEM_SETTINGS, null)
|
||||
} else if (item.itemId == 2) {
|
||||
ProfileRemoveDialog(this, profileId, profile.name?.getText(this)?.toString() ?: "?")
|
||||
ProfileRemoveDialog(this, profileId, profile.name?.getText(this) ?: "?")
|
||||
}
|
||||
true
|
||||
}
|
||||
|
@ -70,13 +70,13 @@ val librusLoginMethods = listOf(
|
||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, LibrusLoginSynergia::class.java)
|
||||
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
||||
.withRequiredLoginMethod { profile, _ ->
|
||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED
|
||||
if (profile?.hasStudentData("accountPassword") == false || true) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED
|
||||
},
|
||||
|
||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, LibrusLoginMessages::class.java)
|
||||
.withIsPossible { _, loginStore -> !loginStore.hasLoginData("fakeLogin") }
|
||||
.withRequiredLoginMethod { profile, _ ->
|
||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED
|
||||
if (profile?.hasStudentData("accountPassword") == false || true) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -7,7 +7,6 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
@ -43,8 +42,8 @@ open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Lon
|
||||
|
||||
if (semester == null && url.contains("start")) {
|
||||
profile?.also { profile ->
|
||||
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
||||
val semesterCookie = cookies.firstOrNull { it.name() == "semester" }?.value()?.toIntOrNull()
|
||||
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
||||
val semesterCookie = cookies["semester"]?.toIntOrNull()
|
||||
|
||||
semesterCookie?.let { data.currentSemester = it }
|
||||
|
||||
@ -75,13 +74,7 @@ open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Lon
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("sessionid")
|
||||
.value(data.webSessionId!!)
|
||||
.domain("dziennikel.appspot.com")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("dziennikel.appspot.com", "sessionid", data.webSessionId)
|
||||
|
||||
Request.builder()
|
||||
.url(url)
|
||||
|
@ -24,7 +24,7 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
||||
onSuccess()
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("dziennikel.appspot.com")
|
||||
data.app.cookieJar.clear("dziennikel.appspot.com")
|
||||
if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
||||
loginWithCredentials()
|
||||
}
|
||||
@ -59,8 +59,8 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
||||
}
|
||||
}
|
||||
|
||||
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
||||
val sessionId = cookies.firstOrNull { it.name() == "sessionid" }?.value()
|
||||
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
||||
val sessionId = cookies["sessionid"]
|
||||
|
||||
if (sessionId == null) {
|
||||
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
||||
|
@ -5,7 +5,6 @@
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
||||
|
||||
import androidx.core.util.set
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_API
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_WEB
|
||||
@ -24,18 +23,8 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
|
||||
loginMethods.clear()
|
||||
if (isWebLoginValid()) {
|
||||
loginMethods += LOGIN_METHOD_IDZIENNIK_WEB
|
||||
app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("ASP.NET_SessionId_iDziennik")
|
||||
.value(webSessionId!!)
|
||||
.domain("iuczniowie.progman.pl")
|
||||
.secure().httpOnly().build(),
|
||||
Cookie.Builder()
|
||||
.name(".ASPXAUTH")
|
||||
.value(webAuth!!)
|
||||
.domain("iuczniowie.progman.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", webSessionId)
|
||||
app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", webAuth)
|
||||
}
|
||||
if (isApiLoginValid())
|
||||
loginMethods += LOGIN_METHOD_IDZIENNIK_API
|
||||
|
@ -7,7 +7,6 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||
@ -24,22 +23,12 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
||||
|
||||
init { run {
|
||||
if (data.isWebLoginValid()) {
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("ASP.NET_SessionId_iDziennik")
|
||||
.value(data.webSessionId!!)
|
||||
.domain("iuczniowie.progman.pl")
|
||||
.secure().httpOnly().build(),
|
||||
Cookie.Builder()
|
||||
.name(".ASPXAUTH")
|
||||
.value(data.webAuth!!)
|
||||
.domain("iuczniowie.progman.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", data.webSessionId)
|
||||
data.app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", data.webAuth)
|
||||
onSuccess()
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("iuczniowie.progman.pl")
|
||||
data.app.cookieJar.clear("iuczniowie.progman.pl")
|
||||
if (data.webSchoolName != null && data.webUsername != null && data.webPassword != null) {
|
||||
loginWithCredentials()
|
||||
}
|
||||
@ -62,11 +51,11 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
||||
|
||||
// login succeeded: there is a start page
|
||||
if (text.contains("czyWyswietlicDostepMobilny")) {
|
||||
val cookies = data.app.cookieJar.getForDomain("iuczniowie.progman.pl")
|
||||
val cookies = data.app.cookieJar.getAll("iuczniowie.progman.pl")
|
||||
run {
|
||||
data.webSessionId = cookies.singleOrNull { it.name() == "ASP.NET_SessionId_iDziennik" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
|
||||
data.webAuth = cookies.singleOrNull { it.name() == ".ASPXAUTH" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
|
||||
data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
||||
data.webSessionId = cookies["ASP.NET_SessionId_iDziennik"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
|
||||
data.webAuth = cookies[".ASPXAUTH"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
|
||||
data.apiBearer = cookies["Bearer"]?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
||||
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
||||
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.librus
|
||||
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_API
|
||||
@ -31,23 +30,11 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
loginMethods += LOGIN_METHOD_LIBRUS_API
|
||||
if (isSynergiaLoginValid()) {
|
||||
loginMethods += LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(synergiaSessionId!!)
|
||||
.domain("synergia.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
app.cookieJar.set("synergia.librus.pl", "DZIENNIKSID", synergiaSessionId)
|
||||
}
|
||||
if (isMessagesLoginValid()) {
|
||||
loginMethods += LOGIN_METHOD_LIBRUS_MESSAGES
|
||||
app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(messagesSessionId!!)
|
||||
.domain("wiadomosci.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
app.cookieJar.set("wiadomosci.librus.pl", "DZIENNIKSID", messagesSessionId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ val LibrusFeatures = listOf(
|
||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_PUSH_CONFIG, listOf(
|
||||
ENDPOINT_LIBRUS_API_PUSH_CONFIG to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
||||
!data.app.config.sync.tokenLibrusList.contains(data.profileId)
|
||||
(data as DataLibrus).isPremium && !data.app.config.sync.tokenLibrusList.contains(data.profileId)
|
||||
},
|
||||
|
||||
|
||||
@ -116,11 +116,11 @@ val LibrusFeatures = listOf(
|
||||
* Homework - using API.
|
||||
* Sync only if account has premium access.
|
||||
*/
|
||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||
/*Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||
ENDPOINT_LIBRUS_API_HOMEWORK to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)).withShouldSync { data ->
|
||||
(data as DataLibrus).isPremium
|
||||
},
|
||||
},*/
|
||||
/**
|
||||
* Behaviour - using API.
|
||||
*/
|
||||
@ -227,9 +227,9 @@ val LibrusFeatures = listOf(
|
||||
*/
|
||||
Feature(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||
ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)).withShouldSync { data ->
|
||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA))/*.withShouldSync { data ->
|
||||
!(data as DataLibrus).isPremium
|
||||
},
|
||||
}*/,
|
||||
|
||||
/**
|
||||
* Messages inbox - using messages website.
|
||||
|
@ -12,7 +12,6 @@ import im.wangchao.mhttp.body.MediaTypeUtils
|
||||
import im.wangchao.mhttp.callback.FileCallbackHandler
|
||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import org.json.JSONObject
|
||||
import org.json.XML
|
||||
import org.jsoup.Jsoup
|
||||
@ -89,14 +88,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(data.messagesSessionId!!)
|
||||
.domain("wiadomosci.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
|
||||
data.app.cookieJar.set("wiadomosci.librus.pl", "DZIENNIKSID", data.messagesSessionId)
|
||||
|
||||
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
val doc = docBuilder.newDocument()
|
||||
@ -180,14 +172,7 @@ open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(data.messagesSessionId!!)
|
||||
.domain("wiadomosci.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
|
||||
data.app.cookieJar.set("wiadomosci.librus.pl", "DZIENNIKSID", data.messagesSessionId)
|
||||
|
||||
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
|
||||
val doc = docBuilder.newDocument()
|
||||
|
@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
class LibrusApiAttendances(override val data: DataLibrus,
|
||||
override val lastSync: Long?,
|
||||
@ -45,7 +46,7 @@ class LibrusApiAttendances(override val data: DataLibrus,
|
||||
val typeObject = data.attendanceTypes[type] ?: null
|
||||
val topic = typeObject?.name ?: ""
|
||||
|
||||
val startTime = data.lessonRanges.get(lessonNo).startTime
|
||||
val startTime = data.lessonRanges.get(lessonNo)?.startTime
|
||||
|
||||
val lesson = if (lessonId != -1L)
|
||||
data.librusLessons.singleOrNull { it.lessonId == lessonId }
|
||||
@ -59,7 +60,7 @@ class LibrusApiAttendances(override val data: DataLibrus,
|
||||
semester,
|
||||
topic,
|
||||
lessonDate,
|
||||
startTime,
|
||||
startTime ?: Time(0, 0, 0),
|
||||
typeObject?.type ?: Attendance.TYPE_CUSTOM
|
||||
)
|
||||
|
||||
|
@ -4,15 +4,12 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
|
||||
|
||||
import pl.szczodrzynski.edziennik.DAY
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_LUCKY_NUMBER
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.getInt
|
||||
import pl.szczodrzynski.edziennik.getJsonObject
|
||||
import pl.szczodrzynski.edziennik.getString
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
@ -41,9 +38,10 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
|
||||
luckyNumber
|
||||
)
|
||||
|
||||
//if (luckyNumberDate > Date.getToday()) {
|
||||
if (luckyNumberDate >= Date.getToday())
|
||||
nextSync = luckyNumberDate.combineWith(Time(15, 0, 0))
|
||||
//}
|
||||
else
|
||||
nextSync = System.currentTimeMillis() + 6*HOUR*1000
|
||||
|
||||
data.luckyNumberList.add(luckyNumberObject)
|
||||
data.metadataList.add(
|
||||
|
@ -21,6 +21,14 @@ class LibrusApiPushConfig(override val data: DataLibrus,
|
||||
}
|
||||
|
||||
init { data.app.config.sync.tokenLibrus?.also { tokenLibrus ->
|
||||
if(tokenLibrus.isEmpty()) {
|
||||
data.setSyncNext(ENDPOINT_LIBRUS_API_PUSH_CONFIG, SYNC_ALWAYS)
|
||||
data.app.config.sync.tokenLibrusList =
|
||||
data.app.config.sync.tokenLibrusList + profileId
|
||||
onSuccess(ENDPOINT_LIBRUS_API_PUSH_CONFIG)
|
||||
return@also
|
||||
}
|
||||
|
||||
apiGet(TAG, "ChangeRegister", payload = JsonObject(
|
||||
"provider" to "FCM",
|
||||
"device" to tokenLibrus,
|
||||
|
@ -8,7 +8,6 @@ import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.body.MediaTypeUtils
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
@ -64,21 +63,15 @@ class LibrusLoginMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||
}
|
||||
|
||||
if (data.isMessagesLoginValid()) {
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(data.messagesSessionId!!)
|
||||
.domain("wiadomosci.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("wiadomosci.librus.pl", "DZIENNIKSID", data.messagesSessionId)
|
||||
onSuccess()
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("wiadomosci.librus.pl")
|
||||
data.app.cookieJar.clear("wiadomosci.librus.pl")
|
||||
if (data.loginMethods.contains(LOGIN_METHOD_LIBRUS_SYNERGIA)) {
|
||||
loginWithSynergia()
|
||||
}
|
||||
else if (data.apiLogin != null && data.apiPassword != null) {
|
||||
else if (data.apiLogin != null && data.apiPassword != null && false) {
|
||||
loginWithCredentials()
|
||||
}
|
||||
else {
|
||||
@ -148,7 +141,7 @@ class LibrusLoginMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||
}
|
||||
|
||||
private fun saveSessionId(response: Response?, text: String?) {
|
||||
var sessionId = data.app.cookieJar.getCookie("wiadomosci.librus.pl", "DZIENNIKSID")
|
||||
var sessionId = data.app.cookieJar.get("wiadomosci.librus.pl", "DZIENNIKSID")
|
||||
sessionId = sessionId?.replace("-MAINT", "") // dunno what's this
|
||||
sessionId = sessionId?.replace("MAINT", "") // dunno what's this
|
||||
if (sessionId == null) {
|
||||
|
@ -37,19 +37,19 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||
}
|
||||
else if (data.portalRefreshToken != null) {
|
||||
if (data.fakeLogin) {
|
||||
data.app.cookieJar.clearForDomain("librus.szkolny.eu")
|
||||
data.app.cookieJar.clear("librus.szkolny.eu")
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("portal.librus.pl")
|
||||
data.app.cookieJar.clear("portal.librus.pl")
|
||||
}
|
||||
accessToken(null, data.portalRefreshToken)
|
||||
}
|
||||
else {
|
||||
if (data.fakeLogin) {
|
||||
data.app.cookieJar.clearForDomain("librus.szkolny.eu")
|
||||
data.app.cookieJar.clear("librus.szkolny.eu")
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("portal.librus.pl")
|
||||
data.app.cookieJar.clear("portal.librus.pl")
|
||||
}
|
||||
authorize(if (data.fakeLogin) FAKE_LIBRUS_AUTHORIZE else LIBRUS_AUTHORIZE_URL)
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import com.google.gson.JsonObject
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
@ -30,17 +29,11 @@ class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Un
|
||||
}
|
||||
|
||||
if (data.isSynergiaLoginValid()) {
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("DZIENNIKSID")
|
||||
.value(data.synergiaSessionId!!)
|
||||
.domain("synergia.librus.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("synergia.librus.pl", "DZIENNIKSID", data.synergiaSessionId)
|
||||
onSuccess()
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("synergia.librus.pl")
|
||||
data.app.cookieJar.clear("synergia.librus.pl")
|
||||
if (data.loginMethods.contains(LOGIN_METHOD_LIBRUS_API)) {
|
||||
loginWithApi()
|
||||
}
|
||||
@ -92,7 +85,7 @@ class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Un
|
||||
}
|
||||
|
||||
if (location?.endsWith("centrum_powiadomien") == true) {
|
||||
val sessionId = data.app.cookieJar.getCookie("synergia.librus.pl", "DZIENNIKSID")
|
||||
val sessionId = data.app.cookieJar.get("synergia.librus.pl", "DZIENNIKSID")
|
||||
if (sessionId == null) {
|
||||
data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_NO_SESSION_ID)
|
||||
.withResponse(response)
|
||||
@ -117,7 +110,7 @@ class LibrusLoginSynergia(override val data: DataLibrus, val onSuccess: () -> Un
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.clearForDomain("synergia.librus.pl")
|
||||
data.app.cookieJar.clear("synergia.librus.pl")
|
||||
Request.builder()
|
||||
.url(LIBRUS_SYNERGIA_TOKEN_LOGIN_URL.replace("TOKEN", token) + "/uczen/widok/centrum_powiadomien")
|
||||
.userAgent(LIBRUS_USER_AGENT)
|
||||
|
@ -8,7 +8,6 @@ import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.FileCallbackHandler
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
@ -105,18 +104,8 @@ open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: L
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name(data.webSessionKey!!)
|
||||
.value(data.webSessionValue!!)
|
||||
.domain("${data.loginServerName}.mobidziennik.pl")
|
||||
.secure().httpOnly().build(),
|
||||
Cookie.Builder()
|
||||
.name("SERVERID")
|
||||
.value(data.webServerId!!)
|
||||
.domain("${data.loginServerName}.mobidziennik.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("${data.loginServerName}.mobidziennik.pl", data.webSessionKey, data.webSessionValue)
|
||||
data.app.cookieJar.set("${data.loginServerName}.mobidziennik.pl", "SERVERID", data.webServerId)
|
||||
|
||||
Request.builder()
|
||||
.url(url)
|
||||
@ -187,18 +176,8 @@ open class MobidziennikWeb(open val data: DataMobidziennik, open val lastSync: L
|
||||
}
|
||||
}
|
||||
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name(data.webSessionKey!!)
|
||||
.value(data.webSessionValue!!)
|
||||
.domain("${data.loginServerName}.mobidziennik.pl")
|
||||
.secure().httpOnly().build(),
|
||||
Cookie.Builder()
|
||||
.name("SERVERID")
|
||||
.value(data.webServerId!!)
|
||||
.domain("${data.loginServerName}.mobidziennik.pl")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("${data.loginServerName}.mobidziennik.pl", data.webSessionKey, data.webSessionValue)
|
||||
data.app.cookieJar.set("${data.loginServerName}.mobidziennik.pl", "SERVERID", data.webServerId)
|
||||
|
||||
Request.builder()
|
||||
.url(url)
|
||||
|
@ -26,7 +26,7 @@ class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit
|
||||
}
|
||||
else {
|
||||
if (data.loginServerName.isNotNullNorEmpty() && data.loginUsername.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
||||
data.app.cookieJar.clearForDomain(data.loginServerName + ".mobidziennik.pl")
|
||||
data.app.cookieJar.clear("${data.loginServerName}.mobidziennik.pl")
|
||||
loginWithCredentials()
|
||||
}
|
||||
else {
|
||||
@ -58,10 +58,10 @@ class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
val cookies = data.app.cookieJar.getForDomain("${data.loginServerName}.mobidziennik.pl")
|
||||
val cookie = cookies.singleOrNull { it.name().length > 32 }
|
||||
val sessionKey = cookie?.name()
|
||||
val sessionId = cookie?.value()
|
||||
val cookies = data.app.cookieJar.getAll("${data.loginServerName}.mobidziennik.pl")
|
||||
val cookie = cookies.entries.firstOrNull { it.key.length > 32 }
|
||||
val sessionKey = cookie?.key
|
||||
val sessionId = cookie?.value
|
||||
if (sessionId == null) {
|
||||
data.error(ApiError(TAG, ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID)
|
||||
.withResponse(response)
|
||||
@ -71,7 +71,7 @@ class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit
|
||||
|
||||
data.webSessionKey = sessionKey
|
||||
data.webSessionValue = sessionId
|
||||
data.webServerId = data.app.cookieJar.getCookie("${data.loginServerName}.mobidziennik.pl", "SERVERID")
|
||||
data.webServerId = data.app.cookieJar.get("${data.loginServerName}.mobidziennik.pl", "SERVERID")
|
||||
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45min */
|
||||
onSuccess()
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.template
|
||||
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_API
|
||||
@ -28,13 +27,7 @@ class DataTemplate(app: App, profile: Profile?, loginStore: LoginStore) : Data(a
|
||||
loginMethods.clear()
|
||||
if (isWebLoginValid()) {
|
||||
loginMethods += LOGIN_METHOD_TEMPLATE_WEB
|
||||
app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("AuthCookie")
|
||||
.value(webCookie!!)
|
||||
.domain("eregister.example.com")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
app.cookieJar.set("eregister.example.com", "AuthCookie", webCookie)
|
||||
}
|
||||
if (isApiLoginValid())
|
||||
loginMethods += LOGIN_METHOD_TEMPLATE_API
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.template.login
|
||||
|
||||
import okhttp3.Cookie
|
||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||
|
||||
class TemplateLoginWeb(val data: DataTemplate, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
@ -23,17 +22,11 @@ class TemplateLoginWeb(val data: DataTemplate, val onSuccess: () -> Unit) {
|
||||
}
|
||||
|
||||
if (data.isWebLoginValid()) {
|
||||
data.app.cookieJar.saveFromResponse(null, listOf(
|
||||
Cookie.Builder()
|
||||
.name("AuthCookie")
|
||||
.value(data.webCookie!!)
|
||||
.domain("eregister.example.com")
|
||||
.secure().httpOnly().build()
|
||||
))
|
||||
data.app.cookieJar.set("eregister.example.com", "AuthCookie", data.webCookie)
|
||||
onSuccess()
|
||||
}
|
||||
else {
|
||||
data.app.cookieJar.clearForDomain("eregister.example.com")
|
||||
data.app.cookieJar.clear("eregister.example.com")
|
||||
if (/*data.webLogin != null && data.webPassword != null && */true) {
|
||||
loginWithCredentials()
|
||||
}
|
||||
|
@ -46,6 +46,6 @@ object Signing {
|
||||
|
||||
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
|
||||
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
|
||||
return "$param1.MTIzNDU2Nzg5MDurcz1Rjg===.$param2".sha256()
|
||||
return "$param1.MTIzNDU2Nzg5MDmD46bIpY===.$param2".sha256()
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import android.app.PendingIntent
|
||||
import android.app.PendingIntent.CanceledException
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.google.firebase.iid.zzaq
|
||||
import com.google.firebase.iid.zzv
|
||||
import com.google.firebase.iid.zzad
|
||||
import com.google.firebase.iid.zzaz
|
||||
import com.google.firebase.messaging.zzc
|
||||
import com.google.gson.JsonObject
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
@ -36,7 +36,7 @@ open class FirebaseService : zzc() {
|
||||
|
||||
// apparently this gets the correct intent from some
|
||||
// kind of queue inside Firebase's InstanceID Receiver
|
||||
final override fun zza(intent: Intent?) = zzaq.zza()?.zzb()
|
||||
final override fun zza(intent: Intent?) = zzaz.zza()?.zzb()
|
||||
final override fun zzb(intent: Intent?): Boolean {
|
||||
val action = intent?.action
|
||||
if (action == "com.google.firebase.messaging.NOTIFICATION_OPEN") {
|
||||
@ -80,7 +80,7 @@ open class FirebaseService : zzc() {
|
||||
val ackBundle = Bundle(
|
||||
"google.message_id" to messageId
|
||||
)
|
||||
zzv.zza(this).zza(2, ackBundle)
|
||||
zzad.zza(this).zza(2, ackBundle)
|
||||
}
|
||||
// check for duplicate message
|
||||
// and add it to queue
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-24.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.network.cookie
|
||||
|
||||
import okhttp3.Cookie
|
||||
|
||||
class DumbCookie(var cookie: Cookie) {
|
||||
|
||||
constructor(domain: String, name: String, value: String, expiresAt: Long? = null) : this(
|
||||
Cookie.Builder()
|
||||
.name(name)
|
||||
.value(value)
|
||||
.also { if (expiresAt != null) it.expiresAt(expiresAt) }
|
||||
.domain(domain)
|
||||
.build()
|
||||
)
|
||||
|
||||
init {
|
||||
cookie = Cookie.Builder()
|
||||
.name(cookie.name())
|
||||
.value(cookie.value())
|
||||
.expiresAt(cookie.expiresAt())
|
||||
.domain(cookie.domain())
|
||||
.build()
|
||||
}
|
||||
|
||||
fun domainMatches(host: String): Boolean {
|
||||
val domain = cookie.domain()
|
||||
return host == domain || host.endsWith(".$domain")
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is DumbCookie) return false
|
||||
if (this.cookie === other.cookie) return true
|
||||
|
||||
return cookie.name() == other.cookie.name()
|
||||
&& cookie.domain() == other.cookie.domain()
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var hash = 17
|
||||
hash = 31 * hash + cookie.name().hashCode()
|
||||
hash = 31 * hash + cookie.domain().hashCode()
|
||||
return hash
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-24.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.network.cookie
|
||||
|
||||
import android.content.Context
|
||||
import okhttp3.Cookie
|
||||
import okhttp3.CookieJar
|
||||
import okhttp3.HttpUrl
|
||||
|
||||
/**
|
||||
* A simple cookie jar that does not care about the [Cookie.secure], [Cookie.hostOnly],
|
||||
* [Cookie.httpOnly] and [Cookie.path] attributes.
|
||||
*/
|
||||
class DumbCookieJar(
|
||||
/**
|
||||
* A context to create the shared prefs file.
|
||||
*/
|
||||
context: Context,
|
||||
|
||||
/**
|
||||
* Whether to persist session cookies as well, when [Cookie.persistent] is false.
|
||||
*/
|
||||
private val persistAll: Boolean = false
|
||||
) : CookieJar {
|
||||
|
||||
private val prefs = context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
|
||||
private val sessionCookies = mutableSetOf<DumbCookie>()
|
||||
private val savedCookies = mutableSetOf<DumbCookie>()
|
||||
private fun save(dc: DumbCookie) {
|
||||
sessionCookies.remove(dc)
|
||||
sessionCookies.add(dc)
|
||||
if (dc.cookie.persistent() || persistAll) {
|
||||
savedCookies.remove(dc)
|
||||
savedCookies.add(dc)
|
||||
}
|
||||
}
|
||||
private fun delete(vararg toRemove: DumbCookie) {
|
||||
sessionCookies.removeAll(toRemove)
|
||||
savedCookies.removeAll(toRemove)
|
||||
}
|
||||
|
||||
override fun saveFromResponse(url: HttpUrl?, cookies: List<Cookie>) {
|
||||
for (cookie in cookies) {
|
||||
val dc = DumbCookie(cookie)
|
||||
save(dc)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadForRequest(url: HttpUrl): List<Cookie> {
|
||||
return sessionCookies.filter {
|
||||
it.cookie.matches(url)
|
||||
}.map { it.cookie }
|
||||
}
|
||||
|
||||
fun get(domain: String, name: String): String? {
|
||||
return sessionCookies.firstOrNull {
|
||||
it.domainMatches(domain) && it.cookie.name() == name
|
||||
}?.cookie?.value()
|
||||
}
|
||||
|
||||
fun set(domain: String, name: String, value: String?, isSession: Boolean) = set(
|
||||
domain, name, value,
|
||||
if (isSession) null
|
||||
else System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000L
|
||||
)
|
||||
|
||||
/**
|
||||
* Add a cookie to the cache.
|
||||
* By default a session cookie is added. If [expiresAt] is set, the cookie is
|
||||
* additionally persisted.
|
||||
*/
|
||||
fun set(domain: String, name: String?, value: String?, expiresAt: Long? = null) {
|
||||
name ?: return
|
||||
if (value == null) {
|
||||
remove(domain, name)
|
||||
return
|
||||
}
|
||||
val dc = DumbCookie(domain, name, value, expiresAt)
|
||||
save(dc)
|
||||
}
|
||||
|
||||
fun getAll(domain: String): Map<String, String> {
|
||||
return sessionCookies.filter {
|
||||
it.domainMatches(domain)
|
||||
}.map { it.cookie.name() to it.cookie.value() }.toMap()
|
||||
}
|
||||
|
||||
fun remove(domain: String, name: String) {
|
||||
val toRemove = sessionCookies.filter {
|
||||
it.domainMatches(domain) && it.cookie.name() == name
|
||||
}
|
||||
delete(*toRemove.toTypedArray())
|
||||
}
|
||||
|
||||
fun clear(domain: String) {
|
||||
val toRemove = sessionCookies.filter {
|
||||
it.domainMatches(domain)
|
||||
}
|
||||
delete(*toRemove.toTypedArray())
|
||||
}
|
||||
}
|
@ -241,7 +241,7 @@ class EventManualDialog(
|
||||
|
||||
with (b.dateDropdown) {
|
||||
db = app.db
|
||||
profileId = profileId
|
||||
profileId = this@EventManualDialog.profileId
|
||||
showWeekDays = false
|
||||
showDays = true
|
||||
showOtherDate = true
|
||||
@ -269,7 +269,7 @@ class EventManualDialog(
|
||||
|
||||
with (b.timeDropdown) {
|
||||
db = app.db
|
||||
profileId = profileId
|
||||
profileId = this@EventManualDialog.profileId
|
||||
showAllDay = true
|
||||
showCustomTime = true
|
||||
lessonsDate = b.dateDropdown.getSelected() as? Date ?: Date.getToday()
|
||||
@ -289,7 +289,7 @@ class EventManualDialog(
|
||||
|
||||
with (b.teamDropdown) {
|
||||
db = app.db
|
||||
profileId = profileId
|
||||
profileId = this@EventManualDialog.profileId
|
||||
showNoTeam = true
|
||||
loadItems()
|
||||
selectTeamClass()
|
||||
@ -299,7 +299,7 @@ class EventManualDialog(
|
||||
|
||||
with (b.subjectDropdown) {
|
||||
db = app.db
|
||||
profileId = profileId
|
||||
profileId = this@EventManualDialog.profileId
|
||||
showNoSubject = true
|
||||
showCustomSubject = false
|
||||
loadItems()
|
||||
@ -309,7 +309,7 @@ class EventManualDialog(
|
||||
|
||||
with (b.teacherDropdown) {
|
||||
db = app.db
|
||||
profileId = profileId
|
||||
profileId = this@EventManualDialog.profileId
|
||||
showNoTeacher = true
|
||||
loadItems()
|
||||
selectDefault(editingEvent?.teacherId)
|
||||
|
@ -438,7 +438,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
if (b.textLayout.counterMaxLength != -1 && b.text.length() > b.textLayout.counterMaxLength)
|
||||
return
|
||||
|
||||
var textHtml = if (app.profile.loginStoreType != LoginStore.LOGIN_TYPE_VULCAN && app.profile.loginStoreType != LoginStore.LOGIN_TYPE_IDZIENNIK) {
|
||||
var textHtml = if (app.profile.loginStoreType != LoginStore.LOGIN_TYPE_VULCAN) {
|
||||
HtmlCompat.toHtml(SpannableString(text), HtmlCompat.TO_HTML_PARAGRAPH_LINES_INDIVIDUAL)
|
||||
.replace("\n", "")
|
||||
.replace(" dir=\"ltr\"", "")
|
||||
|
@ -6,12 +6,11 @@ package pl.szczodrzynski.edziennik.utils.html
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.text.Html
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.BulletSpan
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.text.HtmlCompat
|
||||
import pl.szczodrzynski.edziennik.dp
|
||||
import pl.szczodrzynski.edziennik.resolveAttr
|
||||
import pl.szczodrzynski.navlib.blendColors
|
||||
@ -59,16 +58,12 @@ object BetterHtml {
|
||||
}*/
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
val htmlSpannable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Html.fromHtml(
|
||||
text,
|
||||
Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM or Html.FROM_HTML_SEPARATOR_LINE_BREAK_LIST or Html.FROM_HTML_SEPARATOR_LINE_BREAK_DIV,
|
||||
null,
|
||||
LiTagHandler()
|
||||
)
|
||||
} else {
|
||||
Html.fromHtml(text, null, LiTagHandler())
|
||||
}
|
||||
val htmlSpannable = HtmlCompat.fromHtml(
|
||||
text,
|
||||
HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM or HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_LIST or HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_DIV,
|
||||
null,
|
||||
LiTagHandler()
|
||||
)
|
||||
|
||||
val spannableBuilder = SpannableStringBuilder(htmlSpannable)
|
||||
val bulletSpans = spannableBuilder.getSpans(0, spannableBuilder.length, BulletSpan::class.java)
|
||||
|
@ -1,6 +1,6 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/material_drawer_account_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/material_drawer_account_header_height"
|
||||
@ -35,10 +35,27 @@
|
||||
android:elevation="2dp"
|
||||
android:focusable="true"
|
||||
android:scaleType="centerCrop"
|
||||
app:biv_selectorOnPress="#80ffffff"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/material_drawer_statusbar_guideline" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/material_drawer_account_header_current_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:minWidth="20dp"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/material_drawer_item_badge_text"
|
||||
app:layout_constraintBottom_toBottomOf="@id/material_drawer_account_header_current"
|
||||
app:layout_constraintStart_toStartOf="@id/material_drawer_account_header_current"
|
||||
tools:text="99" />
|
||||
|
||||
<com.mikepenz.materialdrawer.view.BezelImageView
|
||||
android:id="@+id/material_drawer_account_header_small_first"
|
||||
style="@style/BezelImageView"
|
||||
@ -50,12 +67,29 @@
|
||||
android:clickable="true"
|
||||
android:elevation="2dp"
|
||||
android:focusable="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="visible"
|
||||
android:scaleType="centerCrop"
|
||||
app:biv_selectorOnPress="#80ffffff"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
app:layout_constraintEnd_toStartOf="@id/material_drawer_account_header_small_second"
|
||||
app:layout_constraintTop_toBottomOf="@+id/material_drawer_statusbar_guideline" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/material_drawer_account_header_small_first_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:minWidth="20dp"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/material_drawer_item_badge_small_text"
|
||||
app:layout_constraintBottom_toBottomOf="@id/material_drawer_account_header_small_first"
|
||||
app:layout_constraintStart_toStartOf="@id/material_drawer_account_header_small_first"
|
||||
tools:text="99" />
|
||||
|
||||
<com.mikepenz.materialdrawer.view.BezelImageView
|
||||
android:id="@+id/material_drawer_account_header_small_second"
|
||||
style="@style/BezelImageView"
|
||||
@ -67,12 +101,29 @@
|
||||
android:clickable="true"
|
||||
android:elevation="2dp"
|
||||
android:focusable="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="visible"
|
||||
android:scaleType="centerCrop"
|
||||
app:biv_selectorOnPress="#80ffffff"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
app:layout_constraintEnd_toStartOf="@id/material_drawer_account_header_small_third"
|
||||
app:layout_constraintTop_toBottomOf="@+id/material_drawer_statusbar_guideline" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/material_drawer_account_header_small_second_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:minWidth="20dp"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/material_drawer_item_badge_small_text"
|
||||
app:layout_constraintBottom_toBottomOf="@id/material_drawer_account_header_small_second"
|
||||
app:layout_constraintStart_toStartOf="@id/material_drawer_account_header_small_second"
|
||||
tools:text="99" />
|
||||
|
||||
<com.mikepenz.materialdrawer.view.BezelImageView
|
||||
android:id="@+id/material_drawer_account_header_small_third"
|
||||
style="@style/BezelImageView"
|
||||
@ -84,12 +135,29 @@
|
||||
android:clickable="true"
|
||||
android:elevation="2dp"
|
||||
android:focusable="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:visibility="visible"
|
||||
android:scaleType="centerCrop"
|
||||
app:biv_selectorOnPress="#80ffffff"
|
||||
app:materialDrawerSelectorOnPress="#80ffffff"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/material_drawer_statusbar_guideline" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/material_drawer_account_header_small_third_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:minWidth="20dp"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/material_drawer_item_badge_small_text"
|
||||
app:layout_constraintBottom_toBottomOf="@id/material_drawer_account_header_small_third"
|
||||
app:layout_constraintStart_toStartOf="@id/material_drawer_account_header_small_third"
|
||||
tools:text="99" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/material_drawer_text_guideline"
|
||||
android:layout_width="wrap_content"
|
||||
@ -138,4 +206,4 @@
|
||||
android:layout_marginBottom="@dimen/material_drawer_account_header_dropdown_margin_bottom"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</merge>
|
||||
|
@ -4,6 +4,8 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/material_drawer_item_profile"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/material_drawer_vertical_padding"
|
||||
android:paddingLeft="@dimen/material_drawer_vertical_padding"
|
||||
@ -44,7 +46,7 @@
|
||||
android:textDirection="anyRtl"
|
||||
android:textSize="@dimen/material_drawer_item_profile_text"
|
||||
app:layout_constraintBottom_toTopOf="@id/material_drawer_email"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/material_drawer_badge_container"
|
||||
app:layout_constraintStart_toEndOf="@id/material_drawer_profileIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
@ -69,9 +71,37 @@
|
||||
android:textDirection="anyRtl"
|
||||
android:textSize="@dimen/material_drawer_item_profile_description"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/material_drawer_badge_container"
|
||||
app:layout_constraintStart_toEndOf="@id/material_drawer_profileIcon"
|
||||
app:layout_constraintTop_toBottomOf="@id/material_drawer_name"
|
||||
tools:text="Some drawer text" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/material_drawer_badge_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:gravity="center"
|
||||
android:paddingStart="@dimen/material_drawer_padding"
|
||||
android:paddingLeft="@dimen/material_drawer_padding"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingRight="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/material_drawer_badge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:minWidth="20dp"
|
||||
android:paddingLeft="1dp"
|
||||
android:paddingRight="1dp"
|
||||
android:singleLine="true"
|
||||
android:textSize="@dimen/material_drawer_item_primary_text"
|
||||
tools:text="99" />
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -197,14 +197,14 @@
|
||||
<string name="error_62_reason">Brak internetu</string>
|
||||
<string name="error_63_reason">Brak internetu: połączenie SSL nie powiodło się</string>
|
||||
<string name="error_100_reason">Brak odpowiedzi serwera. Dziennik może być przeciążony lub mieć przerwę techniczną.</string>
|
||||
<string name="error_101_reason">Dane logowania niekompletne</string>
|
||||
<string name="error_101_reason">Dane logowania niekompletne. Skontaktuj się z twórcą aplikacji.</string>
|
||||
<string name="error_102_reason">Nieprawidłowe dane logowania</string>
|
||||
<string name="error_105_reason">Profil nie został ustawiony</string>
|
||||
<string name="error_106_reason">Profil jest archiwalny - synchronizacja profilu z poprzedniego roku szkolnego nie jest możliwa</string>
|
||||
<string name="error_110_reason">Nieprawidłowy sposób logowania</string>
|
||||
<string name="error_111_reason">Nie można wywołać metody logowania</string>
|
||||
<string name="error_110_reason">Nieprawidłowy sposób logowania. Skontaktuj się z twórcą aplikacji.</string>
|
||||
<string name="error_111_reason">Nie można wywołać metody logowania. Skontaktuj się z twórcą aplikacji.</string>
|
||||
<string name="error_112_reason">Nie zaimplementowano</string>
|
||||
<string name="error_113_reason">Wystąpił błąd podczas pobierania pliku</string>
|
||||
<string name="error_113_reason">Wystąpił błąd podczas pobierania pliku. Dziennik może być przeciążony lub mieć przerwę techniczną.</string>
|
||||
|
||||
<string name="error_115_reason">Brak uczniów przypisanych do konta</string>
|
||||
|
||||
|
22
build.gradle
22
build.gradle
@ -5,8 +5,8 @@ buildscript {
|
||||
kotlin_version = '1.3.61'
|
||||
|
||||
release = [
|
||||
versionName: "4.0-beta.14",
|
||||
versionCode: 4000014
|
||||
versionName: "4.0-rc.2",
|
||||
versionCode: 4000029
|
||||
]
|
||||
|
||||
setup = [
|
||||
@ -17,6 +17,8 @@ buildscript {
|
||||
]
|
||||
|
||||
versions = [
|
||||
gradleAndroid : "4.0.0-beta03",
|
||||
|
||||
kotlin : ext.kotlin_version,
|
||||
ktx : "1.2.0",
|
||||
|
||||
@ -32,24 +34,24 @@ buildscript {
|
||||
navigationFragment: "1.0.0",
|
||||
legacy : "1.0.0",
|
||||
|
||||
room : "2.2.4",
|
||||
room : "2.2.5",
|
||||
lifecycle : "2.2.0",
|
||||
work : "2.3.2",
|
||||
work : "2.3.4",
|
||||
|
||||
firebase : '17.2.2',
|
||||
firebasemessaging: "20.1.0",
|
||||
firebasemessaging: "20.1.3",
|
||||
play_services : "17.0.0",
|
||||
|
||||
materialdialogs : "0.9.6.0",
|
||||
materialdrawer : "cad66092a6",
|
||||
materialdrawer : "817e45765c367034b03046aaea6e95eeabcb40e9",
|
||||
iconics : "4.0.1",
|
||||
font_cmd : "3.5.95.1-kotlin",
|
||||
|
||||
navlib : "5c8b13c0d9db0d9e822fdae82c8afca6c01ab41e",
|
||||
navlib : "28cdab341470dffa5f331379fe9702482681d7de",
|
||||
|
||||
gifdrawable : "1.2.15",
|
||||
|
||||
retrofit : '2.6.2'
|
||||
retrofit : "2.6.4"
|
||||
]
|
||||
}
|
||||
|
||||
@ -61,11 +63,11 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0-beta01'
|
||||
classpath "com.android.tools.build:gradle:${versions.gradleAndroid}"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
classpath 'me.tatarka:gradle-retrolambda:3.7.0'
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
classpath 'io.fabric.tools:gradle:1.28.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip
|
||||
|
Reference in New Issue
Block a user