Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.pennapps.labs.pennmobile.compose.presentation.theme.AppColors
import com.pennapps.labs.pennmobile.compose.presentation.theme.AppTheme
import com.pennapps.labs.pennmobile.compose.presentation.theme.GilroyFontFamily
import com.pennapps.labs.pennmobile.compose.presentation.theme.cabinFontFamily
import com.pennapps.labs.pennmobile.compose.presentation.theme.sfProFontFamily
import kotlinx.coroutines.delay

Expand Down Expand Up @@ -101,7 +101,7 @@ fun AppSnackBar(
Text(
text = message,
color = snackBarContentColor,
fontFamily = GilroyFontFamily,
fontFamily = cabinFontFamily,
fontSize = 15.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.weight(1f),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ val provider =
certificates = R.array.com_google_android_gms_fonts_certs,
)

// Define the GoogleFont references
private val CabinFont = GoogleFont("Cabin")
private val GoogleSansFont = GoogleFont("Google Sans")

// Cabin Font Family
val cabinFontFamily =
FontFamily(
androidx.compose.ui.text.googlefonts.Font(googleFont = CabinFont, fontProvider = provider, weight = FontWeight.Normal), // Regular
androidx.compose.ui.text.googlefonts.Font(googleFont = CabinFont, fontProvider = provider, weight = FontWeight.Medium),
androidx.compose.ui.text.googlefonts.Font(googleFont = CabinFont, fontProvider = provider, weight = FontWeight.SemiBold),
)

// Google Sans Font Family
val googleSansFontFamily =
FontFamily(
androidx.compose.ui.text.googlefonts.Font(googleFont = GoogleSansFont, fontProvider = provider, weight = FontWeight.Normal), // Regular
androidx.compose.ui.text.googlefonts.Font(googleFont = GoogleSansFont, fontProvider = provider, weight = FontWeight.Medium),
androidx.compose.ui.text.googlefonts.Font(googleFont = GoogleSansFont, fontProvider = provider, weight = FontWeight.SemiBold),
)

val GilroyFontFamily =
FontFamily(
Font(R.font.gilroy_light, FontWeight.Normal),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.pennapps.labs.pennmobile.compose.presentation.theme

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp


/**
* Object to hold custom TextStyles for consistent typography across the app.
*/
object CustomTextStyles {

/**
* Text style for all headers in the dining hall screen
*/
@Composable
fun DiningHallsHeader(): TextStyle {
return TextStyle(
fontFamily = GilroyFontFamily,
fontWeight = FontWeight.ExtraBold,
fontSize = 20.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant,
lineHeight = 28.sp,
letterSpacing = 0.sp
)
}

}
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/**
* @file AppModule.kt
* @brief Hilt module for providing application-wide singleton dependencies.
*
* First ever Dagger Hilt module written for Penn Mobile.
*
* This module is responsible for providing foundational objects that are used across
* the entire application lifecycle, such as SharedPreferences and a global CoroutineScope.
* All dependencies provided here are scoped as singletons.
*
* Created by Andrew Chelimo on 2/11/2025
*/
package com.pennapps.labs.pennmobile.di

import android.content.Context
Expand All @@ -14,32 +26,34 @@ import kotlinx.coroutines.SupervisorJob
import javax.inject.Qualifier
import javax.inject.Singleton

/**
* First ever Dagger Hilt module written for Penn Mobile.
*
* It is responsible for providing foundational objects
* like SharedPreferences and a main-thread CoroutineScope.
*
* Created by Andrew Chelimo on 2/11/2025
*/
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
/**
* Provides a singleton instance of [SharedPreferences].
*
* @param context The application context, used to get the default SharedPreferences.
*/
@Singleton
@Provides
fun providesSharedPreferences(
@ApplicationContext context: Context,
): SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)

/**
* Provides a coroutine scope that is tied to the application lifecycle
* Provides a coroutine scope that is tied to the application lifecycle.
* This scope is configured with a SupervisorJob, ensuring that the failure of one
* child coroutine does not cancel the entire scope. It uses the Main dispatcher.
*/
@Singleton
@Provides
@AppScope
fun providesAppCoroutineScope(): CoroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
}

/**
* Qualifier to distinguish the application-level CoroutineScope from other scopes.
*/
@Qualifier
@Retention(AnnotationRetention.RUNTIME)
annotation class AppScope
annotation class AppScope
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/**
* @file NetworkModule.kt
* @brief Hilt module for providing network-related singleton components.
*
* This module is responsible for setting up and providing all dependencies required for
* network operations throughout the application. It includes the configuration for Gson,
* OkHttpClient, Retrofit, and the specific API service interfaces. All dependencies
* provided here are scoped as singletons to ensure a single, shared instance is used
* across the app.
*/
package com.pennapps.labs.pennmobile.di

import com.google.gson.Gson
Expand Down Expand Up @@ -32,6 +42,11 @@ import javax.inject.Singleton
object NetworkModule {
private const val PENN_MOBILE_BASE_URL = "https://pennmobile.org/api/"

/**
* Provides a customized [Gson] instance for Retrofit.
* This instance is configured with several custom type adapters to handle the specific
* JSON structures from the Penn Mobile API.
*/
@Provides
@Singleton
fun provideGson(): Gson =
Expand Down Expand Up @@ -84,13 +99,24 @@ object NetworkModule {
)
}.create()

/**
* Provides an [HttpLoggingInterceptor] for debugging network requests.
* This interceptor is configured to log the body of network requests and responses,
* which is invaluable for debugging during development.
*/
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor =
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}

/**
* Provides the application-wide [OkHttpClient].
* This client is configured with connection timeouts and the logging interceptor.
*
* @param logging The [HttpLoggingInterceptor] to be added for network debugging.
*/
@Provides
@Singleton
fun provideOkHttpClient(logging: HttpLoggingInterceptor): OkHttpClient =
Expand All @@ -102,6 +128,14 @@ object NetworkModule {
.addInterceptor(logging)
.build()

/**
* Provides the application-wide [Retrofit] instance.
* This instance is configured with the base URL, the custom OkHttpClient, and
* multiple converter factories to handle different response types.
*
* @param gson The custom [Gson] instance for JSON serialization/deserialization.
* @param client The configured [OkHttpClient] for making requests.
*/
@Provides
@Singleton
fun providesRetrofit(
Expand All @@ -117,7 +151,13 @@ object NetworkModule {
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()

/**
* Provides the [StudentLife] API service interface.
* Retrofit creates an implementation of this interface to handle API calls.
*
* @param retrofit The configured [Retrofit] instance.
*/
@Provides
@Singleton
fun providesStudentLife(retrofit: Retrofit): StudentLife = retrofit.create(StudentLife::class.java)
}
}
Loading
Loading