Skip to content

Commit 89d507d

Browse files
feat: Add option to completely disable Google books API (#248)
Signed-off-by: starry-shivam <[email protected]>
1 parent 857a79c commit 89d507d

File tree

21 files changed

+123
-36
lines changed

21 files changed

+123
-36
lines changed

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/src/main/java/com/starry/myne/api/BookAPI.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import android.content.Context
2020
import com.starry.myne.BuildConfig
2121
import com.starry.myne.api.models.BookSet
2222
import com.starry.myne.api.models.ExtraInfo
23+
import com.starry.myne.helpers.PreferenceUtil
2324
import com.starry.myne.helpers.book.BookLanguage
2425
import kotlinx.coroutines.Dispatchers
2526
import kotlinx.coroutines.withContext
@@ -44,8 +45,10 @@ import kotlin.coroutines.suspendCoroutine
4445
* This class is responsible for handling all the API requests related to books.
4546
* It uses OkHttp for making network requests and Gson for parsing JSON responses.
4647
* @param context The context of the application.
48+
*
49+
* Do not use this class directly. Use the [BookAPI] instance from dependency injection.
4750
*/
48-
class BookAPI(context: Context) {
51+
class BookAPI(context: Context, private val preferenceUtil: PreferenceUtil) {
4952

5053
private val baseApiUrl = "https://myne.krsh.dev/books"
5154
private val googleBooksUrl = "https://www.googleapis.com/books/v1/volumes"
@@ -162,6 +165,13 @@ class BookAPI(context: Context) {
162165
// Function to fetch extra info such as cover image, page count, and description of a book.
163166
// From Google Books API.
164167
suspend fun getExtraInfo(bookName: String): ExtraInfo? = suspendCoroutine { continuation ->
168+
// Return null without making any network call to Google Books API
169+
// if the use of Google API is disabled by the user.
170+
if (!preferenceUtil.getBoolean(PreferenceUtil.USE_GOOGLE_API_BOOL, true)) {
171+
continuation.resume(null)
172+
return@suspendCoroutine
173+
}
174+
165175
val encodedName = URLEncoder.encode(bookName, "UTF-8")
166176
val url = "${googleBooksUrl}?q=$encodedName&startIndex=0&maxResults=1&key=$googleApiKey"
167177
val request = Request.Builder().get().url(url).build()

app/src/main/java/com/starry/myne/di/MainModule.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import javax.inject.Singleton
3636
@Module
3737
class MainModule {
3838

39+
// Core application related. ==========================================================
40+
3941
@Provides
4042
fun provideAppContext(@ApplicationContext context: Context) = context
4143

@@ -52,15 +54,20 @@ class MainModule {
5254

5355
@Singleton
5456
@Provides
55-
fun provideBooksApi(@ApplicationContext context: Context) = BookAPI(context)
57+
fun providePreferenceUtil(@ApplicationContext context: Context) = PreferenceUtil(context)
58+
59+
// Network & Books related. ==========================================================
5660

5761
@Singleton
5862
@Provides
59-
fun provideBookDownloader(@ApplicationContext context: Context) = BookDownloader(context)
63+
fun provideBooksApi(
64+
@ApplicationContext context: Context,
65+
preferenceUtil: PreferenceUtil
66+
) = BookAPI(context, preferenceUtil)
6067

6168
@Singleton
6269
@Provides
63-
fun providePreferenceUtil(@ApplicationContext context: Context) = PreferenceUtil(context)
70+
fun provideBookDownloader(@ApplicationContext context: Context) = BookDownloader(context)
6471

6572
@Singleton
6673
@Provides

app/src/main/java/com/starry/myne/helpers/Preferencesutils.kt

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.starry.myne.helpers
1818

1919
import android.content.Context
2020
import android.content.SharedPreferences
21+
import androidx.core.content.edit
2122

2223
/**
2324
* A helper class to manage shared preferences
@@ -34,6 +35,7 @@ class PreferenceUtil(context: Context) {
3435
const val AMOLED_THEME_BOOL = "amoled_theme"
3536
const val MATERIAL_YOU_BOOL = "material_you"
3637
const val INTERNAL_READER_BOOL = "internal_reader"
38+
const val USE_GOOGLE_API_BOOL = "use_google_books_api"
3739
const val READER_FONT_SIZE_INT = "reader_font_size"
3840
const val READER_FONT_STYLE_STR = "reader_font_style"
3941
const val PREFERRED_BOOK_LANG_STR = "preferred_book_language"
@@ -43,16 +45,25 @@ class PreferenceUtil(context: Context) {
4345
const val LIBRARY_SWIPE_TOOLTIP_BOOL = "show_library_tooltip"
4446
}
4547

46-
//
47-
private var prefs: SharedPreferences =
48+
// SharedPreferences instance
49+
private val prefs: SharedPreferences =
4850
context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
4951

52+
init {
53+
// setup default values
54+
prefs.edit {
55+
if (!keyExists(INTERNAL_READER_BOOL)) putBoolean(INTERNAL_READER_BOOL, true)
56+
if (!keyExists(USE_GOOGLE_API_BOOL)) putBoolean(USE_GOOGLE_API_BOOL, true)
57+
}
58+
}
59+
5060
/**
5161
* Check if a key exists in the preferences
5262
*
5363
* @param key The key to check
5464
* @return True if the key exists, false otherwise
5565
*/
66+
@Suppress("unused")
5667
fun keyExists(key: String): Boolean = prefs.contains(key)
5768

5869
/**
@@ -62,9 +73,7 @@ class PreferenceUtil(context: Context) {
6273
* @param value The value to insert
6374
*/
6475
fun putString(key: String, value: String) {
65-
val prefsEditor = prefs.edit()
66-
prefsEditor.putString(key, value)
67-
prefsEditor.apply()
76+
prefs.edit { putString(key, value) }
6877
}
6978

7079
/**
@@ -74,9 +83,7 @@ class PreferenceUtil(context: Context) {
7483
* @param value The value to insert
7584
*/
7685
fun putInt(key: String, value: Int) {
77-
val prefsEditor = prefs.edit()
78-
prefsEditor.putInt(key, value)
79-
prefsEditor.apply()
86+
prefs.edit { putInt(key, value) }
8087
}
8188

8289
/**
@@ -86,9 +93,7 @@ class PreferenceUtil(context: Context) {
8693
* @param value The value to insert
8794
*/
8895
fun putBoolean(key: String, value: Boolean) {
89-
val prefsEditor = prefs.edit()
90-
prefsEditor.putBoolean(key, value)
91-
prefsEditor.apply()
96+
prefs.edit { putBoolean(key, value) }
9297
}
9398

9499
/**

app/src/main/java/com/starry/myne/ui/screens/settings/composables/SettingsItems.kt

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ import androidx.compose.foundation.layout.Box
2323
import androidx.compose.foundation.layout.Column
2424
import androidx.compose.foundation.layout.Row
2525
import androidx.compose.foundation.layout.Spacer
26-
import androidx.compose.foundation.layout.fillMaxSize
2726
import androidx.compose.foundation.layout.fillMaxWidth
2827
import androidx.compose.foundation.layout.height
29-
import androidx.compose.foundation.layout.offset
3028
import androidx.compose.foundation.layout.padding
3129
import androidx.compose.foundation.layout.size
3230
import androidx.compose.foundation.layout.width
31+
import androidx.compose.foundation.layout.wrapContentHeight
3332
import androidx.compose.foundation.shape.CircleShape
3433
import androidx.compose.material.icons.Icons
3534
import androidx.compose.material.icons.automirrored.filled.ArrowForwardIos
@@ -57,6 +56,7 @@ import androidx.compose.ui.platform.LocalView
5756
import androidx.compose.ui.text.font.FontWeight
5857
import androidx.compose.ui.tooling.preview.Preview
5958
import androidx.compose.ui.unit.dp
59+
import androidx.compose.ui.unit.em
6060
import androidx.compose.ui.unit.sp
6161
import com.starry.myne.helpers.weakHapticFeedback
6262
import com.starry.myne.ui.theme.poppinsFont
@@ -76,16 +76,19 @@ fun SettingItem(icon: ImageVector, mainText: String, subText: String, onClick: (
7676
modifier = Modifier
7777
.padding(bottom = 8.dp)
7878
.fillMaxWidth()
79-
.height(69.dp),
79+
.wrapContentHeight(),
8080
) {
8181
Row(
8282
modifier = Modifier
8383
.padding(vertical = 10.dp, horizontal = 14.dp)
84-
.fillMaxSize(),
84+
.fillMaxWidth(),
8585
verticalAlignment = Alignment.CenterVertically,
8686
horizontalArrangement = Arrangement.SpaceBetween
8787
) {
88-
Row(verticalAlignment = Alignment.CenterVertically) {
88+
Row(
89+
verticalAlignment = Alignment.CenterVertically,
90+
modifier = Modifier.weight(1f, fill = false)
91+
) {
8992
Box(
9093
modifier = Modifier
9194
.size(40.dp)
@@ -101,9 +104,7 @@ fun SettingItem(icon: ImageVector, mainText: String, subText: String, onClick: (
101104
}
102105

103106
Spacer(modifier = Modifier.width(14.dp))
104-
Column(
105-
modifier = Modifier.offset(y = (2).dp)
106-
) {
107+
Column {
107108
Text(
108109
text = mainText,
109110
fontFamily = poppinsFont,
@@ -119,18 +120,18 @@ fun SettingItem(icon: ImageVector, mainText: String, subText: String, onClick: (
119120
fontFamily = poppinsFont,
120121
color = Color.Gray,
121122
fontSize = 13.sp,
123+
lineHeight = 1.3.em,
122124
fontWeight = FontWeight.Medium,
123-
modifier = Modifier.offset(y = (-4).dp)
124125
)
125126
}
126127
}
128+
Spacer(modifier = Modifier.width(8.dp))
127129
Icon(
128130
imageVector = Icons.AutoMirrored.Filled.ArrowForwardIos,
129131
contentDescription = "",
130132
modifier = Modifier.size(15.dp),
131133
tint = MaterialTheme.colorScheme.onSurface
132134
)
133-
134135
}
135136
}
136137
}
@@ -151,16 +152,19 @@ fun SettingItemWIthSwitch(
151152
modifier = Modifier
152153
.padding(bottom = 8.dp)
153154
.fillMaxWidth()
154-
.height(69.dp),
155+
.wrapContentHeight(),
155156
) {
156157
Row(
157158
modifier = Modifier
158159
.padding(vertical = 10.dp, horizontal = 14.dp)
159-
.fillMaxSize(),
160+
.fillMaxWidth(),
160161
verticalAlignment = Alignment.CenterVertically,
161162
horizontalArrangement = Arrangement.SpaceBetween
162163
) {
163-
Row(verticalAlignment = Alignment.CenterVertically) {
164+
Row(
165+
verticalAlignment = Alignment.CenterVertically,
166+
modifier = Modifier.weight(1f, fill = false)
167+
) {
164168
Box(
165169
modifier = Modifier
166170
.size(40.dp)
@@ -176,9 +180,7 @@ fun SettingItemWIthSwitch(
176180
}
177181

178182
Spacer(modifier = Modifier.width(14.dp))
179-
Column(
180-
modifier = Modifier.offset(y = (2).dp)
181-
) {
183+
Column {
182184
Text(
183185
text = mainText,
184186
fontFamily = poppinsFont,
@@ -194,11 +196,12 @@ fun SettingItemWIthSwitch(
194196
fontFamily = poppinsFont,
195197
color = Color.Gray,
196198
fontSize = 13.sp,
199+
lineHeight = 1.3.em,
197200
fontWeight = FontWeight.Medium,
198-
modifier = Modifier.offset(y = (-4).dp)
199201
)
200202
}
201203
}
204+
Spacer(modifier = Modifier.width(8.dp))
202205
Switch(
203206
checked = switchState.value,
204207
onCheckedChange = {

app/src/main/java/com/starry/myne/ui/screens/settings/composables/SettingsScreen.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.starry.myne.ui.screens.settings.composables
1818

1919
import android.content.Intent
20-
import android.net.Uri
2120
import android.os.Build
2221
import android.provider.Settings
2322
import androidx.compose.foundation.Image
@@ -78,6 +77,7 @@ import androidx.compose.ui.text.font.FontWeight
7877
import androidx.compose.ui.tooling.preview.Preview
7978
import androidx.compose.ui.unit.dp
8079
import androidx.compose.ui.unit.sp
80+
import androidx.core.net.toUri
8181
import androidx.navigation.NavController
8282
import androidx.navigation.compose.rememberNavController
8383
import com.starry.myne.BuildConfig
@@ -207,6 +207,7 @@ private fun GeneralOptionsUI(
207207
val context = LocalContext.current
208208
val coroutineScope = rememberCoroutineScope()
209209

210+
val googleBooksApiSwitchState = remember { mutableStateOf(viewModel.getUseGoogleApiValue()) }
210211
val internalReaderValue = when (viewModel.getInternalReaderValue()) {
211212
true -> stringResource(id = R.string.reader_option_inbuilt)
212213
false -> stringResource(id = R.string.reader_option_external)
@@ -248,7 +249,7 @@ private fun GeneralOptionsUI(
248249
// See: https://github.com/Pool-Of-Tears/GreenStash/issues/130 for more.
249250
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !Utils.isMiui()) {
250251
val intent = Intent(Settings.ACTION_APP_LOCALE_SETTINGS).apply {
251-
data = Uri.parse("package:${context.packageName}")
252+
data = "package:${context.packageName}".toUri()
252253
}
253254
context.startActivity(intent)
254255
} else {
@@ -260,8 +261,16 @@ private fun GeneralOptionsUI(
260261
}
261262
}
262263
)
263-
264-
264+
SettingItemWIthSwitch(
265+
icon = ImageVector.vectorResource(id = R.drawable.ic_settings_google_api),
266+
mainText = stringResource(id = R.string.google_books_api_setting),
267+
subText = stringResource(id = R.string.google_books_api_setting_desc),
268+
switchState = googleBooksApiSwitchState,
269+
onCheckChange = {
270+
viewModel.setUseGoogleApiValue(it)
271+
googleBooksApiSwitchState.value = it
272+
}
273+
)
265274
}
266275

267276
if (showReaderDialog.value) {

app/src/main/java/com/starry/myne/ui/screens/settings/viewmodels/SettingsViewModel.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ class SettingsViewModel @Inject constructor(
6969
preferenceUtil.putBoolean(PreferenceUtil.INTERNAL_READER_BOOL, newValue)
7070
}
7171

72+
fun setUseGoogleApiValue(newValue: Boolean) {
73+
preferenceUtil.putBoolean(PreferenceUtil.USE_GOOGLE_API_BOOL, newValue)
74+
}
75+
7276
// Getters ================================================================================
7377

7478
fun getThemeValue() = preferenceUtil.getInt(
@@ -87,6 +91,10 @@ class SettingsViewModel @Inject constructor(
8791
PreferenceUtil.INTERNAL_READER_BOOL, true
8892
)
8993

94+
fun getUseGoogleApiValue() = preferenceUtil.getBoolean(
95+
PreferenceUtil.USE_GOOGLE_API_BOOL, true
96+
)
97+
9098
@Composable
9199
fun getCurrentTheme(): ThemeMode {
92100
return if (theme.value == ThemeMode.Auto) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="24"
5+
android:viewportHeight="24">
6+
7+
<path
8+
android:fillColor="#000000"
9+
android:pathData="M19.76,10.77L19.67,10.42H12.23V13.58H16.68C16.432,14.544 15.867,15.397 15.077,16.003C14.286,16.608 13.316,16.931 12.32,16.92C11.021,16.909 9.773,16.413 8.82,15.53C8.352,15.068 7.979,14.519 7.723,13.913C7.468,13.308 7.334,12.658 7.33,12C7.345,10.679 7.868,9.415 8.79,8.47C9.729,7.58 10.976,7.089 12.27,7.1C13.378,7.109 14.445,7.521 15.27,8.26L17.47,6C16.02,4.706 14.143,3.994 12.2,4C11.131,3.994 10.071,4.198 9.081,4.601C8.091,5.004 7.19,5.599 6.43,6.35C4.984,7.852 4.168,9.852 4.152,11.937C4.135,14.022 4.918,16.035 6.34,17.56C7.128,18.345 8.064,18.965 9.094,19.384C10.125,19.803 11.228,20.012 12.34,20C13.348,20.007 14.348,19.81 15.278,19.42C16.208,19.03 17.049,18.455 17.75,17.73C19.126,16.217 19.87,14.235 19.83,12.19C19.841,11.716 19.817,11.241 19.76,10.77Z" />
10+
11+
</vector>

app/src/main/res/values-ar/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@
105105
<string name="default_locale_setting">اللغة الافتراضية</string>
106106
<string name="default_locale_setting_desc">حدد لغتك المفضلة.</string>
107107
<string name="locale_setting_not_found">عذرا! هذه الميزة ليست مدعومة حاليا من قبل نظام التشغيل الخاص بك.</string>
108+
<string name="google_books_api_setting">واجهة برمجة تطبيقات كتب Google</string>
109+
<string name="google_books_api_setting_desc">استخدم واجهة برمجة تطبيقات كتب Google لجلب معلومات إضافية عن الكتب.</string>
108110
<string name="display_setting_header">العرض</string>
109111
<string name="theme_setting">المظهر الافتراضى</string>
110112
<string name="theme_dialog_title">تغيير المظهر</string>

app/src/main/res/values-bn/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@
105105
<string name="default_locale_setting">ডিফল্ট Locale</string>
106106
<string name="default_locale_setting_desc">আপনার পছন্দের Locale নির্বাচন করুন।</string>
107107
<string name="locale_setting_not_found">দুঃখিত! এই ফিচার এখনও আপনার ওএস এর জন্য আসেনি৷</string>
108+
<string name="google_books_api_setting">গুগল বই API</string>
109+
<string name="google_books_api_setting_desc">অতিরিক্ত বইয়ের তথ্য আনতে Google Books API ব্যবহার করুন।</string>
108110
<string name="display_setting_header">ডিসপ্লে</string>
109111
<string name="theme_setting">ডিফল্ট থিম</string>
110112
<string name="theme_dialog_title">থিম বদলান</string>

0 commit comments

Comments
 (0)