mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 05:48:19 +01:00
[UI] Add new Home fragment. Add Lucky number card and number selection dialog.
This commit is contained in:
parent
0759468fa7
commit
6e6dd34872
@ -29,6 +29,9 @@ import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import im.wangchao.mhttp.Response
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team
|
||||
@ -503,3 +506,15 @@ fun View.findParentById(targetId: Int): View? {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long = 0, action: () -> Unit) = launch {
|
||||
delay(delayMillis)
|
||||
if (repeatMillis > 0) {
|
||||
while (true) {
|
||||
action()
|
||||
delay(repeatMillis)
|
||||
}
|
||||
} else {
|
||||
action()
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.feedback.HelpFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.editor.GradesEditorFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2
|
||||
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
|
||||
import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.ui.modules.messages.MessageFragment
|
||||
@ -122,7 +122,7 @@ class MainActivity : AppCompatActivity() {
|
||||
val list: MutableList<NavTarget> = mutableListOf()
|
||||
|
||||
// home item
|
||||
list += NavTarget(DRAWER_ITEM_HOME, R.string.menu_home_page, HomeFragment::class)
|
||||
list += NavTarget(DRAWER_ITEM_HOME, R.string.menu_home_page, HomeFragmentV2::class)
|
||||
.withTitle(R.string.app_name)
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_home_outline)
|
||||
.isInDrawer(true)
|
||||
@ -702,7 +702,10 @@ class MainActivity : AppCompatActivity() {
|
||||
loadProfile(intentProfileId, intentTargetId, extras)
|
||||
}
|
||||
intentProfileId != -1 -> {
|
||||
loadProfile(intentProfileId, intentTargetId, extras)
|
||||
if (app.profile.id != intentProfileId)
|
||||
loadProfile(intentProfileId, intentTargetId, extras)
|
||||
else
|
||||
loadTarget(intentTargetId, extras)
|
||||
}
|
||||
intentTargetId != -1 -> {
|
||||
drawer.currentProfile = app.profile.id
|
||||
|
@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.Notifier.ID_NOTIFICATIONS
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.notification.getNotificationTitle
|
||||
import pl.szczodrzynski.edziennik.utils.models.Notification
|
||||
import kotlin.math.min
|
||||
|
||||
@ -33,9 +34,9 @@ class NotifyTask : IApiTask(-1) {
|
||||
val pendingIntent = PendingIntent.getActivity(app, notification.id, intent, 0)
|
||||
val notificationBuilder = NotificationCompat.Builder(app, app.notifier.notificationGroup)
|
||||
// title, text, type, date
|
||||
.setContentTitle(notification.title)
|
||||
.setContentTitle(notification.profileName)
|
||||
.setContentText(notification.text)
|
||||
.setSubText(Notification.stringType(app, notification.type))
|
||||
.setSubText(app.getNotificationTitle(notification.type))
|
||||
.setWhen(notification.addedDate)
|
||||
.setTicker(app.getString(R.string.notification_ticker_format, Notification.stringType(app, notification.type)))
|
||||
// icon, color, lights, priority
|
||||
|
@ -375,7 +375,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
}
|
||||
|
||||
fun shouldSyncLuckyNumber(): Boolean {
|
||||
return (db.luckyNumberDao().getNearestFutureNow(profileId, Date.getToday()) ?: -1) == -1
|
||||
return (db.luckyNumberDao().getNearestFutureNow(profileId, Date.getToday().value) ?: -1) == -1
|
||||
}
|
||||
|
||||
fun error(tag: String, errorCode: Int, response: Response? = null, throwable: Throwable? = null, apiResponse: JsonObject? = null) {
|
||||
|
@ -37,7 +37,10 @@ public abstract class LuckyNumberDao {
|
||||
|
||||
@Nullable
|
||||
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate >= :date ORDER BY luckyNumberDate DESC LIMIT 1")
|
||||
public abstract LuckyNumber getNearestFutureNow(int profileId, Date date);
|
||||
public abstract LuckyNumber getNearestFutureNow(int profileId, int date);
|
||||
|
||||
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate >= :date ORDER BY luckyNumberDate DESC LIMIT 1")
|
||||
public abstract LiveData<LuckyNumber> getNearestFuture(int profileId, int date);
|
||||
|
||||
@RawQuery(observedEntities = {LuckyNumber.class})
|
||||
abstract LiveData<List<LuckyNumberFull>> getAll(SupportSQLiteQuery query);
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.home
|
||||
|
||||
import android.text.InputType
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
|
||||
class StudentNumberDialog(
|
||||
val activity: AppCompatActivity,
|
||||
val profile: Profile,
|
||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "StudentNumberDialog"
|
||||
}
|
||||
|
||||
private lateinit var dialog: AlertDialog
|
||||
|
||||
init { run {
|
||||
if (activity.isFinishing)
|
||||
return@run
|
||||
onShowListener?.invoke(TAG)
|
||||
MaterialDialog.Builder(activity)
|
||||
.title(R.string.card_lucky_number_set_title)
|
||||
.content(R.string.card_lucky_number_set_text)
|
||||
.inputType(InputType.TYPE_CLASS_NUMBER)
|
||||
.input(null, if (profile.studentNumber == -1) "" else profile.studentNumber.toString()) { _: MaterialDialog?, input: CharSequence ->
|
||||
try {
|
||||
profile.studentNumber = input.toString().toInt()
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(activity, R.string.incorrect_format, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
.dismissListener {
|
||||
onDismissListener?.invoke(TAG)
|
||||
}.show()
|
||||
}}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2.Companion.swapCards
|
||||
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
|
||||
|
||||
class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, private val refreshLayout: SwipeRefreshLayoutNoIndicator?) : ItemTouchHelper.Callback() {
|
||||
companion object {
|
||||
private const val TAG = "CardItemTouchHelperCallback"
|
||||
private const val DRAG_FLAGS = ItemTouchHelper.UP or ItemTouchHelper.DOWN
|
||||
private const val SWIPE_FLAGS = 0
|
||||
}
|
||||
|
||||
private var dragCardView: MaterialCardView? = null
|
||||
|
||||
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
|
||||
return makeMovementFlags(DRAG_FLAGS, SWIPE_FLAGS)
|
||||
}
|
||||
|
||||
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
|
||||
val fromPosition = viewHolder.adapterPosition
|
||||
val toPosition = target.adapterPosition
|
||||
|
||||
swapCards(fromPosition, toPosition, cardAdapter)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) = Unit
|
||||
|
||||
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
|
||||
super.onSelectedChanged(viewHolder, actionState)
|
||||
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG && viewHolder != null) {
|
||||
dragCardView = viewHolder.itemView as MaterialCardView
|
||||
dragCardView?.isDragged = true
|
||||
refreshLayout?.isEnabled = false
|
||||
} else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE && dragCardView != null) {
|
||||
refreshLayout?.isEnabled = true
|
||||
dragCardView?.isDragged = false
|
||||
dragCardView = null
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||
|
||||
interface HomeCard {
|
||||
fun bind(position: Int, holder: HomeCardAdapter.ViewHolder)
|
||||
fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder)
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
|
||||
class HomeCardAdapter(var items: MutableList<HomeCard>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
companion object {
|
||||
private const val TAG = "HomeCardAdapter"
|
||||
}
|
||||
|
||||
var itemTouchHelper: ItemTouchHelper? = null
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
(holder as ViewHolder).bind(itemTouchHelper)
|
||||
items[position].bind(position, holder)
|
||||
}
|
||||
|
||||
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
|
||||
items.getOrNull(holder.adapterPosition)?.unbind(holder.adapterPosition, holder as ViewHolder)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
return ViewHolder(
|
||||
LayoutInflater.from(parent.context).inflate(R.layout.card_home, parent, false) as MaterialCardView
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
class ViewHolder(val root: MaterialCardView) : RecyclerView.ViewHolder(root) {
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
fun bind(itemTouchHelper: ItemTouchHelper?) {
|
||||
/*root.setOnTouchListener { _: View?, event: MotionEvent ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
itemTouchHelper?.startDrag(this)
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
false
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.plusAssign
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeDummyCard(val id: Int) : HomeCard, CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "HomeDummyCard"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
|
||||
private var job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
var timer: Job? = null
|
||||
var time = 0
|
||||
|
||||
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) { launch {
|
||||
holder.root.removeAllViews()
|
||||
//holder.setIsRecyclable(false)
|
||||
|
||||
val text = TextView(holder.root.context).apply {
|
||||
text = "This is a card #$id"
|
||||
}
|
||||
holder.root += text
|
||||
|
||||
timer = startCoroutineTimer(repeatMillis = 1000) {
|
||||
time++
|
||||
text.text = "Coroutine timer at #$id! $time seconds"
|
||||
}
|
||||
|
||||
/*val button = MaterialButton(holder.root.context).apply {
|
||||
setText("Cancel")
|
||||
onClick {
|
||||
timer.cancel()
|
||||
}
|
||||
}
|
||||
holder.root += button*/
|
||||
}}
|
||||
|
||||
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) {
|
||||
timer?.cancel()
|
||||
timer = null
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.AccessibilityDelegateCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate
|
||||
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.R
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentHomeV2Binding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeLuckyNumberCard
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeFragmentV2 : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
|
||||
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) {
|
||||
val fromCard = cardAdapter.items[fromPosition]
|
||||
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
|
||||
cardAdapter.items[toPosition] = fromCard
|
||||
cardAdapter.notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentHomeV2Binding
|
||||
|
||||
private lateinit var job: Job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
context!!.theme.applyStyle(Themes.appTheme, true)
|
||||
b = FragmentHomeV2Binding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
job = Job()
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// TODO check if app, activity, b can be null
|
||||
if (app.profile == null || !isAdded)
|
||||
return
|
||||
|
||||
val items = mutableListOf<HomeCard>(
|
||||
HomeLuckyNumberCard(0, app, activity, this, app.profile),
|
||||
HomeDummyCard(1),
|
||||
HomeDummyCard(2),
|
||||
HomeDummyCard(3),
|
||||
HomeDummyCard(4),
|
||||
HomeDummyCard(5),
|
||||
HomeDummyCard(6),
|
||||
HomeDummyCard(7),
|
||||
HomeDummyCard(8),
|
||||
HomeDummyCard(9),
|
||||
HomeDummyCard(10),
|
||||
HomeDummyCard(11),
|
||||
HomeDummyCard(12),
|
||||
HomeDummyCard(13),
|
||||
HomeDummyCard(14),
|
||||
HomeDummyCard(15),
|
||||
HomeDummyCard(16)
|
||||
)
|
||||
|
||||
val adapter = HomeCardAdapter(items)
|
||||
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))
|
||||
adapter.itemTouchHelper = itemTouchHelper
|
||||
b.list.layoutManager = LinearLayoutManager(activity)
|
||||
b.list.adapter = adapter
|
||||
b.list.setAccessibilityDelegateCompat(object : RecyclerViewAccessibilityDelegate(b.list) {
|
||||
override fun getItemDelegate(): AccessibilityDelegateCompat {
|
||||
return object : ItemDelegate(this) {
|
||||
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info)
|
||||
val position: Int = b.list.getChildLayoutPosition(host)
|
||||
if (position != 0) {
|
||||
info.addAction(AccessibilityActionCompat(
|
||||
R.id.move_card_up_action,
|
||||
host.resources.getString(R.string.card_action_move_up)
|
||||
))
|
||||
}
|
||||
if (position != adapter.itemCount - 1) {
|
||||
info.addAction(AccessibilityActionCompat(
|
||||
R.id.move_card_down_action,
|
||||
host.resources.getString(R.string.card_action_move_down)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
override fun performAccessibilityAction(host: View, action: Int, args: Bundle): Boolean {
|
||||
val fromPosition: Int = b.list.getChildLayoutPosition(host)
|
||||
if (action == R.id.move_card_down_action) {
|
||||
swapCards(fromPosition, fromPosition + 1, adapter)
|
||||
return true
|
||||
} else if (action == R.id.move_card_up_action) {
|
||||
swapCards(fromPosition, fromPosition - 1, adapter)
|
||||
return true
|
||||
}
|
||||
return super.performAccessibilityAction(host, action, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
itemTouchHelper.attachToRecyclerView(b.list)
|
||||
}
|
||||
}
|
@ -33,17 +33,17 @@ class HomeTimetableCard(
|
||||
private val layoutInflater: LayoutInflater,
|
||||
private val insertPoint: ViewGroup
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "HomeTimetableCard"
|
||||
const val TIME_TILL = 0
|
||||
const val TIME_LEFT = 1
|
||||
}
|
||||
|
||||
private lateinit var timetableTimer: Timer
|
||||
private lateinit var b: CardTimetableBinding
|
||||
|
||||
private var bellSyncTime: Time? = null
|
||||
|
||||
private companion object {
|
||||
const val TIME_TILL = 0
|
||||
const val TIME_LEFT = 1
|
||||
}
|
||||
|
||||
private var counterType = TIME_TILL
|
||||
private val counterTarget = Time(0, 0, 0)
|
||||
|
||||
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.plusAssign
|
||||
import androidx.core.view.setMargins
|
||||
import androidx.lifecycle.Observer
|
||||
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.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.databinding.CardHomeLuckyNumberBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.home.StudentNumberDialog
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeLuckyNumberCard(
|
||||
val id: Int,
|
||||
val app: App,
|
||||
val activity: MainActivity,
|
||||
val fragment: HomeFragmentV2,
|
||||
val profile: Profile
|
||||
) : HomeCard, CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "HomeLuckyNumberCard"
|
||||
}
|
||||
|
||||
private var job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) { launch {
|
||||
holder.root.removeAllViews()
|
||||
val b = CardHomeLuckyNumberBinding.inflate(LayoutInflater.from(holder.root.context))
|
||||
b.root.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
|
||||
setMargins(8.dp)
|
||||
}
|
||||
holder.root += b.root
|
||||
|
||||
val today = Date.getToday()
|
||||
val todayValue = today.value
|
||||
|
||||
val subTextRes = if (profile.studentNumber == -1)
|
||||
R.string.home_lucky_number_details_click_to_set
|
||||
else
|
||||
R.string.home_lucky_number_details
|
||||
b.subText.setText(subTextRes, profile.name ?: "", profile.studentNumber)
|
||||
|
||||
app.db.luckyNumberDao().getNearestFuture(App.profileId, todayValue).observe(fragment, Observer { luckyNumber ->
|
||||
val isYours = luckyNumber?.number == profile.studentNumber
|
||||
val titleRes = when {
|
||||
luckyNumber == null -> R.string.home_lucky_number_no_info
|
||||
luckyNumber.number == -1 -> R.string.home_lucky_number_no_number
|
||||
else -> when (isYours) {
|
||||
true -> when (luckyNumber.date.value) {
|
||||
todayValue -> R.string.home_lucky_number_yours_today
|
||||
todayValue + 1 -> R.string.home_lucky_number_yours_tomorrow
|
||||
else -> R.string.home_lucky_number_yours_later
|
||||
}
|
||||
false -> when (luckyNumber.date.value) {
|
||||
todayValue -> R.string.home_lucky_number_today
|
||||
todayValue + 1 -> R.string.home_lucky_number_tomorrow
|
||||
else -> R.string.home_lucky_number_later
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b.title.setText(
|
||||
titleRes,
|
||||
luckyNumber?.number ?: 0,
|
||||
luckyNumber?.date?.formattedString ?: ""
|
||||
)
|
||||
|
||||
val drawableRes = when {
|
||||
luckyNumber == null || luckyNumber.number == -1 -> R.drawable.emoji_sad
|
||||
isYours -> R.drawable.emoji_glasses
|
||||
!isYours -> R.drawable.emoji_smiling
|
||||
else -> R.drawable.emoji_no_face
|
||||
}
|
||||
b.image.setImageResource(drawableRes)
|
||||
})
|
||||
|
||||
holder.root.onClick {
|
||||
StudentNumberDialog(activity, profile, onDismissListener = {
|
||||
app.profileSaveAsync(profile)
|
||||
val newSubTextRes = if (profile.studentNumber == -1)
|
||||
R.string.home_lucky_number_details_click_to_set
|
||||
else
|
||||
R.string.home_lucky_number_details
|
||||
b.subText.setText(newSubTextRes, profile.name ?: "", profile.studentNumber)
|
||||
})
|
||||
}
|
||||
}}
|
||||
|
||||
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) = Unit
|
||||
}
|
28
app/src/main/res/drawable/emoji_glasses.xml
Normal file
28
app/src/main/res/drawable/emoji_glasses.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="M63.79,8.64C1.48,8.64 0,78.5 0,92.33c0,13.83 28.56,25.03 63.79,25.03c35.24,0 63.79,-11.21 63.79,-25.03C127.58,78.5 126.11,8.64 63.79,8.64z"
|
||||
android:fillColor="#FCC21B"/>
|
||||
<path
|
||||
android:pathData="M63.91,104.82c-3.43,0 -6.87,-0.43 -10.25,-1.31c-1.6,-0.42 -2.56,-2.06 -2.15,-3.66c0.42,-1.6 2.06,-2.56 3.66,-2.14c11.65,3.04 24.21,-0.21 32.78,-8.48c1.19,-1.15 3.09,-1.12 4.24,0.08c1.15,1.19 1.12,3.09 -0.08,4.24C84.54,100.85 74.32,104.82 63.91,104.82z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M55.53,67.26c-0.01,0.01 -0.02,0.02 -0.02,0.02C55.51,67.27 55.52,67.26 55.53,67.26z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M98.21,41.34c-13.36,0 -15.15,2.03 -21.4,3.36C70.56,46.02 64,46.02 64,46.02s-6.56,0 -12.81,-1.33c-6.25,-1.33 -8.05,-3.36 -21.4,-3.36c-13.36,0 -29.37,2.89 -29.37,2.89v8.51c0,0 3.59,0.47 3.91,3.75c0.16,1.33 -3.12,28.35 23.51,28.35c18.9,0 26.87,-11.33 29.45,-20.54c1.17,-4.37 2.19,-9.37 6.72,-9.37c4.53,0 5.55,5 6.72,9.37c2.58,9.22 10.54,20.54 29.45,20.54c26.63,0 23.35,-27.03 23.51,-28.35c0.31,-3.28 3.91,-3.75 3.91,-3.75v-8.51C127.58,44.23 111.57,41.34 98.21,41.34z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M95.94,45.05c-6.62,0.23 -11.65,1.31 -11.65,1.31c-9.84,2.06 -10.55,8.14 -9.93,12.97c0.8,6.07 3.29,13.75 10.04,18.49c0.53,0.38 1.76,0.79 2.35,-0.77c0,0 -0.02,0.11 0,0c2.22,-10.48 5.52,-20.14 10.78,-29.89l0,0C98.14,45.37 96.71,45.02 95.94,45.05z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
<path
|
||||
android:pathData="M31.06,45.02c-4.27,-0.09 -9.11,0.19 -13.65,1.34c-5.1,1.28 -7.07,3.85 -7.6,9.39c-0.53,5.43 -1.13,19.27 8.73,24.46c0.57,0.3 1.83,0.5 2.44,-0.91l0,0C24,66.21 25.61,60.13 32.54,47.22l0,0C33.11,45.49 31.83,45.03 31.06,45.02z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
</vector>
|
22
app/src/main/res/drawable/emoji_neutral.xml
Normal file
22
app/src/main/res/drawable/emoji_neutral.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="M64,9.56c-62.41,0 -63.88,69.96 -63.88,83.8c0,13.86 28.59,25.08 63.88,25.08c35.28,0 63.88,-11.22 63.88,-25.08C127.88,79.52 126.4,9.56 64,9.56z"
|
||||
android:fillColor="#FCC21B"/>
|
||||
<path
|
||||
android:pathData="M42.21,62.3c-4.49,0.04 -8.17,-4.27 -8.22,-9.62c-0.05,-5.37 3.55,-9.75 8.04,-9.79c4.48,-0.04 8.17,4.27 8.22,9.64C50.3,57.88 46.7,62.25 42.21,62.3z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M86.32,62.3c4.48,-0.01 8.11,-4.36 8.1,-9.71c-0.01,-5.37 -3.66,-9.7 -8.14,-9.69c-4.49,0.01 -8.13,4.36 -8.12,9.73C78.18,57.98 81.83,62.31 86.32,62.3z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M89.69,84.75H38.31c-1.66,0 -3,-1.34 -3,-3s1.34,-3 3,-3h51.39c1.66,0 3,1.34 3,3S91.35,84.75 89.69,84.75z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
</vector>
|
19
app/src/main/res/drawable/emoji_no_face.xml
Normal file
19
app/src/main/res/drawable/emoji_no_face.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="M64,9.56c-62.41,0 -63.88,69.96 -63.88,83.8c0,13.86 28.59,25.08 63.88,25.08c35.28,0 63.88,-11.22 63.88,-25.08C127.88,79.52 126.4,9.56 64,9.56z"
|
||||
android:fillColor="#FCC21B"/>
|
||||
<path
|
||||
android:pathData="M42.21,65.3c-4.49,0.04 -8.17,-4.27 -8.22,-9.62c-0.05,-5.37 3.55,-9.75 8.04,-9.79c4.48,-0.04 8.17,4.27 8.22,9.64C50.3,60.88 46.7,65.25 42.21,65.3z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M86.32,65.3c4.48,-0.01 8.11,-4.36 8.1,-9.71c-0.01,-5.37 -3.66,-9.7 -8.14,-9.69c-4.49,0.01 -8.13,4.36 -8.12,9.73C78.18,60.98 81.83,65.31 86.32,65.3z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
</vector>
|
22
app/src/main/res/drawable/emoji_sad.xml
Normal file
22
app/src/main/res/drawable/emoji_sad.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="M64,9.62c-62.41,0 -63.88,69.96 -63.88,83.8c0,13.86 28.59,25.08 63.88,25.08c35.28,0 63.88,-11.22 63.88,-25.08C127.88,79.58 126.4,9.62 64,9.62z"
|
||||
android:fillColor="#FCC21B"/>
|
||||
<path
|
||||
android:pathData="M41.99,65.5c-4.49,0.04 -8.17,-4.27 -8.22,-9.62c-0.05,-5.37 3.55,-9.75 8.04,-9.79c4.48,-0.04 8.17,4.27 8.22,9.64C50.08,61.09 46.47,65.46 41.99,65.5z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M86.1,65.5c4.48,-0.01 8.11,-4.36 8.1,-9.71c-0.01,-5.37 -3.66,-9.7 -8.14,-9.69c-4.49,0.01 -8.13,4.36 -8.12,9.73C77.95,61.18 81.61,65.51 86.1,65.5z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M43.08,97.67c1.99,1.34 4.5,0.46 6.71,0c6.18,-1.28 11.6,-1.33 14.2,-1.33s8.03,0.05 14.2,1.33c2.21,0.46 4.72,1.34 6.71,0c2.52,-1.71 0.66,-7.83 -3.31,-11.97c-2.4,-2.5 -8.13,-7.35 -17.61,-7.35c-9.48,0 -15.2,4.85 -17.61,7.35C42.42,89.85 40.56,95.97 43.08,97.67z"
|
||||
android:fillColor="#ED6C30"/>
|
||||
</vector>
|
22
app/src/main/res/drawable/emoji_smiling.xml
Normal file
22
app/src/main/res/drawable/emoji_smiling.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="M127.94,93.75c0,14.02 -28.61,25.39 -63.93,25.39S0.06,107.77 0.06,93.75c0,-14.03 1.48,-84.89 63.95,-84.89C126.47,8.86 127.94,79.72 127.94,93.75"
|
||||
android:fillColor="#FCC21B"/>
|
||||
<path
|
||||
android:pathData="M48.14,57.33c0,5.47 -3.66,9.9 -8.19,9.9c-4.53,0 -8.21,-4.43 -8.21,-9.9c0,-5.48 3.68,-9.91 8.21,-9.91C44.48,47.42 48.14,51.85 48.14,57.33"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M80.14,57.33c0,5.47 3.66,9.9 8.21,9.9c4.53,0 8.21,-4.43 8.21,-9.9c0,-5.48 -3.68,-9.91 -8.21,-9.91C83.8,47.42 80.14,51.85 80.14,57.33"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
<path
|
||||
android:pathData="M66.8,93.74c-0.72,0 -1.48,-0.03 -2.25,-0.07C46.53,92.59 39.69,82.82 39.41,82.4c-1,-1.48 -0.62,-3.48 0.85,-4.48c1.46,-1 3.45,-0.62 4.46,0.83c0.25,0.37 5.61,7.61 20.22,8.47c14.57,0.84 20.91,-8.67 20.99,-8.77c0.95,-1.49 2.97,-1.92 4.45,-0.96c1.49,0.97 1.93,2.96 0.95,4.45C91.01,82.46 83.52,93.74 66.8,93.74z"
|
||||
android:fillColor="#2F2F2F"/>
|
||||
</vector>
|
17
app/src/main/res/layout/card_home.xml
Normal file
17
app/src/main/res/layout/card_home.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
-->
|
||||
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<include layout="@layout/card_home_lucky_number" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
46
app/src/main/res/layout/card_home_lucky_number.xml
Normal file
46
app/src/main/res/layout/card_home_lucky_number.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:layout_margin="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
app:srcCompat="@drawable/emoji_sad" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Title"
|
||||
android:text="@string/home_lucky_number_no_info" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
tools:text="Oranż Metylowy • Numer w dzienniku to 23" />
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
20
app/src/main/res/layout/fragment_home_v2.xml
Normal file
20
app/src/main/res/layout/fragment_home_v2.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-23.
|
||||
-->
|
||||
|
||||
<layout xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/card_home" />
|
||||
|
||||
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
|
||||
</layout>
|
9
app/src/main/res/values/ids.xml
Normal file
9
app/src/main/res/values/ids.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<item name="move_card_down_action" type="id"/>
|
||||
<item name="move_card_up_action" type="id"/>
|
||||
</resources>
|
@ -1032,4 +1032,16 @@
|
||||
<string name="menu_remove_notifications">Usuń wszystkie</string>
|
||||
<string name="menu_remove_notifications_success">Wyczyszczono powiadomienia</string>
|
||||
<string name="timetable_select_day">Wybierz dzień</string>
|
||||
<string name="card_action_move_up">Przesuń w górę</string>
|
||||
<string name="card_action_move_down">Przesuń w dół</string>
|
||||
<string name="home_lucky_number_details_click_to_set">%s • Kliknij, aby ustawić swój numerek.</string>
|
||||
<string name="home_lucky_number_details">%s • Numer w dzienniku to %d</string>
|
||||
<string name="home_lucky_number_no_info">Brak informacji o szczęśliwym numerku.</string>
|
||||
<string name="home_lucky_number_yours_today">Dzisiaj to Ty masz szczęśliwy numerek!</string>
|
||||
<string name="home_lucky_number_yours_tomorrow">Jutro to Ty masz szczęśliwy numerek!</string>
|
||||
<string name="home_lucky_number_yours_later">Dnia %s Twój numerek jest szczęśliwy.</string>
|
||||
<string name="home_lucky_number_later">Dnia %s szczęśliwy numerek to %d.</string>
|
||||
<string name="home_lucky_number_today">%d to dzisiejszy szczęśliwy numerek.</string>
|
||||
<string name="home_lucky_number_tomorrow">%d to szczęśliwy numerek na jutro.</string>
|
||||
<string name="home_lucky_number_no_number">Nie ma dzisiaj szczęśliwego numerka.</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user