Browse Source

Several improvements in UI (better colors for night mode, added icons).

Better handling of startup (login activity would reset if put in the background).
Allow use of schemeless hostname for login.
Destroy main activity and clear cache on logout.
Change of endpoint for favorites retrieval for one with much better performance.
housekeeping/remove-warnings
Antoine POPINEAU 5 years ago
parent
commit
e84455390b
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
  1. 17
      app/src/main/AndroidManifest.xml
  2. 28
      app/src/main/java/com/github/apognu/otter/activities/LoginActivity.kt
  3. 26
      app/src/main/java/com/github/apognu/otter/activities/MainActivity.kt
  4. 6
      app/src/main/java/com/github/apognu/otter/activities/SettingsActivity.kt
  5. 29
      app/src/main/java/com/github/apognu/otter/activities/SplashActivity.kt
  6. 24
      app/src/main/java/com/github/apognu/otter/adapters/FavoritesAdapter.kt
  7. 5
      app/src/main/java/com/github/apognu/otter/fragments/FavoritesFragment.kt
  8. 22
      app/src/main/java/com/github/apognu/otter/repositories/FavoritesRepository.kt
  9. 16
      app/src/main/java/com/github/apognu/otter/repositories/PlaylistTracksRepository.kt
  10. 9
      app/src/main/java/com/github/apognu/otter/repositories/SearchRepository.kt
  11. 9
      app/src/main/java/com/github/apognu/otter/repositories/TracksRepository.kt
  12. 12
      app/src/main/java/com/github/apognu/otter/utils/Models.kt
  13. 9
      app/src/main/res/drawable/brightness.xml
  14. 9
      app/src/main/res/drawable/logout.xml
  15. 9
      app/src/main/res/drawable/quality.xml
  16. 9
      app/src/main/res/drawable/storage.xml
  17. 5
      app/src/main/res/layout/activity_login.xml
  18. 8
      app/src/main/res/values-night/colors.xml
  19. 4
      app/src/main/res/values/colors.xml
  20. 8
      app/src/main/res/values/styles.xml
  21. 5
      app/src/main/res/xml/settings.xml

17
app/src/main/AndroidManifest.xml

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.apognu.otter">
<uses-permission android:name="android.permission.INTERNET" />
@ -14,15 +13,18 @@ @@ -14,15 +13,18 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:screenOrientation="portrait"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!-- <meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.android.exoplayer2.ext.cast.DefaultCastOptionsProvider"/> -->
<activity android:name="com.github.apognu.otter.activities.LoginActivity" android:noHistory="true" android:launchMode="singleInstance">
<activity
android:name="com.github.apognu.otter.activities.SplashActivity"
android:launchMode="singleInstance"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
@ -31,8 +33,13 @@ @@ -31,8 +33,13 @@
</intent-filter>
</activity>
<activity
android:name="com.github.apognu.otter.activities.LoginActivity"
android:launchMode="singleInstance" />
<activity android:name="com.github.apognu.otter.activities.MainActivity" />
<activity android:name="com.github.apognu.otter.activities.SearchActivity" android:launchMode="singleTop"/>
<activity
android:name="com.github.apognu.otter.activities.SearchActivity"
android:launchMode="singleTop" />
<activity android:name="com.github.apognu.otter.activities.SettingsActivity" />
<activity android:name="com.github.apognu.otter.activities.LicencesActivity" />

