Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show on App Launch: Translations #4980

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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 @@ -364,6 +364,8 @@ open class BrowserActivity : DuckDuckGoActivity() {
return
}
}

viewModel.handleShowOnAppLaunchOption()
}

private fun configureObservers() {
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/java/com/duckduckgo/app/browser/BrowserViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.duckduckgo.anvil.annotations.ContributesRemoteFeature
import com.duckduckgo.anvil.annotations.ContributesViewModel
import com.duckduckgo.app.browser.defaultbrowsing.DefaultBrowserDetector
import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter
import com.duckduckgo.app.fire.DataClearer
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.LastOpenedTab
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.NewTabPage
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.SpecificPage
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore
import com.duckduckgo.app.global.ApplicationClearDataState
import com.duckduckgo.app.global.rating.AppEnjoymentPromptEmitter
import com.duckduckgo.app.global.rating.AppEnjoymentPromptOptions
Expand Down Expand Up @@ -55,6 +60,7 @@ import com.duckduckgo.feature.toggles.api.Toggle
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import timber.log.Timber

Expand All @@ -69,6 +75,7 @@ class BrowserViewModel @Inject constructor(
private val dispatchers: DispatcherProvider,
private val pixel: Pixel,
private val skipUrlConversionOnNewTabFeature: SkipUrlConversionOnNewTabFeature,
private val showOnAppLaunchOptionDataStore: ShowOnAppLaunchOptionDataStore,
) : ViewModel(),
CoroutineScope {

Expand Down Expand Up @@ -284,6 +291,21 @@ class BrowserViewModel @Inject constructor(
fun onBookmarksActivityResult(url: String) {
command.value = Command.OpenSavedSite(url)
}

fun handleShowOnAppLaunchOption() {
viewModelScope.launch {
when (val option = showOnAppLaunchOptionDataStore.optionFlow.first()) {
LastOpenedTab -> Unit
NewTabPage -> onNewTabRequested()
is SpecificPage -> {
val liveSelectedTabUrl = tabRepository.getSelectedTab()?.url
if (liveSelectedTabUrl != option.url) {
onOpenInNewTabRequested(option.url)
}
}
}
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.lifecycle.viewModelScope
import com.duckduckgo.anvil.annotations.ContributesViewModel
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore
import com.duckduckgo.app.pixels.AppPixelName
import com.duckduckgo.app.pixels.AppPixelName.AUTOCOMPLETE_GENERAL_SETTINGS_TOGGLED_OFF
import com.duckduckgo.app.pixels.AppPixelName.AUTOCOMPLETE_GENERAL_SETTINGS_TOGGLED_ON
import com.duckduckgo.app.pixels.AppPixelName.AUTOCOMPLETE_RECENT_SITES_GENERAL_SETTINGS_TOGGLED_OFF
Expand Down Expand Up @@ -143,6 +144,7 @@ class GeneralSettingsViewModel @Inject constructor(

fun onShowOnAppLaunchButtonClick() {
sendCommand(Command.LaunchShowOnAppLaunchScreen)
pixel.fire(AppPixelName.SETTINGS_GENERAL_APP_LAUNCH_PRESSED)
}

private fun observeShowOnAppLaunchOption() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 DuckDuckGo
*
* 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 com.duckduckgo.app.generalsettings.showonapplaunch

import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore
import com.duckduckgo.app.statistics.api.BrowserFeatureStateReporterPlugin
import com.duckduckgo.app.statistics.pixels.Pixel.PixelParameter
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesBinding
import com.squareup.anvil.annotations.ContributesMultibinding
import javax.inject.Inject
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking

interface ShowOnAppLaunchReporterPlugin

@ContributesMultibinding(
scope = AppScope::class,
boundType = BrowserFeatureStateReporterPlugin::class,
)
@ContributesBinding(scope = AppScope::class, boundType = ShowOnAppLaunchReporterPlugin::class)
class ShowOnAppLaunchStateReporterPlugin
@Inject
constructor(
private val dispatcherProvider: DispatcherProvider,
private val showOnAppLaunchOptionDataStore: ShowOnAppLaunchOptionDataStore,
) : ShowOnAppLaunchReporterPlugin, BrowserFeatureStateReporterPlugin {

override fun featureStateParams(): Map<String, String> {
val option =
runBlocking(dispatcherProvider.io()) {
showOnAppLaunchOptionDataStore.optionFlow.first()
}
val dailyPixelValue = ShowOnAppLaunchOption.getDailyPixelValue(option)
return mapOf(PixelParameter.LAUNCH_SCREEN to dailyPixelValue)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2024 DuckDuckGo
*
* 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 com.duckduckgo.app.generalsettings.showonapplaunch

import android.net.Uri
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore

class ShowOnAppLaunchUrlConverterImpl : UrlConverter {

override fun convertUrl(url: String?): String {
if (url.isNullOrBlank()) return ShowOnAppLaunchOptionDataStore.DEFAULT_SPECIFIC_PAGE_URL

val uri = Uri.parse(url.trim())

val convertedUri = if (uri.scheme == null) {
Uri.Builder().scheme("http").authority(uri.path?.lowercase())
} else {
uri.buildUpon()
.scheme(uri.scheme?.lowercase())
.authority(uri.authority?.lowercase())
}
.apply {
query(uri.query)
fragment(uri.fragment)
}
.build()
.toString()

return Uri.decode(convertedUri)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.lifecycle.viewModelScope
import com.duckduckgo.anvil.annotations.ContributesViewModel
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore
import com.duckduckgo.app.statistics.pixels.Pixel
import com.duckduckgo.common.utils.DispatcherProvider
import com.duckduckgo.di.scopes.ActivityScope
import javax.inject.Inject
Expand All @@ -37,6 +38,8 @@ import timber.log.Timber
class ShowOnAppLaunchViewModel @Inject constructor(
private val dispatcherProvider: DispatcherProvider,
private val showOnAppLaunchOptionDataStore: ShowOnAppLaunchOptionDataStore,
private val urlConverter: UrlConverter,
private val pixel: Pixel,
) : ViewModel() {

data class ViewState(
Expand Down Expand Up @@ -64,14 +67,21 @@ class ShowOnAppLaunchViewModel @Inject constructor(
fun onShowOnAppLaunchOptionChanged(option: ShowOnAppLaunchOption) {
Timber.i("User changed show on app launch option to $option")
viewModelScope.launch(dispatcherProvider.io()) {
firePixel(option)
showOnAppLaunchOptionDataStore.setShowOnAppLaunchOption(option)
}
}

fun setSpecificPageUrl(url: String) {
Timber.i("Setting specific page url to $url")
viewModelScope.launch(dispatcherProvider.io()) {
showOnAppLaunchOptionDataStore.setSpecificPageUrl(url)
val convertedUrl = urlConverter.convertUrl(url)
showOnAppLaunchOptionDataStore.setSpecificPageUrl(convertedUrl)
}
}

private fun firePixel(option: ShowOnAppLaunchOption) {
val pixelName = ShowOnAppLaunchOption.getPixelName(option)
pixel.fire(pixelName)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 DuckDuckGo
*
* 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 com.duckduckgo.app.generalsettings.showonapplaunch

interface UrlConverter {

fun convertUrl(url: String?): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

package com.duckduckgo.app.generalsettings.showonapplaunch.model

import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_GENERAL_APP_LAUNCH_LAST_OPENED_TAB_SELECTED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_GENERAL_APP_LAUNCH_NEW_TAB_PAGE_SELECTED
import com.duckduckgo.app.pixels.AppPixelName.SETTINGS_GENERAL_APP_LAUNCH_SPECIFIC_PAGE_SELECTED

sealed class ShowOnAppLaunchOption(val id: Int) {

data object LastOpenedTab : ShowOnAppLaunchOption(1)
Expand All @@ -30,5 +34,17 @@ sealed class ShowOnAppLaunchOption(val id: Int) {
3 -> SpecificPage("")
else -> throw IllegalArgumentException("Unknown id: $id")
}

fun getPixelName(option: ShowOnAppLaunchOption) = when (option) {
LastOpenedTab -> SETTINGS_GENERAL_APP_LAUNCH_LAST_OPENED_TAB_SELECTED
NewTabPage -> SETTINGS_GENERAL_APP_LAUNCH_NEW_TAB_PAGE_SELECTED
is SpecificPage -> SETTINGS_GENERAL_APP_LAUNCH_SPECIFIC_PAGE_SELECTED
}

fun getDailyPixelValue(option: ShowOnAppLaunchOption) = when (option) {
LastOpenedTab -> "last_opened_tab"
NewTabPage -> "new_tab_page"
is SpecificPage -> "specific_page"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
import com.duckduckgo.app.generalsettings.showonapplaunch.ShowOnAppLaunchUrlConverterImpl
import com.duckduckgo.app.generalsettings.showonapplaunch.UrlConverter
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
Expand All @@ -37,6 +39,9 @@ object ShowOnAppLaunchDataStoreModule {
@Provides
@ShowOnAppLaunch
fun showOnAppLaunchDataStore(context: Context): DataStore<Preferences> = context.showOnAppLaunchDataStore

@Provides
fun showOnAppLaunchUrlConverter(): UrlConverter = ShowOnAppLaunchUrlConverterImpl()
}

@Qualifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.duckduckgo.app.generalsettings.showonapplaunch.store

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.MutablePreferences
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
Expand All @@ -25,6 +26,7 @@ import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchO
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.LastOpenedTab
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.NewTabPage
import com.duckduckgo.app.generalsettings.showonapplaunch.model.ShowOnAppLaunchOption.SpecificPage
import com.duckduckgo.app.generalsettings.showonapplaunch.store.ShowOnAppLaunchOptionDataStore.Companion.DEFAULT_SPECIFIC_PAGE_URL
import com.duckduckgo.di.scopes.AppScope
import com.squareup.anvil.annotations.ContributesBinding
import javax.inject.Inject
Expand All @@ -37,6 +39,10 @@ interface ShowOnAppLaunchOptionDataStore {

suspend fun setShowOnAppLaunchOption(showOnAppLaunchOption: ShowOnAppLaunchOption)
suspend fun setSpecificPageUrl(url: String)

companion object {
const val DEFAULT_SPECIFIC_PAGE_URL = "https://duckduckgo.com/"
}
}

@ContributesBinding(AppScope::class)
Expand Down Expand Up @@ -67,19 +73,22 @@ class ShowOnAppLaunchOptionPrefsDataStore @Inject constructor(
preferences[intPreferencesKey(KEY_SHOW_ON_APP_LAUNCH_OPTION)] = showOnAppLaunchOption.id

if (showOnAppLaunchOption is SpecificPage) {
preferences[stringPreferencesKey(KEY_SHOW_ON_APP_LAUNCH_SPECIFIC_PAGE_URL)]
preferences.setShowOnAppLaunch(showOnAppLaunchOption.url)
}
}
}

override suspend fun setSpecificPageUrl(url: String) {
store.edit { preferences ->
preferences[stringPreferencesKey(KEY_SHOW_ON_APP_LAUNCH_SPECIFIC_PAGE_URL)] = url
preferences.setShowOnAppLaunch(url)
}
}

private fun MutablePreferences.setShowOnAppLaunch(url: String) {
set(stringPreferencesKey(KEY_SHOW_ON_APP_LAUNCH_SPECIFIC_PAGE_URL), url)
}

companion object {
private const val DEFAULT_SPECIFIC_PAGE_URL = "duckduckgo.com"
private const val KEY_SHOW_ON_APP_LAUNCH_OPTION = "SHOW_ON_APP_LAUNCH_OPTION"
private const val KEY_SHOW_ON_APP_LAUNCH_SPECIFIC_PAGE_URL = "SHOW_ON_APP_LAUNCH_SPECIFIC_PAGE_URL"
}
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ enum class AppPixelName(override val pixelName: String) : Pixel.PixelName {
SETTINGS_PRIVATE_SEARCH_MORE_SEARCH_SETTINGS_PRESSED("ms_private_search_more_search_settings_pressed"),
SETTINGS_COOKIE_POPUP_PROTECTION_PRESSED("ms_cookie_popup_protection_setting_pressed"),
SETTINGS_FIRE_BUTTON_PRESSED("ms_fire_button_setting_pressed"),
SETTINGS_GENERAL_APP_LAUNCH_PRESSED("m_settings_general_app_launch_pressed"),
SETTINGS_GENERAL_APP_LAUNCH_LAST_OPENED_TAB_SELECTED("m_settings_general_app_launch_last_opened_tab_selected"),
SETTINGS_GENERAL_APP_LAUNCH_NEW_TAB_PAGE_SELECTED("m_settings_general_app_launch_new_tab_page_selected"),
SETTINGS_GENERAL_APP_LAUNCH_SPECIFIC_PAGE_SELECTED("m_settings_general_app_launch_specific_page_selected"),

SURVEY_CTA_SHOWN(pixelName = "mus_cs"),
SURVEY_CTA_DISMISSED(pixelName = "mus_cd"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ class TabDataRepository @Inject constructor(
siteData.clear()
}

override suspend fun getSelectedTab(): TabEntity? =
withContext(dispatchers.io()) { tabsDao.selectedTab() }

override suspend fun select(tabId: String) {
databaseExecutor().scheduleDirect {
val selection = TabSelectionEntity(tabId = tabId)
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/res/values-bg/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -804,4 +804,10 @@
<string name="onboardingFireButtonDaxDialogOkButton">Изпробвайте го</string>
<string name="onboardingFireButtonDaxDialogCancelButton">Пропускане</string>

<!-- Show on App Launch Option -->
<string name="showOnAppLaunchOptionTitle">Показване при стартиране на приложението</string>
<string name="showOnAppLaunchOptionLastOpenedTab">Последно отворен раздел</string>
<string name="showOnAppLaunchOptionNewTabPage">Страница с нов раздел</string>
<string name="showOnAppLaunchOptionSpecificPage">Конкретна страница</string>

</resources>
6 changes: 6 additions & 0 deletions app/src/main/res/values-cs/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,10 @@
<string name="onboardingFireButtonDaxDialogOkButton">Vyzkoušejte ho</string>
<string name="onboardingFireButtonDaxDialogCancelButton">Přeskočit</string>

<!-- Show on App Launch Option -->
<string name="showOnAppLaunchOptionTitle">Zobrazit při spuštění aplikace</string>
<string name="showOnAppLaunchOptionLastOpenedTab">Naposledy otevřená karta</string>
<string name="showOnAppLaunchOptionNewTabPage">Stránka Nová karta</string>
<string name="showOnAppLaunchOptionSpecificPage">Konkrétní stránka</string>

</resources>
Loading
Loading