add tv shows support to parser, start implementing account fragment
This commit is contained in:
parent
b27a218b51
commit
7b708f5aa0
|
@ -14,6 +14,7 @@ android {
|
||||||
versionName "0.1-alpha1"
|
versionName "0.1-alpha1"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
resValue "string", "build_time", buildTime()
|
||||||
setProperty("archivesBaseName", "teapod-$versionName")
|
setProperty("archivesBaseName", "teapod-$versionName")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,3 +64,7 @@ dependencies {
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static def buildTime() {
|
||||||
|
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
|
||||||
|
}
|
|
@ -79,7 +79,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
||||||
Log.i(javaClass.name, "please login!")
|
Log.i(javaClass.name, "please login!")
|
||||||
|
|
||||||
LoginDialog(this).positiveButton {
|
LoginDialog(this).positiveButton {
|
||||||
EncryptedPreferences.saveCredentials(email, password, context)
|
EncryptedPreferences.saveCredentials(login, password, context)
|
||||||
}.negativeButton {
|
}.negativeButton {
|
||||||
Log.i(javaClass.name, "Login canceled, exiting.")
|
Log.i(javaClass.name, "Login canceled, exiting.")
|
||||||
finish()
|
finish()
|
||||||
|
@ -88,17 +88,14 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showDetailFragment(media: GUIMedia) {
|
fun showDetailFragment(media: GUIMedia) {
|
||||||
val streams = AoDParser().loadStreams(media.link) // load the streams for the selected media
|
val streamMedia = AoDParser().loadStreams(media.link) // load the streams for the selected media
|
||||||
|
|
||||||
val mediaFragment = MediaFragment(media, streams)
|
val mediaFragment = MediaFragment(media, streamMedia)
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.commit {
|
||||||
add(R.id.nav_host_fragment, mediaFragment, "MediaFragment")
|
add(R.id.nav_host_fragment, mediaFragment, "MediaFragment")
|
||||||
addToBackStack(null)
|
addToBackStack(null)
|
||||||
show(mediaFragment)
|
show(mediaFragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
println("visible !!!: " + mediaFragment.isVisible)
|
|
||||||
println(supportFragmentManager.backStackEntryCount)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startPlayer(streamUrl: String) {
|
fun startPlayer(streamUrl: String) {
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package org.mosad.teapod.parser
|
package org.mosad.teapod.parser
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import org.jsoup.Connection
|
import org.jsoup.Connection
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.mosad.teapod.preferences.EncryptedPreferences
|
import org.mosad.teapod.preferences.EncryptedPreferences
|
||||||
|
import org.mosad.teapod.util.DataTypes.MediaType
|
||||||
import org.mosad.teapod.util.GUIMedia
|
import org.mosad.teapod.util.GUIMedia
|
||||||
|
import org.mosad.teapod.util.StreamMedia
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class AoDParser {
|
class AoDParser {
|
||||||
|
|
||||||
|
@ -60,7 +64,9 @@ class AoDParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.anime-on-demand.de/animes
|
/**
|
||||||
|
* list all animes from the website
|
||||||
|
*/
|
||||||
fun listAnimes(): ArrayList<GUIMedia> = runBlocking {
|
fun listAnimes(): ArrayList<GUIMedia> = runBlocking {
|
||||||
if (sessionCookies.isEmpty()) login()
|
if (sessionCookies.isEmpty()) login()
|
||||||
|
|
||||||
|
@ -92,12 +98,12 @@ class AoDParser {
|
||||||
/**
|
/**
|
||||||
* load streams for the media path
|
* load streams for the media path
|
||||||
*/
|
*/
|
||||||
fun loadStreams(mediaPath: String): List<String> = runBlocking {
|
fun loadStreams(mediaPath: String): StreamMedia = runBlocking {
|
||||||
if (sessionCookies.isEmpty()) login()
|
if (sessionCookies.isEmpty()) login()
|
||||||
|
|
||||||
if (!loginSuccess) {
|
if (!loginSuccess) {
|
||||||
println("please log in") // TODO
|
println("please log in") // TODO
|
||||||
return@runBlocking listOf()
|
return@runBlocking StreamMedia(MediaType.OTHER)
|
||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
|
@ -114,14 +120,20 @@ class AoDParser {
|
||||||
//println("first entry: ${playlists.first()}")
|
//println("first entry: ${playlists.first()}")
|
||||||
//println("csrf token is: $csrfToken")
|
//println("csrf token is: $csrfToken")
|
||||||
|
|
||||||
return@withContext loadStreamInfo(playlists.first(), csrfToken)
|
val type = if (res.select("h2").eachText().filter { it == "Episoden" }.any()) {
|
||||||
|
MediaType.TVSHOW
|
||||||
|
} else {
|
||||||
|
MediaType.MOVIE
|
||||||
|
}
|
||||||
|
|
||||||
|
return@withContext loadStreamInfo(playlists.first(), csrfToken, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load the playlist path and parse it, read the stream info from json
|
* load the playlist path and parse it, read the stream info from json
|
||||||
*/
|
*/
|
||||||
private fun loadStreamInfo(playlistPath: String, csrfToken: String): List<String> = runBlocking {
|
private fun loadStreamInfo(playlistPath: String, csrfToken: String, type: MediaType): StreamMedia = runBlocking {
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val headers = mutableMapOf(
|
val headers = mutableMapOf(
|
||||||
Pair("Accept", "application/json, text/javascript, */*; q=0.01"),
|
Pair("Accept", "application/json, text/javascript, */*; q=0.01"),
|
||||||
|
@ -139,13 +151,37 @@ class AoDParser {
|
||||||
|
|
||||||
//println(res.body())
|
//println(res.body())
|
||||||
|
|
||||||
// TODO if it's a series there sources for each episode
|
println(type)
|
||||||
val sources = JsonParser.parseString(res.body()).asJsonObject
|
return@withContext when (type) {
|
||||||
.get("playlist").asJsonArray.first().asJsonObject
|
MediaType.MOVIE -> {
|
||||||
.get("sources").asJsonArray
|
val movie = JsonParser.parseString(res.body()).asJsonObject
|
||||||
|
.get("playlist").asJsonArray
|
||||||
|
|
||||||
return@withContext sources.toList().map {
|
val streamList = arrayListOf<String>()
|
||||||
it.asJsonObject.get("file").asString
|
movie.first().asJsonObject.get("sources").asJsonArray.toList().forEach {
|
||||||
|
streamList.add(it.asJsonObject.get("file").asString)
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamMedia(MediaType.MOVIE, streamList)
|
||||||
|
}
|
||||||
|
MediaType.TVSHOW -> {
|
||||||
|
val episodes = JsonParser.parseString(res.body()).asJsonObject
|
||||||
|
.get("playlist").asJsonArray
|
||||||
|
|
||||||
|
val streamList = arrayListOf<String>()
|
||||||
|
episodes.forEach {
|
||||||
|
val streamUrl = it.asJsonObject.get("sources").asJsonArray
|
||||||
|
.first().asJsonObject
|
||||||
|
.get("file").asString
|
||||||
|
streamList.add(streamUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamMedia(MediaType.TVSHOW, streamList)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Log.e(javaClass.name, "Wrong Type, please report this issue.")
|
||||||
|
StreamMedia(MediaType.OTHER)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
package org.mosad.teapod.ui
|
package org.mosad.teapod.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import kotlinx.android.synthetic.main.fragment_media.*
|
import kotlinx.android.synthetic.main.fragment_media.*
|
||||||
import org.mosad.teapod.MainActivity
|
import org.mosad.teapod.MainActivity
|
||||||
import org.mosad.teapod.R
|
import org.mosad.teapod.R
|
||||||
|
import org.mosad.teapod.util.DataTypes.MediaType
|
||||||
import org.mosad.teapod.util.GUIMedia
|
import org.mosad.teapod.util.GUIMedia
|
||||||
import java.net.URL
|
import org.mosad.teapod.util.StreamMedia
|
||||||
import java.net.URLEncoder
|
|
||||||
|
|
||||||
class MediaFragment(val media: GUIMedia, val streams: List<String>) : Fragment() {
|
class MediaFragment(private val guiMedia: GUIMedia, private val streamMedia: StreamMedia) : Fragment() {
|
||||||
|
|
||||||
|
private lateinit var adapterEpisodes: ArrayAdapter<String>
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_media, container, false)
|
return inflater.inflate(R.layout.fragment_media, container, false)
|
||||||
|
@ -22,25 +26,51 @@ class MediaFragment(val media: GUIMedia, val streams: List<String>) : Fragment()
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
// load poster
|
// generic gui
|
||||||
Glide.with(requireContext()).load(media.posterLink).into(image_poster)
|
Glide.with(requireContext()).load(guiMedia.posterLink).into(image_poster)
|
||||||
text_title.text = media.title
|
text_title.text = guiMedia.title
|
||||||
text_desc.text = media.shortDesc
|
text_desc.text = guiMedia.shortDesc
|
||||||
|
|
||||||
println("media streams: $streams")
|
// specific gui
|
||||||
|
if (streamMedia.type == MediaType.TVSHOW) {
|
||||||
|
val episodes = streamMedia.streams.mapIndexed { index, _ ->
|
||||||
|
"${guiMedia.title} - Ep. ${index + 1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
adapterEpisodes = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_1, episodes)
|
||||||
|
list_episodes.adapter = adapterEpisodes
|
||||||
|
|
||||||
|
} else if (streamMedia.type == MediaType.MOVIE) {
|
||||||
|
list_episodes.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
println("media streams: ${streamMedia.streams}")
|
||||||
|
|
||||||
initActions()
|
initActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initActions() {
|
private fun initActions() {
|
||||||
button_play.setOnClickListener { onClickButtonPlay() }
|
button_play.setOnClickListener {
|
||||||
|
onClickButtonPlay()
|
||||||
|
}
|
||||||
|
|
||||||
|
list_episodes.setOnItemClickListener { _, _, position, _ ->
|
||||||
|
playStream(streamMedia.streams[position])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onClickButtonPlay() {
|
private fun onClickButtonPlay() {
|
||||||
println("play ${streams.first()}")
|
when (streamMedia.type) {
|
||||||
|
MediaType.MOVIE -> playStream(streamMedia.streams.first())
|
||||||
|
MediaType.TVSHOW -> playStream(streamMedia.streams.first())
|
||||||
|
MediaType.OTHER -> Log.e(javaClass.name, "Wrong Type, please report this issue.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun playStream(url: String) {
|
||||||
val mainActivity = activity as MainActivity
|
val mainActivity = activity as MainActivity
|
||||||
mainActivity.startPlayer(streams.first())
|
mainActivity.startPlayer(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,8 +5,12 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import kotlinx.android.synthetic.main.fragment_account.*
|
import kotlinx.android.synthetic.main.fragment_account.*
|
||||||
|
import org.mosad.teapod.BuildConfig
|
||||||
import org.mosad.teapod.R
|
import org.mosad.teapod.R
|
||||||
|
import org.mosad.teapod.preferences.EncryptedPreferences
|
||||||
|
import org.mosad.teapod.ui.components.LoginDialog
|
||||||
|
|
||||||
class AccountFragment : Fragment() {
|
class AccountFragment : Fragment() {
|
||||||
|
|
||||||
|
@ -17,6 +21,27 @@ class AccountFragment : Fragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
text_account.text = "This is the Account Fragment"
|
text_account_login.text = EncryptedPreferences.login
|
||||||
|
text_info_about_desc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time))
|
||||||
|
|
||||||
|
initActions()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initActions() {
|
||||||
|
linear_account_login.setOnClickListener {
|
||||||
|
LoginDialog(requireContext()).positiveButton {
|
||||||
|
EncryptedPreferences.saveCredentials(login, password, context)
|
||||||
|
}.show {
|
||||||
|
login = EncryptedPreferences.login
|
||||||
|
password = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
linear_about.setOnClickListener {
|
||||||
|
MaterialDialog(requireContext())
|
||||||
|
.title(R.string.info_about)
|
||||||
|
.message(R.string.info_about_dialog)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,8 +25,6 @@ package org.mosad.teapod.ui.components
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.WhichButton
|
|
||||||
import com.afollestad.materialdialogs.actions.getActionButton
|
|
||||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||||
import com.afollestad.materialdialogs.bottomsheets.setPeekHeight
|
import com.afollestad.materialdialogs.bottomsheets.setPeekHeight
|
||||||
import com.afollestad.materialdialogs.customview.customView
|
import com.afollestad.materialdialogs.customview.customView
|
||||||
|
@ -40,7 +38,7 @@ class LoginDialog(val context: Context) {
|
||||||
private val editTextLogin: EditText
|
private val editTextLogin: EditText
|
||||||
private val editTextPassword: EditText
|
private val editTextPassword: EditText
|
||||||
|
|
||||||
var email = ""
|
var login = ""
|
||||||
var password = ""
|
var password = ""
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -61,7 +59,7 @@ class LoginDialog(val context: Context) {
|
||||||
|
|
||||||
fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
||||||
dialog.positiveButton {
|
dialog.positiveButton {
|
||||||
email = editTextLogin.text.toString()
|
login = editTextLogin.text.toString()
|
||||||
password = editTextPassword.text.toString()
|
password = editTextPassword.text.toString()
|
||||||
|
|
||||||
func()
|
func()
|
||||||
|
@ -81,7 +79,7 @@ class LoginDialog(val context: Context) {
|
||||||
fun show(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
fun show(func: LoginDialog.() -> Unit): LoginDialog = apply {
|
||||||
func()
|
func()
|
||||||
|
|
||||||
editTextLogin.setText(email)
|
editTextLogin.setText(login)
|
||||||
editTextPassword.setText(password)
|
editTextPassword.setText(password)
|
||||||
|
|
||||||
show()
|
show()
|
||||||
|
|
|
@ -19,7 +19,5 @@ class HomeFragment : Fragment() {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
text_home.text = "This is the home fragment"
|
text_home.text = "This is the home fragment"
|
||||||
|
|
||||||
println("HomeFragment created")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -48,10 +48,8 @@ class SearchFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String?): Boolean {
|
override fun onQueryTextChange(newText: String?): Boolean {
|
||||||
println("new text is: $newText")
|
|
||||||
adapter.filter.filter(newText)
|
adapter.filter.filter(newText)
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,10 +20,6 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<G
|
||||||
private var filteredMedia = originalMedia.map { it.copy() }
|
private var filteredMedia = originalMedia.map { it.copy() }
|
||||||
private val customFilter = CustomFilter()
|
private val customFilter = CustomFilter()
|
||||||
|
|
||||||
init {
|
|
||||||
println("initial filtered size is: ${filteredMedia.size}")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.linear_media, parent, false)
|
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.linear_media, parent, false)
|
||||||
|
|
||||||
|
@ -68,8 +64,6 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<G
|
||||||
results.values = filteredList
|
results.values = filteredList
|
||||||
results.count = filteredList.size
|
results.count = filteredList.size
|
||||||
|
|
||||||
println("filtered size is: ${results.count}")
|
|
||||||
|
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
package org.mosad.teapod.util
|
package org.mosad.teapod.util
|
||||||
|
|
||||||
|
class DataTypes {
|
||||||
|
enum class MediaType {
|
||||||
|
OTHER,
|
||||||
|
MOVIE,
|
||||||
|
TVSHOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class GUIMedia(val title: String, val posterLink: String, val shortDesc : String, val link: String) {
|
data class GUIMedia(val title: String, val posterLink: String, val shortDesc : String, val link: String) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class StreamMedia(val type: DataTypes.MediaType, val streams: ArrayList<String> = arrayListOf())
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M8,5v14l11,-7z"/>
|
||||||
|
</vector>
|
|
@ -4,20 +4,144 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fafafa"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.account.AccountFragment">
|
tools:context=".ui.account.AccountFragment">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_account"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:background="#ffffff"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_account"
|
android:id="@+id/text_account"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:paddingStart="7dp"
|
||||||
android:layout_marginTop="8dp"
|
android:paddingEnd="7dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:text="@string/account"
|
||||||
android:textAlignment="center"
|
android:textColor="@android:color/primary_text_light"
|
||||||
android:textSize="20sp"
|
android:textSize="16sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:textStyle="bold" />
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
<LinearLayout
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:id="@+id/linear_account_login"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:contentDescription="@string/account"
|
||||||
|
android:minWidth="48dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/ic_baseline_account_box_24"
|
||||||
|
app:srcCompat="@drawable/ic_baseline_account_box_24" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_account_login"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/account_login_ex"
|
||||||
|
android:textColor="@android:color/primary_text_light"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_account_login_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/account_login_desc"
|
||||||
|
android:textColor="@android:color/secondary_text_light" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:background="#ffffff"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_info"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingStart="7dp"
|
||||||
|
android:paddingEnd="7dp"
|
||||||
|
android:text="@string/info"
|
||||||
|
android:textColor="@android:color/primary_text_light"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_about"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="48dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
app:srcCompat="@drawable/ic_baseline_info_24" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_info_about"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/info_about"
|
||||||
|
android:textColor="@android:color/primary_text_light"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_info_about_desc"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/info_about_desc"
|
||||||
|
android:textColor="@android:color/secondary_text_light" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fafafa"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.home.HomeFragment">
|
tools:context=".ui.home.HomeFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fafafa"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.library.LibraryFragment">
|
tools:context=".ui.library.LibraryFragment">
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fafafa"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.MediaFragment">
|
tools:context=".ui.MediaFragment">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
@ -24,11 +24,21 @@
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_play"
|
android:id="@+id/button_play"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="7dp"
|
android:layout_marginStart="7dp"
|
||||||
android:layout_marginTop="25dp"
|
android:layout_marginTop="24dp"
|
||||||
android:layout_marginEnd="7dp"
|
android:layout_marginEnd="7dp"
|
||||||
android:text="Play"
|
android:background="#4A4141"
|
||||||
|
android:drawableStart="@drawable/ic_baseline_play_arrow_24"
|
||||||
|
android:drawablePadding="10dp"
|
||||||
|
android:drawableTint="#FFFFFF"
|
||||||
|
android:gravity="left|center_vertical"
|
||||||
|
android:paddingStart="160dp"
|
||||||
|
android:paddingEnd="160dp"
|
||||||
|
android:text="@string/button_play"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textColor="@android:color/primary_text_dark"
|
||||||
|
android:textSize="16sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/image_poster" />
|
app:layout_constraintTop_toBottomOf="@+id/image_poster" />
|
||||||
|
@ -57,5 +67,13 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/text_title" />
|
app:layout_constraintTop_toBottomOf="@+id/text_title" />
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/list_episodes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="17dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/text_desc" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#fafafa"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.search.SearchFragment">
|
tools:context=".ui.search.SearchFragment">
|
||||||
|
|
||||||
<SearchView
|
<SearchView
|
||||||
|
|
|
@ -8,6 +8,18 @@
|
||||||
<!-- search fragment -->
|
<!-- search fragment -->
|
||||||
<string name="search_hint">Search for movies and series</string>
|
<string name="search_hint">Search for movies and series</string>
|
||||||
|
|
||||||
|
<!-- media fragment -->
|
||||||
|
<string name="button_play">Play</string>
|
||||||
|
|
||||||
|
<!-- settings fragment -->
|
||||||
|
<string name="account">Account</string>
|
||||||
|
<string name="account_login_ex">user@example.com</string>
|
||||||
|
<string name="account_login_desc">Tap to edit</string>
|
||||||
|
<string name="info">Info</string>
|
||||||
|
<string name="info_about">Teapod by @Seil0</string>
|
||||||
|
<string name="info_about_desc" translatable="false">Version %1$s (%2$s)</string>
|
||||||
|
<string name="info_about_dialog" translatable="false">This software is published under the terms and conditions of GPL 3. For further information visit git.mosad.xyz/Seil0 \n\n© 2020 seil0@mosad.xyz</string>
|
||||||
|
|
||||||
<!-- dialogs -->
|
<!-- dialogs -->
|
||||||
<string name="save">save</string>
|
<string name="save">save</string>
|
||||||
<string name="cancel">@android:string/cancel</string>
|
<string name="cancel">@android:string/cancel</string>
|
||||||
|
|
Loading…
Reference in New Issue