Skip to content

Commit

Permalink
Test replacing studentLife with studentLife2 which is retrofit2 in ko…
Browse files Browse the repository at this point in the history
…tlin.
  • Loading branch information
meiron03 committed Mar 18, 2024
1 parent c8d07ac commit 87b4a1e
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 36 deletions.
2 changes: 2 additions & 0 deletions PennMobile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ android {
packagingOptions {
pickFirst 'META-INF/LICENSE.txt'
pickFirst 'META-INF/NOTICE.txt'
exclude 'META-INF/rxjava.properties'
}
}

Expand Down Expand Up @@ -91,6 +92,7 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'com.kaspersky.android-components:kaspresso:1.5.3'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.pennapps.labs.pennmobile

import StudentLife2
import android.content.*
import android.os.Bundle
import android.os.Handler
Expand Down Expand Up @@ -33,7 +34,7 @@ class HomeFragment : Fragment() {

private lateinit var mActivity: MainActivity
private lateinit var sharedPreferences: SharedPreferences
private lateinit var mStudentLife: StudentLife
private lateinit var mStudentLife: StudentLife2

private var _binding : FragmentHomeBinding? = null
private val binding get() = _binding!!
Expand Down Expand Up @@ -84,23 +85,23 @@ class HomeFragment : Fragment() {

/* Mildly suspicious idea to hide the RecyclerView until blurviews (for news and posts) are
done processing. Processing the blurviews is slow and makes the app looks sloppy. Ideally
this is replaced by something less hacky (such as using a ListView instead) though perhaps
this is replaced by something less hacky (such as using a ListView instead) though perhaps
it is simpler to just remove the blur altogether.
This takes advantage of a RecyclerView idiosyncracy: when a RecyclerView resides inside a
nested scrollview, all of the elements are inflated:
https://stackoverflow.com/questions/44453846/recyclerview-inside-nestedscrollview-causes-recyclerview-to-inflate-all-elements
https://www.reddit.com/r/androiddev/comments/d8gi9v/recyclerview_inside_nestedscrollview_causes/
This is can be used to figure out when the blurviews are finished processing.
Since when the adapter is set in getHomePage, onBindViewHolder() is called for each cell.
Thus, for the news and post cells which use blur, when the blur is finished processing,
the adapter notifies homepageViewModel. When both blurs are processed, the blurViewsLoaded
Thus, for the news and post cells which use blur, when the blur is finished processing,
the adapter notifies homepageViewModel. When both blurs are processed, the blurViewsLoaded
liveData in the ViewModel is toggled to true which HomeFragment observes.
If in the future, the homepage is stuck on loading forever, this might be why. To remove
this functionality and stop waiting for the blur views to finish, just remove the observer
If in the future, the homepage is stuck on loading forever, this might be why. To remove
this functionality and stop waiting for the blur views to finish, just remove the observer
below and change getHomePage() so that when HomeAdapter is set, homeCellsRv.visibility is
set to View.VISIBLE instead of View.INVISIBLE and hide loadingPanel
*/
Expand Down Expand Up @@ -155,6 +156,7 @@ class HomeFragment : Fragment() {
return
}

//val studentLife = MainActivity.studentLifeInstance
val studentLife = mStudentLife
mActivity.mNetworkManager.getAccessToken {
val sp = sharedPreferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.pennapps.labs.pennmobile.api

import StudentLife2
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.pennapps.labs.pennmobile.classes.Contact
Expand All @@ -14,15 +15,15 @@ import com.pennapps.labs.pennmobile.classes.LaundryRoom
import com.pennapps.labs.pennmobile.classes.LaundryRoomSimple
import com.pennapps.labs.pennmobile.classes.LaundryUsage
import com.pennapps.labs.pennmobile.classes.Post
import com.squareup.okhttp.OkHttpClient
import retrofit.RestAdapter
import retrofit.client.OkClient
import retrofit.converter.GsonConverter
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

class NetworkContainer {
val pennMobileAPI: StudentLife
private val endpoint : String = "https://pennmobile.org/api"
val pennMobileAPI: StudentLife2
private val endpoint : String = "https://pennmobile.org/api/"
init {
val gsonBuilder = GsonBuilder()
gsonBuilder.registerTypeAdapter(
Expand Down Expand Up @@ -72,17 +73,20 @@ class NetworkContainer {
object : TypeToken<MutableList<Post?>?>() {}.type,
PostsSerializer()
)
val gson = gsonBuilder.create()
val okHttpClient = OkHttpClient()
okHttpClient.setConnectTimeout(35, TimeUnit.SECONDS) // Connection timeout
okHttpClient.setReadTimeout(35, TimeUnit.SECONDS) // Read timeout
okHttpClient.setWriteTimeout(35, TimeUnit.SECONDS) // Write timeout
val restAdapter = RestAdapter.Builder()
.setConverter(GsonConverter(gson))
.setClient(OkClient(okHttpClient))
.setEndpoint(endpoint)
val gson = GsonBuilder().create()
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(35, TimeUnit.SECONDS)
.readTimeout(35, TimeUnit.SECONDS)
.writeTimeout(35, TimeUnit.SECONDS)
.build()
pennMobileAPI = restAdapter.create(StudentLife::class.java)

val retrofit = Retrofit.Builder()
.baseUrl(endpoint)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
pennMobileAPI = retrofit.create(StudentLife2::class.java)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import com.pennapps.labs.pennmobile.classes.AccessTokenResponse
import com.pennapps.labs.pennmobile.classes.Account
import com.pennapps.labs.pennmobile.classes.Article
import com.pennapps.labs.pennmobile.classes.CalendarEvent
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
import com.pennapps.labs.pennmobile.classes.GSR
import com.pennapps.labs.pennmobile.classes.GSRBookingResult
import com.pennapps.labs.pennmobile.classes.GSRLocation
import com.pennapps.labs.pennmobile.classes.GSRReservation
import com.pennapps.labs.pennmobile.classes.LaundryRequest
import com.pennapps.labs.pennmobile.classes.LaundryRoom
import com.pennapps.labs.pennmobile.classes.LaundryRoomSimple
import com.pennapps.labs.pennmobile.classes.LaundryUsage
import com.pennapps.labs.pennmobile.classes.Poll
import com.pennapps.labs.pennmobile.classes.Post
import com.pennapps.labs.pennmobile.classes.SaveAccountResponse
import com.pennapps.labs.pennmobile.classes.Venue
import com.pennapps.labs.pennmobile.classes.WhartonStatus
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.*
import io.reactivex.Observable

interface StudentLife2 {
@FormUrlEncoded
@POST("accounts/token/")
fun getAccessToken(
@Field("code") authCode: String,
@Field("grant_type") grantType: String,
@Field("client_id") clientID: String,
@Field("redirect_uri") redirectURI: String,
@Field("code_verifier") codeVerifier: String
): Call<AccessTokenResponse>

@FormUrlEncoded
@POST("accounts/token/")
fun refreshAccessToken(
@Field("refresh_token") refreshToken: String,
@Field("grant_type") grantType: String,
@Field("client_id") clientID: String
): Call<AccessTokenResponse>

@GET("dining/venues")
fun venues(): Observable<List<Venue>>

@GET("dining/menus/{day}")
fun getMenus(@Path("day") day: String): Observable<List<DiningHall.Menu>>

@GET("dining/weekly_menu/{id}")
fun dailyMenu(@Path("id") id: Int): Observable<DiningHall>

@GET("dining/preferences")
fun getDiningPreferences(@Header("Authorization") bearerToken: String): Observable<DiningPreferences>

@GET("laundry/halls/ids")
fun laundryRooms(): Observable<List<LaundryRoomSimple>>

@GET("laundry/hall/{id}")
fun room(@Path("id") id: Int): Observable<LaundryRoom>

@GET("gsr/locations")
fun location(): Observable<List<GSRLocation>>

@GET("gsr/availability/{id}/{gid}")
fun gsrRoom(
@Header("Authorization") bearerToken: String,
@Path("id") id: String,
@Path("gid") gid: Int,
@Query("start") date: String
): Observable<GSR>

@GET("gsr/wharton")
fun isWharton(@Header("Authorization") bearerToken: String): Observable<WhartonStatus>

@FormUrlEncoded
@POST("gsr/book/")
fun bookGSR(
@Header("Authorization") bearerToken: String,
@Field("start_time") start: String,
@Field("end_time") end: String,
@Field("gid") gid: Int,
@Field("id") id: Int,
@Field("room_name") roomName: String
): Call<GSRBookingResult>

@GET("laundry/usage/{id}")
fun usage(@Path("id") id: Int): Observable<LaundryUsage>

@GET("events/fling")
fun getFlingEvents(): Observable<List<FlingEvent>>

@GET("penndata/news")
fun getNews(): Observable<Article>

@GET("penndata/calendar")
fun getCalendar(): Observable<List<CalendarEvent>>

@GET("gsr/reservations")
fun getGsrReservations(@Header("Authorization") bearerToken: String): Observable<List<GSRReservation>>

@FormUrlEncoded
@POST("gsr/cancel/")
fun cancelReservation(
@Header("Authorization") bearerToken: String,
@Header("X-Device-ID") deviceID: String,
@Field("booking_id") bookingID: String,
@Field("sessionid") sessionID: String
): Call<ResponseBody>

@POST("users/{pennkey}/activate/")
fun saveAccount(
@Header("Authorization") bearerToken: String,
@Path("pennkey") pennkey: String,
@Body account: Account
): Call<SaveAccountResponse>

@GET("laundry/preferences")
fun getLaundryPref(@Header("Authorization") bearerToken: String): Observable<List<Int>>

@POST("laundry/preferences/")
fun sendLaundryPref(
@Header("Authorization") bearerToken: String,
@Body rooms: LaundryRequest
): Call<ResponseBody>

@POST("dining/preferences/")
fun sendDiningPref(
@Header("Authorization") bearerToken: String,
@Body body: DiningRequest
): Call<ResponseBody>

@GET("portal/posts/browse/")
fun validPostsList(@Header("Authorization") bearerToken: String): Observable<List<Post>>

@FormUrlEncoded
@POST("portal/polls/browse/")
fun browsePolls(
@Header("Authorization") bearerToken: String,
@Field("id_hash") idHash: String
): Observable<List<Poll>>

@FormUrlEncoded
@POST("portal/votes/")
fun createPollVote(
@Header("Authorization") bearerToken: String,
@Field("id_hash") idHash: String,
@Field("poll_options") pollOptions: ArrayList<Int>
): Call<ResponseBody>

@GET("penndata/fitness/rooms/")
fun getFitnessRooms(): Observable<List<FitnessRoom>>

@GET("penndata/fitness/usage/{id}")
fun getFitnessRoomUsage(
@Path("id") id: Int,
@Query("num_samples") samples: Int,
@Query("group_by") groupBy: String
): Observable<FitnessRoomUsage>

@GET("penndata/fitness/preferences")
fun getFitnessPreferences(@Header("Authorization") bearerToken: String): Observable<List<Int>>

@POST("penndata/fitness/preferences/")
fun sendFitnessPref(
@Header("Authorization") bearerToken: String,
@Body rooms: FitnessRequest
): Call<ResponseBody>
}
Loading

0 comments on commit 87b4a1e

Please sign in to comment.