add onboarding (login), change default theme to dark

closes #14
pull/28/head
Jannik 2 years ago
parent 3f45d769d2
commit 8a22554846
Signed by: Seil0
GPG Key ID: E8459F3723C52C24

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.mosad.teapod">
<uses-permission android:name="android.permission.INTERNET" />
@ -10,9 +11,9 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme.Light">
android:theme="@style/AppTheme.Dark">
<activity
android:name=".SplashActivity"
android:name=".activity.SplashActivity"
android:label="@string/app_name"
android:theme="@style/SplashTheme"
android:screenOrientation="portrait">
@ -22,20 +23,28 @@
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:name=".activity.onboarding.OnboardingActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustPan">
</activity>
<activity
android:name=".activity.main.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".player.PlayerActivity"
android:name="org.mosad.teapod.activity.player.PlayerActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|layoutDirection"
android:excludeFromRecents="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:parentActivityName=".MainActivity"
android:parentActivityName=".activity.main.MainActivity"
android:supportsPictureInPicture="true"
android:taskAffinity=".player.PlayerActivity"
android:theme="@style/PlayerTheme" />
android:theme="@style/PlayerTheme"
tools:targetApi="n" />
</application>
</manifest>

@ -1,8 +1,9 @@
package org.mosad.teapod
package org.mosad.teapod.activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.mosad.teapod.activity.main.MainActivity
class SplashActivity : AppCompatActivity() {

@ -20,7 +20,7 @@
*
*/
package org.mosad.teapod
package org.mosad.teapod.activity.main
import android.content.Intent
import android.os.Bundle
@ -34,16 +34,18 @@ import com.afollestad.materialdialogs.callbacks.onDismiss
import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.runBlocking
import org.mosad.teapod.R
import org.mosad.teapod.databinding.ActivityMainBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.player.PlayerActivity
import org.mosad.teapod.activity.player.PlayerActivity
import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.LoginDialog
import org.mosad.teapod.ui.fragments.AccountFragment
import org.mosad.teapod.ui.fragments.HomeFragment
import org.mosad.teapod.ui.fragments.LibraryFragment
import org.mosad.teapod.ui.fragments.SearchFragment
import org.mosad.teapod.activity.main.fragments.AccountFragment
import org.mosad.teapod.activity.main.fragments.HomeFragment
import org.mosad.teapod.activity.main.fragments.LibraryFragment
import org.mosad.teapod.activity.main.fragments.SearchFragment
import org.mosad.teapod.activity.onboarding.OnboardingActivity
import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.StorageController
import java.net.SocketTimeoutException
@ -120,8 +122,8 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
private fun getThemeResource(): Int {
return when (Preferences.theme) {
DataTypes.Theme.DARK -> R.style.AppTheme_Dark
else -> R.style.AppTheme_Light
DataTypes.Theme.LIGHT -> R.style.AppTheme_Light
else -> R.style.AppTheme_Dark
}
}
@ -138,22 +140,23 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
EncryptedPreferences.readCredentials(this)
StorageController.load(this)
try {
// make sure credentials are set, run's async
if (EncryptedPreferences.password.isEmpty()) {
showLoginDialog(true)
} else {
// try to login in, as most sites can only bee loaded once loged in
if (!AoDParser.login()) showLoginDialog(false)
}
} catch (ex: SocketTimeoutException) {
Log.w(javaClass.name, "Timeout during login!")
// show waring dialog before finishing
MaterialDialog(this).show {
title(R.string.dialog_timeout_head)
message(R.string.dialog_timeout_desc)
onDismiss { exitAndRemoveTask() }
// show onbaording
if (EncryptedPreferences.password.isEmpty()) {
showOnboarding()
} else {
try {
if (!AoDParser.login()) {
showLoginDialog()
}
} catch (ex: SocketTimeoutException) {
Log.w(javaClass.name, "Timeout during login!")
// show waring dialog before finishing
MaterialDialog(this).show {
title(R.string.dialog_timeout_head)
message(R.string.dialog_timeout_desc)
onDismiss { exitAndRemoveTask() }
}
}
}
@ -164,12 +167,12 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
wasInitialized = true
}
private fun showLoginDialog(firstTry: Boolean) {
LoginDialog(this, firstTry).positiveButton {
private fun showLoginDialog() {
LoginDialog(this, false).positiveButton {
EncryptedPreferences.saveCredentials(login, password, context)
if (!AoDParser.login()) {
showLoginDialog(false)
showLoginDialog()
Log.w(javaClass.name, "Login failed, please try again.")
}
}.negativeButton {
@ -178,6 +181,14 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
}.show()
}
/**
* start the onboarding activity and finish the main activity
*/
private fun showOnboarding() {
startActivity(Intent(this, OnboardingActivity::class.java))
finish()
}
/**
* Show a fragment on top of the current fragment.
* The current fragment is replaced and the new one is added

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.os.Bundle
import android.util.Log
@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import org.mosad.teapod.BuildConfig
import org.mosad.teapod.MainActivity
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentAccountBinding
import org.mosad.teapod.parser.AoDParser

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.graphics.drawable.Drawable
import android.os.Bundle
@ -14,7 +14,7 @@ import com.bumptech.glide.request.transition.Transition
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.mosad.teapod.MainActivity
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentHomeBinding
import org.mosad.teapod.parser.AoDParser

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater
@ -9,7 +9,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.mosad.teapod.MainActivity
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentLibraryBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.adapter.MediaItemAdapter

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
@ -12,8 +12,8 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.coroutines.*
import org.mosad.teapod.MainActivity
import org.mosad.teapod.R
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentMediaBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.*

@ -1,4 +1,4 @@
package org.mosad.teapod.ui.fragments
package org.mosad.teapod.activity.main.fragments
import android.os.Bundle
import android.view.LayoutInflater
@ -7,7 +7,7 @@ import android.view.ViewGroup
import android.widget.SearchView
import androidx.fragment.app.Fragment
import kotlinx.coroutines.*
import org.mosad.teapod.MainActivity
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.FragmentSearchBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.decoration.MediaItemDecoration

@ -0,0 +1,54 @@
package org.mosad.teapod.activity.onboarding
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.coroutines.*
import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentOnLoginBinding
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.EncryptedPreferences
class OnLoginFragment: Fragment() {
private lateinit var binding: FragmentOnLoginBinding
private var loginJob: Job? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentOnLoginBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initActions()
}
private fun initActions() {
binding.buttonLogin.setOnClickListener {
// get login credentials from gui
val email = binding.editTextLogin.text.toString()
val password = binding.editTextPassword.text.toString()
EncryptedPreferences.saveCredentials(email, password, requireContext()) // save the credentials
binding.buttonLogin.isClickable = false
loginJob = GlobalScope.launch {
if (AoDParser.login()) {
// if login was successful, switch to main
if (activity is OnboardingActivity) {
(activity as OnboardingActivity).launchMainActivity()
}
} else {
withContext(Dispatchers.Main) {
binding.textLoginDesc.text = getString(R.string.on_login_failed)
binding.buttonLogin.isClickable = true
}
}
}
}
}
}

@ -0,0 +1,31 @@
package org.mosad.teapod.activity.onboarding
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.mosad.teapod.databinding.FragmentOnWelcomeBinding
class OnWelcomeFragment: Fragment() {
private lateinit var binding: FragmentOnWelcomeBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentOnWelcomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initActions()
}
private fun initActions() {
binding.buttonGetStarted.setOnClickListener {
if (activity is OnboardingActivity) {
(activity as OnboardingActivity).nextFragment()
}
}
}
}

@ -0,0 +1,78 @@
package org.mosad.teapod.activity.onboarding
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
import org.mosad.teapod.activity.main.MainActivity
import org.mosad.teapod.databinding.ActivityOnboardingBinding
class OnboardingActivity : AppCompatActivity() {
private lateinit var binding: ActivityOnboardingBinding
private lateinit var pagerAdapter: FragmentStateAdapter
private val fragments = arrayOf(OnLoginFragment())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityOnboardingBinding.inflate(layoutInflater)
setContentView(binding.root)
pagerAdapter = ScreenSlidePagerAdapter(this)
binding.viewPager.adapter = pagerAdapter
TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
}.attach()
// we don't use the skip button, instead we use the start button to skip the last fragment
binding.buttonSkip.visibility = View.GONE
// hide tab layout if only one tab is displayed
if (fragments.size <= 1) {
binding.tabLayout.visibility = View.GONE
}
}
override fun onBackPressed() {
if (binding.viewPager.currentItem == 0) {
super.onBackPressed()
} else {
binding.viewPager.currentItem = binding.viewPager.currentItem - 1
}
}
fun nextFragment() {
if (binding.viewPager.currentItem < fragments.size - 1) {
binding.viewPager.currentItem++
} else {
launchMainActivity()
}
}
fun btnSkipClick(@Suppress("UNUSED_PARAMETER")v: View) {
//launchMainActivity() // currently not used in Teapod
}
fun launchMainActivity() {
startActivity(Intent(this, MainActivity::class.java))
finish()
}
/**
* A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
* sequence.
*/
private inner class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
}

@ -1,4 +1,4 @@
package org.mosad.teapod.player
package org.mosad.teapod.activity.player
import android.animation.Animator
import android.animation.AnimatorListenerAdapter

@ -1,4 +1,4 @@
package org.mosad.teapod.player
package org.mosad.teapod.activity.player
import android.app.Application
import android.net.Uri
@ -15,7 +15,6 @@ import kotlinx.coroutines.runBlocking
import org.mosad.teapod.R
import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.fragments.MediaFragment
import org.mosad.teapod.util.DataTypes
import org.mosad.teapod.util.Episode
import org.mosad.teapod.util.Media

@ -56,7 +56,7 @@ object AoDParser {
fun login(): Boolean = runBlocking {
withContext(Dispatchers.Default) {
withContext(Dispatchers.IO) {
// get the authenticity token
val resAuth = Jsoup.connect(baseUrl + loginPath)
.header("User-Agent", userAgent)

@ -11,7 +11,7 @@ object Preferences {
internal set
var autoplay = true
internal set
var theme = DataTypes.Theme.LIGHT
var theme = DataTypes.Theme.DARK
internal set
private fun getSharedPref(context: Context): SharedPreferences {
@ -62,8 +62,8 @@ object Preferences {
)
theme = DataTypes.Theme.valueOf(
sharedPref.getString(
context.getString(R.string.save_key_theme), DataTypes.Theme.LIGHT.toString()
) ?: DataTypes.Theme.LIGHT.toString()
context.getString(R.string.save_key_theme), DataTypes.Theme.DARK.toString()
) ?: DataTypes.Theme.DARK.toString()
)
}

@ -6,7 +6,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import org.mosad.teapod.databinding.PlayerEpisodesListBinding
import org.mosad.teapod.player.PlayerViewModel
import org.mosad.teapod.activity.player.PlayerViewModel
import org.mosad.teapod.util.adapter.PlayerEpisodeItemAdapter
class EpisodesListPlayer @JvmOverloads constructor(

@ -13,7 +13,7 @@ import android.widget.TextView
import androidx.core.view.children
import org.mosad.teapod.R
import org.mosad.teapod.databinding.PlayerLanguageSettingsBinding
import org.mosad.teapod.player.PlayerViewModel
import org.mosad.teapod.activity.player.PlayerViewModel
import java.util.*
class LanguageSettingsPlayer @JvmOverloads constructor(

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false">
<solid android:color="?iconColor"/>
</shape>
</item>
</layer-list>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape
android:innerRadius="0dp"
android:shape="ring"
android:thickness="4dp"
android:useLevel="false">
<solid android:color="@color/colorAccent" />
</shape>
</item>
</layer-list>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dot_selected"
android:state_selected="true"/>
<item android:drawable="@drawable/dot_default"/>
</selector>

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.viewpager2.widget.ViewPager2>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_marginBottom="0dp"
android:background="@android:color/transparent"
app:tabBackground="@drawable/dot_tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"
app:tabPaddingStart="6dp"
app:tabPaddingEnd="6dp"/>
<Button
android:id="@+id/button_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:background="@null"
android:onClick="btnNextClick"
android:text="@string/next"
android:visibility="gone" />
<Button
android:id="@+id/button_skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:background="@null"
android:onClick="btnSkipClick"
android:text="@string/skip"
tools:visibility="gone" />
</RelativeLayout>

@ -7,7 +7,7 @@
android:layout_height="match_parent"
android:background="#000000"
android:keepScreenOn="true"
tools:context=".player.PlayerActivity">
tools:context=".activity.player.PlayerActivity">
<com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/video_view"

@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.AboutFragment">
tools:context=".activity.main.fragments.AboutFragment">
<LinearLayout
android:layout_width="match_parent"

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.AccountFragment">
tools:context=".activity.main.fragments.AccountFragment">
<ScrollView
android:layout_width="match_parent"

@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.HomeFragment">
tools:context=".activity.main.fragments.HomeFragment">
<ScrollView
android:layout_width="match_parent"

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.LibraryFragment">
tools:context=".activity.main.fragments.LibraryFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_media_library"

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.MediaFragment">
tools:context=".activity.main.fragments.MediaFragment">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
@ -134,9 +134,9 @@
android:id="@+id/image_my_list_action"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/my_list"
android:src="@drawable/ic_baseline_add_24"
app:tint="?buttonBackground"
android:contentDescription="@string/my_list" />
app:tint="?buttonBackground" />
<TextView
android:id="@+id/text_my_list_action"

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary">
<ImageView
android:id="@+id/image_login"
android:layout_width="128dp"
android:layout_height="128dp"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground"
app:tint="?buttonBackground" />
<LinearLayout
android:id="@+id/linear_login"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_login">
<TextView
android:id="@+id/text_login_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/on_login_heading"
android:textAlignment="center"
android:textSize="26sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_login_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:text="@string/on_login_desc"
android:textAlignment="center"
android:textSize="18sp" />
<EditText
android:id="@+id/edit_text_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/login"
android:importantForAutofill="no"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/edit_text_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:ems="10"
android:hint="@string/password"
android:importantForAutofill="no"
android:inputType="textPassword" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_login"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="7dp"
android:layout_marginTop="7dp"
android:layout_marginEnd="7dp"
android:text="@string/login"
android:textAllCaps="false"
android:textColor="#FFFFFFFF"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image_logo"
android:layout_width="128dp"
android:layout_height="128dp"
android:contentDescription="@string/app_name"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_launcher_foreground"
app:tint="?buttonBackground" />
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_logo">
<TextView
android:id="@+id/text_app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textAlignment="center"
android:textSize="26sp"
android:textStyle="bold" />
<TextView
android:id="@+id/text_welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:text="@string/on_welcome"
android:textAlignment="center"
android:textSize="18sp" />
</LinearLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/button_get_started"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="40dp"
android:text="@string/on_get_started"
android:textAllCaps="false"
android:textColor="#FFFFFFFF"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>

@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?themePrimary"
tools:context=".ui.fragments.SearchFragment">
tools:context=".activity.main.fragments.SearchFragment">
<SearchView
android:id="@+id/search_text"

@ -7,25 +7,25 @@
<fragment
android:id="@+id/navigation_home"
android:name="org.mosad.teapod.ui.fragments.HomeFragment"
android:name="org.mosad.teapod.activity.main.fragments.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_library"
android:name="org.mosad.teapod.ui.fragments.LibraryFragment"
android:name="org.mosad.teapod.activity.main.fragments.LibraryFragment"
android:label="@string/title_library"
tools:layout="@layout/fragment_library" />
<fragment
android:id="@+id/navigation_search"
android:name="org.mosad.teapod.ui.fragments.SearchFragment"
android:name="org.mosad.teapod.activity.main.fragments.SearchFragment"
android:label="@string/title_search"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/navigation_account"
android:name="org.mosad.teapod.ui.fragments.AccountFragment"
android:name="org.mosad.teapod.activity.main.fragments.AccountFragment"
android:label="@string/title_account"
tools:layout="@layout/fragment_account" />

@ -56,6 +56,16 @@
<string name="episodes">Folgen</string>
<string name="episode">Folge</string>
<!-- Onboarding -->
<string name="skip">Überspringen</string>
<string name="next">Weiter</string>
<string name="start">Fertig</string>
<string name="on_welcome">Willkommen!\nTeapod ist eine inoffizielle App für AoD.</string>
<string name="on_get_started">Los geht\'s</string>
<string name="on_login_heading">Login</string>
<string name="on_login_desc">Um Teapod verwenden zu können musst du dich mit deinem AoD Account anmelden. Deine Login-Daten werden verschlüsselt auf deinem Gerät gespeichert.</string>
<string name="on_login_failed">Login nicht erfolgreich! Stelle sicher das deine Login-Daten korrekt sind und versuche es erneut.</string>
<!-- dialogs -->
<string name="save">speichern</string>
<string name="cancel">@android:string/cancel</string>

@ -72,6 +72,16 @@
<string name="episodes">Episodes</string>
<string name="episode">Episode</string>
<!-- Onboarding -->
<string name="skip">Skip</string>
<string name="next">Next</string>
<string name="start">Start</string>
<string name="on_welcome">Welcome!\nTeapod is an unofficial App for AoD.</string>
<string name="on_get_started">Get started</string>
<string name="on_login_heading">Login</string>
<string name="on_login_desc">To use Teapod you need to log in with your AoD account. Your Login-Data will be stored encrypted on your device.</string>
<string name="on_login_failed">Could not login! Make sure Username and Password are correct and try again.</string>
<!-- dialogs -->
<string name="save">save</string>
<string name="cancel">@android:string/cancel</string>
@ -81,7 +91,7 @@
<!-- etc -->
<string name="login">Login</string>
<string name="login_desc">You need to login before you can use Teapod. The Login-Data will be stored encrypted on your device.</string>
<string name="login_failed_desc">Could not login. Please try again.</string>
<string name="login_failed_desc"> Please try again.</string>
<string name="password">Password</string>
<!-- save keys -->

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close