Skip to content

Commit

Permalink
Merge branch 'release-69'
Browse files Browse the repository at this point in the history
  • Loading branch information
UweTrottmann committed Sep 15, 2023
2 parents e4405cb + 7f0c285 commit 2eeb24c
Show file tree
Hide file tree
Showing 157 changed files with 8,908 additions and 411 deletions.
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ Release notes

Releases marked with 🧪 were released on [the beta program](https://github.com/UweTrottmann/SeriesGuide/wiki/Beta) only.

Version 69
----------
*2023-09-15*

* 🔧 Streaming search: add latest supported countries.
* 🔧 Notifications: on Android 12 and newer, ask for permission to set precise alarm.
* 🔧 Trakt: add link to delete account.
* 🔧 Appearance: small adjustments.

#### 69.0.3
*2023-09-14*

* 🔨 Appearance: to get a matching navigation bar color on Samsung devices use a non-transparent
background on all devices.
* 🔧 Appearance: adjust light theme highlight color to be less washed out.
* 🔧 Trakt: add link to delete account.
* 📝 Latest user interface translations from Crowdin.

#### 69.0.2 🧪
*2023-08-18*

* 🔧 Calendar: change calendar settings symbol from eye to a filter to hopefully be more intuitive.
* 🔧 Notifications: on Android 12 and newer, ask for permission to set precise alarm.
* 📝 Latest user interface translations from Crowdin.

#### 69.0.1 🧪
*2023-08-10*

* 🔨 Do not apply corrections (e.g. for US time zones) on episodes when a custom time is set and the
other way around.
* 📝 Latest user interface translations from Crowdin.

#### 69.0.0 🧪
*2023-08-04*

* 🔧 Streaming search: add latest supported countries.
* 🔧 Cloud: do not automatically sign in (if e.g. signed in previously or on other devices).
* 🔧 Device backup: include the database when backing up to e.g. Google One. Only include auto
backup files for device-to-device transfer (Android 12 and newer).
* 📝 Latest user interface translations from Crowdin.

Version 68
----------
*2023-07-06*
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Android app to help you keep track of your favorite TV shows and movies.
<a href="https://seriesgui.de">Download</a> •
<a href="https://seriesgui.de/whypay">Support the dev</a> •
<a href="CONTRIBUTING.md">Contributing</a> •
<a href="https://discuss.seriesgui.de/">Help & Ideas</a>
<a href="https://discuss.seriesgui.de/">Announcements & Help</a>
</p>

<p align="center">
Expand All @@ -18,9 +18,6 @@ Android app to help you keep track of your favorite TV shows and movies.
<a href="https://github.com/UweTrottmann/SeriesGuide/actions/workflows/assemble-test-lint.yml">
<img src="https://img.shields.io/github/actions/workflow/status/UweTrottmann/SeriesGuide/assemble-test-lint.yml?branch=main&style=flat">
</a>
<a href="https://twitter.com/SeriesGuide">
<img src="https://img.shields.io/twitter/follow/SeriesGuide?label=Follow%20%40SeriesGuide&style=flat">
</a>
</p>

<p align="center">
Expand Down
9 changes: 8 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ android {
useLibrary("android.test.base")

buildFeatures {
buildConfig = true
// https://firebase.google.com/support/release-notes/android
viewBinding = true
}
Expand Down Expand Up @@ -63,7 +64,7 @@ android {
}

kotlinOptions {
jvmTarget = "1.8"
jvmTarget = JavaVersion.VERSION_1_8.toString()
// Using experimental flatMapLatest for Paging 3
freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi"
}
Expand Down Expand Up @@ -146,6 +147,12 @@ kapt {
}
}

// Manually set JVM target of kapt https://youtrack.jetbrains.com/issue/KT-55947/Unable-to-set-kapt-jvm-target-version
// Matches target version set in android block.
tasks.withType(org.jetbrains.kotlin.gradle.internal.KaptGenerateStubsTask::class).configureEach {
kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString()
}

dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.android)
Expand Down
51 changes: 1 addition & 50 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,5 @@

# Currently no need to obfuscate anything
-dontobfuscate
# Output unused code so we may optimize it
# Output unused code so it can be optimized
-printusage unused.txt

# Ignore notes about reflection use in support library
-dontnote android.support.**

# Amazon IAP library
-dontwarn com.amazon.**
-keep class com.amazon.** { *; }
#-keepattributes *Annotation* // already in default config

# Crashlytics 2.+
-keep class com.crashlytics.** { *; }
-keep class com.crashlytics.android.**
-keepattributes SourceFile, LineNumberTable
#-keepattributes *Annotation* // already in default config

