add tv shows support to parser, start implementing account fragment
This commit is contained in:
		| @ -14,6 +14,7 @@ android { | ||||
|         versionName "0.1-alpha1" | ||||
|  | ||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||||
|         resValue "string", "build_time", buildTime() | ||||
|         setProperty("archivesBaseName", "teapod-$versionName") | ||||
|     } | ||||
|  | ||||
| @ -63,3 +64,7 @@ dependencies { | ||||
|     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!") | ||||
|  | ||||
|             LoginDialog(this).positiveButton { | ||||
|                 EncryptedPreferences.saveCredentials(email, password, context) | ||||
|                 EncryptedPreferences.saveCredentials(login, password, context) | ||||
|             }.negativeButton { | ||||
|                 Log.i(javaClass.name, "Login canceled, exiting.") | ||||
|                 finish() | ||||
| @ -88,17 +88,14 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS | ||||
|     } | ||||
|  | ||||
|     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 { | ||||
|             add(R.id.nav_host_fragment, mediaFragment, "MediaFragment") | ||||
|             addToBackStack(null) | ||||
|             show(mediaFragment) | ||||
|         } | ||||
|  | ||||
|         println("visible !!!: " + mediaFragment.isVisible) | ||||
|         println(supportFragmentManager.backStackEntryCount) | ||||
|     } | ||||
|  | ||||
|     fun startPlayer(streamUrl: String) { | ||||
|  | ||||
| @ -1,11 +1,15 @@ | ||||
| package org.mosad.teapod.parser | ||||
|  | ||||
| import android.util.Log | ||||
| import com.google.gson.JsonParser | ||||
| import kotlinx.coroutines.* | ||||
| import org.jsoup.Connection | ||||
| import org.jsoup.Jsoup | ||||
| import org.mosad.teapod.preferences.EncryptedPreferences | ||||
| import org.mosad.teapod.util.DataTypes.MediaType | ||||
| import org.mosad.teapod.util.GUIMedia | ||||
| import org.mosad.teapod.util.StreamMedia | ||||
| import kotlin.collections.ArrayList | ||||
|  | ||||
| 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 { | ||||
|         if (sessionCookies.isEmpty()) login() | ||||
|  | ||||
| @ -92,12 +98,12 @@ class AoDParser { | ||||
|     /** | ||||
|      * load streams for the media path | ||||
|      */ | ||||
|     fun loadStreams(mediaPath: String): List<String> = runBlocking { | ||||
|     fun loadStreams(mediaPath: String): StreamMedia = runBlocking { | ||||
|         if (sessionCookies.isEmpty()) login() | ||||
|  | ||||
|         if (!loginSuccess) { | ||||
|             println("please log in") // TODO | ||||
|             return@runBlocking listOf() | ||||
|             return@runBlocking StreamMedia(MediaType.OTHER) | ||||
|         } | ||||
|  | ||||
|         withContext(Dispatchers.Default) { | ||||
| @ -114,14 +120,20 @@ class AoDParser { | ||||
|             //println("first entry: ${playlists.first()}") | ||||
|             //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 | ||||
|      */ | ||||
|     private fun loadStreamInfo(playlistPath: String, csrfToken: String): List<String> = runBlocking { | ||||
|     private fun loadStreamInfo(playlistPath: String, csrfToken: String, type: MediaType): StreamMedia = runBlocking { | ||||
|         withContext(Dispatchers.Default) { | ||||
|             val headers = mutableMapOf( | ||||
|                 Pair("Accept", "application/json, text/javascript, */*; q=0.01"), | ||||
| @ -139,13 +151,37 @@ class AoDParser { | ||||
|  | ||||
|             //println(res.body()) | ||||
|  | ||||
|             // TODO if it's a series there sources for each episode | ||||
|             val sources = JsonParser.parseString(res.body()).asJsonObject | ||||
|                 .get("playlist").asJsonArray.first().asJsonObject | ||||
|                 .get("sources").asJsonArray | ||||
|             println(type) | ||||
|             return@withContext when (type) { | ||||
|                 MediaType.MOVIE -> { | ||||
|                     val movie = JsonParser.parseString(res.body()).asJsonObject | ||||
|                         .get("playlist").asJsonArray | ||||
|  | ||||
|             return@withContext sources.toList().map { | ||||
|                 it.asJsonObject.get("file").asString | ||||
|                     val streamList = arrayListOf<String>() | ||||
|                     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 | ||||
|  | ||||
| import android.os.Bundle | ||||
| import android.util.Log | ||||
| import androidx.fragment.app.Fragment | ||||
| import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import android.widget.ArrayAdapter | ||||
| import com.bumptech.glide.Glide | ||||
| import kotlinx.android.synthetic.main.fragment_media.* | ||||
| import org.mosad.teapod.MainActivity | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.util.DataTypes.MediaType | ||||
| import org.mosad.teapod.util.GUIMedia | ||||
| import java.net.URL | ||||
| import java.net.URLEncoder | ||||
| import org.mosad.teapod.util.StreamMedia | ||||
|  | ||||
| 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? { | ||||
|         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?) { | ||||
|         super.onViewCreated(view, savedInstanceState) | ||||
|  | ||||
|         // load poster | ||||
|         Glide.with(requireContext()).load(media.posterLink).into(image_poster) | ||||
|         text_title.text = media.title | ||||
|         text_desc.text = media.shortDesc | ||||
|         // generic gui | ||||
|         Glide.with(requireContext()).load(guiMedia.posterLink).into(image_poster) | ||||
|         text_title.text = guiMedia.title | ||||
|         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() | ||||
|     } | ||||
|  | ||||
|     private fun initActions() { | ||||
|         button_play.setOnClickListener { onClickButtonPlay() } | ||||
|         button_play.setOnClickListener { | ||||
|             onClickButtonPlay() | ||||
|         } | ||||
|  | ||||
|         list_episodes.setOnItemClickListener { _, _, position, _ -> | ||||
|             playStream(streamMedia.streams[position]) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     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 | ||||
|         mainActivity.startPlayer(streams.first()) | ||||
|         mainActivity.startPlayer(url) | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -5,8 +5,12 @@ import android.view.LayoutInflater | ||||
| import android.view.View | ||||
| import android.view.ViewGroup | ||||
| import androidx.fragment.app.Fragment | ||||
| import com.afollestad.materialdialogs.MaterialDialog | ||||
| import kotlinx.android.synthetic.main.fragment_account.* | ||||
| import org.mosad.teapod.BuildConfig | ||||
| import org.mosad.teapod.R | ||||
| import org.mosad.teapod.preferences.EncryptedPreferences | ||||
| import org.mosad.teapod.ui.components.LoginDialog | ||||
|  | ||||
| class AccountFragment : Fragment() { | ||||
|  | ||||
| @ -17,6 +21,27 @@ class AccountFragment : Fragment() { | ||||
|     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||
|         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.widget.EditText | ||||
| 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.setPeekHeight | ||||
| import com.afollestad.materialdialogs.customview.customView | ||||
| @ -40,7 +38,7 @@ class LoginDialog(val context: Context) { | ||||
|     private val editTextLogin: EditText | ||||
|     private val editTextPassword: EditText | ||||
|  | ||||
|     var email = "" | ||||
|     var login = "" | ||||
|     var password = "" | ||||
|  | ||||
|     init { | ||||
| @ -61,7 +59,7 @@ class LoginDialog(val context: Context) { | ||||
|  | ||||
|     fun positiveButton(func: LoginDialog.() -> Unit): LoginDialog = apply { | ||||
|         dialog.positiveButton { | ||||
|             email = editTextLogin.text.toString() | ||||
|             login = editTextLogin.text.toString() | ||||
|             password = editTextPassword.text.toString() | ||||
|  | ||||
|             func() | ||||
| @ -81,7 +79,7 @@ class LoginDialog(val context: Context) { | ||||
|     fun show(func: LoginDialog.() -> Unit): LoginDialog = apply { | ||||
|         func() | ||||
|  | ||||
|         editTextLogin.setText(email) | ||||
|         editTextLogin.setText(login) | ||||
|         editTextPassword.setText(password) | ||||
|  | ||||
|         show() | ||||
|  | ||||
| @ -19,7 +19,5 @@ class HomeFragment : Fragment() { | ||||
|         super.onViewCreated(view, savedInstanceState) | ||||
|  | ||||
|         text_home.text = "This is the home fragment" | ||||
|  | ||||
|         println("HomeFragment created") | ||||
|     } | ||||
| } | ||||
| @ -48,10 +48,8 @@ class SearchFragment : Fragment() { | ||||
|             } | ||||
|  | ||||
|             override fun onQueryTextChange(newText: String?): Boolean { | ||||
|                 println("new text is: $newText") | ||||
|                 adapter.filter.filter(newText) | ||||
|                 adapter.notifyDataSetChanged() | ||||
|  | ||||
|                 return false | ||||
|             } | ||||
|         }) | ||||
|  | ||||
| @ -20,10 +20,6 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<G | ||||
|     private var filteredMedia = originalMedia.map { it.copy() } | ||||
|     private val customFilter = CustomFilter() | ||||
|  | ||||
|     init { | ||||
|         println("initial filtered size is: ${filteredMedia.size}") | ||||
|     } | ||||
|  | ||||
|     override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { | ||||
|         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.count = filteredList.size | ||||
|  | ||||
|             println("filtered size is: ${results.count}") | ||||
|  | ||||
|             return results | ||||
|         } | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,17 @@ | ||||
| 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) { | ||||
|     override fun toString(): String { | ||||
|         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" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="#fafafa" | ||||
|     android:background="#f5f5f5" | ||||
|     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 | ||||
|                     android:id="@+id/text_account" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content" | ||||
|         android:layout_marginStart="8dp" | ||||
|         android:layout_marginTop="8dp" | ||||
|         android:layout_marginEnd="8dp" | ||||
|         android:textAlignment="center" | ||||
|         android:textSize="20sp" | ||||
|         app:layout_constraintBottom_toBottomOf="parent" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintTop_toTopOf="parent" /> | ||||
|                     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> | ||||
| @ -4,7 +4,7 @@ | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="#fafafa" | ||||
|     android:background="#f5f5f5" | ||||
|     tools:context=".ui.home.HomeFragment"> | ||||
|  | ||||
|     <TextView | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="#fafafa" | ||||
|     android:background="#f5f5f5" | ||||
|     tools:context=".ui.library.LibraryFragment"> | ||||
|  | ||||
|     <ListView | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="#fafafa" | ||||
|     android:background="#f5f5f5" | ||||
|     tools:context=".ui.MediaFragment"> | ||||
|  | ||||
|     <androidx.constraintlayout.widget.ConstraintLayout | ||||
| @ -24,11 +24,21 @@ | ||||
|         <Button | ||||
|             android:id="@+id/button_play" | ||||
|             android:layout_width="0dp" | ||||
|             android:layout_height="48dp" | ||||
|             android:layout_height="wrap_content" | ||||
|             android:layout_marginStart="7dp" | ||||
|             android:layout_marginTop="25dp" | ||||
|             android:layout_marginTop="24dp" | ||||
|             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_constraintStart_toStartOf="parent" | ||||
|             app:layout_constraintTop_toBottomOf="@+id/image_poster" /> | ||||
| @ -57,5 +67,13 @@ | ||||
|             app:layout_constraintEnd_toEndOf="parent" | ||||
|             app:layout_constraintStart_toStartOf="parent" | ||||
|             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> | ||||
| </FrameLayout> | ||||
| @ -4,7 +4,7 @@ | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:background="#fafafa" | ||||
|     android:background="#f5f5f5" | ||||
|     tools:context=".ui.search.SearchFragment"> | ||||
|  | ||||
|     <SearchView | ||||
|  | ||||
| @ -8,6 +8,18 @@ | ||||
|     <!-- search fragment --> | ||||
|     <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 --> | ||||
|     <string name="save">save</string> | ||||
|     <string name="cancel">@android:string/cancel</string> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user