add tv shows support to parser, start implementing account fragment
This commit is contained in:
		| @ -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()) | ||||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_info_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_info_24.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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> | ||||||
							
								
								
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_play_arrow_24.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								app/src/main/res/drawable/ic_baseline_play_arrow_24.xml
									
									
									
									
									
										Normal file
									
								
							| @ -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"> | ||||||
|  |  | ||||||
|     <TextView |     <ScrollView | ||||||
|         android:id="@+id/text_account" |  | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="match_parent"> | ||||||
|         android:layout_marginStart="8dp" |  | ||||||
|         android:layout_marginTop="8dp" |         <LinearLayout | ||||||
|         android:layout_marginEnd="8dp" |             android:layout_width="match_parent" | ||||||
|         android:textAlignment="center" |             android:layout_height="wrap_content" | ||||||
|         android:textSize="20sp" |             android:orientation="vertical"> | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |  | ||||||
|         app:layout_constraintEnd_toEndOf="parent" |             <LinearLayout | ||||||
|         app:layout_constraintStart_toStartOf="parent" |                 android:id="@+id/linear_account" | ||||||
|         app:layout_constraintTop_toTopOf="parent" /> |                 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_account" | ||||||
|  |                     android:layout_width="match_parent" | ||||||
|  |                     android:layout_height="wrap_content" | ||||||
|  |                     android:paddingStart="7dp" | ||||||
|  |                     android:paddingEnd="7dp" | ||||||
|  |                     android:text="@string/account" | ||||||
|  |                     android:textColor="@android:color/primary_text_light" | ||||||
|  |                     android:textSize="16sp" | ||||||
|  |                     android:textStyle="bold" /> | ||||||
|  |  | ||||||
|  |                 <LinearLayout | ||||||
|  |                     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> | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user