forked from github/szkolny
[API] Improve Lab fragment. Fix OkHttp crashing on API <21.
This commit is contained in:
parent
fada483d55
commit
9261848369
@ -145,7 +145,11 @@ dependencies {
|
|||||||
implementation("com.github.ozodrukh:CircularReveal:2.0.1@aar") {transitive = true}
|
implementation("com.github.ozodrukh:CircularReveal:2.0.1@aar") {transitive = true}
|
||||||
implementation "com.heinrichreimersoftware:material-intro:1.5.8" // do not update
|
implementation "com.heinrichreimersoftware:material-intro:1.5.8" // do not update
|
||||||
implementation "com.jaredrummler:colorpicker:1.0.2"
|
implementation "com.jaredrummler:colorpicker:1.0.2"
|
||||||
implementation "com.squareup.okhttp3:okhttp:3.12.2"
|
implementation("com.squareup.okhttp3:okhttp") {
|
||||||
|
version {
|
||||||
|
strictly "3.12.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
implementation "com.theartofdev.edmodo:android-image-cropper:2.8.0" // do not update
|
implementation "com.theartofdev.edmodo:android-image-cropper:2.8.0" // do not update
|
||||||
implementation "com.wdullaer:materialdatetimepicker:4.1.2"
|
implementation "com.wdullaer:materialdatetimepicker:4.1.2"
|
||||||
implementation "com.yuyh.json:jsonviewer:1.0.6"
|
implementation "com.yuyh.json:jsonviewer:1.0.6"
|
||||||
|
@ -173,6 +173,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
devMode = BuildConfig.DEBUG
|
devMode = BuildConfig.DEBUG
|
||||||
|
if (BuildConfig.DEBUG)
|
||||||
|
debugMode = true
|
||||||
|
|
||||||
Signing.getCert(this)
|
Signing.getCert(this)
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
@ -28,6 +29,9 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdziennikTask"
|
private const val TAG = "EdziennikTask"
|
||||||
|
|
||||||
|
var profile: Profile? = null
|
||||||
|
var loginStore: LoginStore? = null
|
||||||
|
|
||||||
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
||||||
fun sync() = EdziennikTask(-1, SyncRequest())
|
fun sync() = EdziennikTask(-1, SyncRequest())
|
||||||
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, onlyEndpoints: List<Int>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, onlyEndpoints, arguments))
|
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, onlyEndpoints: List<Int>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, onlyEndpoints, arguments))
|
||||||
@ -59,6 +63,8 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
// save the profile ID and name as the current task's
|
// save the profile ID and name as the current task's
|
||||||
taskName = app.getString(R.string.edziennik_notification_api_sync_title_format, profile.name)
|
taskName = app.getString(R.string.edziennik_notification_api_sync_title_format, profile.name)
|
||||||
}
|
}
|
||||||
|
EdziennikTask.profile = this.profile
|
||||||
|
EdziennikTask.loginStore = this.loginStore
|
||||||
}
|
}
|
||||||
|
|
||||||
private var edziennikInterface: EdziennikInterface? = null
|
private var edziennikInterface: EdziennikInterface? = null
|
||||||
|
@ -26,7 +26,7 @@ class DumbCookieJar(
|
|||||||
) : CookieJar {
|
) : CookieJar {
|
||||||
|
|
||||||
private val prefs = context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
|
private val prefs = context.getSharedPreferences("cookies", Context.MODE_PRIVATE)
|
||||||
private val sessionCookies = mutableSetOf<DumbCookie>()
|
val sessionCookies = mutableSetOf<DumbCookie>()
|
||||||
private val savedCookies = mutableSetOf<DumbCookie>()
|
private val savedCookies = mutableSetOf<DumbCookie>()
|
||||||
private fun save(dc: DumbCookie) {
|
private fun save(dc: DumbCookie) {
|
||||||
sessionCookies.remove(dc)
|
sessionCookies.remove(dc)
|
||||||
|
@ -9,26 +9,25 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.sqlite.db.SimpleSQLiteQuery
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.addOnPageSelectedListener
|
||||||
import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding
|
import pl.szczodrzynski.edziennik.databinding.TemplateFragmentBinding
|
||||||
import pl.szczodrzynski.edziennik.onClick
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.FragmentLazyPagerAdapter
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class LabFragment : Fragment(), CoroutineScope {
|
class LabFragment : Fragment(), CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LabFragment"
|
private const val TAG = "LabFragment"
|
||||||
|
var pageSelection = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var app: App
|
private lateinit var app: App
|
||||||
private lateinit var activity: MainActivity
|
private lateinit var activity: MainActivity
|
||||||
private lateinit var b: LabFragmentBinding
|
private lateinit var b: TemplateFragmentBinding
|
||||||
|
|
||||||
private val job: Job = Job()
|
private val job: Job = Job()
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
@ -40,29 +39,30 @@ class LabFragment : Fragment(), CoroutineScope {
|
|||||||
activity = (getActivity() as MainActivity?) ?: return null
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
context ?: return null
|
context ?: return null
|
||||||
app = activity.application as App
|
app = activity.application as App
|
||||||
b = LabFragmentBinding.inflate(inflater)
|
b = TemplateFragmentBinding.inflate(inflater)
|
||||||
|
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||||
return b.root
|
return b.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
if (!isAdded) return
|
if (!isAdded) return
|
||||||
|
|
||||||
b.last10unseen.onClick {
|
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||||
launch(Dispatchers.Default) {
|
fragmentManager ?: return,
|
||||||
val events = app.db.eventDao().getAllNow(App.profileId)
|
b.refreshLayout,
|
||||||
val ids = events.sortedBy { it.date }.filter { it.type == Event.TYPE_HOMEWORK }.takeLast(10)
|
listOf(
|
||||||
ids.forEach {
|
LabPageFragment() to "click me",
|
||||||
app.db.metadataDao().setSeen(App.profileId, it, false)
|
LabProfileFragment() to "JSON"
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
b.viewPager.apply {
|
||||||
|
offscreenPageLimit = 1
|
||||||
|
adapter = pagerAdapter
|
||||||
|
currentItem = pageSelection
|
||||||
|
addOnPageSelectedListener {
|
||||||
|
pageSelection = it
|
||||||
}
|
}
|
||||||
}
|
b.tabLayout.setupWithViewPager(this)
|
||||||
|
|
||||||
b.rodo.onClick {
|
|
||||||
app.db.teacherDao().query(SimpleSQLiteQuery("UPDATE teachers SET teacherSurname = \"\" WHERE profileId = ${App.profileId}"))
|
|
||||||
}
|
|
||||||
|
|
||||||
b.removeHomework.onClick {
|
|
||||||
app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonPrimitive
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonArray
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonElement
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonArrayViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonElementViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonObjectViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class LabJsonAdapter(
|
||||||
|
val activity: AppCompatActivity,
|
||||||
|
var onJsonElementClick: ((item: LabJsonElement) -> Unit)? = null
|
||||||
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "AttendanceAdapter"
|
||||||
|
private const val ITEM_TYPE_OBJECT = 0
|
||||||
|
private const val ITEM_TYPE_ARRAY = 1
|
||||||
|
private const val ITEM_TYPE_ELEMENT = 2
|
||||||
|
const val STATE_CLOSED = 0
|
||||||
|
const val STATE_OPENED = 1
|
||||||
|
|
||||||
|
fun expand(item: Any, level: Int): MutableList<Any> {
|
||||||
|
val json = when (item) {
|
||||||
|
is LabJsonObject -> item.jsonObject
|
||||||
|
is LabJsonArray -> item.jsonArray
|
||||||
|
is JsonObject -> item
|
||||||
|
is JsonArray -> item
|
||||||
|
is JsonPrimitive -> item
|
||||||
|
else -> return mutableListOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (json) {
|
||||||
|
is JsonObject -> json.entrySet().mapNotNull { wrap(it.key, it.value, level) }
|
||||||
|
is JsonArray -> json.mapIndexedNotNull { index, jsonElement -> wrap(index.toString(), jsonElement, level) }
|
||||||
|
else -> listOf(LabJsonElement("?", json, level))
|
||||||
|
}.toMutableList()
|
||||||
|
}
|
||||||
|
fun wrap(key: String, item: JsonElement, level: Int = 0): Any? {
|
||||||
|
return when (item) {
|
||||||
|
is JsonObject -> LabJsonObject(key, item, level + 1)
|
||||||
|
is JsonArray -> LabJsonArray(key, item, level + 1)
|
||||||
|
is JsonElement -> LabJsonElement(key, item, level + 1)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val app = activity.applicationContext as App
|
||||||
|
|
||||||
|
private val job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
var items = mutableListOf<Any>()
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
return when (viewType) {
|
||||||
|
ITEM_TYPE_OBJECT -> JsonObjectViewHolder(inflater, parent)
|
||||||
|
ITEM_TYPE_ARRAY -> JsonArrayViewHolder(inflater, parent)
|
||||||
|
ITEM_TYPE_ELEMENT -> JsonElementViewHolder(inflater, parent)
|
||||||
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return when (items[position]) {
|
||||||
|
is LabJsonObject -> ITEM_TYPE_OBJECT
|
||||||
|
is LabJsonArray -> ITEM_TYPE_ARRAY
|
||||||
|
is LabJsonElement -> ITEM_TYPE_ELEMENT
|
||||||
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val onClickListener = View.OnClickListener { view ->
|
||||||
|
val model = view.getTag(R.string.tag_key_model)
|
||||||
|
if (model is LabJsonElement) {
|
||||||
|
onJsonElementClick?.invoke(model)
|
||||||
|
return@OnClickListener
|
||||||
|
}
|
||||||
|
if (model !is ExpandableItemModel<*>)
|
||||||
|
return@OnClickListener
|
||||||
|
expandModel(model, view)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun expandModel(model: ExpandableItemModel<*>?, view: View?, notifyAdapter: Boolean = true) {
|
||||||
|
model ?: return
|
||||||
|
val position = items.indexOf(model)
|
||||||
|
if (position == -1)
|
||||||
|
return
|
||||||
|
|
||||||
|
view?.findViewById<View>(R.id.dropdownIcon)?.let { dropdownIcon ->
|
||||||
|
ObjectAnimator.ofFloat(
|
||||||
|
dropdownIcon,
|
||||||
|
View.ROTATION,
|
||||||
|
if (model.state == STATE_CLOSED) 0f else 180f,
|
||||||
|
if (model.state == STATE_CLOSED) 180f else 0f
|
||||||
|
).setDuration(200).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// hide the preview, show summary
|
||||||
|
val preview = view?.findViewById<View>(R.id.previewContainer)
|
||||||
|
val summary = view?.findViewById<View>(R.id.summaryContainer)
|
||||||
|
preview?.isInvisible = model.state == STATE_CLOSED
|
||||||
|
summary?.isInvisible = model.state != STATE_CLOSED
|
||||||
|
|
||||||
|
if (model.state == STATE_CLOSED) {
|
||||||
|
|
||||||
|
val subItems = when {
|
||||||
|
//model.items.isEmpty() -> listOf(AttendanceEmpty())
|
||||||
|
else -> expand(model, model.level)
|
||||||
|
}
|
||||||
|
|
||||||
|
model.state = STATE_OPENED
|
||||||
|
items.addAll(position + 1, subItems)
|
||||||
|
if (notifyAdapter) notifyItemRangeInserted(position + 1, subItems.size)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val start = position + 1
|
||||||
|
var end: Int = items.size
|
||||||
|
for (i in start until items.size) {
|
||||||
|
val model1 = items[i]
|
||||||
|
val level = (model1 as? ExpandableItemModel<*>)?.level ?: 3
|
||||||
|
if (level <= model.level) {
|
||||||
|
end = i
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
if (model1 is ExpandableItemModel<*> && model1.state == STATE_OPENED) {
|
||||||
|
model1.state = STATE_CLOSED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end != -1) {
|
||||||
|
items.subList(start, end).clear()
|
||||||
|
if (notifyAdapter) notifyItemRangeRemoved(start, end - start)
|
||||||
|
}
|
||||||
|
|
||||||
|
model.state = STATE_CLOSED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
|
if (holder !is BindableViewHolder<*, *>)
|
||||||
|
return
|
||||||
|
|
||||||
|
val viewType = when (holder) {
|
||||||
|
is JsonObjectViewHolder -> ITEM_TYPE_OBJECT
|
||||||
|
is JsonArrayViewHolder -> ITEM_TYPE_ARRAY
|
||||||
|
is JsonElementViewHolder -> ITEM_TYPE_ELEMENT
|
||||||
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
|
}
|
||||||
|
holder.itemView.setTag(R.string.tag_key_view_type, viewType)
|
||||||
|
holder.itemView.setTag(R.string.tag_key_position, position)
|
||||||
|
holder.itemView.setTag(R.string.tag_key_model, item)
|
||||||
|
|
||||||
|
when {
|
||||||
|
holder is JsonObjectViewHolder && item is LabJsonObject -> holder.onBind(activity, app, item, position, this)
|
||||||
|
holder is JsonArrayViewHolder && item is LabJsonArray -> holder.onBind(activity, app, item, position, this)
|
||||||
|
holder is JsonElementViewHolder && item is LabJsonElement -> holder.onBind(activity, app, item, position, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(onClickListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.sqlite.db.SimpleSQLiteQuery
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||||
|
import pl.szczodrzynski.fslogin.decode
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class LabPageFragment : LazyFragment(), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "LabPageFragment"
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var app: App
|
||||||
|
private lateinit var activity: MainActivity
|
||||||
|
private lateinit var b: LabFragmentBinding
|
||||||
|
|
||||||
|
private val job: Job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
// local/private variables go here
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
|
context ?: return null
|
||||||
|
app = activity.application as App
|
||||||
|
b = LabFragmentBinding.inflate(inflater)
|
||||||
|
return b.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageCreated(): Boolean {
|
||||||
|
b.last10unseen.onClick {
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
val events = app.db.eventDao().getAllNow(App.profileId)
|
||||||
|
val ids = events.sortedBy { it.date }.filter { it.type == Event.TYPE_HOMEWORK }.takeLast(10)
|
||||||
|
ids.forEach {
|
||||||
|
app.db.metadataDao().setSeen(App.profileId, it, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.rodo.onClick {
|
||||||
|
app.db.teacherDao().query(SimpleSQLiteQuery("UPDATE teachers SET teacherSurname = \"\" WHERE profileId = ${App.profileId}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.removeHomework.onClick {
|
||||||
|
app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}")
|
||||||
|
}
|
||||||
|
|
||||||
|
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
|
||||||
|
startCoroutineTimer(500L, 300L) {
|
||||||
|
val text = app.cookieJar.sessionCookies
|
||||||
|
.map { it.cookie }
|
||||||
|
.sortedBy { it.domain() }
|
||||||
|
.groupBy { it.domain() }
|
||||||
|
.map {
|
||||||
|
listOf(
|
||||||
|
it.key.asBoldSpannable(),
|
||||||
|
":\n",
|
||||||
|
it.value
|
||||||
|
.sortedBy { it.name() }
|
||||||
|
.map {
|
||||||
|
listOf(
|
||||||
|
" ",
|
||||||
|
it.name(),
|
||||||
|
"=",
|
||||||
|
it.value().decode().take(40).asItalicSpannable().asColoredSpannable(colorSecondary)
|
||||||
|
).concat("")
|
||||||
|
}.concat("\n")
|
||||||
|
).concat("")
|
||||||
|
}.concat("\n\n")
|
||||||
|
b.cookies.text = text
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonParser
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
|
||||||
|
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||||
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class LabProfileFragment : LazyFragment(), CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "LabProfileFragment"
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var app: App
|
||||||
|
private lateinit var activity: MainActivity
|
||||||
|
private lateinit var b: TemplateListPageFragmentBinding
|
||||||
|
|
||||||
|
private val job: Job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
// local/private variables go here
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
|
context ?: return null
|
||||||
|
app = activity.application as App
|
||||||
|
b = TemplateListPageFragmentBinding.inflate(inflater)
|
||||||
|
return b.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||||
|
val adapter = LabJsonAdapter(activity)
|
||||||
|
val json = JsonObject().also { json ->
|
||||||
|
json.add("app.profile", app.profile.studentData)
|
||||||
|
json.add("app.config", JsonParser().parse(app.gson.toJson(app.config.values)))
|
||||||
|
EdziennikTask.profile?.let {
|
||||||
|
json.add("API.profile", it.studentData)
|
||||||
|
} ?: {
|
||||||
|
json.addProperty("API.profile", "null")
|
||||||
|
}()
|
||||||
|
EdziennikTask.loginStore?.let {
|
||||||
|
json.add("API.loginStore", it.data)
|
||||||
|
} ?: {
|
||||||
|
json.addProperty("API.loginStore", "null")
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
adapter.items = LabJsonAdapter.expand(json, 0)
|
||||||
|
|
||||||
|
b.list.adapter = adapter
|
||||||
|
b.list.apply {
|
||||||
|
setHasFixedSize(true)
|
||||||
|
layoutManager = LinearLayoutManager(context)
|
||||||
|
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||||
|
addOnScrollListener(onScrollListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
// show/hide relevant views
|
||||||
|
b.progressBar.isVisible = false
|
||||||
|
b.list.isVisible = true
|
||||||
|
b.noData.isVisible = false
|
||||||
|
|
||||||
|
}; return true }
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.models
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
|
|
||||||
|
data class LabJsonArray(
|
||||||
|
val key: String,
|
||||||
|
val jsonArray: JsonArray,
|
||||||
|
override var level: Int
|
||||||
|
) : ExpandableItemModel<JsonElement>(jsonArray.toMutableList())
|
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.models
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
|
||||||
|
data class LabJsonElement(
|
||||||
|
val key: String,
|
||||||
|
val jsonElement: JsonElement,
|
||||||
|
var level: Int
|
||||||
|
)
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.models
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
|
|
||||||
|
data class LabJsonObject(
|
||||||
|
val key: String,
|
||||||
|
val jsonObject: JsonObject,
|
||||||
|
override var level: Int
|
||||||
|
) : ExpandableItemModel<JsonElement>(jsonObject.entrySet().map { it.value }.toMutableList())
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.viewholder
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.LabItemObjectBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.LabJsonAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonArray
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
|
||||||
|
class JsonArrayViewHolder(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
parent: ViewGroup,
|
||||||
|
val b: LabItemObjectBinding = LabItemObjectBinding.inflate(inflater, parent, false)
|
||||||
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<LabJsonArray, LabJsonAdapter> {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "JsonArrayViewHolder"
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBind(activity: AppCompatActivity, app: App, item: LabJsonArray, position: Int, adapter: LabJsonAdapter) {
|
||||||
|
val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme)
|
||||||
|
|
||||||
|
b.dropdownIcon.rotation = when (item.state) {
|
||||||
|
AttendanceAdapter.STATE_CLOSED -> 0f
|
||||||
|
else -> 180f
|
||||||
|
}
|
||||||
|
b.previewContainer.isInvisible = item.state != AttendanceAdapter.STATE_CLOSED
|
||||||
|
b.summaryContainer.isInvisible = item.state == AttendanceAdapter.STATE_CLOSED
|
||||||
|
|
||||||
|
b.key.text = item.key
|
||||||
|
b.previewContainer.text = item.jsonArray.toString().take(200)
|
||||||
|
b.summaryContainer.text = item.jsonArray.size().toString() + " elements"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.viewholder
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.gson.JsonNull
|
||||||
|
import com.google.gson.JsonPrimitive
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.LabItemElementBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.LabJsonAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonElement
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
|
||||||
|
class JsonElementViewHolder(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
parent: ViewGroup,
|
||||||
|
val b: LabItemElementBinding = LabItemElementBinding.inflate(inflater, parent, false)
|
||||||
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<LabJsonElement, LabJsonAdapter> {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "JsonObjectViewHolder"
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBind(activity: AppCompatActivity, app: App, item: LabJsonElement, position: Int, adapter: LabJsonAdapter) {
|
||||||
|
val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme)
|
||||||
|
|
||||||
|
b.type.text = when (item.jsonElement) {
|
||||||
|
is JsonPrimitive -> when {
|
||||||
|
item.jsonElement.isNumber -> "Number"
|
||||||
|
item.jsonElement.isString -> "String"
|
||||||
|
item.jsonElement.isBoolean -> "Boolean"
|
||||||
|
else -> "Primitive"
|
||||||
|
}
|
||||||
|
is JsonNull -> "null"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
|
||||||
|
b.key.text = listOf(
|
||||||
|
item.key.asColoredSpannable(colorSecondary),
|
||||||
|
": ",
|
||||||
|
item.jsonElement.toString().asItalicSpannable()
|
||||||
|
).concat("")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.debug.viewholder
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.LabItemObjectBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.LabJsonAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
|
||||||
|
class JsonObjectViewHolder(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
parent: ViewGroup,
|
||||||
|
val b: LabItemObjectBinding = LabItemObjectBinding.inflate(inflater, parent, false)
|
||||||
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<LabJsonObject, LabJsonAdapter> {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "JsonObjectViewHolder"
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBind(activity: AppCompatActivity, app: App, item: LabJsonObject, position: Int, adapter: LabJsonAdapter) {
|
||||||
|
val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme)
|
||||||
|
|
||||||
|
b.dropdownIcon.rotation = when (item.state) {
|
||||||
|
AttendanceAdapter.STATE_CLOSED -> 0f
|
||||||
|
else -> 180f
|
||||||
|
}
|
||||||
|
b.previewContainer.isInvisible = item.state != AttendanceAdapter.STATE_CLOSED
|
||||||
|
b.summaryContainer.isInvisible = item.state == AttendanceAdapter.STATE_CLOSED
|
||||||
|
|
||||||
|
b.key.text = item.key
|
||||||
|
b.previewContainer.text = item.jsonObject.toString().take(200)
|
||||||
|
b.summaryContainer.text = item.jsonObject.size().toString() + " elements"
|
||||||
|
}
|
||||||
|
}
|
@ -54,6 +54,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Remove all homework body (null)"
|
android:text="Remove all homework body (null)"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/cookies"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
tools:text="Cookies:\n\nsynergia.librus.pl\n DZIENNIKSID=L01~1234567890abcdef"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</layout>
|
</layout>
|
||||||
|
34
app/src/main/res/layout/lab_item_element.xml
Normal file
34
app/src/main/res/layout/lab_item_element.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end"
|
||||||
|
tools:text="lessonRanges: 8" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/type"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:text="Int"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
75
app/src/main/res/layout/lab_item_object.xml
Normal file
75
app/src/main/res/layout/lab_item_object.xml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2020-5-12.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:baselineAligned="false"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/key"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Medium"
|
||||||
|
tools:text="lessonRanges" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:text="JsonObject"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsImageView
|
||||||
|
android:id="@+id/dropdownIcon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:iiv_color="?android:textColorSecondary"
|
||||||
|
app:iiv_icon="cmd-chevron-down"
|
||||||
|
app:iiv_size="18dp"
|
||||||
|
tools:src="@android:drawable/ic_menu_more" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/previewContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
|
tools:text="{"accountId":8765432,"accountLogin":"2345678u","accountToken":"49azsnNZfxxfdSYb6lKU8NambrMXjeCrw7yA" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summaryContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
|
tools:text="8 elements"
|
||||||
|
tools:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
Loading…
Reference in New Issue
Block a user