conventionschedule-android/app/src/main/java/com/adlerosn/brasilfurfest/schedule/fragment/ConventionSummaryFragment.kt

361 lines
18 KiB
Kotlin
Raw Normal View History

2018-07-13 21:09:43 +00:00
package com.adlerosn.brasilfurfest.schedule.fragment
import android.app.AlertDialog
2018-07-18 05:51:07 +00:00
import android.content.Context
2018-07-13 21:09:43 +00:00
import android.content.DialogInterface
2018-07-14 19:43:24 +00:00
import android.content.Intent
2018-07-13 21:09:43 +00:00
import android.os.Bundle
import android.support.v4.app.Fragment
2018-07-16 23:15:20 +00:00
import android.support.v4.content.ContextCompat
2018-07-13 21:09:43 +00:00
import android.support.v4.content.res.ResourcesCompat
2018-07-18 15:01:16 +00:00
import android.util.Log
2018-07-13 21:09:43 +00:00
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
2018-07-14 19:43:24 +00:00
import com.adlerosn.brasilfurfest.AssetImageViewerActivity
2018-07-27 03:39:36 +00:00
import com.adlerosn.brasilfurfest.CountdownActivity
2018-07-13 21:09:43 +00:00
import com.adlerosn.brasilfurfest.R
2018-07-18 05:51:07 +00:00
import com.adlerosn.brasilfurfest.helper.*
2018-07-16 23:15:20 +00:00
import com.adlerosn.brasilfurfest.schedule.EventActivity
2018-07-13 21:09:43 +00:00
import com.adlerosn.brasilfurfest.schedule.ScheduleManager
2018-12-12 04:30:34 +00:00
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.dataholder.PeekableEvent
2018-07-16 23:15:20 +00:00
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.Actions
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConFavorite
2018-07-13 21:09:43 +00:00
import kotlinx.android.synthetic.main.dialogview_schedule_registration_tier.view.*
import kotlinx.android.synthetic.main.dialogview_schedule_registration_tiers.view.*
import kotlinx.android.synthetic.main.fragment_schedule_summary.view.*
2018-07-26 02:29:15 +00:00
import kotlinx.android.synthetic.main.fragment_schedule_summary_countdown.view.*
2018-07-16 23:15:20 +00:00
import kotlinx.android.synthetic.main.fragment_schedule_summary_eventitem.view.*
import kotlinx.android.synthetic.main.fragment_schedule_summary_r621violation.view.*
2018-07-14 19:43:24 +00:00
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
2018-07-18 15:01:16 +00:00
import java.io.PrintWriter
import java.io.StringWriter
2018-07-16 23:15:20 +00:00
import java.text.SimpleDateFormat
2018-07-13 21:09:43 +00:00
import java.util.*
2018-07-16 23:15:20 +00:00
import kotlin.math.floor
import kotlin.math.roundToInt
2018-07-13 21:09:43 +00:00
class ConventionSummaryFragment : Fragment(), Observer {
companion object {
fun newInstance(scheduleManager: ScheduleManager): Fragment {
return ConventionSummaryFragment().apply {
arguments = Bundle().apply {
putSerializable("scheduleManager", scheduleManager)
}
}
}
}
override fun update(o: Observable?, arg: Any?) {
try {
2018-12-12 04:30:34 +00:00
safeActivity.runOnUiThread {
updateView()
2018-07-16 23:15:20 +00:00
}
} catch (e: Throwable) {
2018-07-18 15:01:16 +00:00
val writer = StringWriter()
e.printStackTrace(PrintWriter(writer))
val s = writer.toString()
Log.e(ConventionSummaryFragment::class.java.simpleName, s)
2018-07-16 23:15:20 +00:00
}
2018-07-13 21:09:43 +00:00
}
lateinit var rootView: View
lateinit var scheduleManager: ScheduleManager
2018-07-14 19:43:24 +00:00
lateinit var timer: Timer
2018-07-13 21:09:43 +00:00
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
arguments?.apply {
scheduleManager = getSerializable("scheduleManager")!! as ScheduleManager
}
rootView = inflater.inflate(R.layout.fragment_schedule_summary, container, false)
updateView()
2018-07-14 19:43:24 +00:00
timer = Timer()
2018-12-12 04:30:34 +00:00
timer.scheduleAtFixedRate(object : TimerTask() {
override fun run() { safeActivity.runOnUiThread {
try {
rootView.let {
this@ConventionSummaryFragment.updateView()
2018-07-14 19:43:24 +00:00
}
2018-12-12 04:30:34 +00:00
} catch (e: Throwable){
val writer = StringWriter()
e.printStackTrace(PrintWriter(writer))
val s = writer.toString()
Log.e(ConventionSummaryFragment::class.java.simpleName, s)
2018-07-14 19:43:24 +00:00
}
2018-12-12 04:30:34 +00:00
} }
}, 3000, 30*1000)
2018-07-13 21:09:43 +00:00
scheduleManager.addObserver(this)
return rootView
}
2018-12-12 04:30:34 +00:00
private fun updateView() {
safeActivity.runOnUiThread {
val conventionTime = scheduleManager.conventionTime
val context = rootView.context
val inflater = context.layoutInflater
rootView.textRegistrationTier.text = scheduleManager.attendeeFavorites.registrationTier.names[context?.runtimeLanguage]
rootView.textRegistrationBenefits.text = scheduleManager.attendeeFavorites.registrationTier.benefits.size.let {
when {
it <= 0 -> context.getString(R.string.schedule_tierbenefit_none)
it == 1 -> context.getString(R.string.schedule_tierbenefit_singular).format(it)
else -> context.getString(R.string.schedule_tierbenefit_plural).format(it)
}
2018-07-13 21:09:43 +00:00
}
2018-12-12 04:30:34 +00:00
val language = inflater.context.runtimeLanguage
rootView.registrationTierSection.setOnClickListener {
val dialog = AlertDialog.Builder(safeActivity).create()
dialog.setTitle(context.getString(R.string.schedule_registrationtier_question))
val scroller = inflater.inflate(R.layout.dialogview_schedule_registration_tiers)
scheduleManager.convention.registrationTiers.sortedBy { it.level }.forEach {
scroller.container.addView(inflater.inflate(R.layout.dialogview_schedule_registration_tier).apply {
tier.text = it.names[language]
it.benefits.forEach {
benefitsList.addView(TextView(context).apply {
this.text = it[language]
this.setTextColor(ResourcesCompat.getColor(resources, R.color.colorBase05, null))
})
}
if (it.benefits.isEmpty()) ticket.visibility = View.GONE
setOnClickListener { _ ->
dialog.dismiss()
scheduleManager.attendeeFavorites.registrationTier = it
}
})
}
dialog.setView(scroller)
dialog.setButton(AlertDialog.BUTTON_NEUTRAL, context.getText(R.string.dialog_cancel)) { dialogInterface: DialogInterface, _: Int -> dialogInterface.dismiss() }
dialog.show()
2018-07-13 21:09:43 +00:00
}
2018-12-12 04:30:34 +00:00
if (!scheduleManager.attendeeFavorites.registrationTierSelectorShown) {
rootView.registrationTierSection.performClick()
scheduleManager.attendeeFavorites.registrationTierSelectorShown = true
2018-07-14 19:43:24 +00:00
}
2018-12-12 04:30:34 +00:00
rootView.mapHotel.setOnClickListener {
Intent(it.context, AssetImageViewerActivity::class.java).apply {
putExtra("asset", scheduleManager.convention.mapHotel[language])
startActivity(this)
}
}
rootView.mapDealers.setOnClickListener {
Intent(it.context, AssetImageViewerActivity::class.java).apply {
putExtra("asset", scheduleManager.convention.mapDealers[language])
startActivity(this)
}
2018-07-14 19:43:24 +00:00
}
2018-07-16 23:15:20 +00:00
2018-07-17 19:38:11 +00:00
// conventionTime.timeInMillis+=32*24*3600*1000.toLong()+3*3600*1000.toLong()
2018-07-16 23:47:27 +00:00
// println(SimpleDateFormat("YYYY/MM/dd - HH:mm:ss", context!!.runtimeLanguage.locale).format(conventionTime.timeInMillis))
2018-07-16 23:15:20 +00:00
2018-12-12 04:30:34 +00:00
val eventCountdown = scheduleManager.nextEditionStartCountdown
if (eventCountdown == null)
rootView.countdown.visibility = View.GONE
else {
rootView.countdown.visibility = View.VISIBLE
rootView.countdownTitle.text = context
.getString(R.string.thingsLacking_to)
.format(
eventCountdown.let { (f, s, t) ->
"%dd %dh %dm".format(f, s, t)
}
)
2018-07-27 03:39:36 +00:00
}
2018-12-12 04:30:34 +00:00
rootView.countdown.setOnClickListener {
Intent(safeActivity, CountdownActivity::class.java).let {
it.putExtra("label", scheduleManager.convention.genericName)
it.putExtra("counter", scheduleManager.nextEditionStartTime)
startActivity(it)
2018-07-16 23:15:20 +00:00
}
2018-12-12 04:30:34 +00:00
}
val allHappening = scheduleManager.convention.events
.filterNot {
it.isCustom
}.map {
AttendeeConFavorite(language, scheduleManager.convention, it)
} +
scheduleManager.attendeeFavorites.toList().filter {
it.isCustom
}
val happeningNow = allHappening
.filter { conventionTime in it.timeRange }
.sortedBy { -it.timeRange.start.timeInMillis }
val nextDayPart = allHappening
.sortedBy {
it.timeRange.start.timeInMillis
}
.firstOrNull {
it.timeRange.start.timeInMillis > conventionTime.timeInMillis
}
?.timeRange
?.start
?.dayRange
?.split(scheduleManager.convention.splitDayIn)
?.dropWhile {
it.start.timeInMillis <= conventionTime.timeInMillis
}
?.getOrNull(0)
val happeningNext = nextDayPart?.let { part ->
allHappening.filter {
part.containsOpenEnded(it.timeRange.start)
2018-07-16 23:15:20 +00:00
}
2018-12-12 04:30:34 +00:00
} ?: listOf()
rootView.eventsNowDescription.text = happeningNow.size.let {
when (it) {
0 -> context.getString(R.string.schedule_now_no_event)
1 -> context.getString(R.string.schedule_now_n_event).format(it)
else -> context.getString(R.string.schedule_now_n_events).format(it)
2018-07-16 23:15:20 +00:00
}
}
2018-12-12 04:30:34 +00:00
rootView.eventsComingDescription.text = happeningNext.size.let {
when (it) {
0 -> context.getString(R.string.schedule_coming_no_event)
1 -> context.getString(R.string.schedule_coming_n_event).format(it)
else -> context.getString(R.string.schedule_coming_n_events).format(it)
}
2018-07-16 23:15:20 +00:00
}
2018-12-12 04:30:34 +00:00
rootView.eventsNowContainer.removeAllViews()
rootView.eventsComingContainer.removeAllViews()
happeningNow.forEach { rootView.eventsNowContainer.addView(renderEventCard(context, it)) }
happeningNext.forEach { rootView.eventsComingContainer.addView(renderEventCard(context, it)) }
2018-07-16 23:15:20 +00:00
2018-12-12 04:30:34 +00:00
rootView.r621watcher.removeAllViews()
if (scheduleManager.convention.r621checker) {
val favorites = scheduleManager.attendeeFavorites.toList()
val r621watchedDays =
scheduleManager.convention.days.map {
it.dayRange
}.filter {
it.start.timeInMillis > scheduleManager.convention.startCalendarOn.timeInMillis
}
r621watchedDays.forEach { dayRange ->
val todayFavorites = favorites.filter { dayRange.containsOpenEnded(it.timeRange.start) }
val sleepFavorites = todayFavorites.filter { it.kind == Actions.Intention.SLEEP }.filterNot { sleep ->
todayFavorites.filter { it.timeRange.containsOpenEnded(sleep.timeRange) }.size > 1
}
val eatFavorites = todayFavorites.filter { it.kind == Actions.Intention.EAT }
val showerFavorites = todayFavorites.filter { it.kind == Actions.Intention.SHOWER }
val daySegment = 24.0 / scheduleManager.convention.splitDayIn
if (
((sleepFavorites.size * daySegment) < 6)
or
((eatFavorites.size * daySegment) < 2)
or
((showerFavorites.size * daySegment) < 1)
) {
rootView.r621watcher.addView(
rule621renderer(
context,
dayRange.start,
sleepFavorites.size * daySegment,
eatFavorites.size * daySegment,
showerFavorites.size * daySegment
)
)
2018-07-16 23:47:27 +00:00
}
}
}
2018-07-18 19:46:28 +00:00
2018-12-12 04:30:34 +00:00
val hashtag = scheduleManager.convention.hashtagReminder
if (hashtag == null) {
rootView.shareReminder.visibility = View.GONE
} else {
rootView.shareReminderTitle.text = hashtag
}
2018-07-18 19:46:28 +00:00
}
2018-07-13 21:09:43 +00:00
}
2018-07-16 23:15:20 +00:00
2018-07-18 05:51:07 +00:00
private fun dowFormatter(context: Context) = SimpleDateFormat("E", context.runtimeLanguage.locale)
private fun hourMinuteFormatter(context: Context) = SimpleDateFormat("HH:mm", context.runtimeLanguage.locale)
2018-07-16 23:15:20 +00:00
2018-07-18 05:51:07 +00:00
private fun renderEventCard(context: Context, attendeeConFavorite: AttendeeConFavorite): View{
val view = context.layoutInflater.inflate(R.layout.fragment_schedule_summary_eventitem)
2018-07-16 23:15:20 +00:00
val event = attendeeConFavorite.findInConvention(scheduleManager.convention)
2018-07-18 05:51:07 +00:00
view.startDay.text = dowFormatter(context).format(attendeeConFavorite.timeRange.start.timeInMillis).capitalize()
view.startText.text = hourMinuteFormatter(context).format(attendeeConFavorite.timeRange.start.timeInMillis)
view.finishText.text = hourMinuteFormatter(context).format(attendeeConFavorite.timeRange.finish.timeInMillis)
2018-07-16 23:15:20 +00:00
view.eventTitle.text = attendeeConFavorite.getString(context)
view.eventSubtitle.text = attendeeConFavorite.getSecondaryString(context)
if(attendeeConFavorite in scheduleManager.attendeeFavorites) {
view.starButton.setOnClickListener {
2018-12-12 04:30:34 +00:00
val dialog = AlertDialog.Builder(safeActivity).create()
2018-07-16 23:15:20 +00:00
dialog.setTitle(context.getString(R.string.schedule_action_interest_remove))
dialog.setButton(AlertDialog.BUTTON_NEUTRAL, context.getString(R.string.dialog_cancel)) { dialogInterface, _ ->
dialogInterface.dismiss()
}
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, context.getString(R.string.list_action_remove)) { dialogInterface, _ ->
dialogInterface.dismiss()
scheduleManager.attendeeFavorites.remove(attendeeConFavorite)
updateView()
}
dialog.show()
}
} else {
view.star.setImageResource(R.drawable.ic_star_border_black_24dp)
view.starButton.setOnClickListener {
view.star.setImageResource(R.drawable.ic_star_half_black_24dp)
scheduleManager.attendeeFavorites.add(attendeeConFavorite)
updateView()
}
}
if (event != null) {
if (
event.hiddenFromTimeTable
or
(scheduleManager.attendeeFavorites.registrationTier.level !in event.attendableBy.map { it.level })
){
view.star.visibility = View.INVISIBLE
view.starButton.setOnClickListener { }
}
}
if (event?.language == null) {
view.flag.visibility = View.GONE
} else {
view.flag.setImageResource(event.language.drawableId)
}
view.setOnClickListener {
context.startActivity(
2018-12-12 04:30:34 +00:00
Intent(safeActivity, EventActivity::class.java).apply {
2018-07-16 23:15:20 +00:00
putExtra("favorite", attendeeConFavorite)
putExtra("offerStar", true)
}
)
}
2018-12-12 04:30:34 +00:00
bindPeekAndPop(
safeActivity,
view as ViewGroup,
view,
if (view.star.visibility == View.INVISIBLE)
null
else
scheduleManager.attendeeFavorites.contains(attendeeConFavorite),
{ doAsync { uiThread { view.starButton.callOnClick() } } },
{ doAsync { uiThread { view.callOnClick() } } },
scheduleManager.convention.events.firstOrNull {
it.conbookId == attendeeConFavorite.conBookId
}?.let { PeekableEvent(it) }
?: PeekableEvent(attendeeConFavorite, view.context)
)
2018-07-16 23:15:20 +00:00
return view
}
2018-12-12 04:30:34 +00:00
val safeActivity = ActivitiesForFragments["ScheduleActivity"]!!
2018-07-18 05:51:07 +00:00
private fun rule621renderer(context: Context, day: GregorianCalendar, sleep: Double, meals: Double, showers: Double): View{
val view = context.layoutInflater.inflate(R.layout.fragment_schedule_summary_r621violation)
view.r621Description.text = context.getString(R.string.on_something).format(
SimpleDateFormat("EEEE (d)", context.runtimeLanguage.locale).format(day.timeInMillis)
2018-07-16 23:47:27 +00:00
)
2018-07-18 05:51:07 +00:00
view.r621_sleep_minimum.text = context.getString(R.string.r621_minimum_is_d).format(6)
view.r621_eat_minimum.text = context.getString(R.string.r621_minimum_is_d).format(2)
view.r621_shower_minimum.text = context.getString(R.string.r621_minimum_is_d).format(1)
view.r621_sleep_found.text = context.getString(R.string.r621_found_d).format(floor(sleep).roundToInt())
view.r621_eat_found.text = context.getString(R.string.r621_found_d).format(floor(meals).roundToInt())
view.r621_shower_found.text = context.getString(R.string.r621_found_d).format(floor(showers).roundToInt())
if(sleep<6) view.r621_sleep_found.setTextColor(ContextCompat.getColor(context, R.color.colorBase06))
if(meals<2) view.r621_eat_found.setTextColor(ContextCompat.getColor(context, R.color.colorBase06))
if(showers<1) view.r621_shower_found.setTextColor(ContextCompat.getColor(context, R.color.colorBase06))
2018-07-16 23:47:27 +00:00
return view
}
2018-07-13 21:09:43 +00:00
}