28
app/src/main/java/com/github/apognu/otter/activities/LoginActivity.kt

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
package com.github.apognu.otter.activities
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.LoginDialog
@ -19,34 +19,30 @@ import kotlinx.coroutines.launch @@ -19,34 +19,30 @@ import kotlinx.coroutines.launch
data class FwCredentials(val token: String)
class LoginActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
getSharedPreferences(AppContext.PREFS_CREDENTIALS, Context.MODE_PRIVATE).apply {
when (contains("access_token")) {
true -> Intent(this@LoginActivity, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_ANIMATION
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
startActivity(this)
setContentView(R.layout.activity_login)
}
false -> setContentView(R.layout.activity_login)
}
}
override fun onResume() {
super.onResume()
login?.setOnClickListener {
val hostname = hostname.text.toString().trim()
var hostname = hostname.text.toString().trim()
val username = username.text.toString()
val password = password.text.toString()
try {
if (hostname.isEmpty()) throw Exception(getString(R.string.login_error_hostname))
val url = Uri.parse(hostname)
if (url.scheme != "https") {
Uri.parse(hostname).apply {
if (scheme == "http") {
throw Exception(getString(R.string.login_error_hostname_https))
}
if (scheme == null) hostname = "https://${hostname}"
}
} catch (e: Exception) {
val message =
if (e.message?.isEmpty() == true) getString(R.string.login_error_hostname)

26
app/src/main/java/com/github/apognu/otter/activities/MainActivity.kt

@ -19,6 +19,7 @@ import com.github.apognu.otter.fragments.BrowseFragment @@ -19,6 +19,7 @@ import com.github.apognu.otter.fragments.BrowseFragment
import com.github.apognu.otter.fragments.QueueFragment
import com.github.apognu.otter.playback.MediaControlsManager
import com.github.apognu.otter.playback.PlayerService
import com.github.apognu.otter.repositories.FavoritedRepository
import com.github.apognu.otter.repositories.FavoritesRepository
import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.*
@ -32,7 +33,12 @@ import kotlinx.coroutines.GlobalScope @@ -32,7 +33,12 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
enum class ResultCode(val code: Int) {
LOGOUT(1001)
}
private val favoriteRepository = FavoritesRepository(this)
private val favoriteCheckRepository = FavoritedRepository(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -127,12 +133,25 @@ class MainActivity : AppCompatActivity() { @@ -127,12 +133,25 @@ class MainActivity : AppCompatActivity() {
R.id.nav_queue -> launchDialog(QueueFragment())
R.id.nav_search -> startActivity(Intent(this, SearchActivity::class.java))
R.id.settings -> startActivity(Intent(this, SettingsActivity::class.java))
R.id.settings -> startActivityForResult(Intent(this, SettingsActivity::class.java), 0)
}
return true
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == ResultCode.LOGOUT.code) {
Intent(this, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
startActivity(this)
finish()
}
}
}
private fun launchFragment(fragment: Fragment) {
supportFragmentManager.fragments.lastOrNull()?.also { oldFragment ->
oldFragment.enterTransition = null
@ -235,11 +254,10 @@ class MainActivity : AppCompatActivity() { @@ -235,11 +254,10 @@ class MainActivity : AppCompatActivity() {
.centerCrop()
.into(now_playing_details_cover)
favoriteRepository.fetch().untilNetwork(IO) { favorites ->
favoriteCheckRepository.fetch().untilNetwork(IO) { favorites ->
GlobalScope.launch(Main) {
val favorites = favorites.map { it.track.id }
track.favorite = favorites.contains(track.id)
when (track.favorite) {
true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite))
false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground))

6
app/src/main/java/com/github/apognu/otter/activities/SettingsActivity.kt

@ -56,13 +56,11 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP @@ -56,13 +56,11 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
.setPositiveButton(android.R.string.yes) { _, _ ->
PowerPreference.getFileByName(AppContext.PREFS_CREDENTIALS).clear()
Intent(context, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
context.cacheDir.deleteRecursively()
startActivity(this)
activity?.setResult(MainActivity.ResultCode.LOGOUT.code)
activity?.finish()
}
}
.setNegativeButton(android.R.string.no, null)
.show()
}

29
app/src/main/java/com/github/apognu/otter/activities/SplashActivity.kt

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
package com.github.apognu.otter.activities
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.github.apognu.otter.utils.AppContext
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getSharedPreferences(AppContext.PREFS_CREDENTIALS, Context.MODE_PRIVATE).apply {
when (contains("access_token")) {
true -> Intent(this@SplashActivity, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_ANIMATION
startActivity(this)
}
false -> Intent(this@SplashActivity, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_ANIMATION
startActivity(this)
}
}
}
}
}

24
app/src/main/java/com/github/apognu/otter/adapters/FavoritesAdapter.kt

@ -18,7 +18,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation @@ -18,7 +18,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.row_track.view.*
import java.util.*
class FavoritesAdapter(private val context: Context?, private val favoriteListener: OnFavoriteListener, val fromQueue: Boolean = false) : FunkwhaleAdapter<Favorite, FavoritesAdapter.ViewHolder>() {
class FavoritesAdapter(private val context: Context?, private val favoriteListener: OnFavoriteListener, val fromQueue: Boolean = false) : FunkwhaleAdapter<Track, FavoritesAdapter.ViewHolder>() {
interface OnFavoriteListener {
fun onToggleFavorite(id: Int, state: Boolean)
}
@ -28,7 +28,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen @@ -28,7 +28,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
override fun getItemCount() = data.size
override fun getItemId(position: Int): Long {
return data[position].track.id.toLong()
return data[position].id.toLong()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@ -44,14 +44,14 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen @@ -44,14 +44,14 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
val favorite = data[position]
Picasso.get()
.maybeLoad(maybeNormalizeUrl(favorite.track.album.cover.original))
.maybeLoad(maybeNormalizeUrl(favorite.album.cover.original))
.fit()
.placeholder(R.drawable.cover)
.transform(RoundedCornersTransformation(16, 0))
.into(holder.cover)
holder.title.text = favorite.track.title
holder.artist.text = favorite.track.artist.name
holder.title.text = favorite.title
holder.artist.text = favorite.artist.name
Build.VERSION_CODES.P.onApi(
{
@ -64,19 +64,19 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen @@ -64,19 +64,19 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
})
if (favorite.track == currentTrack || favorite.track.current) {
if (favorite == currentTrack || favorite.current) {
holder.title.setTypeface(holder.title.typeface, Typeface.BOLD)
holder.artist.setTypeface(holder.artist.typeface, Typeface.BOLD)
}
context?.let {
when (favorite.track.favorite) {
when (favorite.favorite) {
true -> holder.favorite.setColorFilter(context.getColor(R.color.colorFavorite))
false -> holder.favorite.setColorFilter(context.getColor(R.color.colorSelected))
}
holder.favorite.setOnClickListener {
favoriteListener.onToggleFavorite(favorite.track.id, !favorite.track.favorite)
favoriteListener.onToggleFavorite(favorite.id, !favorite.favorite)
data.remove(favorite)
notifyItemRemoved(holder.adapterPosition)
@ -90,9 +90,9 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen @@ -90,9 +90,9 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
setOnMenuItemClickListener {
when (it.itemId) {
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(favorite.track)))
R.id.track_play_next -> CommandBus.send(Command.PlayNext(favorite.track))
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(favorite.track))
R.id.track_add_to_queue -> CommandBus.send(Command.AddToQueue(listOf(favorite)))
R.id.track_play_next -> CommandBus.send(Command.PlayNext(favorite))
R.id.queue_remove -> CommandBus.send(Command.RemoveFromQueue(favorite))
}
true
@ -132,7 +132,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen @@ -132,7 +132,7 @@ class FavoritesAdapter(private val context: Context?, private val favoriteListen
true -> CommandBus.send(Command.PlayTrack(layoutPosition))
false -> {
data.subList(layoutPosition, data.size).plus(data.subList(0, layoutPosition)).apply {
CommandBus.send(Command.ReplaceQueue(this.map { it.track }))
CommandBus.send(Command.ReplaceQueue(this))
context.toast("All tracks were added to your queue")
}

5
app/src/main/java/com/github/apognu/otter/fragments/FavoritesFragment.kt

@ -11,7 +11,7 @@ import kotlinx.coroutines.Dispatchers.Main @@ -11,7 +11,7 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class FavoritesFragment : FunkwhaleFragment<Favorite, FavoritesAdapter>() {
class FavoritesFragment : FunkwhaleFragment<Track, FavoritesAdapter>() {
override val viewRes = R.layout.fragment_favorites
override val recycler: RecyclerView get() = favorites
@ -22,7 +22,6 @@ class FavoritesFragment : FunkwhaleFragment<Favorite, FavoritesAdapter>() { @@ -22,7 +22,6 @@ class FavoritesFragment : FunkwhaleFragment<Favorite, FavoritesAdapter>() {
adapter = FavoritesAdapter(context, FavoriteListener())
repository = FavoritesRepository(context)
favoritesRepository = FavoritesRepository(context)
watchEventBus()
}
@ -38,7 +37,7 @@ class FavoritesFragment : FunkwhaleFragment<Favorite, FavoritesAdapter>() { @@ -38,7 +37,7 @@ class FavoritesFragment : FunkwhaleFragment<Favorite, FavoritesAdapter>() {
}
play.setOnClickListener {
CommandBus.send(Command.ReplaceQueue(adapter.data.shuffled().map { it.track }))
CommandBus.send(Command.ReplaceQueue(adapter.data.shuffled()))
}
}

22
app/src/main/java/com/github/apognu/otter/repositories/FavoritesRepository.kt

@ -12,16 +12,16 @@ import kotlinx.coroutines.Dispatchers.IO @@ -12,16 +12,16 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.runBlocking
import java.io.BufferedReader
class FavoritesRepository(override val context: Context?) : Repository<Favorite, FavoritesCache>() {
override val cacheId = "favorites"
override val upstream = HttpUpstream<Favorite, FunkwhaleResponse<Favorite>>(HttpUpstream.Behavior.AtOnce, "/api/v1/favorites/tracks?playable=true", object : TypeToken<FavoritesResponse>() {}.type)
class FavoritesRepository(override val context: Context?) : Repository<Track, TracksCache>() {
override val cacheId = "favorites.v2"
override val upstream = HttpUpstream<Track, FunkwhaleResponse<Track>>(HttpUpstream.Behavior.AtOnce, "/api/v1/tracks?favorites=true&playable=true", object : TypeToken<TracksResponse>() {}.type)
override fun cache(data: List<Favorite>) = FavoritesCache(data)
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(FavoritesCache::class.java).deserialize(reader)
override fun cache(data: List<Track>) = TracksCache(data)
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(TracksCache::class.java).deserialize(reader)
override fun onDataFetched(data: List<Favorite>) = data.map {
override fun onDataFetched(data: List<Track>) = data.map {
it.apply {
it.track.favorite = true
it.favorite = true
}
}
@ -53,3 +53,11 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite, @@ -53,3 +53,11 @@ class FavoritesRepository(override val context: Context?) : Repository<Favorite,
}
}
}
class FavoritedRepository(override val context: Context?) : Repository<Int, FavoritedCache>() {
override val cacheId = "favorited"
override val upstream = HttpUpstream<Int, FunkwhaleResponse<Int>>(HttpUpstream.Behavior.Single, "/api/v1/favorites/tracks/all?playable=true", object : TypeToken<FavoritedResponse>() {}.type)
override fun cache(data: List<Int>) = FavoritedCache(data)
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(FavoritedCache::class.java).deserialize(reader)
}

16
app/src/main/java/com/github/apognu/otter/repositories/PlaylistTracksRepository.kt

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
package com.github.apognu.otter.repositories
import android.content.Context
import com.github.apognu.otter.utils.*
import com.github.apognu.otter.utils.FunkwhaleResponse
import com.github.apognu.otter.utils.PlaylistTrack
import com.github.apognu.otter.utils.PlaylistTracksCache
import com.github.apognu.otter.utils.PlaylistTracksResponse
import com.github.kittinunf.fuel.gson.gsonDeserializerOf
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.runBlocking
@ -15,17 +18,10 @@ class PlaylistTracksRepository(override val context: Context?, playlistId: Int) @@ -15,17 +18,10 @@ class PlaylistTracksRepository(override val context: Context?, playlistId: Int)
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(PlaylistTracksCache::class.java).deserialize(reader)
override fun onDataFetched(data: List<PlaylistTrack>): List<PlaylistTrack> = runBlocking {
val favorites = FavoritesRepository(context).fetch(Origin.Network.origin).receive().data
log(favorites.toString())
val favorites = FavoritedRepository(context).fetch(Origin.Network.origin).receive().data
data.map { track ->
val favorite = favorites.find { it.track.id == track.track.id }
if (favorite != null) {
track.track.favorite = true
}
track.track.favorite = favorites.contains(track.track.id)
track
}
}

9
app/src/main/java/com/github/apognu/otter/repositories/SearchRepository.kt

@ -18,15 +18,10 @@ class SearchRepository(override val context: Context?, query: String) : Reposito @@ -18,15 +18,10 @@ class SearchRepository(override val context: Context?, query: String) : Reposito
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(TracksCache::class.java).deserialize(reader)
override fun onDataFetched(data: List<Track>): List<Track> = runBlocking {
val favorites = FavoritesRepository(context).fetch(Origin.Network.origin).receive().data
val favorites = FavoritedRepository(context).fetch(Origin.Network.origin).receive().data
data.map { track ->
val favorite = favorites.find { it.track.id == track.id }
if (favorite != null) {
track.favorite = true
}
track.favorite = favorites.contains(track.id)
track
}
}

9
app/src/main/java/com/github/apognu/otter/repositories/TracksRepository.kt

@ -18,15 +18,10 @@ class TracksRepository(override val context: Context?, albumId: Int) : Repositor @@ -18,15 +18,10 @@ class TracksRepository(override val context: Context?, albumId: Int) : Repositor
override fun uncache(reader: BufferedReader) = gsonDeserializerOf(TracksCache::class.java).deserialize(reader)
override fun onDataFetched(data: List<Track>): List<Track> = runBlocking {
val favorites = FavoritesRepository(context).fetch(Origin.Network.origin).receive().data
val favorites = FavoritedRepository(context).fetch(Origin.Network.origin).receive().data
data.map { track ->
val favorite = favorites.find { it.track.id == track.id }
if (favorite != null) {
track.favorite = true
}
track.favorite = favorites.contains(track.id)
track
}
}

12
app/src/main/java/com/github/apognu/otter/utils/Models.kt

@ -8,7 +8,7 @@ class AlbumsCache(data: List<Album>) : CacheItem<Album>(data) @@ -8,7 +8,7 @@ class AlbumsCache(data: List<Album>) : CacheItem<Album>(data)
class TracksCache(data: List<Track>) : CacheItem<Track>(data)
class PlaylistsCache(data: List<Playlist>) : CacheItem<Playlist>(data)
class PlaylistTracksCache(data: List<PlaylistTrack>) : CacheItem<PlaylistTrack>(data)
class FavoritesCache(data: List<Favorite>) : CacheItem<Favorite>(data)
class FavoritedCache(data: List<Int>) : CacheItem<Int>(data)
class QueueCache(data: List<Track>) : CacheItem<Track>(data)
abstract class FunkwhaleResponse<D : Any> {
@ -18,6 +18,10 @@ abstract class FunkwhaleResponse<D : Any> { @@ -18,6 +18,10 @@ abstract class FunkwhaleResponse<D : Any> {
abstract fun getData(): List<D>
}
data class UserResponse(override val count: Int, override val next: String?, val results: List<Artist>) : FunkwhaleResponse<Artist>() {
override fun getData() = results
}
data class ArtistsResponse(override val count: Int, override val next: String?, val results: List<Artist>) : FunkwhaleResponse<Artist>() {
override fun getData() = results
}
@ -30,8 +34,8 @@ data class TracksResponse(override val count: Int, override val next: String?, v @@ -30,8 +34,8 @@ data class TracksResponse(override val count: Int, override val next: String?, v
override fun getData() = results
}
data class FavoritesResponse(override val count: Int, override val next: String?, val results: List<Favorite>) : FunkwhaleResponse<Favorite>() {
override fun getData() = results
data class FavoritedResponse(override val count: Int, override val next: String?, val results: List<Favorited>) : FunkwhaleResponse<Int>() {
override fun getData() = results.map { it.track }
}
data class PlaylistsResponse(override val count: Int, override val next: String?, val results: List<Playlist>) : FunkwhaleResponse<Playlist>() {
@ -100,7 +104,7 @@ data class Track( @@ -100,7 +104,7 @@ data class Track(
}
}
data class Favorite(val id: Int, val track: Track)
data class Favorited(val track: Int)
data class Playlist(
val id: Int,

9
app/src/main/res/drawable/brightness.xml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69L23.31,12 20,8.69zM12,18c-0.89,0 -1.74,-0.2 -2.5,-0.55C11.56,16.5 13,14.42 13,12s-1.44,-4.5 -3.5,-5.45C10.26,6.2 11.11,6 12,6c3.31,0 6,2.69 6,6s-2.69,6 -6,6z"/>
</vector>

9
app/src/main/res/drawable/logout.xml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>

9
app/src/main/res/drawable/quality.xml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,15L9.5,15v-2h-2v2L6,15L6,9h1.5v2.5h2L9.5,9L11,9v6zM18,14c0,0.55 -0.45,1 -1,1h-0.75v1.5h-1.5L14.75,15L14,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v4zM14.5,13.5h2v-3h-2v3z"/>
</vector>

9
app/src/main/res/drawable/storage.xml

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM12,8h-2L10,4h2v4zM15,8h-2L13,4h2v4zM18,8h-2L16,4h2v4z"/>
</vector>

5
app/src/main/res/layout/activity_login.xml

@ -33,6 +33,7 @@ @@ -33,6 +33,7 @@
android:hint="@string/login_hostname"
android:textColorHint="@drawable/login_input"
app:boxStrokeColor="@drawable/login_input"
app:errorTextAppearance="@style/AppTheme.ErrorStyle"
app:hintTextColor="@drawable/login_input">
<com.google.android.material.textfield.TextInputEditText
@ -54,6 +55,7 @@ @@ -54,6 +55,7 @@
android:hint="@string/login_username"
android:textColorHint="@drawable/login_input"
app:boxStrokeColor="@drawable/login_input"
app:errorTextAppearance="@style/AppTheme.ErrorStyle"
app:hintTextColor="@drawable/login_input">
<com.google.android.material.textfield.TextInputEditText
@ -75,6 +77,7 @@ @@ -75,6 +77,7 @@
android:hint="@string/login_password"
android:textColorHint="@drawable/login_input"
app:boxStrokeColor="@drawable/login_input"
app:errorTextAppearance="@style/AppTheme.ErrorStyle"
app:hintTextColor="@drawable/login_input"
app:passwordToggleEnabled="true">
@ -94,5 +97,5 @@ @@ -94,5 +97,5 @@
android:layout_height="wrap_content"
android:backgroundTint="@color/colorAccent"
android:text="@string/login_submit"
android:textColor="@android:color/white" />
android:textColor="@color/whiteWhileLight" />
</LinearLayout>

8
app/src/main/res/values-night/colors.xml

@ -3,12 +3,16 @@ @@ -3,12 +3,16 @@
<color name="surface">#121212</color>
<color name="colorPrimary">#283f4e</color>
<color name="colorAccent">#99440c</color>
<color name="colorAccent">#f1b44f</color>
<color name="colorSelected">#525252</color>
<color name="colorFavorite">#eba999</color>
<color name="itemTitle">#caffffff</color>
<color name="controlForeground">#caffffff</color>
<color name="controlColor">#53bce7</color>
<color name="controlColor">#327eae</color>
<color name="whiteWhileLight">#000000</color>
<color name="blackWhileLight">#ffffff</color>
</resources>

4
app/src/main/res/values/colors.xml

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
<color name="colorPrimary">#327eae</color>
<color name="colorPrimaryDark">#3d3e40</color>
<color name="colorAccent">#d35400</color>
<color name="colorError">#b94705</color>
<color name="colorSelected">#dadada</color>
<color name="colorFavorite">#e17055</color>
@ -14,4 +15,7 @@ @@ -14,4 +15,7 @@
<color name="controlForeground">@color/colorPrimary</color>
<color name="controlColor">@color/colorPrimary</color>
<color name="whiteWhileLight">#ffffff</color>
<color name="blackWhileLight">#000000</color>
</resources>

8
app/src/main/res/values/styles.xml

@ -27,8 +27,9 @@ @@ -27,8 +27,9 @@
<style name="AppTheme.Title">
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textSize">28sp</item>
<item name="android:textSize">24sp</item>
<item name="android:textColor">@color/itemTitle</item>
<item name="android:textStyle">bold</item>
</style>
<style name="AppTheme.ItemTitle">
@ -44,6 +45,7 @@ @@ -44,6 +45,7 @@
<style name="AppTheme.Preference" parent="PreferenceThemeOverlay">
<item name="android:textColor">@color/itemTitle</item>
<item name="android:tint">@color/blackWhileLight</item>
<item name="preferenceCategoryStyle">@style/AppTheme.PreferenceCategory</item>
</style>
@ -74,4 +76,8 @@ @@ -74,4 +76,8 @@
<item name="android:background">@android:color/transparent</item>
</style>
<style name="AppTheme.ErrorStyle" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/colorError</item>
</style>
</resources>

5
app/src/main/res/xml/settings.xml

@ -8,11 +8,13 @@ @@ -8,11 +8,13 @@
android:defaultValue="quality"
android:entries="@array/media_qualities"
android:entryValues="@array/media_qualities_values"
android:icon="@drawable/quality"
android:key="media_quality"
android:title="@string/settings_media_quality" />
<SeekBarPreference
android:defaultValue="1"
android:icon="@drawable/storage"
android:key="media_cache_size"
android:max="5"
android:min="0"
@ -28,14 +30,17 @@ @@ -28,14 +30,17 @@
android:defaultValue="system"
android:entries="@array/night_mode"
android:entryValues="@array/night_mode_values"
android:icon="@drawable/brightness"
android:key="night_mode"
android:title="@string/settings_night_mode" />
<Preference
android:icon="@drawable/favorite"
android:key="oss_licences"
android:title="@string/title_oss_licences" />
<Preference
android:icon="@drawable/logout"
android:key="logout"
android:title="@string/settings_logout" />

Loading…
Cancel
Save