Commit d5ec86b5 authored by Filip Wiesner's avatar Filip Wiesner

TimetableEventDetail work (VM)

parent be9aa09f
......@@ -13,8 +13,8 @@
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="391" />
<option name="y" value="36" />
<option name="x" value="290" />
<option name="y" value="-195" />
</Point>
</option>
</LayoutPositions>
......@@ -36,11 +36,28 @@
<LayoutPositions />
</value>
</entry>
<entry key="action_navigationFragment_to_timetableDetailFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="timetableDetailFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="483" />
<option name="y" value="128" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
......
package com.cvut.blackbird
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.cvut.blackbird.extensions.withDefault
import com.cvut.blackbird.flows.NavigationFragment
class NavigationViewModel: ViewModel() {
var selectedDestination = MutableLiveData<Int>() withDefault NavigationFragment.STARTING_SCREEN
}
\ No newline at end of file
......@@ -7,6 +7,20 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver
import org.jetbrains.anko.childrenSequence
import android.R.attr.endColor
import android.R.attr.startColor
import com.cvut.blackbird.R.id.view
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import android.animation.Animator
import android.animation.ArgbEvaluator
import android.opengl.ETC1.getHeight
import android.opengl.ETC1.getWidth
import android.os.Build
import android.annotation.TargetApi
import android.animation.ValueAnimator
import android.os.Parcel
import android.os.Parcelable
var View.centerX : Float
get() = x + (width/2)
......@@ -80,6 +94,67 @@ inline fun View.revealFrom(duration: Long? = null, f:RevealPosition.() -> Unit)
revealFrom(pos.x.toInt(), pos.y.toInt(), duration)
}
class CircularRevealSettings(
val x: Int, val y: Int,
val width: Int, val height: Int
): Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readInt(),
parcel.readInt(),
parcel.readInt())
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(x)
parcel.writeInt(y)
parcel.writeInt(width)
parcel.writeInt(height)
}
override fun describeContents() = 0
companion object CREATOR : Parcelable.Creator<CircularRevealSettings> {
override fun createFromParcel(parcel: Parcel): CircularRevealSettings {
return CircularRevealSettings(parcel)
}
override fun newArray(size: Int): Array<CircularRevealSettings?> {
return arrayOfNulls(size)
}
}
}
fun View.registerCircularReveal(settings: CircularRevealSettings, startColor: Int, endColor: Int) =
doOnLayoutChange {
val duration = 500L
val finalRadius = Math.sqrt(
(settings.width * settings.width + settings.height * settings.height)
.toDouble()
).toFloat()
val anim: Animator = ViewAnimationUtils.createCircularReveal(this,
settings.x,
settings.y,
0f,
finalRadius
).setDuration(duration)
anim.interpolator = FastOutSlowInInterpolator()
anim.start()
startColorAnimation(startColor, endColor, duration)
}
fun View.startColorAnimation(startColor: Int, endColor: Int, duration: Long) {
val anim = ValueAnimator()
anim.setIntValues(startColor, endColor)
anim.setEvaluator(ArgbEvaluator())
anim.addUpdateListener { valueAnimator -> setBackgroundColor(valueAnimator.animatedValue as Int) }
anim.duration = duration
anim.start()
}
fun View.setVisible() {visibility = VISIBLE}
fun View.setInvisible() {visibility = INVISIBLE}
......@@ -93,6 +168,14 @@ inline fun View.doOnGlobalLayout(crossinline action: (View) -> Unit) {
} }
viewTreeObserver.addOnGlobalLayoutListener(viewGlobalObserver)
}
inline fun View.doOnLayoutChange (crossinline action: (View) -> Unit) {
addOnLayoutChangeListener(object : View.OnLayoutChangeListener {
override fun onLayoutChange(v: View, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) {
v.removeOnLayoutChangeListener(this)
action(v)
}
})
}
class RevealPosition(private val view: View) {
public var x = view.centerX
......
......@@ -5,12 +5,17 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.cvut.blackbird.NavigationViewModel
import com.cvut.blackbird.R
import com.cvut.blackbird.flows.tasks.TasksFragment
import com.cvut.blackbird.flows.profile.ProfileFragment
import com.cvut.blackbird.flows.search.SearchFragment
import com.cvut.blackbird.flows.timetable.TimetableFragment
import com.cvut.blackbird.flows.timetable.TimetableViewModel
import com.cvut.blackbird.support.glue.bind
import com.cvut.blackbird.support.glue.toPassValueTo
import kotlinx.android.synthetic.main.navigation_fragment.*
class NavigationFragment : Fragment() {
......@@ -18,6 +23,8 @@ class NavigationFragment : Fragment() {
const val STARTING_SCREEN = R.id.nav_tasks
}
private lateinit var viewModel: NavigationViewModel
private lateinit var tasksFrament: Fragment
private lateinit var timetableFragment: Fragment
private lateinit var searchFragment: Fragment
......@@ -31,19 +38,27 @@ class NavigationFragment : Fragment() {
profileFragment = ProfileFragment.newInstance()
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
= inflater.inflate(R.layout.navigation_fragment, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = ViewModelProviders.of(activity!!).get(NavigationViewModel::class.java)
bottom_navigation.setOnNavigationItemSelectedListener {selected ->
viewModel.selectedDestination.value = selected.itemId
val fragment = when (selected.itemId) {
R.id.nav_tasks -> tasksFrament
R.id.nav_timetable -> timetableFragment
R.id.nav_serach -> searchFragment
R.id.nav_profile -> profileFragment
else -> Fragment()
else -> TODO("what happened ma dude?")
}
activity!!.supportFragmentManager.beginTransaction()
......@@ -54,6 +69,8 @@ class NavigationFragment : Fragment() {
return@setOnNavigationItemSelectedListener true
}
bottom_navigation.selectedItemId = STARTING_SCREEN
bottom_navigation.selectedItemId = viewModel.selectedDestination.value ?: STARTING_SCREEN
}
}
......@@ -14,9 +14,11 @@ import com.cvut.blackbird.support.wobbly.WobblyElement
import com.github.florent37.kotlin.pleaseanimate.please
class TimetableBall(context: Context): WobblyElement(context) {
lateinit var payload: Event
override fun setupLayout(data: Any?) {
data as Event
payload = data
background = when {
data.eventType == EventType.LECTURE -> context.resources.getDrawable(R.drawable.ic_timetable_lecture, context.theme)
data.eventType == EventType.TUTORIAL -> context.resources.getDrawable(R.drawable.ic_timetable_tutorial, context.theme)
......@@ -46,15 +48,5 @@ class TimetableBall(context: Context): WobblyElement(context) {
width = 60.dpToPx
}
gravity = Gravity.CENTER
// doOnLayout { revealFrom { top(); left() } }
// doOnLayout {
// alpha = 0f
// please(500) {
// animate(it).toBe {
// alpha(1f)
// }
// }.start()
// }
}
}
\ No newline at end of file
package com.cvut.blackbird.flows.timetable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.cvut.blackbird.R
import com.cvut.blackbird.extensions.registerCircularReveal
import com.cvut.blackbird.model.entities.Event
import com.cvut.blackbird.support.glue.bind
import com.cvut.blackbird.support.glue.toPassValueTo
import kotlinx.android.synthetic.main.auth_fragment_transition.*
class TimetableDetailFragment : Fragment() {
lateinit var event: Event
companion object {
const val REVEAL_SETTINGS = "revealSettings"
const val START_COLOR = "startColor"
const val END_COLOR = "endColor"
fun newInstance(event: Event) = TimetableDetailFragment()
.apply { this.event = event }
}
private lateinit var viewModel: TimetableViewModel
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(activity!!).get(TimetableViewModel::class.java)
this bind viewModel.eventDetail toPassValueTo ::setupEvent
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_timetable_detail, container, false)
if (arguments != null)
view.registerCircularReveal(
arguments!!.getParcelable(REVEAL_SETTINGS)!!,
arguments!!.getInt(START_COLOR),
arguments!!.getInt(END_COLOR)
)
return view
}
private fun setupEvent(event: Event) {
textView.text = event.linked?.course
}
}
\ No newline at end of file
......@@ -9,11 +9,17 @@ import android.util.TypedValue
import android.view.*
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.findNavController
import com.cvut.blackbird.R
import com.cvut.blackbird.extensions.*
import com.cvut.blackbird.flows.timetable.TimetableDetailFragment.Companion.END_COLOR
import com.cvut.blackbird.flows.timetable.TimetableDetailFragment.Companion.REVEAL_SETTINGS
import com.cvut.blackbird.flows.timetable.TimetableDetailFragment.Companion.START_COLOR
import com.cvut.blackbird.model.entities.Event
import com.cvut.blackbird.support.glue.bind
import com.cvut.blackbird.support.glue.clickTo
......@@ -88,9 +94,17 @@ class TimetableFragment : Fragment() {
}
fun Fragment.getColor(id: Int) = ContextCompat.getColor(requireContext(),id)
private fun onLectureClick(element: View) {
// detail.setVisible()
// detail.revealFrom { top(); right() }
if (element is TimetableBall) {
viewModel.eventDetail.value = element.payload
view?.findNavController()?.navigate(R.id.action_navigationFragment_to_timetableDetailFragment, bundleOf(
REVEAL_SETTINGS to CircularRevealSettings(element.globalCenterX,element.globalCenterY,2000,2000),
START_COLOR to getColor(R.color.colorAccent),
END_COLOR to Color.TRANSPARENT
))
}
}
private val days = arrayOf("Mon", "Tue", "Wed", "Thu", "Fri")
......@@ -102,7 +116,8 @@ class TimetableFragment : Fragment() {
get(column+1)?.
get(position)?: Event.empty
override fun getItemView(position: Int, column: Int): WobblyElement = TimetableBall(activity!!).apply { setOnClickListener { onLectureClick(it) } }
override fun getItemView(position: Int, column: Int): WobblyElement = TimetableBall(activity!!)
.apply { setOnClickListener { onLectureClick(it) } }
override fun getItemCount(column: Int): Int = viewModel.timetable
.value?.get(column+1)?.size ?: 0
......
......@@ -28,6 +28,8 @@ class TimetableViewModel : ViewModel() {
val timetable: LiveData<Map<Int,List<Event>>> get() = _timetable
val displayedWeek: LiveData<DateTime> get() = _displayedWeek
val eventDetail = MutableLiveData<Event>() withDefault Event.empty
init {
if (_displayedWeek.value!!.dayOfWeek > 5) _displayedWeek.apply { value = value?.plusWeeks(1) }
......@@ -70,3 +72,5 @@ class TimetableViewModel : ViewModel() {
fun nextWeek() { _displayedWeek.apply { value = value!!.plusWeeks(1) } }
fun previousWeek() { _displayedWeek.apply { value = value!!.minusWeeks(1) } }
}
//class
package com.cvut.blackbird.model.services
import com.chibatching.kotpref.Kotpref
import com.chibatching.kotpref.KotprefModel
import com.chibatching.kotpref.bulk
import com.cvut.blackbird.model.entities.Student
......@@ -20,7 +19,7 @@ object UserInfo: KotprefModel() {
var programme by stringPref()
var studyGroup by intPref()
public fun setStudent(student: Student) = bulk {
fun setStudent(student: Student): Unit = bulk {
username = student.username ?: ""
surname = student.surname ?: ""
email = student.email ?: ""
......
<vector android:height="64dp" android:viewportHeight="33"
android:viewportWidth="33" android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M7.282,32.706c-0.081,0 -0.163,-0.02 -0.237,-0.06c-0.162,-0.087 -0.263,-0.257 -0.263,-0.44v-7.124C2.405,22.806 0,18.821 0,13.828C0,6.112 7.093,0.294 16.5,0.294S33,6.112 33,13.828c0,7.715 -7.093,13.533 -16.5,13.533c-0.309,0 -0.612,-0.017 -0.916,-0.033l-0.02,-0.001l-8.007,5.296C7.474,32.678 7.378,32.706 7.282,32.706zM16.5,1.294C7.664,1.294 1,6.683 1,13.828c0,3.323 1.128,7.842 6.503,10.499c0.17,0.084 0.278,0.258 0.278,0.448v6.501l7.369,-4.874c0.09,-0.06 0.199,-0.095 0.302,-0.082l0.186,0.01c0.286,0.016 0.571,0.031 0.861,0.031c8.836,0 15.5,-5.388 15.5,-12.533S25.336,1.294 16.5,1.294z"/>
</vector>
......@@ -83,7 +83,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_raven" />
app:srcCompat="@drawable/ic_raven"/>
<TextView
android:id="@+id/infoMessage"
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/auth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimaryDark"
tools:context=".flows.authentication.AuthFragment">
<ImageView
android:id="@+id/imageView2"
android:layout_width="200dp"
android:layout_height="200dp"
android:tag="birdLogo"
android:tint="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8"
app:srcCompat="@drawable/ic_raven" />
<ImageView
android:id="@+id/imageView"
android:layout_width="240dp"
android:layout_height="229dp"
android:tag="birdSpeech"
android:layout_marginBottom="8dp"
android:scaleX="-1"
android:tint="@android:color/white"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/imageView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.42"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.19999999"
app:srcCompat="@drawable/ic_speech_bubble" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="45dp"
android:layout_marginTop="40dp"
android:layout_marginEnd="45dp"
android:layout_marginBottom="80dp"
android:gravity="center"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toTopOf="@+id/imageView"
tools:text="Preparing some stuff for you.\n\nWait a sec..." />
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".flows.timetable.TimetableDetailFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
\ No newline at end of file
......@@ -13,10 +13,19 @@
<action
android:id="@+id/action_navigationFragment_to_authFragment"
app:destination="@id/authFragment" />
<action
android:id="@+id/action_navigationFragment_to_timetableDetailFragment"
app:destination="@id/timetableDetailFragment" />
</fragment>
<fragment
android:id="@+id/authFragment"
android:name="com.cvut.blackbird.flows.authentication.AuthFragment"
android:label="auth_fragment"
tools:layout="@layout/auth_fragment" />
<fragment
android:id="@+id/timetableDetailFragment"
android:name="com.cvut.blackbird.flows.timetable.TimetableDetailFragment"
android:label="fragment_timetable_detail"
tools:layout="@layout/fragment_timetable_detail" >
</fragment>
</navigation>
\ No newline at end of file
......@@ -5,4 +5,7 @@
<string name="network_disconnected">Offline</string>
<string name="under_development_disclaimer">Under Development</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment