From b39afb1563988ba8717a8d27eb6cbf58968f752c Mon Sep 17 00:00:00 2001 From: meiron03 Date: Sat, 23 Sep 2023 04:43:20 -0400 Subject: [PATCH] connected preferences to backend. --- .../labs/pennmobile/PottruckFragment.kt | 85 +++++++++++++------ .../pennmobile/adapters/FitnessAdapter.kt | 69 ++++++--------- .../labs/pennmobile/api/StudentLife.java | 11 +++ .../classes/FitnessPreferenceViewModel.kt | 34 +++++++- .../labs/pennmobile/classes/FitnessRequest.kt | 5 ++ .../src/main/res/layout/fitness_list_item.xml | 34 +++----- PennMobile/src/main/res/values/strings.xml | 4 + 7 files changed, 147 insertions(+), 95 deletions(-) create mode 100644 PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessRequest.kt diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/PottruckFragment.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/PottruckFragment.kt index b6f7687b..96bfd9b4 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/PottruckFragment.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/PottruckFragment.kt @@ -11,6 +11,7 @@ import androidx.appcompat.widget.Toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.preference.PreferenceManager import androidx.recyclerview.widget.ConcatAdapter import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -18,11 +19,18 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.appbar.AppBarLayout import com.pennapps.labs.pennmobile.adapters.FitnessAdapter import com.pennapps.labs.pennmobile.adapters.FitnessHeaderAdapter +import com.pennapps.labs.pennmobile.adapters.HomeAdapter import com.pennapps.labs.pennmobile.api.StudentLife +import com.pennapps.labs.pennmobile.classes.FitnessAdapterDataModel import com.pennapps.labs.pennmobile.classes.FitnessPreferenceViewModel +import com.pennapps.labs.pennmobile.classes.HomeCell +import com.pennapps.labs.pennmobile.classes.HomeCellInfo import com.pennapps.labs.pennmobile.components.collapsingtoolbar.ToolbarBehavior import com.pennapps.labs.pennmobile.utils.Utils - +import kotlinx.android.synthetic.main.fragment_home.home_cells_rv +import kotlinx.android.synthetic.main.fragment_home.home_refresh_layout +import kotlinx.android.synthetic.main.fragment_home.internetConnectionHome +import kotlinx.android.synthetic.main.loading_panel.loadingPanel class PottruckFragment : Fragment() { private lateinit var mActivity : MainActivity @@ -38,6 +46,7 @@ class PottruckFragment : Fragment() { private lateinit var otherAdapter : FitnessAdapter private lateinit var favoriteHeaderAdapter : FitnessHeaderAdapter private lateinit var otherHeaderAdapter : FitnessHeaderAdapter + private lateinit var concatAdapter : ConcatAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -83,35 +92,29 @@ class PottruckFragment : Fragment() { } val sortedRooms = fitnessRooms.sortedBy {it.roomName} - dataModel = FitnessPreferenceViewModel(sortedRooms) + dataModel = FitnessPreferenceViewModel(mActivity, mStudentLife, sortedRooms) mActivity.runOnUiThread { - - favoritesAdapter = FitnessAdapter(true, dataModel) - otherAdapter = FitnessAdapter(false, dataModel) - - favoriteHeaderAdapter = FitnessHeaderAdapter("Favorites") - otherHeaderAdapter = FitnessHeaderAdapter("Other Facilities") - - val concatenated = ConcatAdapter(favoriteHeaderAdapter, favoritesAdapter, - otherHeaderAdapter, otherAdapter) - - recyclerView.adapter = concatenated - loadingPanel.visibility = View.GONE - swipeRefresh.isRefreshing = false - - // set click listener for favorites button - val fitnessPref : ImageView = view.findViewById(R.id.fitness_preferences) - fitnessPref.setOnClickListener { - dataModel.savePreferences() - val prefDialog = FitnessPreferencesFragment(dataModel, object: CloseListener{ - override fun updateAdapters() { - favoritesAdapter.notifyDataSetChanged() - otherAdapter.notifyDataSetChanged() + val sp = PreferenceManager.getDefaultSharedPreferences(mActivity) + val context = mActivity.applicationContext + val bearerToken = "Bearer " + sp.getString(context.getString(R.string.access_token), "").toString() + + mStudentLife.getFitnessPreferences(bearerToken).subscribe({ favorites -> + mActivity.runOnUiThread { + for (roomId in favorites) { + dataModel.addId(roomId) } - }) - prefDialog.show(mActivity.supportFragmentManager, "Fitness Preferences Dialog") - } + dataModel.updatePositionMap() + + setAdapters() + } + }, { throwable -> + mActivity.runOnUiThread { + // empty preferences + setAdapters() + Log.e("Pottruck Fragment", "Could not load Fitness Preferences", throwable) + } + }) } }, { Log.e("PottruckFragment", "Error getting fitness rooms", it) @@ -123,6 +126,34 @@ class PottruckFragment : Fragment() { }) } + private fun setAdapters() { + favoritesAdapter = FitnessAdapter(true, dataModel) + otherAdapter = FitnessAdapter(false, dataModel) + + favoriteHeaderAdapter = FitnessHeaderAdapter("Favorites") + otherHeaderAdapter = FitnessHeaderAdapter("Other Facilities") + + val concatAdapter = ConcatAdapter(favoriteHeaderAdapter, favoritesAdapter, + otherHeaderAdapter, otherAdapter) + + recyclerView.adapter = concatAdapter + loadingPanel.visibility = View.GONE + swipeRefresh.isRefreshing = false + + // set click listener for favorites button + val fitnessPref : ImageView = mView.findViewById(R.id.fitness_preferences) + fitnessPref.setOnClickListener { + dataModel.savePreferences() + val prefDialog = FitnessPreferencesFragment(dataModel, object: CloseListener{ + override fun updateAdapters() { + favoritesAdapter.notifyDataSetChanged() + otherAdapter.notifyDataSetChanged() + } + }) + prefDialog.show(mActivity.supportFragmentManager, "Fitness Preferences Dialog") + } + } + /** * Checks if app is connected to internet. If not, it displays a banner * @return true if connected to internet and false otherwise diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/adapters/FitnessAdapter.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/adapters/FitnessAdapter.kt index 2abbf585..18c7a401 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/adapters/FitnessAdapter.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/adapters/FitnessAdapter.kt @@ -49,43 +49,26 @@ class FitnessAdapter(private val isFavorite : Boolean, private val dataModel: Fi private lateinit var mStudentLife : StudentLife class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { - val mainView : ConstraintLayout - val roomView : TextView - val statusView : TextView - val hoursView : TextView - val imageView : ImageView - val progressBar : ProgressBar - val arrowView : ImageView - - val timeCapacityView : TextView - val lastUpdatedView : TextView - val capacityViewCircle : com.google.android.material.progressindicator.CircularProgressIndicator - val capacityView : TextView - - private val extraInfoView : LinearLayout - private val barChart : BarChart + val mainView : ConstraintLayout = view.findViewById(R.id.fitness_list_info_layout) + val roomView : TextView = view.findViewById(R.id.item_fitness_name) + val statusView : TextView = view.findViewById(R.id.item_fitness_status) + val hoursView : TextView = view.findViewById(R.id.item_fitness_hours) + val imageView : ImageView = view.findViewById(R.id.item_fitness_image) + val progressBar : ProgressBar = view.findViewById(R.id.fitness_progress) + val arrowView : ImageView = view.findViewById(R.id.fitness_more_indicator) + + val timeCapacityView : TextView = view.findViewById(R.id.timeCapacity) + val lastUpdatedView : TextView = view.findViewById(R.id.item_pottruck_last_updated) + val capacityViewCircle : com.google.android.material.progressindicator.CircularProgressIndicator = + view.findViewById(R.id.item_pottruck_capacity_circle) + val capacityView : TextView = view.findViewById(R.id.item_pottruck_capacity) + + private val extraInfoView : LinearLayout = view.findViewById(R.id.fitness_list_extra_layout) + private val barChart : BarChart = view.findViewById(R.id.barchart_times) var extraIsVisible = false var hasExtraData = false - init { - mainView = view.findViewById(R.id.fitness_list_info_layout) - roomView = view.findViewById(R.id.item_fitness_name) - imageView = view.findViewById(R.id.item_fitness_image) - statusView = view.findViewById(R.id.item_fitness_status) - hoursView = view.findViewById(R.id.item_fitness_hours) - arrowView = view.findViewById(R.id.fitness_more_indicator) - - timeCapacityView = view.findViewById(R.id.timeCapacity) - lastUpdatedView = view.findViewById(R.id.item_pottruck_last_updated) - capacityViewCircle = view.findViewById(R.id.item_pottruck_capacity_circle) - capacityView = view.findViewById(R.id.item_pottruck_capacity) - - extraInfoView = view.findViewById(R.id.fitness_list_extra_layout) - progressBar = view.findViewById(R.id.fitness_progress) - barChart = view.findViewById(R.id.barchart_times) - } - fun getExtraData(context: Context, activity: Activity, studentLife : StudentLife, room: FitnessRoom ) { @@ -317,7 +300,7 @@ class FitnessAdapter(private val isFavorite : Boolean, private val dataModel: Fi // get image from url Glide.with(mContext).load(room.imageURL).into(holder.imageView) - var busyness : String + val busyness : String // update the capacity if (room.capacity == null) { @@ -328,18 +311,18 @@ class FitnessAdapter(private val isFavorite : Boolean, private val dataModel: Fi val capacityInt = room.capacity!!.toInt() val capacity = "$capacityInt%" - if (capacityInt == 0) { - busyness = "Empty" + busyness = if (capacityInt == 0) { + "Empty" } else if (capacityInt < 10) { - busyness = "Not very busy" + "Not very busy" } else if (capacityInt < 30) { - busyness = "Slightly busy" + "Slightly busy" } else if (capacityInt < 60) { - busyness = "Pretty busy" + "Pretty busy" } else if (capacityInt < 90) { - busyness = "Extremely busy" + "Extremely busy" } else { - busyness = "Packed" + "Packed" } holder.capacityViewCircle.progress = capacityInt @@ -349,11 +332,11 @@ class FitnessAdapter(private val isFavorite : Boolean, private val dataModel: Fi // update the time and capacity var curHour = currentTime.hour - val ampm = if (curHour >= 12) "PM" else "AM" + val amPm = if (curHour >= 12) "PM" else "AM" if (curHour > 12) curHour -= 12 if (curHour == 0) curHour += 12 - val timeCap = "$curHour $ampm: $busyness" + val timeCap = "$curHour $amPm: $busyness" holder.timeCapacityView.text = HtmlCompat.fromHtml(timeCap, HtmlCompat.FROM_HTML_MODE_COMPACT) // update the time for last updated diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java index 2f5cb292..34710782 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/api/StudentLife.java @@ -7,6 +7,7 @@ import com.pennapps.labs.pennmobile.classes.DiningHall; import com.pennapps.labs.pennmobile.classes.DiningPreferences; import com.pennapps.labs.pennmobile.classes.DiningRequest; +import com.pennapps.labs.pennmobile.classes.FitnessRequest; import com.pennapps.labs.pennmobile.classes.FitnessRoom; import com.pennapps.labs.pennmobile.classes.FitnessRoomUsage; import com.pennapps.labs.pennmobile.classes.FlingEvent; @@ -206,4 +207,14 @@ Observable getFitnessRoomUsage( @Path("id") int id, @Query("num_samples") int samples, @Query("group_by") String groupBy); + + @GET("/penndata/fitness/preferences") + Observable> getFitnessPreferences( + @Header("Authorization") String bearerToken); + + @POST("/penndata/fitness/preferences/") + void sendFitnessPref( + @Header("Authorization") String bearerToken, + @Body FitnessRequest rooms, + Callback callback); } diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessPreferenceViewModel.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessPreferenceViewModel.kt index 78ba319c..18e957f7 100644 --- a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessPreferenceViewModel.kt +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessPreferenceViewModel.kt @@ -1,8 +1,16 @@ package com.pennapps.labs.pennmobile.classes +import android.app.Activity import android.util.Log +import androidx.preference.PreferenceManager +import com.pennapps.labs.pennmobile.R +import com.pennapps.labs.pennmobile.api.StudentLife +import retrofit.ResponseCallback +import retrofit.RetrofitError +import retrofit.client.Response -class FitnessPreferenceViewModel(private val roomList: List) : FitnessAdapterDataModel { +class FitnessPreferenceViewModel(private val activity: Activity, + private val studentLife: StudentLife, private val roomList: List) : FitnessAdapterDataModel { private val roomTot = roomList.size @@ -48,6 +56,14 @@ class FitnessPreferenceViewModel(private val roomList: List) : Fitn return favoriteRooms.contains(roomId) } + fun clearFavorites() { + favoriteRooms.clear() + } + + fun addId(roomId: Int) { + favoriteRooms.add(roomId) + } + fun updatePositionMap() { val numFavorites = favoriteRooms.size var curFavIndex = 0 @@ -71,9 +87,21 @@ class FitnessPreferenceViewModel(private val roomList: List) : Fitn favoriteRooms.addAll(prevFavoriteRooms) } - fun updateRemotePreferences() { - + val sp = PreferenceManager.getDefaultSharedPreferences(activity) + val context = activity.applicationContext + val bearerToken = "Bearer " + sp.getString(context.getString(R.string.access_token), "").toString() + + studentLife.sendFitnessPref(bearerToken, FitnessRequest(ArrayList(favoriteRooms)), + object : ResponseCallback() { + override fun success(response: Response) { + Log.i("Fitness Preference View Model", "fitness preferences saved") + } + override fun failure(error: RetrofitError) { + Log.e("Fitness Preference View Model", "Error saving fitness " + + "preferences: $error", error) + } + }) } } \ No newline at end of file diff --git a/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessRequest.kt b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessRequest.kt new file mode 100644 index 00000000..ec79705f --- /dev/null +++ b/PennMobile/src/main/java/com/pennapps/labs/pennmobile/classes/FitnessRequest.kt @@ -0,0 +1,5 @@ +package com.pennapps.labs.pennmobile.classes + +class FitnessRequest(favoriteFitnessRooms: ArrayList) { + var rooms: ArrayList = favoriteFitnessRooms +} \ No newline at end of file diff --git a/PennMobile/src/main/res/layout/fitness_list_item.xml b/PennMobile/src/main/res/layout/fitness_list_item.xml index ffd60689..cd185cb6 100644 --- a/PennMobile/src/main/res/layout/fitness_list_item.xml +++ b/PennMobile/src/main/res/layout/fitness_list_item.xml @@ -9,9 +9,6 @@ android:layout_weight="10" > @@ -250,13 +240,13 @@ android:id="@+id/fitness_mf" android:layout_width="wrap_content" android:layout_height="match_parent" - android:text="Mon - Fri" + android:text="@string/fitness_mf" android:gravity="center_vertical|start" /> @@ -270,13 +260,13 @@ android:id="@+id/fitness_sat" android:layout_width="wrap_content" android:layout_height="match_parent" - android:text="Saturday" + android:text="@string/fitness_sat" android:gravity="center_vertical|start" /> @@ -325,7 +315,7 @@ diff --git a/PennMobile/src/main/res/values/strings.xml b/PennMobile/src/main/res/values/strings.xml index fc4dcc76..3df8682a 100644 --- a/PennMobile/src/main/res/values/strings.xml +++ b/PennMobile/src/main/res/values/strings.xml @@ -228,4 +228,8 @@ Vote Pottruck + Sunday + Mon - Fri + Saturday + Capacity