mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-15 00:02:48 -05:00
some work on v4 authentication
This commit is contained in:
@@ -18,12 +18,16 @@
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.TVTime"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- android:screenOrientation="portrait">-->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="app" android:host="@string/intent_route_auth_return" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.owenlejeune.tvtime
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.compose.animation.rememberSplineBasedDecay
|
||||
import androidx.compose.foundation.Image
|
||||
@@ -59,6 +60,13 @@ class MainActivity : MonetCompatActivity() {
|
||||
SessionManager.initialize()
|
||||
}
|
||||
|
||||
var mainNavStartRoute = BottomNavItem.Items[0].route
|
||||
intent.data?.let {
|
||||
when (it.host) {
|
||||
getString(R.string.intent_route_auth_return) -> mainNavStartRoute = BottomNavItem.Account.route
|
||||
}
|
||||
}
|
||||
|
||||
lifecycleScope.launchWhenCreated {
|
||||
monet.awaitMonetReady()
|
||||
setContent {
|
||||
@@ -66,7 +74,7 @@ class MainActivity : MonetCompatActivity() {
|
||||
TVTimeTheme(monetCompat = monet) {
|
||||
val appNavController = rememberNavController()
|
||||
Box {
|
||||
MainNavigationRoutes(appNavController = appNavController)
|
||||
MainNavigationRoutes(appNavController = appNavController, mainNavStartRoute = mainNavStartRoute)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +82,11 @@ class MainActivity : MonetCompatActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppScaffold(appNavController: NavHostController, preferences: AppPreferences = get(AppPreferences::class.java)) {
|
||||
private fun AppScaffold(
|
||||
appNavController: NavHostController,
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route,
|
||||
preferences: AppPreferences = get(AppPreferences::class.java)
|
||||
) {
|
||||
val windowSize = rememberWindowSizeClass()
|
||||
|
||||
val navController = rememberNavController()
|
||||
@@ -127,7 +139,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions,
|
||||
topBarScrollBehaviour = scrollBehavior
|
||||
topBarScrollBehaviour = scrollBehavior,
|
||||
mainNavStartRoute = mainNavStartRoute
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -180,7 +193,11 @@ class MainActivity : MonetCompatActivity() {
|
||||
item: BottomNavItem
|
||||
) {
|
||||
appBarTitle.value = item.name
|
||||
navController.navigate(item.route) {
|
||||
navigateToRoute(navController, item.route)
|
||||
}
|
||||
|
||||
private fun navigateToRoute(navController: NavController, route: String) {
|
||||
navController.navigate(route) {
|
||||
navController.graph.startDestinationRoute?.let { screenRoute ->
|
||||
popUpTo(screenRoute) {
|
||||
saveState = true
|
||||
@@ -220,7 +237,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
navController: NavHostController,
|
||||
topBarScrollBehaviour: TopAppBarScrollBehavior,
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route
|
||||
) {
|
||||
if (windowSize == WindowSizeClass.Expanded) {
|
||||
DualColumnMainContent(
|
||||
@@ -228,14 +246,16 @@ class MainActivity : MonetCompatActivity() {
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions,
|
||||
topBarScrollBehaviour = topBarScrollBehaviour
|
||||
topBarScrollBehaviour = topBarScrollBehaviour,
|
||||
mainNavStartRoute = mainNavStartRoute
|
||||
)
|
||||
} else {
|
||||
SingleColumnMainContent(
|
||||
appNavController = appNavController,
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions
|
||||
appBarActions = appBarActions,
|
||||
mainNavStartRoute = mainNavStartRoute
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -245,13 +265,15 @@ class MainActivity : MonetCompatActivity() {
|
||||
appNavController: NavHostController,
|
||||
navController: NavHostController,
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route
|
||||
) {
|
||||
MainMediaView(
|
||||
appNavController = appNavController,
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions
|
||||
appBarActions = appBarActions,
|
||||
mainNavStartRoute = mainNavStartRoute
|
||||
)
|
||||
}
|
||||
|
||||
@@ -261,7 +283,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
navController: NavHostController,
|
||||
topBarScrollBehaviour: TopAppBarScrollBehavior,
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route
|
||||
) {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
@@ -295,7 +318,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
appNavController = appNavController,
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions
|
||||
appBarActions = appBarActions,
|
||||
mainNavStartRoute = mainNavStartRoute
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -306,7 +330,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
appNavController: NavHostController,
|
||||
navController: NavHostController,
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<RowScope.() -> Unit> = mutableStateOf({})
|
||||
appBarActions: MutableState<RowScope.() -> Unit> = mutableStateOf({}),
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route
|
||||
) {
|
||||
Column {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
@@ -324,7 +349,8 @@ class MainActivity : MonetCompatActivity() {
|
||||
appNavController = appNavController,
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
appBarActions = appBarActions
|
||||
appBarActions = appBarActions,
|
||||
startDestination = mainNavStartRoute
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -337,11 +363,12 @@ class MainActivity : MonetCompatActivity() {
|
||||
@Composable
|
||||
private fun MainNavigationRoutes(
|
||||
startDestination: String = MainNavItem.MainView.route,
|
||||
mainNavStartRoute: String = BottomNavItem.Items[0].route,
|
||||
appNavController: NavHostController,
|
||||
) {
|
||||
NavHost(navController = appNavController, startDestination = startDestination) {
|
||||
composable(MainNavItem.MainView.route) {
|
||||
AppScaffold(appNavController = appNavController)
|
||||
AppScaffold(appNavController = appNavController, mainNavStartRoute = mainNavStartRoute)
|
||||
}
|
||||
composable(
|
||||
MainNavItem.DetailView.route.plus("/{${NavConstants.TYPE_KEY}}/{${NavConstants.ID_KEY}}"),
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.owenlejeune.tvtime
|
||||
|
||||
import android.app.Application
|
||||
import com.facebook.stetho.Stetho
|
||||
import com.kieronquinn.monetcompat.core.MonetCompat
|
||||
import com.owenlejeune.tvtime.di.modules.appModule
|
||||
import com.owenlejeune.tvtime.di.modules.networkModule
|
||||
import com.owenlejeune.tvtime.di.modules.preferencesModule
|
||||
@@ -28,6 +29,8 @@ class TvTimeApplication: Application() {
|
||||
)
|
||||
}
|
||||
|
||||
MonetCompat.enablePaletteCompat()
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Stetho.initializeWithDefaults(this)
|
||||
}
|
||||
|
||||
@@ -98,7 +98,13 @@ class TmdbClient: KoinComponent {
|
||||
private inner class V4Interceptor: Interceptor {
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val builder = chain.request().newBuilder()
|
||||
builder.header("Authorization", "Bearer ${BuildConfig.TMDB_Api_v4Key}")
|
||||
with(chain.request()) {
|
||||
if (url.encodedPathSegments.contains("auth")) {
|
||||
builder.header("Authorization", "Bearer ${BuildConfig.TMDB_Api_v4Key}")
|
||||
} else {
|
||||
builder.header("Authorization", "Bearer ${SessionManager.currentSession!!.accessToken}")
|
||||
}
|
||||
}
|
||||
|
||||
val locale = Locale.current
|
||||
val languageCode = "${locale.language}-${locale.region}"
|
||||
|
||||
@@ -23,4 +23,7 @@ interface AuthenticationApi {
|
||||
|
||||
@POST("authentication/token/validate_with_login")
|
||||
suspend fun validateTokenWithLogin(@Body body: TokenValidationBody): Response<CreateTokenResponse>
|
||||
|
||||
@POST("authentication/session/convert/4")
|
||||
suspend fun createSessionFromV4Token(@Body body: V4TokenBody): Response<CreateSessionResponse>
|
||||
}
|
||||
@@ -27,4 +27,8 @@ class AuthenticationService {
|
||||
suspend fun validateTokenWithLogin(body: TokenValidationBody): Response<CreateTokenResponse> {
|
||||
return service.validateTokenWithLogin(body)
|
||||
}
|
||||
|
||||
suspend fun createSessionFromV4Token(body: V4TokenBody): Response<CreateSessionResponse> {
|
||||
return service.createSessionFromV4Token(body)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
class V4TokenBody(
|
||||
@SerializedName("access_token") val accessToken: String
|
||||
)
|
||||
@@ -59,9 +59,10 @@ fun MainNavGraph(
|
||||
appNavController: NavHostController,
|
||||
navController: NavHostController,
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({}),
|
||||
startDestination: String = BottomNavItem.Items[0].route
|
||||
) {
|
||||
NavHost(navController = navController, startDestination = BottomNavItem.Movies.route) {
|
||||
NavHost(navController = navController, startDestination = startDestination) {
|
||||
composable(BottomNavItem.Movies.route) {
|
||||
appBarActions.value = {}
|
||||
MediaTab(appNavController = appNavController, mediaType = MediaViewType.MOVIE)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.owenlejeune.tvtime.ui.screens.tabs.bottom
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
@@ -7,13 +8,11 @@ import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -52,7 +51,13 @@ fun AccountTab(
|
||||
appBarTitle: MutableState<String>,
|
||||
appBarActions: MutableState<@Composable (RowScope.() -> Unit)> = mutableStateOf({})
|
||||
) {
|
||||
if (appBarTitle.value.equals(stringResource(id = R.string.nav_account_title))) {
|
||||
val lastSelectedOption = remember { mutableStateOf("") }
|
||||
|
||||
if (SessionManager.isV4SignInInProgress) {
|
||||
v4SignInPart2(lastSelectedOption)
|
||||
}
|
||||
|
||||
if (appBarTitle.value == stringResource(id = R.string.nav_account_title)) {
|
||||
when (SessionManager.currentSession?.isAuthorized) {
|
||||
false -> {
|
||||
appBarTitle.value =
|
||||
@@ -74,34 +79,30 @@ fun AccountTab(
|
||||
}
|
||||
}
|
||||
|
||||
val lastSelectedOption = remember { mutableStateOf("") }
|
||||
|
||||
appBarActions.value = {
|
||||
AccountDropdownMenu(session = SessionManager.currentSession, lastSelectedOption = lastSelectedOption)
|
||||
}
|
||||
|
||||
if (lastSelectedOption.value.isNotBlank() || lastSelectedOption.value.isBlank()) {
|
||||
SessionManager.currentSession?.let { session ->
|
||||
val tabs = if (session.isAuthorized) {
|
||||
AccountTabNavItem.AuthorizedItems
|
||||
} else {
|
||||
AccountTabNavItem.GuestItems
|
||||
SessionManager.currentSession?.let { session ->
|
||||
val tabs = if (session.isAuthorized) {
|
||||
AccountTabNavItem.AuthorizedItems
|
||||
} else {
|
||||
AccountTabNavItem.GuestItems
|
||||
}
|
||||
|
||||
Column {
|
||||
when(session.isAuthorized) {
|
||||
true -> { AuthorizedSessionIcon() }
|
||||
false -> { GuestSessionIcon() }
|
||||
}
|
||||
|
||||
Column {
|
||||
when(session.isAuthorized) {
|
||||
true -> { AuthorizedSessionIcon() }
|
||||
false -> { GuestSessionIcon() }
|
||||
}
|
||||
|
||||
val pagerState = rememberPagerState()
|
||||
ScrollableTabs(tabs = tabs, pagerState = pagerState)
|
||||
AccountTabs(
|
||||
appNavController = appNavController,
|
||||
tabs = tabs,
|
||||
pagerState = pagerState
|
||||
)
|
||||
}
|
||||
val pagerState = rememberPagerState()
|
||||
ScrollableTabs(tabs = tabs, pagerState = pagerState)
|
||||
AccountTabs(
|
||||
appNavController = appNavController,
|
||||
tabs = tabs,
|
||||
pagerState = pagerState
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,6 +339,11 @@ private fun NoSessionMenuItems(
|
||||
text = { Text(text = stringResource(id = R.string.action_sign_in)) },
|
||||
onClick = { showSignInDialog.value = true }
|
||||
)
|
||||
// val context = LocalContext.current
|
||||
// DropdownMenuItem(
|
||||
// text = { Text(text = stringResource(id = R.string.action_sign_in)) },
|
||||
// onClick = { v4SignInPart1(context) }
|
||||
// )
|
||||
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = stringResource(id = R.string.action_sign_in_as_guest)) },
|
||||
@@ -348,6 +354,21 @@ private fun NoSessionMenuItems(
|
||||
)
|
||||
}
|
||||
|
||||
private fun v4SignInPart1(context: Context) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
SessionManager.signInWithV4Part1(context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun v4SignInPart2(lastSelectedOption: MutableState<String>) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val signIn = SessionManager.signInWithV4Part2()
|
||||
if (signIn) {
|
||||
lastSelectedOption.value = NO_SESSION_SIGN_IN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun GuestSessionIcon() {
|
||||
val guestName = stringResource(id = R.string.account_name_guest)
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
package com.owenlejeune.tvtime.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import com.owenlejeune.tvtime.R
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.AuthenticationService
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.GuestSessionService
|
||||
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.*
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.AuthenticationV4Service
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthAccessBody
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthDeleteBody
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthRequestBody
|
||||
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -21,7 +29,10 @@ object SessionManager: KoinComponent {
|
||||
val currentSession: Session?
|
||||
get() = _currentSession
|
||||
|
||||
var isV4SignInInProgress: Boolean = false
|
||||
|
||||
private val authenticationService by lazy { TmdbClient().createAuthenticationService() }
|
||||
private val authenticationV4Service by lazy { TmdbClient().createV4AuthenticationService() }
|
||||
|
||||
fun clearSession(onResponse: (isSuccessful: Boolean) -> Unit) {
|
||||
currentSession?.let { session ->
|
||||
@@ -39,6 +50,22 @@ object SessionManager: KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
fun clearSessionV4(onResponse: (isSuccessful: Boolean) -> Unit) {
|
||||
currentSession?.let { session ->
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val deleteResponse = authenticationV4Service.deleteAccessToken(AuthDeleteBody(session.sessionId))
|
||||
withContext(Dispatchers.Main) {
|
||||
if (deleteResponse.isSuccessful) {
|
||||
_currentSession = null
|
||||
preferences.guestSessionId = ""
|
||||
preferences.authorizedSessionId = ""
|
||||
}
|
||||
onResponse(deleteResponse.isSuccessful)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun initialize() {
|
||||
if (preferences.guestSessionId.isNotEmpty()) {
|
||||
val session = GuestSession()
|
||||
@@ -91,7 +118,57 @@ object SessionManager: KoinComponent {
|
||||
return false
|
||||
}
|
||||
|
||||
abstract class Session(val sessionId: String, val isAuthorized: Boolean) {
|
||||
suspend fun signInWithV4Part1(context: Context) {
|
||||
isV4SignInInProgress = true
|
||||
|
||||
val service = AuthenticationV4Service()
|
||||
val requestTokenResponse = service.createRequestToken(AuthRequestBody(redirect = ""))
|
||||
if (requestTokenResponse.isSuccessful) {
|
||||
requestTokenResponse.body()?.let { ctr ->
|
||||
_currentSession = InProgressSession(ctr.requestToken)
|
||||
val browserIntent = Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse(
|
||||
context.getString(R.string.tmdb_auth_url, ctr.requestToken)
|
||||
)
|
||||
)
|
||||
context.startActivity(browserIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun signInWithV4Part2(): Boolean {
|
||||
if (isV4SignInInProgress && _currentSession is InProgressSession) {
|
||||
val requestToken = _currentSession!!.sessionId
|
||||
val authResponse = authenticationV4Service.createAccessToken(AuthAccessBody(requestToken))
|
||||
if (authResponse.isSuccessful) {
|
||||
authResponse.body()?.let { ar ->
|
||||
if (ar.success) {
|
||||
val sessionResponse = authenticationService.createSessionFromV4Token(V4TokenBody(ar.accessToken))
|
||||
if (sessionResponse.isSuccessful) {
|
||||
sessionResponse.body()?.let { sr ->
|
||||
preferences.authorizedSessionId = sr.sessionId
|
||||
preferences.guestSessionId = ""
|
||||
_currentSession = AuthorizedSession(accessToken = ar.accessToken)
|
||||
_currentSession?.initialize()
|
||||
isV4SignInInProgress = false
|
||||
return true
|
||||
}
|
||||
}
|
||||
// preferences.authorizedSessionId = ar.accessToken
|
||||
// preferences.guestSessionId = ""
|
||||
// _currentSession = AuthorizedSession()
|
||||
// _currentSession?.initialize()
|
||||
// isV4SignInInProgress = false
|
||||
// return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
abstract class Session(val sessionId: String, val isAuthorized: Boolean, val accessToken: String = "") {
|
||||
protected open var _ratedMovies: List<RatedMovie> = emptyList()
|
||||
val ratedMovies: List<RatedMovie>
|
||||
get() = _ratedMovies
|
||||
@@ -187,7 +264,18 @@ object SessionManager: KoinComponent {
|
||||
}
|
||||
}
|
||||
|
||||
private class AuthorizedSession: Session(preferences.authorizedSessionId, true) {
|
||||
private class InProgressSession(requestToken: String): Session(requestToken, false) {
|
||||
override suspend fun initialize() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
override suspend fun refresh(changed: Array<Changed>) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class AuthorizedSession(accessToken: String = ""): Session(preferences.authorizedSessionId, true, accessToken) {
|
||||
private val service by lazy { AccountService() }
|
||||
|
||||
override suspend fun initialize() {
|
||||
|
||||
@@ -100,4 +100,8 @@
|
||||
<string name="username_label">Username</string>
|
||||
<string name="password_label">Password</string>
|
||||
<string name="no_account_message">Don\'t have an account?</string>
|
||||
<string name="tmdb_auth_url">"https://www.themoviedb.org/auth/access?request_token=%1$s"</string>
|
||||
|
||||
<!-- intent routes -->
|
||||
<string name="intent_route_auth_return">tvtime.auth.return</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user