From 874c566814c2fb78929094ee17462093de09b0d9 Mon Sep 17 00:00:00 2001 From: LandWarderer2772 <84073086+LandWarderer2772@users.noreply.github.com> Date: Wed, 10 Jun 2026 07:34:04 +0000 Subject: [PATCH 1/3] Remove app update checker and add easter egg Removed AppUpdateRepository's fetchUpdate logic, AppUpdateActivity, and their associated UI components and preference settings. Implemented a Konfetti-based easter egg showing random presets (including a unicorn emoji) that triggers when the app version preference is tapped 8 times. --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 3 - .../futon/core/github/AppUpdateRepository.kt | 58 ---------- .../landwarderer/futon/core/nav/AppRouter.kt | 2 - .../core/ui/dialog/ErrorDetailsDialog.kt | 16 +-- .../futon/main/ui/MainActivity.kt | 1 - .../futon/main/ui/MainMenuProvider.kt | 8 +- .../futon/main/ui/MainViewModel.kt | 3 - .../settings/about/AboutSettingsFragment.kt | 67 +++++++---- .../settings/about/AboutSettingsViewModel.kt | 24 +--- .../futon/settings/about/AppUpdateActivity.kt | 102 ----------------- .../settings/about/AppUpdateViewModel.kt | 22 ---- .../futon/settings/about/Presets.kt | 108 ++++++++++++++++++ app/src/main/res/drawable/unicorn.png | Bin 0 -> 39976 bytes .../main/res/layout/activity_app_update.xml | 92 --------------- app/src/main/res/xml/pref_about.xml | 9 +- gradle/libs.versions.toml | 3 + 17 files changed, 159 insertions(+), 360 deletions(-) delete mode 100644 app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateActivity.kt delete mode 100644 app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateViewModel.kt create mode 100644 app/src/main/kotlin/io/github/landwarderer/futon/settings/about/Presets.kt create mode 100644 app/src/main/res/drawable/unicorn.png delete mode 100644 app/src/main/res/layout/activity_app_update.xml diff --git a/app/build.gradle b/app/build.gradle index b0866de1e4..795ab21f70 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -220,6 +220,7 @@ dependencies { implementation libs.disk.lru.cache implementation libs.markwon implementation libs.kizzyrpc + implementation libs.konfetti.xml implementation libs.conscrypt.android implementation libs.sentry.android diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 62357e3251..f1ec24034a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -307,9 +307,6 @@ - diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt index 0deceba200..4aa90d5bce 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/github/AppUpdateRepository.kt @@ -2,82 +2,29 @@ package io.github.landwarderer.futon.core.github import android.content.Context import dagger.hilt.android.qualifiers.ApplicationContext -import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.R import io.github.landwarderer.futon.core.network.BaseHttpClient -import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request -import org.json.JSONObject import javax.inject.Inject import javax.inject.Singleton -private const val BUILD_TYPE_RELEASE = "release" - @Singleton class AppUpdateRepository @Inject constructor( - private val settings: AppSettings, @BaseHttpClient private val okHttp: OkHttpClient, @ApplicationContext context: Context, ) { -// TODO("Fix update checking.") - private val availableUpdate = MutableStateFlow(null) - private val latestReleaseUrl = buildString { - append("https://api.github.com/repos/") - append(context.getString(R.string.github_updates_repo)) - append("/releases/latest") - } - private val changelogUrl = buildString { append("https://raw.githubusercontent.com/") append(context.getString(R.string.github_updates_repo)) append("/refs/heads/devel/CHANGELOG.md") } - val isUpdateAvailable: Boolean - get() = availableUpdate.value != null - - fun observeAvailableUpdate() = availableUpdate.asStateFlow() - - suspend fun fetchUpdate(): AppVersion? = withContext(Dispatchers.IO) { - runCatchingCancellable { - val request = Request.Builder() - .get() - .url(latestReleaseUrl) - .build() - val response = okHttp.newCall(request).await() - val json = JSONObject(response.body?.string() ?: "{}") - - val currentVersion = VersionId(BuildConfig.VERSION_NAME) - val releaseVersion = VersionId(json.getString("tag_name").removePrefix("v")) - - // Only return update if there's a newer version available - if (releaseVersion <= currentVersion) { - return@runCatchingCancellable null - } - - AppVersion( - id = json.getLong("id"), - url = json.getString("html_url"), - name = json.getString("name").removePrefix("v"), - apkSize = 0L, // No longer downloading, so size not needed - apkUrl = "", // No longer downloading - description = json.getString("body"), - ) - }.onFailure { - it.printStackTraceDebug("AppUpdateRepository::fetchUpdate") - }.onSuccess { - availableUpdate.value = it - }.getOrNull() - } - suspend fun fetchChangelog(): String? = withContext(Dispatchers.IO) { runCatchingCancellable { val request = Request.Builder() @@ -89,9 +36,4 @@ class AppUpdateRepository @Inject constructor( it.printStackTraceDebug("AppUpdateRepository::fetchChangelog") }.getOrNull() } - - @Suppress("KotlinConstantConditions") - suspend fun isUpdateSupported(): Boolean { - return true // Updates are always available now (just checking for newer version) - } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt index 6c1fbd8f5a..a483076902 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/nav/AppRouter.kt @@ -86,7 +86,6 @@ import io.github.landwarderer.futon.search.domain.SearchKind import io.github.landwarderer.futon.search.ui.MangaListActivity import io.github.landwarderer.futon.search.ui.multi.SearchActivity import io.github.landwarderer.futon.settings.SettingsActivity -import io.github.landwarderer.futon.settings.about.AppUpdateActivity import io.github.landwarderer.futon.settings.override.OverrideConfigActivity import io.github.landwarderer.futon.settings.reader.ReaderTapGridConfigActivity import io.github.landwarderer.futon.settings.sources.auth.SourceAuthActivity @@ -200,7 +199,6 @@ class AppRouter private constructor( fun openBookmarks() = startActivity(AllBookmarksActivity::class.java) - fun openAppUpdate() = startActivity(AppUpdateActivity::class.java) fun openSuggestions() { startActivity(suggestionsIntent(contextOrNull() ?: return)) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/dialog/ErrorDetailsDialog.kt b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/dialog/ErrorDetailsDialog.kt index e4afcc6335..fd979d7268 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/dialog/ErrorDetailsDialog.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/core/ui/dialog/ErrorDetailsDialog.kt @@ -8,7 +8,6 @@ import androidx.core.view.isVisible import com.google.android.material.dialog.MaterialAlertDialogBuilder import dagger.hilt.android.AndroidEntryPoint import io.github.landwarderer.futon.R -import io.github.landwarderer.futon.core.github.AppUpdateRepository import io.github.landwarderer.futon.core.nav.AppRouter import io.github.landwarderer.futon.core.nav.router import io.github.landwarderer.futon.core.ui.AlertDialogFragment @@ -20,16 +19,12 @@ import io.github.landwarderer.futon.core.util.ext.report import io.github.landwarderer.futon.core.util.ext.requireSerializable import io.github.landwarderer.futon.core.util.ext.setTextAndVisible import io.github.landwarderer.futon.databinding.DialogErrorDetailsBinding -import javax.inject.Inject @AndroidEntryPoint class ErrorDetailsDialog : AlertDialogFragment(), View.OnClickListener { private lateinit var exception: Throwable - @Inject - lateinit var appUpdateRepository: AppUpdateRepository - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val args = requireArguments() @@ -48,9 +43,7 @@ class ErrorDetailsDialog : AlertDialogFragment(), Vie binding.buttonBrowser.isVisible = isUrlAvailable binding.textViewBrowser.isVisible = isUrlAvailable binding.textViewDescription.setTextAndVisible( - if (appUpdateRepository.isUpdateAvailable) { - R.string.error_disclaimer_app_outdated - } else if (exception.isReportable()) { + if (exception.isReportable()) { R.string.error_disclaimer_report } else { 0 @@ -67,12 +60,7 @@ class ErrorDetailsDialog : AlertDialogFragment(), Vie .setNeutralButton(androidx.preference.R.string.copy) { _, _ -> context?.copyToClipboard(getString(R.string.error), exception.stackTraceToString()) } - if (appUpdateRepository.isUpdateAvailable) { - builder.setPositiveButton(R.string.update) { _, _ -> - router.openAppUpdate() - dismiss() - } - } else if (exception.isReportable()) { + if (exception.isReportable()) { builder.setPositiveButton(R.string.report) { _, _ -> exception.report(silent = true) dismiss() diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt index f68ad31fdc..d9f5c20648 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainActivity.kt @@ -154,7 +154,6 @@ class MainActivity : BaseActivity(), AppBarOwner, BottomNav viewModel.isLoading.observe(this@MainActivity, this@MainActivity::onLoadingStateChanged) viewModel.isResumeEnabled.observe(this@MainActivity, this@MainActivity::onResumeEnabledChanged) viewModel.feedCounter.observe(this@MainActivity, ::onFeedCounterChanged) - viewModel.appUpdate.observe(this@MainActivity, MenuInvalidator(this@MainActivity)) viewModel.onFirstStart.observeEvent(this@MainActivity) { router.showWelcomeSheet() } viewModel.isBottomNavPinned.observe(this@MainActivity, ::setNavbarPinned) searchSuggestionViewModel.isIncognitoModeEnabled.observe(this@MainActivity, this@MainActivity::onIncognitoModeChanged) diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainMenuProvider.kt b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainMenuProvider.kt index 53a9647421..6900ad03a7 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainMenuProvider.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainMenuProvider.kt @@ -19,8 +19,7 @@ class MainMenuProvider( override fun onPrepareMenu(menu: Menu) { menu.findItem(R.id.action_incognito)?.isChecked = viewModel.isIncognitoModeEnabled.value - val hasAppUpdate = viewModel.appUpdate.value != null - menu.findItem(R.id.action_app_update)?.isVisible = hasAppUpdate + menu.findItem(R.id.action_app_update)?.isVisible = false } override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) { @@ -34,11 +33,6 @@ class MainMenuProvider( true } - R.id.action_app_update -> { - router.openAppUpdate() - true - } - R.id.action_downloads -> { router.openDownloads() true diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainViewModel.kt index fafbafc1cc..38e10c10a8 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/main/ui/MainViewModel.kt @@ -8,7 +8,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.plus import io.github.landwarderer.futon.core.exceptions.EmptyHistoryException -import io.github.landwarderer.futon.core.github.AppUpdateRepository import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.prefs.observeAsFlow import io.github.landwarderer.futon.core.prefs.observeAsStateFlow @@ -25,7 +24,6 @@ import javax.inject.Inject @HiltViewModel class MainViewModel @Inject constructor( private val historyRepository: HistoryRepository, - private val appUpdateRepository: AppUpdateRepository, trackingRepository: TrackingRepository, private val settings: AppSettings, readingResumeEnabledUseCase: ReadingResumeEnabledUseCase, @@ -43,7 +41,6 @@ class MainViewModel @Inject constructor( initialValue = false, ) - val appUpdate = appUpdateRepository.observeAvailableUpdate() val feedCounter = trackingRepository.observeUnreadUpdatesCount() .withErrorHandling() diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsFragment.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsFragment.kt index 3e0d6295cf..e0a29e87c4 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsFragment.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsFragment.kt @@ -1,30 +1,30 @@ package io.github.landwarderer.futon.settings.about -import android.content.Intent import android.os.Bundle import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout import androidx.annotation.StringRes +import androidx.core.content.ContextCompat import androidx.fragment.app.viewModels import androidx.preference.Preference -import androidx.preference.SwitchPreferenceCompat import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.combine import io.github.landwarderer.futon.BuildConfig import io.github.landwarderer.futon.R -import io.github.landwarderer.futon.core.github.AppVersion -import io.github.landwarderer.futon.core.github.VersionId -import io.github.landwarderer.futon.core.github.isStable import io.github.landwarderer.futon.core.nav.router import io.github.landwarderer.futon.core.prefs.AppSettings import io.github.landwarderer.futon.core.ui.BasePreferenceFragment -import io.github.landwarderer.futon.core.util.ext.observe -import io.github.landwarderer.futon.core.util.ext.observeEvent +import nl.dionsegijn.konfetti.core.models.Shape +import nl.dionsegijn.konfetti.xml.KonfettiView +import kotlin.random.Random @AndroidEntryPoint class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { private val viewModel by viewModels() + private var versionClickCount = 0 + private lateinit var konfettiView: KonfettiView override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_about) @@ -32,27 +32,37 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { title = getString(R.string.app_version, BuildConfig.VERSION_NAME) } findPreference(AppSettings.KEY_LINK_TELEGRAM)?.isVisible = false - findPreference(AppSettings.KEY_UPDATES_UNSTABLE)?.run { - isEnabled = VersionId(BuildConfig.VERSION_NAME).isStable - if (!isEnabled) isChecked = true - } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - combine(viewModel.isUpdateSupported, viewModel.isLoading, ::Pair) - .observe(viewLifecycleOwner) { (isUpdateSupported, isLoading) -> - findPreference(AppSettings.KEY_UPDATES_UNSTABLE)?.isVisible = isUpdateSupported - findPreference(AppSettings.KEY_APP_VERSION)?.isEnabled = isUpdateSupported && !isLoading - } - viewModel.onUpdateAvailable.observeEvent(viewLifecycleOwner, ::onUpdateAvailable) + konfettiView = KonfettiView(requireContext()).apply { + layoutParams = FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + // Ensure it doesn't consume clicks + isClickable = false + isFocusable = false + } + + (view as? ViewGroup)?.addView(konfettiView) + } + + override fun onDestroyView() { + (view as? ViewGroup)?.removeView(konfettiView) + super.onDestroyView() } override fun onPreferenceTreeClick(preference: Preference): Boolean { return when (preference.key) { AppSettings.KEY_APP_VERSION -> { - viewModel.checkForUpdates() + versionClickCount++ + if (versionClickCount == 8) { + versionClickCount = 0 + triggerEasterEgg() + } true } @@ -82,12 +92,19 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { } } - private fun onUpdateAvailable(version: AppVersion?) { - if (version == null) { - Snackbar.make(listView, R.string.no_update_available, Snackbar.LENGTH_SHORT).show() - } else { - startActivity(Intent(requireContext(), AppUpdateActivity::class.java)) - } + private fun triggerEasterEgg() { + val drawable = ContextCompat.getDrawable(requireContext(), R.drawable.unicorn) + val drawableShape = drawable?.let { Shape.DrawableShape(it, true) } + + val presets = listOf( + Presets.festive(drawableShape), + Presets.explode(drawableShape), + Presets.parade(drawableShape), + Presets.rain(drawableShape) + ) + + val randomPreset = presets[Random.nextInt(presets.size)] + konfettiView.start(randomPreset) } private fun openLink( diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsViewModel.kt index 14b9b26a5d..02b7f36a09 100644 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsViewModel.kt +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AboutSettingsViewModel.kt @@ -1,32 +1,10 @@ package io.github.landwarderer.futon.settings.about -import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.stateIn -import io.github.landwarderer.futon.core.github.AppUpdateRepository -import io.github.landwarderer.futon.core.github.AppVersion import io.github.landwarderer.futon.core.ui.BaseViewModel -import io.github.landwarderer.futon.core.util.ext.MutableEventFlow -import io.github.landwarderer.futon.core.util.ext.call import javax.inject.Inject @HiltViewModel -class AboutSettingsViewModel @Inject constructor( - private val appUpdateRepository: AppUpdateRepository, -) : BaseViewModel() { +class AboutSettingsViewModel @Inject constructor() : BaseViewModel() { - val isUpdateSupported = flow { - emit(appUpdateRepository.isUpdateSupported()) - }.stateIn(viewModelScope, SharingStarted.Eagerly, false) - - val onUpdateAvailable = MutableEventFlow() - - fun checkForUpdates() { - launchLoadingJob { - val update = appUpdateRepository.fetchUpdate() - onUpdateAvailable.call(update) - } - } } diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateActivity.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateActivity.kt deleted file mode 100644 index b42438fe3b..0000000000 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateActivity.kt +++ /dev/null @@ -1,102 +0,0 @@ -package io.github.landwarderer.futon.settings.about - -import android.os.Bundle -import android.view.View -import android.view.ViewGroup.MarginLayoutParams -import androidx.activity.viewModels -import androidx.core.text.buildSpannedString -import androidx.core.view.WindowInsetsCompat -import androidx.core.view.updateLayoutParams -import androidx.core.view.updatePadding -import com.google.android.material.snackbar.Snackbar -import dagger.hilt.android.AndroidEntryPoint -import io.noties.markwon.Markwon -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import io.github.landwarderer.futon.R -import io.github.landwarderer.futon.core.github.AppVersion -import io.github.landwarderer.futon.core.nav.router -import io.github.landwarderer.futon.core.ui.BaseActivity -import io.github.landwarderer.futon.core.util.ext.consumeAllSystemBarsInsets -import io.github.landwarderer.futon.core.util.ext.getDisplayMessage -import io.github.landwarderer.futon.core.util.ext.observe -import io.github.landwarderer.futon.core.util.ext.observeEvent -import io.github.landwarderer.futon.core.util.ext.setTextAndVisible -import io.github.landwarderer.futon.core.util.ext.systemBarsInsets -import io.github.landwarderer.futon.databinding.ActivityAppUpdateBinding - -@AndroidEntryPoint -class AppUpdateActivity : BaseActivity(), View.OnClickListener { - - private val viewModel: AppUpdateViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(ActivityAppUpdateBinding.inflate(layoutInflater)) - viewModel.nextVersion.observe(this, ::onNextVersionChanged) - viewBinding.buttonCancel.setOnClickListener(this) - viewBinding.buttonUpdate.setOnClickListener(this) - - viewModel.isLoading.observe(this) { isLoading -> - viewBinding.buttonUpdate.isEnabled = viewModel.nextVersion.value != null && !isLoading - } - viewModel.onError.observeEvent(this, ::onError) - } - - override fun onApplyWindowInsets( - v: View, - insets: WindowInsetsCompat - ): WindowInsetsCompat { - val barsInsets = insets.systemBarsInsets - viewBinding.root.updatePadding(top = barsInsets.top) - viewBinding.dockedToolbarChild.updateLayoutParams { - leftMargin = barsInsets.left - rightMargin = barsInsets.right - bottomMargin = barsInsets.bottom - } - viewBinding.scrollView.updatePadding( - left = barsInsets.left, - right = barsInsets.right, - ) - return insets.consumeAllSystemBarsInsets() - } - - override fun onClick(v: View) { - when (v.id) { - R.id.button_cancel -> finishAfterTransition() - R.id.button_update -> openGitHub() - } - } - - private suspend fun onNextVersionChanged(version: AppVersion?) { - viewBinding.buttonUpdate.isEnabled = version != null && !viewModel.isLoading.value - if (version == null) { - viewBinding.textViewContent.setText(R.string.loading_) - return - } - val markwon = Markwon.create(this) - val message = withContext(Dispatchers.IO) { - buildSpannedString { - append(getString(R.string.new_version_s, version.name)) - appendLine() - appendLine() - append(markwon.toMarkdown(version.description)) - appendLine() - appendLine() - append(getString(R.string.github_download_warning)) - } - } - markwon.setParsedMarkdown(viewBinding.textViewContent, message) - } - - private fun openGitHub() { - val latestVersion = viewModel.nextVersion.value ?: return - if (!router.openExternalBrowser(latestVersion.url, getString(R.string.open_in_browser))) { - Snackbar.make(viewBinding.scrollView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() - } - } - - private fun onError(e: Throwable) { - viewBinding.textViewError.setTextAndVisible(R.string.error_occurred) - } -} diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateViewModel.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateViewModel.kt deleted file mode 100644 index fb495345bc..0000000000 --- a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/AppUpdateViewModel.kt +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.landwarderer.futon.settings.about - -import dagger.hilt.android.lifecycle.HiltViewModel -import io.github.landwarderer.futon.core.github.AppUpdateRepository -import io.github.landwarderer.futon.core.ui.BaseViewModel -import javax.inject.Inject - -@HiltViewModel -class AppUpdateViewModel @Inject constructor( - private val repository: AppUpdateRepository, -) : BaseViewModel() { - - val nextVersion = repository.observeAvailableUpdate() - - init { - if (nextVersion.value == null) { - launchLoadingJob { - repository.fetchUpdate() - } - } - } -} diff --git a/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/Presets.kt b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/Presets.kt new file mode 100644 index 0000000000..decad05737 --- /dev/null +++ b/app/src/main/kotlin/io/github/landwarderer/futon/settings/about/Presets.kt @@ -0,0 +1,108 @@ +package io.github.landwarderer.futon.settings.about + +import android.graphics.drawable.Drawable +import nl.dionsegijn.konfetti.core.Angle +import nl.dionsegijn.konfetti.core.Party +import nl.dionsegijn.konfetti.core.Position +import nl.dionsegijn.konfetti.core.Rotation +import nl.dionsegijn.konfetti.core.Spread +import nl.dionsegijn.konfetti.core.emitter.Emitter +import nl.dionsegijn.konfetti.core.models.Shape +import nl.dionsegijn.konfetti.core.models.Size +import java.util.concurrent.TimeUnit + +class Presets { + companion object { + fun festive(drawable: Shape.DrawableShape? = null): List { + val party = Party( + speed = 30f, + maxSpeed = 50f, + damping = 0.9f, + angle = Angle.TOP, + spread = 45, + size = listOf(Size.SMALL, Size.LARGE, Size.LARGE), + shapes = listOf(Shape.Square, Shape.Circle, drawable).filterNotNull(), + timeToLive = 3000L, + rotation = Rotation(), + colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def), + emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(30), + position = Position.Relative(0.5, 1.0) + ) + + return listOf( + party, + party.copy( + speed = 55f, + maxSpeed = 65f, + spread = 10, + emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(10), + ), + party.copy( + speed = 50f, + maxSpeed = 60f, + spread = 120, + emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(40), + ), + party.copy( + speed = 65f, + maxSpeed = 80f, + spread = 10, + emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(10), + ) + ) + } + + fun explode(drawable: Shape.DrawableShape? = null): List { + return listOf( + Party( + speed = 0f, + maxSpeed = 30f, + damping = 0.9f, + spread = 360, + shapes = listOf(Shape.Square, Shape.Circle, drawable).filterNotNull(), + colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def), + emitter = Emitter(duration = 100, TimeUnit.MILLISECONDS).max(100), + position = Position.Relative(0.5, 0.3) + ) + ) + } + + fun parade(drawable: Shape.DrawableShape? = null): List { + val party = Party( + speed = 10f, + maxSpeed = 30f, + damping = 0.9f, + angle = Angle.RIGHT - 45, + spread = Spread.SMALL, + shapes = listOf(Shape.Square, Shape.Circle, drawable).filterNotNull(), + colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def), + emitter = Emitter(duration = 5, TimeUnit.SECONDS).perSecond(30), + position = Position.Relative(0.0, 0.5) + ) + + return listOf( + party, + party.copy( + angle = party.angle - 90, // flip angle from right to left + position = Position.Relative(1.0, 0.5) + ), + ) + } + + fun rain(drawable: Shape.DrawableShape? = null): List { + return listOf( + Party( + speed = 0f, + maxSpeed = 15f, + damping = 0.9f, + angle = Angle.BOTTOM, + spread = Spread.ROUND, + shapes = listOf(Shape.Square, Shape.Circle, drawable).filterNotNull(), + colors = listOf(0xfce18a, 0xff726d, 0xf4306d, 0xb48def), + emitter = Emitter(duration = 5, TimeUnit.SECONDS).perSecond(100), + position = Position.Relative(0.0, 0.0).between(Position.Relative(1.0, 0.0)) + ) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/unicorn.png b/app/src/main/res/drawable/unicorn.png new file mode 100644 index 0000000000000000000000000000000000000000..e95bfca72f7c9957fdfc10967349791e3f3effa5 GIT binary patch literal 39976 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 z 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 TfnL`K0hhXpj&julo3Q@?6qYjT literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_app_update.xml b/app/src/main/res/layout/activity_app_update.xml deleted file mode 100644 index 84f64f3038..0000000000 --- a/app/src/main/res/layout/activity_app_update.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - -