Skip to content

Commit

Permalink
feat: Allow enabling/disabling icon requests
Browse files Browse the repository at this point in the history
This can be done via the flag at the website repo, or via the local prefs override at the debug menu.

TODO: Update link once new form is placed.
  • Loading branch information
SuperDragonXD committed Dec 25, 2024
1 parent fcc7be4 commit 6b371f9
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import retrofit2.create

@Module
@InstallIn(SingletonComponent::class)
class ApiModule {
class GithubApiModule {

@Provides
@Singleton
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2024 Lawnchair Launcher
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.lawnchair.lawnicons.api

import app.lawnchair.lawnicons.model.IconRequestSettings
import retrofit2.http.GET

interface IconRequestSettingsAPI {
@GET("lawnicons-request/settings.json")
suspend fun getIconRequestSettings(): IconRequestSettings
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 Lawnchair Launcher
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.lawnchair.lawnicons.api

import app.lawnchair.lawnicons.util.kotlinxJson
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit
import retrofit2.converter.kotlinx.serialization.asConverterFactory
import retrofit2.create

@Module
@InstallIn(SingletonComponent::class)
class WebsiteApiModule {

@Provides
@Singleton
fun providesWebsiteIconRequestApi(): IconRequestSettingsAPI {
return Retrofit.Builder()
.baseUrl("https://lawnchair.app/")
.addConverterFactory(kotlinxJson.asConverterFactory("application/json".toMediaType()))
.build()
.create()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2024 Lawnchair Launcher
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.lawnchair.lawnicons.model

import kotlinx.serialization.Serializable

@Serializable
data class IconRequestSettings(
val enabled: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2024 Lawnchair Launcher
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package app.lawnchair.lawnicons.repository

import app.lawnchair.lawnicons.api.IconRequestSettingsAPI
import javax.inject.Inject

class IconRequestSettingsRepository @Inject constructor(
private val api: IconRequestSettingsAPI,
) {
suspend fun getEnabledState() = api.getIconRequestSettings().enabled
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import app.lawnchair.lawnicons.BuildConfig

/**
* A class that abstracts the functionality of SharedPreferences
* We use SharedPreferences to avoid the unneccesary complexity Preference DataStore has
*
* @param prefs The SharedPreferences instance to use
*/
abstract class BasePreferenceManager(
Expand Down Expand Up @@ -83,6 +85,7 @@ class PreferenceManager private constructor(
val showFirstLaunchSnackbar = BoolPref("show_first_launch_snackbar", true)
val showNewIconsCard = BoolPref("show_new_icons_card", true)
val showDebugMenu = BoolPref("debug_menu", false)
val forceEnableIconRequest = BoolPref("force_icon_request", false)
val currentLawniconsVersion = IntPref("current_lawnicons_version", BuildConfig.VERSION_CODE)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package app.lawnchair.lawnicons.ui.components.home

import android.content.Context
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -33,6 +35,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
Expand Down Expand Up @@ -108,6 +111,7 @@ private fun SheetContent(

SwitchPref(prefs.showDebugMenu)
SwitchPref(prefs.showNewIconsCard)
SwitchPref(prefs.forceEnableIconRequest)
SwitchPref(prefs.showFirstLaunchSnackbar)

SimpleListRow(
Expand Down Expand Up @@ -159,14 +163,22 @@ private fun SwitchPref(
pref: BasePreferenceManager.BoolPref,
modifier: Modifier = Modifier,
) {
val interactionSource = remember { MutableInteractionSource() }
SimpleListRow(
pref.key,
endIcon = {
Switch(
checked = pref.asState().value,
onCheckedChange = { pref.set(it) },
interactionSource = interactionSource,
)
},
modifier = modifier,
modifier = modifier.clickable(
interactionSource = interactionSource,
indication = null,
enabled = true,
onClickLabel = null,
onClick = {},
),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import app.lawnchair.lawnicons.ui.util.Constants
@Composable
fun HomeBottomBar(
context: Context,
iconRequestsEnabled: Boolean,
iconRequestModel: IconRequestModel?,
snackbarHostState: SnackbarHostState,
onNavigate: () -> Unit,
Expand Down Expand Up @@ -61,6 +62,7 @@ fun HomeBottomBar(

IconRequestIconButton(
snackbarHostState = snackbarHostState,
iconRequestsEnabled = iconRequestsEnabled,
iconRequestModel = iconRequestModel,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,20 @@ import kotlinx.coroutines.launch

@Composable
fun IconRequestFAB(
iconRequestsEnabled: Boolean,
iconRequestModel: IconRequestModel?,
lazyGridState: LazyGridState,
snackbarHostState: SnackbarHostState,
modifier: Modifier = Modifier,
) {
val prefs = preferenceManager()
val list = iconRequestModel?.list ?: emptyList()
val enabled = iconRequestModel != null
val requestsEnabled = iconRequestsEnabled || prefs.forceEnableIconRequest.get()

RequestHandler(
enabled = enabled,
iconRequestsEnabled = requestsEnabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
onLongClick = {},
Expand Down Expand Up @@ -85,17 +89,22 @@ fun IconRequestFAB(
@Composable
fun IconRequestIconButton(
snackbarHostState: SnackbarHostState,
iconRequestsEnabled: Boolean,
iconRequestModel: IconRequestModel?,
modifier: Modifier = Modifier,
) {
val prefs = preferenceManager()

val list = iconRequestModel?.list ?: emptyList()
val enabled = iconRequestModel != null
val requestsEnabled = iconRequestsEnabled || prefs.forceEnableIconRequest.get()

val tooltipState = rememberTooltipState()
val scope = rememberCoroutineScope()

RequestHandler(
enabled = enabled,
iconRequestsEnabled = requestsEnabled,
iconRequestList = list,
snackbarHostState = snackbarHostState,
onLongClick = {
Expand Down Expand Up @@ -133,6 +142,7 @@ fun IconRequestIconButton(
@Composable
fun RequestHandler(
enabled: Boolean,
iconRequestsEnabled: Boolean,
iconRequestList: List<IconRequest>,
snackbarHostState: SnackbarHostState,
onLongClick: () -> Unit,
Expand All @@ -151,6 +161,7 @@ fun RequestHandler(

HandleTouchInteractions(
enabled = enabled,
iconRequestsEnabled = iconRequestsEnabled,
interactionSource = interactionSource,
viewConfiguration = LocalViewConfiguration.current,
context = context,
Expand Down Expand Up @@ -180,6 +191,7 @@ fun RequestHandler(
@Composable
private fun HandleTouchInteractions(
enabled: Boolean,
iconRequestsEnabled: Boolean,
interactionSource: MutableInteractionSource,
viewConfiguration: ViewConfiguration,
context: Context,
Expand Down Expand Up @@ -208,15 +220,23 @@ private fun HandleTouchInteractions(

is PressInteraction.Release -> {
if (!isLongClick) {
handleRequestClick(
iconRequestList,
context,
directLinkEnabled,
encodedRequestList,
requestList,
coroutineScope,
snackbarHostState,
)
if (iconRequestsEnabled) {
handleRequestClick(
iconRequestList,
context,
directLinkEnabled,
encodedRequestList,
requestList,
coroutineScope,
snackbarHostState,
)
} else {
openSnackbarRequestsDisabled(
context,
coroutineScope,
snackbarHostState,
)
}
}
}

Expand Down Expand Up @@ -274,6 +294,23 @@ private fun openSnackbarFirstLaunchContent(
}
}

private fun openSnackbarRequestsDisabled(
context: Context,
coroutineScope: CoroutineScope,
snackbarHostState: SnackbarHostState,
) {
coroutineScope.launch {
val result = snackbarHostState
.showSnackbar(
message = context.getString(R.string.icon_requests_suspended),
duration = SnackbarDuration.Short,
)
if (result == SnackbarResult.Dismissed) {
snackbarHostState.currentSnackbarData?.dismiss()
}
}
}

private fun openSnackbarWarningContent(
context: Context,
list: String,
Expand Down Expand Up @@ -308,5 +345,6 @@ private fun openLink(context: Context, link: String) {
}

private fun buildForm(string: String): String {
// TODO: override with new link once available
return "https://docs.google.com/forms/d/e/1FAIpQLSe8ItNYse9f4z2aT1QgXkKeueVTucRdUYNhUpys5ShHPyRijg/viewform?entry.1759726669=$string"
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ private fun Home(
if (!isExpandedScreen) {
HomeBottomBar(
context = context,
iconRequestsEnabled = iconRequestsEnabled,
iconRequestModel = iconRequestModel,
snackbarHostState = snackbarHostState,
onNavigate = onNavigateToAbout,
Expand All @@ -127,6 +128,7 @@ private fun Home(
floatingActionButton = {
if (isExpandedScreen) {
IconRequestFAB(
iconRequestsEnabled = iconRequestsEnabled,
iconRequestModel = iconRequestModel,
lazyGridState = lazyGridState,
snackbarHostState = snackbarHostState,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package app.lawnchair.lawnicons.ui.util

object Constants {
const val ICON_REQUEST_FORM = "https://forms.gle/xt7sJhgWEasuo9TR9"
const val ICON_REQUEST_FORM = "https://lawnchair.app/lawnicons-request"
const val GITHUB = "https://github.com/LawnchairLauncher/lawnicons"

const val ICON_PICKER_INTENT_ACTION = "com.novalauncher.THEME"
Expand Down
Loading

0 comments on commit 6b371f9

Please sign in to comment.