diff --git a/app/src/main/java/org/hackillinois/android/API.kt b/app/src/main/java/org/hackillinois/android/API.kt index 5c981420a..20125a05d 100644 --- a/app/src/main/java/org/hackillinois/android/API.kt +++ b/app/src/main/java/org/hackillinois/android/API.kt @@ -1,7 +1,6 @@ package org.hackillinois.android import org.hackillinois.android.database.entity.* -import org.hackillinois.android.model.TimesWrapper import org.hackillinois.android.model.checkin.CheckIn import org.hackillinois.android.model.event.EventsList import org.hackillinois.android.model.leaderboard.LeaderboardList @@ -62,11 +61,6 @@ interface API { @POST("staff/attendance/") suspend fun staffMeetingCheckIn(@Body eventId: MeetingEventId): MeetingCheckInResponse - // UPLOAD - - @GET("upload/blobstore/times/") - suspend fun times(): TimesWrapper - // USER @GET("user/") diff --git a/app/src/main/java/org/hackillinois/android/view/home/CountdownManager.kt b/app/src/main/java/org/hackillinois/android/view/home/CountdownManager.kt index 8fe3fddd9..994085c88 100644 --- a/app/src/main/java/org/hackillinois/android/view/home/CountdownManager.kt +++ b/app/src/main/java/org/hackillinois/android/view/home/CountdownManager.kt @@ -3,32 +3,29 @@ package org.hackillinois.android.view.home import android.os.CountDownTimer import org.hackillinois.android.common.isBeforeNow import org.hackillinois.android.common.timeUntilMs -import org.hackillinois.android.model.TimesWrapper import java.util.* class CountdownManager(val listener: CountDownListener) { - // 2023-02-24 15:00:00 + // 02-23-2024 15:30:00 private val eventStartTime: Calendar = Calendar.getInstance().apply { timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = 1677272400000 + timeInMillis = 1708723800000 } - // 2023-02-24 19:00:00 + // 02-23-2024 19:00:00 private val hackingStartTime: Calendar = Calendar.getInstance().apply { timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = 1677286800000 + timeInMillis = 1708736400000 } - // 2023-02-26 9:00:00 + // 02-25-2024 9:00:00 private val hackingEndTime: Calendar = Calendar.getInstance().apply { timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = 1677423600000 + timeInMillis = 1708873200000 } private var times = listOf(eventStartTime, hackingStartTime, hackingEndTime) - - // placeholders in case design team decides to change this private val titles = listOf("HACKILLINOIS BEGINS IN", "HACKING BEGINS IN", "HACKING ENDS IN", "MEMORIES MADE") private var timer: CountDownTimer? = null @@ -37,6 +34,7 @@ class CountdownManager(val listener: CountDownListener) { private val refreshRateMs = 500L fun start() { + // find current state of the countdown in terms of timestamps while (state < times.size && times[state].isBeforeNow()) { state++ } @@ -44,21 +42,24 @@ class CountdownManager(val listener: CountDownListener) { } private fun startTimer() { + // if past the last timestamp, don't start another timer if (state >= times.size) { - listener.updateTitle(titles[state]) - + listener.updateTitle(titles[titles.size - 1]) // set to be last title return } - listener.updateTitle(titles[state]) + // else set the current title and start timer until next timestamp + listener.updateTitle(titles[state]) val millisTillTimerFinishes = times[state].timeUntilMs() timer = object : CountDownTimer(millisTillTimerFinishes, refreshRateMs) { + // update the time on each tick override fun onTick(millisUntilFinished: Long) { val timeUntil = times[state].timeUntilMs() listener.updateTime(timeUntil) } + // increment the state when timer is finished override fun onFinish() { state++ startTimer() @@ -77,28 +78,6 @@ class CountdownManager(val listener: CountDownListener) { } } - fun setAPITimes(timesWrapper: TimesWrapper) { - onPause() - val apiEventStartTime = Calendar.getInstance().apply { - timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = timesWrapper.data.eventStart * 1000L - } - - val apiHackingStartTime = Calendar.getInstance().apply { - timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = timesWrapper.data.hackStart * 1000L - } - - val apiHackingEndTime = Calendar.getInstance().apply { - timeZone = TimeZone.getTimeZone("America/Chicago") - timeInMillis = timesWrapper.data.hackEnd * 1000L - } - - times = listOf(apiEventStartTime, apiHackingStartTime, apiHackingEndTime) - state = 0 - startTimer() - } - interface CountDownListener { fun updateTime(timeUntil: Long) fun updateTitle(newTitle: String) diff --git a/app/src/main/java/org/hackillinois/android/view/home/EventProgressManager.kt b/app/src/main/java/org/hackillinois/android/view/home/EventProgressManager.kt new file mode 100644 index 000000000..3c11438aa --- /dev/null +++ b/app/src/main/java/org/hackillinois/android/view/home/EventProgressManager.kt @@ -0,0 +1,106 @@ +package org.hackillinois.android.view.home + +import android.os.CountDownTimer +import org.hackillinois.android.R +import org.hackillinois.android.common.isBeforeNow +import org.hackillinois.android.common.timeUntilMs +import java.util.* + +class EventProgressManager(val listener: CountDownListener) { + + // CORRECT TIMES ARE NOT SET YET + // 02-23-2024 15:30:00 + private val checkInTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708723800000 + } + + // 02-23-2024 16:00:00 + private val scavengerHuntTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708725600000 + } + + // 02-23-2024 18:00:00 + private val openingCeremonyTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708732800000 + } + + // 02-23-2024 19:00:00 + private val hackingTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708736400000 + } + + // 02-25-2024 11:00:00 + private val projectShowcaseTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708880400000 + } + + // 02-25-2024 15:00:00 + private val closingCeremonyTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708894800000 + } + + // 02-25-2024 16:00:00 + private val afterHackathonTime: Calendar = Calendar.getInstance().apply { + timeZone = TimeZone.getTimeZone("America/Chicago") + timeInMillis = 1708898400000 + } + + private var times = listOf(checkInTime, scavengerHuntTime, openingCeremonyTime, hackingTime, projectShowcaseTime, closingCeremonyTime, afterHackathonTime) + private var backgrounds = listOf(R.drawable.home_bg_start, R.drawable.home_check_in_bg, R.drawable.home_scavenger_hunt_bg, R.drawable.home_opening_bg, R.drawable.home_hacking_bg, R.drawable.home_project_showcase_bg, R.drawable.home_closing_bg, R.drawable.home_final_bg) + private var timer: CountDownTimer? = null + private var state = 0 + + private val refreshRateMs = 500L + + fun start() { + // find current state of the event progress + while (state < times.size && times[state].isBeforeNow()) { + state++ + } + startTimer() + } + + private fun startTimer() { + // if past the last event, don't start another timer + if (state >= times.size) { + listener.updateBackground(backgrounds[backgrounds.size - 1]) + return + } + + // else set the current title and start timer until next timestamp + listener.updateBackground(backgrounds[state]) + val millisTillTimerFinishes = times[state].timeUntilMs() + + timer = object : CountDownTimer(millisTillTimerFinishes, refreshRateMs) { + override fun onTick(millisUntilFinished: Long) { + // do nothing + } + + override fun onFinish() { + state++ + startTimer() + } + }.start() + } + + fun onPause() { + timer?.cancel() + timer = null + } + + fun onResume() { + if (timer == null) { + start() + } + } + + interface CountDownListener { + fun updateBackground(newBackgroundResource: Int) + } +} diff --git a/app/src/main/java/org/hackillinois/android/view/home/HomeFragment.kt b/app/src/main/java/org/hackillinois/android/view/home/HomeFragment.kt index 5b335f503..d99dee4db 100644 --- a/app/src/main/java/org/hackillinois/android/view/home/HomeFragment.kt +++ b/app/src/main/java/org/hackillinois/android/view/home/HomeFragment.kt @@ -4,27 +4,27 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.ImageView import android.widget.TextView import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import org.hackillinois.android.App import org.hackillinois.android.R import org.hackillinois.android.common.TimeInfo import org.hackillinois.android.viewmodel.HomeViewModel -import java.lang.Exception -class HomeFragment : Fragment(), CountdownManager.CountDownListener { +class HomeFragment : Fragment(), CountdownManager.CountDownListener, EventProgressManager.CountDownListener { private lateinit var daysValue: TextView private lateinit var hoursValue: TextView private lateinit var minutesValue: TextView private lateinit var countdownTextView: TextView + private lateinit var homeBackgroundImageView: ImageView + private lateinit var homeBackgroundTagsImageView: ImageView + private lateinit var infoButton: ImageView private lateinit var viewModel: HomeViewModel - private val countDownManager = CountdownManager(this) + private val countDownManager = CountdownManager(this) // for timer countdown + private val eventProgressManager = EventProgressManager(this) // for updating background of home page private var isActive = false @@ -41,6 +41,20 @@ class HomeFragment : Fragment(), CountdownManager.CountDownListener { hoursValue = view.findViewById(R.id.hoursValue) minutesValue = view.findViewById(R.id.minutesValue) countdownTextView = view.findViewById(R.id.countdownTextView) + homeBackgroundImageView = view.findViewById(R.id.homeBackgroundImageView) + homeBackgroundTagsImageView = view.findViewById(R.id.homeBackgroundTagsImageView) + infoButton = view.findViewById(R.id.homeInfoImageView) + + // set info button's functionality to toggle tag descriptions on home page when pressed on/off + infoButton.setOnClickListener { + if (homeBackgroundTagsImageView.visibility == View.INVISIBLE) { + homeBackgroundTagsImageView.visibility = View.VISIBLE + infoButton.setImageResource(R.drawable.question_mark_toggled) + } else { + homeBackgroundTagsImageView.visibility = View.INVISIBLE + infoButton.setImageResource(R.drawable.question_mark) + } + } return view } @@ -49,25 +63,21 @@ class HomeFragment : Fragment(), CountdownManager.CountDownListener { super.onStart() isActive = true countDownManager.start() + eventProgressManager.start() } override fun onPause() { super.onPause() isActive = false countDownManager.onPause() + eventProgressManager.onPause() } override fun onResume() { super.onResume() isActive = true countDownManager.onResume() - GlobalScope.launch(Dispatchers.Main) { - try { - val time = App.getAPI().times() - countDownManager.setAPITimes(time) - } catch (e: Exception) { - } - } + eventProgressManager.onResume() } override fun onStop() { @@ -91,5 +101,11 @@ class HomeFragment : Fragment(), CountdownManager.CountDownListener { } } + override fun updateBackground(newBackgroundResource: Int) { + if (isActive) { + homeBackgroundImageView.setImageResource(newBackgroundResource) + } + } + private fun padNumber(number: Long) = String.format("%02d", number) } diff --git a/app/src/main/res/drawable/home_bg_scenery.png b/app/src/main/res/drawable/home_bg_scenery.png new file mode 100644 index 000000000..8aebe9d9f Binary files /dev/null and b/app/src/main/res/drawable/home_bg_scenery.png differ diff --git a/app/src/main/res/drawable/home_bg_start.png b/app/src/main/res/drawable/home_bg_start.png new file mode 100644 index 000000000..9f7482f58 Binary files /dev/null and b/app/src/main/res/drawable/home_bg_start.png differ diff --git a/app/src/main/res/drawable/home_bg_tags.png b/app/src/main/res/drawable/home_bg_tags.png new file mode 100644 index 000000000..7d35da0ce Binary files /dev/null and b/app/src/main/res/drawable/home_bg_tags.png differ diff --git a/app/src/main/res/drawable/home_check_in_bg.png b/app/src/main/res/drawable/home_check_in_bg.png new file mode 100644 index 000000000..ea45c3974 Binary files /dev/null and b/app/src/main/res/drawable/home_check_in_bg.png differ diff --git a/app/src/main/res/drawable/home_closing_bg.png b/app/src/main/res/drawable/home_closing_bg.png new file mode 100644 index 000000000..19882d9da Binary files /dev/null and b/app/src/main/res/drawable/home_closing_bg.png differ diff --git a/app/src/main/res/drawable/home_final_bg.png b/app/src/main/res/drawable/home_final_bg.png new file mode 100644 index 000000000..08beadbe4 Binary files /dev/null and b/app/src/main/res/drawable/home_final_bg.png differ diff --git a/app/src/main/res/drawable/home_hacking_bg.png b/app/src/main/res/drawable/home_hacking_bg.png new file mode 100644 index 000000000..de00168b0 Binary files /dev/null and b/app/src/main/res/drawable/home_hacking_bg.png differ diff --git a/app/src/main/res/drawable/home_opening_bg.png b/app/src/main/res/drawable/home_opening_bg.png new file mode 100644 index 000000000..70d05a270 Binary files /dev/null and b/app/src/main/res/drawable/home_opening_bg.png differ diff --git a/app/src/main/res/drawable/home_project_showcase_bg.png b/app/src/main/res/drawable/home_project_showcase_bg.png new file mode 100644 index 000000000..37cfdc53a Binary files /dev/null and b/app/src/main/res/drawable/home_project_showcase_bg.png differ diff --git a/app/src/main/res/drawable/home_scavenger_hunt_bg.png b/app/src/main/res/drawable/home_scavenger_hunt_bg.png new file mode 100644 index 000000000..853e6877d Binary files /dev/null and b/app/src/main/res/drawable/home_scavenger_hunt_bg.png differ diff --git a/app/src/main/res/drawable/question_mark.png b/app/src/main/res/drawable/question_mark.png new file mode 100644 index 000000000..559c2d46f Binary files /dev/null and b/app/src/main/res/drawable/question_mark.png differ diff --git a/app/src/main/res/drawable/question_mark_toggled.png b/app/src/main/res/drawable/question_mark_toggled.png new file mode 100644 index 000000000..9c85d488e Binary files /dev/null and b/app/src/main/res/drawable/question_mark_toggled.png differ diff --git a/app/src/main/res/drawable/rounded_countdown_time_bg.xml b/app/src/main/res/drawable/rounded_countdown_time_bg.xml new file mode 100644 index 000000000..8080fbafa --- /dev/null +++ b/app/src/main/res/drawable/rounded_countdown_time_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_countdown_title_bg.xml b/app/src/main/res/drawable/rounded_countdown_title_bg.xml new file mode 100644 index 000000000..3e8f511ae --- /dev/null +++ b/app/src/main/res/drawable/rounded_countdown_title_bg.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 253996c68..536fadbc4 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -5,184 +5,210 @@ android:id="@+id/home_layout" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/nightBlue"> + android:background="@color/witchyPurple"> + app:layout_constraintTop_toTopOf="parent" /> - + + + + + app:layout_constraintStart_toEndOf="@+id/countdownTextView" + app:layout_constraintTop_toTopOf="@+id/countdownTextView" /> + android:gravity="center" + android:paddingVertical="3dp" + android:text="@string/home_banner" + android:textColor="@color/burntBark" + android:textSize="14sp" + app:layout_constraintEnd_toEndOf="@+id/countdownConstraintLayout" + app:layout_constraintStart_toStartOf="@+id/countdownConstraintLayout" + app:layout_constraintTop_toTopOf="@+id/guideline_home" /> + app:layout_constraintTop_toBottomOf="@+id/countdownTextView"> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + android:paddingBottom="6dp"> - + android:includeFontPadding="false" + android:paddingTop="4dp" + android:textColor="@color/burntBark" + android:textSize="36sp" + tools:text="12" /> + android:textColor="@color/burntBark" + android:textSize="12sp" /> + + android:paddingBottom="6dp"> - + android:includeFontPadding="false" + android:paddingTop="4dp" + android:textColor="@color/burntBark" + android:textSize="36sp" + tools:text="23" /> + android:textColor="@color/burntBark" + android:textSize="12sp" /> + + + android:paddingBottom="6dp"> - + android:includeFontPadding="false" + android:paddingTop="4dp" + android:textColor="@color/burntBark" + android:textSize="36sp" + tools:text="43" /> + android:textColor="@color/burntBark" + android:textSize="12sp" /> - - + + - - + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 0eeae1791..a5b52a62b 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -61,4 +61,5 @@ #C62A6C +