Skip to content

Commit

Permalink
feat: added setting to configure custom API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
IllusionMan1212 committed Aug 26, 2024
1 parent 53c0afc commit a1c6008
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 10 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<application
android:name=".LGApp"
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:localeConfig="@xml/locales_config"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.illusionman1212.lyricsgrabbr.data

import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.core.app.NotificationManagerCompat
import com.illusionman1212.lyricsgrabbr.R
import com.illusionman1212.lyricsgrabbr.data.network.GET
Expand Down Expand Up @@ -32,11 +33,9 @@ class HomeRepository(private val context: Context) {
return pkgs.contains(packageName)
}

suspend fun makeSearchRequest(lContext: Context, song: String, artist: String): Pair<String?, Boolean> {
val builder = Uri.Builder()
val url = builder.scheme("https")
.authority("api.illusionman1212.com")
.appendPath("lyrics")
suspend fun makeSearchRequest(lContext: Context, baseUrl: String, song: String, artist: String): Pair<String?, Boolean> {
val url = Uri.parse(baseUrl)
.buildUpon()
.appendPath("search")
.appendQueryParameter("q", "$song $artist")
.appendQueryParameter("disableFuzzy", "true")
Expand Down Expand Up @@ -76,7 +75,7 @@ class HomeRepository(private val context: Context) {
return Pair(lContext.resources.getString(R.string.timeout), false)
}

return Pair(lContext.resources.getString(R.string.generic_error), false)
return Pair(e.message, false)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.core.stringSetPreferencesKey
import kotlinx.coroutines.flow.map

Expand All @@ -19,6 +20,7 @@ data class SettingsPreferences(
val whitelist: Set<String> = emptySet(),
val keepScreenOn: Boolean = false,
val whitelistPromptSeen: Boolean = false,
val geniURLbaseURL: String = "https://api.illusionman1212.com/lyrics",
)

class SettingsPreferencesRepository(
Expand All @@ -29,6 +31,7 @@ class SettingsPreferencesRepository(
private val WHITELIST = stringSetPreferencesKey("apps_whitelist")
private val KEEP_SCREEN_ON = booleanPreferencesKey("keep_screen_on")
private val WHITELIST_PROMPT_SEEN = booleanPreferencesKey("whitelist_prompt_seen")
private val GENIURL_BASE_URL = stringPreferencesKey("geniurl_base_url")
}

val preferences = dataStore.data.map { mapSettingsPreferences(it) }
Expand Down Expand Up @@ -63,12 +66,19 @@ class SettingsPreferencesRepository(
}
}

suspend fun setGeniURLBaseURL(url: String) {
dataStore.edit { prefs ->
prefs[GENIURL_BASE_URL] = url
}
}

private fun mapSettingsPreferences(prefs: Preferences): SettingsPreferences {
return SettingsPreferences(
prefs[APP_THEME] ?: Theme.SYSTEM.ordinal,
prefs[WHITELIST] ?: emptySet(),
prefs[KEEP_SCREEN_ON] ?: false,
prefs[WHITELIST_PROMPT_SEEN] ?: false,
prefs[GENIURL_BASE_URL] ?: "https://api.illusionman1212.com/lyrics",
)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.illusionman1212.lyricsgrabbr.ui.screens

import android.util.Patterns
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -19,6 +20,7 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Apps
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.ScreenLockPortrait
import androidx.compose.material.icons.outlined.Cloud
import androidx.compose.material.icons.outlined.Palette
import androidx.compose.material.icons.outlined.Translate
import androidx.compose.material3.Icon
Expand All @@ -27,6 +29,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Switch
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -96,6 +99,7 @@ fun SettingsPage(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Appearance(viewModel, uiState)
geniURL(viewModel, uiState)
Listening(navigateToWhitelist)
PowerManagement(viewModel, uiState)
}
Expand Down Expand Up @@ -185,6 +189,63 @@ private fun PowerManagement(viewModel: SettingsViewModel, uiState: SettingsState
}
}

@Composable
private fun geniURL(viewModel: SettingsViewModel, uiState: SettingsState) {
var dialogOpen by remember { mutableStateOf(false) }

SettingGroup(title = "geniURL") {
DialogSetting(
title = stringResource(id = R.string.api_base_url),
value = uiState.geniURLbaseURL,
icon = Icons.Outlined.Cloud,
onClick = { dialogOpen = true }
)
}

if (dialogOpen) {
BaseURLDialog(
uiState = uiState,
viewModel = viewModel,
onDismiss = { dialogOpen = false },
)
}
}

@Composable
private fun BaseURLDialog(uiState: SettingsState, viewModel: SettingsViewModel, onDismiss: () -> Unit) {
var value by remember { mutableStateOf(uiState.geniURLbaseURL) }
var isValidUrl by remember { mutableStateOf(true) }

LGAlertDialog(
onDismiss = onDismiss,
title = stringResource(id = R.string.base_url),
buttons = {
TextButton(
onClick = {
viewModel.setGeniURLBaseURL(value)
onDismiss()
},
enabled = isValidUrl
) {
Text(stringResource(id = R.string.confirm))
}
TextButton(onClick = onDismiss) {
Text(stringResource(id = R.string.cancel))
}
},
modifier = Modifier.fillMaxWidth()
) {
TextField(
value = value,
isError = !isValidUrl,
onValueChange = { newValue ->
isValidUrl = Patterns.WEB_URL.matcher(newValue.lowercase()).matches() && newValue.startsWith("http", true)
value = newValue
},
)
}
}

@Composable
fun ThemeDialog(
uiState: SettingsState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ import androidx.lifecycle.viewmodel.viewModelFactory
import com.illusionman1212.lyricsgrabbr.LGApp
import com.illusionman1212.lyricsgrabbr.NotificationEvent
import com.illusionman1212.lyricsgrabbr.data.HomeRepository
import com.illusionman1212.lyricsgrabbr.data.SettingsPreferencesRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -85,7 +87,7 @@ data class HomeState(
val error: String? = null,
)

class HomeViewModel(private val homeRepository: HomeRepository): ViewModel() {
class HomeViewModel(private val homeRepository: HomeRepository, private val settingsRepository: SettingsPreferencesRepository): ViewModel() {
private val _uiState = MutableStateFlow(HomeState())
val uiState = _uiState.asStateFlow()
private val json = Json {
Expand All @@ -107,7 +109,8 @@ class HomeViewModel(private val homeRepository: HomeRepository): ViewModel() {
_uiState.update { HomeState(true, uiState.value.results, uiState.value.notification, null) }

withContext(Dispatchers.IO) {
val (res, isSuccess) = homeRepository.makeSearchRequest(context, song, artist)
val baseUrl = settingsRepository.preferences.first().geniURLbaseURL
val (res, isSuccess) = homeRepository.makeSearchRequest(context, baseUrl, song, artist)
if (isSuccess) {
val results = json.decodeFromString(SearchResultsResponse.serializer(), res!!).all.map {
SearchResult(
Expand Down Expand Up @@ -136,7 +139,7 @@ class HomeViewModel(private val homeRepository: HomeRepository): ViewModel() {
val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
val application = (this[APPLICATION_KEY] as LGApp)
HomeViewModel(application.homeRepository)
HomeViewModel(application.homeRepository, application.settingsPreferencesRepository)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ data class SettingsState(
val applications: Map<String, AppInfo> = emptyMap(),
val whitelistSearchQuery: String = "",
val keepScreenOn: Boolean = false,
val geniURLbaseURL: String = "",
val whitelistPromptSeen: Boolean = true,
)

Expand All @@ -55,6 +56,15 @@ class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesReposi
}
}

fun setGeniURLBaseURL(baseUrl: String) {
viewModelScope.launch(Dispatchers.IO) {
settingsPrefsRepo.setGeniURLBaseURL(baseUrl)
_uiState.update { state ->
state.copy(geniURLbaseURL = baseUrl)
}
}
}

fun toggleKeepScreenOn() {
viewModelScope.launch(Dispatchers.IO) {
settingsPrefsRepo.toggleKeepScreenOn()
Expand Down Expand Up @@ -165,6 +175,7 @@ class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesReposi
appTheme = it.appTheme,
keepScreenOn = it.keepScreenOn,
whitelistPromptSeen = it.whitelistPromptSeen,
geniURLbaseURL = it.geniURLbaseURL,
)
}
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<!-- General -->
<string name="go_back">رجوع</string>
<string name="cancel">إلغاء</string>
<string name="confirm">تأكيد</string>
<string name="timeout">لقد انتهت مهلة الطلب، حاول مرة أخرى لاحقًا</string>
<string name="generic_error">لقد حدث خطأ، حاول مرة أخرى لاحقاً</string>
<string name="internal_server_error">تأكد من تشغيل خادم geniURL الخاص بك إذا كنت تستضيف ذاتيًا أو اتصل بمضيفك.</string>
Expand Down Expand Up @@ -47,6 +48,8 @@
<string name="keep_device_awake_title">أبق الجهاز مستيقظا</string>
<string name="keep_device_awake_desc">أبق الجهاز مستيقظا على صفحة كلمات الأغاني (يزيد من استخدام البطارية)</string>
<string name="screen_will_stay_on">ستبقى الشاشة على قيد التشغيل</string>
<string name="api_base_url">عنوان URL الأساسي لواجهة برمجة التطبيقات (API)</string>
<string name="base_url">عنوان URL الأساسي</string>

<!-- Lyrics -->
<string name="instrumental">هذه الأغنية موسيقية</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<!-- General -->
<string name="go_back">Go Back</string>
<string name="cancel">Cancel</string>
<string name="confirm">Confirm</string>
<string name="timeout">Request has timed out, try again later</string>
<string name="generic_error">An error has occurred, try again later</string>
<string name="internal_server_error">Internal server error. Make sure your geniURL server is running if self-hosting or contact your hoster.</string>
Expand Down Expand Up @@ -46,6 +47,8 @@
<string name="keep_device_awake_title">Keep device awake</string>
<string name="keep_device_awake_desc">Keep device awake on lyrics page (Increases battery usage)</string>
<string name="screen_will_stay_on">Screen Will Stay On</string>
<string name="api_base_url">API Base URL</string>
<string name="base_url">Base URL</string>

<!-- Lyrics -->
<string name="instrumental">This song is an instrumental</string>
Expand Down

0 comments on commit a1c6008

Please sign in to comment.