# EventBus
# Keep subscriber methods
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-dontwarn sun.misc.Unsafe

# OkHttp 3
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn org.conscrypt.ConscryptHostnameVerifier

# Apache HTTP was removed as of Android M
-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient
-dontwarn com.google.android.gms.internal.**

## Testing
-dontwarn android.test.**

# Ignore some notes about unused classes referenced in method signatures
-dontnote uk.co.senab.photoview.**
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
android:name="com.battlelancer.seriesguide.SgApp"
android:allowBackup="true"
android:backupAgent="com.battlelancer.seriesguide.SgBackupAgent"
android:fullBackupContent="@xml/sg_full_backup_rules"
android:dataExtractionRules="@xml/sg_backup_rules_android_12"
android:fullBackupContent="@xml/sg_backup_rules"
android:fullBackupOnly="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ import com.battlelancer.seriesguide.util.Errors
import com.battlelancer.seriesguide.util.ThemeUtils
import com.battlelancer.seriesguide.util.Utils
import com.battlelancer.seriesguide.util.safeShow
import com.firebase.ui.auth.AuthMethodPickerLayout
import com.firebase.ui.auth.AuthUI
import com.firebase.ui.auth.ErrorCodes
import com.firebase.ui.auth.IdpResponse
import com.google.android.gms.tasks.Task
import com.google.android.material.snackbar.Snackbar
import com.google.firebase.auth.AuthResult
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import org.greenrobot.eventbus.EventBus
Expand All @@ -37,7 +36,8 @@ import timber.log.Timber

