Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@
# Sentry Config File
sentry.properties
/opencode.json
# JVM crash and replay logs
hs_err_pid*.log
replay_pid*.log
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,20 @@ android {
buildTypes {
debug {
applicationIdSuffix = '.debug'
buildConfigField "String", "SENTRY_DSN", '""'
}
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
buildConfigField "String", "SENTRY_DSN", "\"${System.getenv('SENTRY_DSN') ?: ''}\""
}
nightly {
initWith release
applicationIdSuffix = '.nightly'
signingConfig signingConfigs.release
buildConfigField "String", "SENTRY_DSN", "\"${System.getenv('SENTRY_DSN') ?: ''}\""
}
}
buildFeatures {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@
</activity-alias>


<meta-data android:name="io.sentry.dsn" android:value="https://81af4c86ec2520fb31d575917d431fe6@o4510583318183936.ingest.de.sentry.io/4510583326507088"/>
<meta-data android:name="io.sentry.auto-init" android:value="false" />
<meta-data android:name="io.sentry.send-default-pii" android:value="false" />
<meta-data android:name="io.sentry.attach-view-hierarchy" android:value="true" />
<meta-data android:name="io.sentry.traces.sample-rate" android:value="0.2" />
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/kotlin/io/github/landwarderer/futon/core/BaseApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ open class BaseApp : Application(), Configuration.Provider {
super.onCreate()
PlatformRegistry.applicationContext = this // TODO replace with OkHttp.initialize
AppCompatDelegate.setDefaultNightMode(settings.theme)
// Initialize Sentry only if user has opted in
if (settings.isCrashAnalyticsEnabled) {
initializeSentry()
}
// TLS 1.3 support for Android < 10
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Security.insertProviderAt(Conscrypt.newProvider(), 1)
Expand Down Expand Up @@ -101,4 +105,21 @@ open class BaseApp : Application(), Configuration.Provider {
registerActivityLifecycleCallbacks(it)
}
}

private fun initializeSentry() {
try {
io.sentry.android.core.SentryAndroid.init(this) { options ->
// DSN is read from BuildConfig which gets it from SENTRY_DSN environment variable
// Only set if DSN is provided (non-empty)
if (BuildConfig.SENTRY_DSN.isNotEmpty()) {
options.dsn = BuildConfig.SENTRY_DSN
options.isEnableAutoSessionTracking = true
options.environment = if (BuildConfig.DEBUG) "debug" else "production"
}
}
} catch (e: Exception) {
// Log error but don't crash if Sentry initialization fails
e.printStackTrace()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,10 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isStatsEnabled: Boolean
get() = prefs.getBoolean(KEY_STATS_ENABLED, false)

var isCrashAnalyticsEnabled: Boolean
get() = prefs.getBoolean(KEY_CRASH_ANALYTICS_ENABLED, true)
set(value) = prefs.edit { putBoolean(KEY_CRASH_ANALYTICS_ENABLED, value) }

val isAutoLocalChaptersCleanupEnabled: Boolean
get() = prefs.getBoolean(KEY_CHAPTERS_CLEAR_AUTO, false)

Expand Down Expand Up @@ -817,6 +821,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_DISCORD_RPC = "discord_rpc"
const val KEY_DISCORD_RPC_SKIP_NSFW = "discord_rpc_skip_nsfw"
const val KEY_DISCORD_TOKEN = "discord_token"
const val KEY_CRASH_ANALYTICS_ENABLED = "crash_analytics_enabled"

// keys for non-persistent preferences
const val KEY_APP_VERSION = "app_version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ import io.github.landwarderer.futon.search.ui.suggestion.SearchSuggestionViewMod
import io.github.landwarderer.futon.search.ui.suggestion.adapter.SearchSuggestionAdapter
import javax.inject.Inject
import com.google.android.material.R as materialR
import io.sentry.Sentry

@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNavOwner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import com.google.android.material.chip.Chip
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import io.github.landwarderer.futon.R
import io.github.landwarderer.futon.core.prefs.AppSettings
import javax.inject.Inject
import io.github.landwarderer.futon.core.model.titleResId
import io.github.landwarderer.futon.core.nav.router
import io.github.landwarderer.futon.core.ui.sheet.BaseAdaptiveSheet
Expand All @@ -33,6 +35,9 @@ import java.util.Locale
class WelcomeSheet : BaseAdaptiveSheet<SheetWelcomeBinding>(), ChipsView.OnChipClickListener, View.OnClickListener,
ActivityResultCallback<Uri?> {

@Inject
lateinit var settings: AppSettings

private val viewModel by viewModels<WelcomeViewModel>()

private val backupSelectCall = registerForActivityResult(
Expand All @@ -52,6 +57,10 @@ class WelcomeSheet : BaseAdaptiveSheet<SheetWelcomeBinding>(), ChipsView.OnChipC
binding.chipBackup.setOnClickListener(this)
binding.chipSync.setOnClickListener(this)
binding.chipDirectories.setOnClickListener(this)
binding.switchCrashReporting.isChecked = settings.isCrashAnalyticsEnabled
binding.switchCrashReporting.setOnCheckedChangeListener { _, isChecked ->
settings.isCrashAnalyticsEnabled = isChecked
}

viewModel.locales.observe(viewLifecycleOwner, ::onLocalesChanged)
viewModel.types.observe(viewLifecycleOwner, ::onTypesChanged)
Expand Down Expand Up @@ -125,4 +134,5 @@ class WelcomeSheet : BaseAdaptiveSheet<SheetWelcomeBinding>(), ChipsView.OnChipC
},
)
}

}
38 changes: 38 additions & 0 deletions app/src/main/res/layout/sheet_welcome.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,44 @@

</HorizontalScrollView>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/margin_normal"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal">

<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/crash_reporting"
android:textAppearance="?textAppearanceTitleSmall" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@string/crash_reporting_summary"
android:textAppearance="?textAppearanceBodySmall" />

</LinearLayout>

<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_crash_reporting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:checked="true" />

</LinearLayout>

<TextView
android:id="@+id/textView_hint"
android:layout_width="match_parent"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<!-- Common dimensions -->
<dimen name="margin_normal">16dp</dimen>
<dimen name="margin_small">8dp</dimen>
<dimen name="margin_large">24dp</dimen>
<!-- List spacing -->
<dimen name="list_spacing_small">6dp</dimen>
<dimen name="list_spacing_normal">8dp</dimen>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -906,4 +906,6 @@
<string name="download_default_directory">Default directory for downloading manga</string>
<string name="private_app_directory_warning">This directory with all data will be deleted if you uninstall the application</string>
<string name="available_pattern">%1$s available</string>
<string name="crash_reporting">Crash Reporting</string>
<string name="crash_reporting_summary">Send anonymous crash logs to help improve the app. Takes effect after restart.</string>
</resources>
7 changes: 7 additions & 0 deletions app/src/main/res/xml/pref_services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,11 @@
app:allowDividerAbove="true"
app:icon="@drawable/ic_discord" />

<SwitchPreferenceCompat
android:defaultValue="true"
android:key="crash_analytics_enabled"
android:summary="@string/crash_reporting_summary"
android:title="@string/crash_reporting"
app:allowDividerAbove="true" />

</PreferenceScreen>
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ desugar = "2.1.5"
diskLruCache = "1.5"
documentfile = "1.1.0"
fragment = "1.8.9"
gradle = "8.13.0"
gradle = "8.13.2"
guava = "33.4.8-android"
hilt = "1.3.0"
json = "20250517"
Expand Down
Loading