/**
* Manages signing in and out with Cloud and account removal.
* Tries to silent sign-in when started. Enables Cloud on sign-in.
* Does not auto/silent sign-in when started so users need to explicitly sign in.
* Enables Cloud on sign-in.
* If Cloud is still enabled, but the account requires validation
* enables to retry sign-in or to sign out (actually just disable Cloud).
*/
Expand Down Expand Up @@ -101,7 +101,7 @@ class CloudSetupFragment : Fragment() {

override fun onStart() {
super.onStart()
trySilentSignIn()
checkSignedIn()
}

override fun onResume() {
Expand Down Expand Up @@ -136,45 +136,13 @@ class CloudSetupFragment : Fragment() {
binding?.syncStatusCloud?.setProgress(event)
}

private fun trySilentSignIn() {
val firebaseUser = FirebaseAuth.getInstance().currentUser
if (firebaseUser != null) {
changeAccount(firebaseUser, null)
return
}

// check if the user is still signed in
val signInTask = AuthUI.getInstance()
.silentSignIn(requireContext(), hexagonTools.firebaseSignInProviders)
if (signInTask.isSuccessful) {
// If the user's cached credentials are valid, the OptionalPendingResult will be "done"
// and the GoogleSignInResult will be available instantly.
Timber.d("Got cached sign-in")
handleSilentSignInResult(signInTask)
} else {
// If the user has not previously signed in on this device or the sign-in has expired,
// this asynchronous branch will attempt to sign in the user silently. Cross-device
// single sign-on will occur in this branch.
Timber.d("Trying async sign-in")
signInTask.addOnCompleteListener { task ->
if (isAdded) {
handleSilentSignInResult(task)
}
}
}
}

/**
* @param task A completed sign-in task.
* If there is a signed in account, displays it.
*/
private fun handleSilentSignInResult(task: Task<AuthResult>) {
val account = if (task.isSuccessful) {
task.result?.user
} else {
null
}
// Note: Do not show error message if silent sign-in fails, just update UI.
changeAccount(account, null)
private fun checkSignedIn() {
val firebaseUser = FirebaseAuth.getInstance().currentUser
// If not signed in account will be null.
changeAccount(firebaseUser, null)
}

/**
Expand Down Expand Up @@ -256,12 +224,20 @@ class CloudSetupFragment : Fragment() {
}

private fun signIn() {
// Note: no need to provide a layout when just email sign-in is available
// as Firebase UI will just directly proceed without asking for the provider.
val authPickerLayout = AuthMethodPickerLayout.Builder(R.layout.auth_picker_email_google)
.setEmailButtonId(R.id.buttonAuthSignInEmail)
.setGoogleButtonId(R.id.buttonAuthSignInGoogle)
.build()

// Create and launch sign-in intent
val intent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(hexagonTools.firebaseSignInProviders)
.setIsSmartLockEnabled(hexagonTools.isGoogleSignInAvailable)
.setTheme(SeriesGuidePreferences.THEME)
.setAuthMethodPickerLayout(authPickerLayout)
.build()

signInWithFirebase.launch(intent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import android.text.format.DateUtils
import androidx.preference.PreferenceManager
import com.battlelancer.seriesguide.backend.CloudEndpointUtils.updateBuilder
import com.battlelancer.seriesguide.backend.settings.HexagonSettings
import com.battlelancer.seriesguide.modules.ApplicationContext
import com.battlelancer.seriesguide.jobs.NetworkJobProcessor
import com.battlelancer.seriesguide.modules.ApplicationContext
import com.battlelancer.seriesguide.util.Errors
import com.battlelancer.seriesguide.util.Errors.Companion.logAndReportHexagon
import com.battlelancer.seriesguide.util.isRetryError
Expand Down Expand Up @@ -227,7 +227,8 @@ class HexagonTools @Inject constructor(
// still signed in
httpRequestInitializer.firebaseUser = account
} else {
// try to silently sign in
// Try to silently sign in. This is fine as Cloud was enabled by the user
// and they reasonably expect to stay signed in.
val signInTask = AuthUI.getInstance().silentSignIn(context, firebaseSignInProviders)
try {
val authResult = Tasks.await(signInTask)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,6 @@ class TraktCommentsFragment : Fragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.listViewShouts
val liftOnScrollTargetViewId = R.id.listViewShouts
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import java.util.Calendar

object AutoBackupTools {

private const val BACKUP_FOLDER_NAME = "Backups"

@Throws(AutoBackupException::class)
fun getBackupDirectory(context: Context): File {
val storage = context.getExternalFilesDir(null)
Expand All @@ -20,7 +22,7 @@ object AutoBackupTools {
throw AutoBackupException("Storage not mounted.")
}

return File(storage, "Backups")
return File(storage, BACKUP_FOLDER_NAME)
}

fun deleteOldBackups(context: Context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,6 @@ abstract class StreamFragment : Fragment() {
companion object {
private const val TRAKT_HISTORY_URL = "https://trakt.tv/users/me/history/"

const val liftOnScrollTargetViewId = R.id.recyclerViewStream
val liftOnScrollTargetViewId = R.id.recyclerViewStream
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ open class ListsActivityImpl : BaseTopActivity() {
binding = ActivityListsBinding.inflate(layoutInflater)
setContentView(binding.root)
ThemeUtils.configureForEdgeToEdge(binding.root)
ThemeUtils.restoreDefaultWindowInsetsBehavior(binding.viewPagerLists)
ThemeUtils.configureAppBarForContentBelow(this)
setupActionBar()
setupBottomNavigation(R.id.navigation_item_lists)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ class SgListFragment : Fragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.recyclerViewListItems
val liftOnScrollTargetViewId = R.id.recyclerViewListItems

private const val ARG_LIST_ID = "LIST_ID"
private const val ARG_LIST_POSITION = "LIST_POSITION"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class SgListItemViewHolder(

binding.textViewShowsTimeAndNetwork.text = TextTools.dotSeparate(
network,
releaseTimeShow?.formatWithDeviceZoneToDayAndTime(context, weekDay)
releaseTimeShow?.formatWithDeviceZoneToDayAndTime()
)

// next episode info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ open class MoviesActivityImpl : BaseTopActivity() {
binding = ActivityMoviesBinding.inflate(layoutInflater)
setContentView(binding.root)
ThemeUtils.configureForEdgeToEdge(binding.root)
ThemeUtils.restoreDefaultWindowInsetsBehavior(binding.viewPagerMovies)
ThemeUtils.configureAppBarForContentBelow(this)
setupActionBar()
setupBottomNavigation(R.id.navigation_item_movies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ class MoviesCollectionFragment : MoviesBaseFragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.gridViewMoviesCollection
val liftOnScrollTargetViewId = R.id.gridViewMoviesCollection
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,6 @@ class MoviesDiscoverFragment : Fragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.recyclerViewMoviesDiscover
val liftOnScrollTargetViewId = R.id.recyclerViewMoviesDiscover
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,6 @@ class MoviesNowFragment : Fragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.recyclerViewNow
val liftOnScrollTargetViewId = R.id.recyclerViewNow
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ class MoviesWatchListFragment : MoviesBaseFragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.gridViewMoviesWatchlist
val liftOnScrollTargetViewId = R.id.gridViewMoviesWatchlist
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class MoviesWatchedFragment : Fragment() {
}

companion object {
const val liftOnScrollTargetViewId = R.id.recyclerViewMoviesWatched
val liftOnScrollTargetViewId = R.id.recyclerViewMoviesWatched

fun newInstance() = MoviesWatchedFragment()
}
Expand Down
Loading

0 comments on commit 2eeb24c

Please sign in to comment.