Merge branch 'libre-tube:master' into master

This commit is contained in:
XelXen 2022-06-27 23:27:22 +05:30 committed by GitHub
commit 7e03cf7aa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
169 changed files with 2099 additions and 1243 deletions

View File

@ -62,3 +62,4 @@ WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OP
## Mirrors (read-only)
<a href="https://gitlab.com/libretube/LibreTube">GitLab</a></p>
<a href="https://notabug.org/LibreTube/LibreTube">NotABug</a></p>

View File

@ -55,35 +55,35 @@ android {
}
dependencies {
//debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
//debugImplementation libs.square.leakcanary
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.android.material:material:1.6.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.2'
implementation 'androidx.navigation:navigation-ui-ktx:2.4.2'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation libs.androidx.appcompat
implementation libs.androidx.constraintlayout
implementation libs.androidx.legacySupport
implementation libs.androidx.multidex
implementation libs.androidx.navigation.fragment
implementation libs.androidx.navigation.ui
implementation libs.androidx.preference
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation libs.androidx.test.junit
androidTestImplementation libs.androidx.test.espressoCore
implementation 'com.squareup.picasso:picasso:2.8'
implementation 'de.hdodenhof:circleimageview:3.1.0'
implementation 'com.google.android.exoplayer:exoplayer:2.17.1'
implementation 'com.google.android.exoplayer:extension-mediasession:2.17.1'
implementation 'androidx.multidex:multidex:2.0.1'
implementation libs.circleimageview
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
//do not update jackson annotations! it does not supports <api26
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.3'
implementation libs.material
implementation libs.exoplayer
implementation(libs.exoplayer.extension.cronet) { exclude group: 'com.google.android.gms' }
implementation libs.exoplayer.extension.mediasession
implementation 'com.arthenica:ffmpeg-kit-min:4.5.1.LTS'
implementation libs.square.picasso
implementation libs.square.retrofit
implementation libs.square.retrofit.converterJackson
// Do not update jackson annotations! It does not supports < API 26.
implementation libs.jacksonAnnotations
implementation libs.mobileffmpeg
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation('com.google.android.exoplayer:extension-cronet:2.17.1') { exclude group: 'com.google.android.gms' }
implementation 'org.chromium.net:cronet-embedded:101.4951.41'
coreLibraryDesugaring libs.desugaring
implementation libs.cronet.embedded
implementation libs.gson
}

View File

@ -11,32 +11,32 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Purple"
android:name=".MyApp"
android:networkSecurityConfig="@xml/network_security_config"
android:largeHeap="true"
android:requestLegacyExternalStorage="true">
android:theme="@style/Theme.Purple">
<activity
android:name=".util.Player"
android:configChanges="orientation|screenSize"
android:exported="false"
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
android:configChanges="orientation|screenSize" />
android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
<activity
android:name=".SettingsActivity"
android:label="@string/settings" />
<activity
android:name=".MainActivity"
android:exported="true"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:exported="true"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:screenOrientation="userPortrait"
android:launchMode="singleTop">
android:supportsPictureInPicture="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -44,16 +44,16 @@
</activity>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_gradient"
android:roundIcon="@mipmap/ic_gradient_round"
android:name=".IconGradient"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_gradient"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_gradient_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -61,16 +61,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_fire"
android:roundIcon="@mipmap/ic_fire_round"
android:name=".IconFire"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_fire"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_fire_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -78,16 +78,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_flame"
android:roundIcon="@mipmap/ic_flame_round"
android:name=".IconFlame"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_flame"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_flame_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -95,16 +95,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_shaped"
android:roundIcon="@mipmap/ic_shaped_round"
android:name=".IconShaped"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_shaped"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_shaped_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -112,16 +112,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_torch"
android:roundIcon="@mipmap/ic_torch_round"
android:name=".IconTorch"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_torch"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_torch_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -129,16 +129,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_legacy"
android:roundIcon="@mipmap/ic_legacy_round"
android:name=".IconLegacy"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_legacy"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_legacy_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@ -146,16 +146,16 @@
</activity-alias>
<activity-alias
android:label="@string/app_name"
android:icon="@mipmap/ic_bird"
android:roundIcon="@mipmap/ic_bird_round"
android:name=".IconBird"
android:enabled="false"
android:targetActivity=".MainActivity"
android:supportsPictureInPicture="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:enabled="false"
android:exported="true"
android:hardwareAccelerated="true"
android:exported="true">
android:icon="@mipmap/ic_bird"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_bird_round"
android:supportsPictureInPicture="true"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@ -17,8 +17,8 @@ import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.preference.PreferenceManager
import com.arthenica.ffmpegkit.FFmpegKit
import com.github.libretube.util.PreferenceHelper
import java.io.File
var IS_DOWNLOAD_RUNNING = false
@ -48,8 +48,7 @@ class DownloadService : Service() {
videoUrl = intent.getStringExtra("videoUrl")!!
audioUrl = intent.getStringExtra("audioUrl")!!
duration = intent.getIntExtra("duration", 1)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
extension = sharedPreferences.getString("video_format", ".mp4")!!
extension = PreferenceHelper.getString(this, "video_format", ".mp4")!!
downloadType = if (audioUrl != "" && videoUrl != "") "mux"
else if (audioUrl != "") "audio"
else if (videoUrl != "") "video"
@ -69,7 +68,6 @@ class DownloadService : Service() {
}
private fun downloadManager() {
// create folder for temporary files
tempDir = File(
applicationContext.getExternalFilesDir(DIRECTORY_DOWNLOADS),
@ -84,9 +82,8 @@ class DownloadService : Service() {
Log.e(TAG, "Directory already have")
}
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
val downloadLocationPref = sharedPreferences.getString("download_location", "")
val folderName = sharedPreferences.getString("download_folder", "")
val downloadLocationPref = PreferenceHelper.getString(this, "download_location", "")
val folderName = PreferenceHelper.getString(this, "download_folder", "LibreTube")
val location = when (downloadLocationPref) {
"downloads" -> Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS)
@ -255,10 +252,11 @@ class DownloadService : Service() {
if (returnCode.toString() != "0") downloadFailedNotification()
else downloadSucceededNotification()
onDestroy()
}, {
// CALLED WHEN SESSION PRINTS LOGS
Log.e(TAG, it.message.toString())
}
},
{
// CALLED WHEN SESSION PRINTS LOGS
Log.e(TAG, it.message.toString())
}
) {
// CALLED WHEN SESSION GENERATES STATISTICS
Log.e(TAG + "stat", it.time.toString())

View File

@ -32,12 +32,11 @@ import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.fragments.isFullScreen
import com.github.libretube.preferences.SponsorBlockSettings
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.LocaleHelper
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.ThemeHelper
import com.google.android.material.bottomnavigation.BottomNavigationView
@ -54,32 +53,12 @@ class MainActivity : AppCompatActivity() {
DynamicColors.applyToActivityIfAvailable(this)
super.onCreate(savedInstanceState)
CronetHelper.initCronet(this.applicationContext)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
RetrofitInstance.url =
sharedPreferences.getString("selectInstance", "https://pipedapi.kavin.rocks/")!!
SponsorBlockSettings.sponsorBlockEnabled =
sharedPreferences.getBoolean("sb_enabled_key", true)
SponsorBlockSettings.sponsorNotificationsEnabled =
sharedPreferences.getBoolean("sb_notifications_key", true)
SponsorBlockSettings.introEnabled =
sharedPreferences.getBoolean("intro_category_key", false)
SponsorBlockSettings.selfPromoEnabled =
sharedPreferences.getBoolean("selfpromo_category_key", false)
SponsorBlockSettings.interactionEnabled =
sharedPreferences.getBoolean("interaction_category_key", false)
SponsorBlockSettings.sponsorsEnabled =
sharedPreferences.getBoolean("sponsors_category_key", true)
SponsorBlockSettings.outroEnabled =
sharedPreferences.getBoolean("outro_category_key", false)
SponsorBlockSettings.fillerEnabled =
sharedPreferences.getBoolean("filler_category_key", false)
SponsorBlockSettings.musicOfftopicEnabled =
sharedPreferences.getBoolean("music_offtopic_category_key", false)
SponsorBlockSettings.previewEnabled =
sharedPreferences.getBoolean("preview_category_key", false)
ThemeHelper().updateTheme(this)
LocaleHelper().updateLanguage(this)
RetrofitInstance.url =
PreferenceHelper.getString(this, "selectInstance", "https://pipedapi.kavin.rocks/")!!
ThemeHelper.updateTheme(this)
LocaleHelper.updateLanguage(this)
// show noInternet Activity if no internet available on app startup
if (!isNetworkAvailable(this)) {
@ -100,12 +79,11 @@ class MainActivity : AppCompatActivity() {
bottomNavigationView.setupWithNavController(navController)
// hide the trending page if enabled
val hideTrendingPage = sharedPreferences.getBoolean("hide_trending_page", false)
val hideTrendingPage = PreferenceHelper.getBoolean(this, "hide_trending_page", false)
if (hideTrendingPage) bottomNavigationView.menu.findItem(R.id.home2).isVisible = false
// navigate to the default start tab
val defaultTab = sharedPreferences.getString("default_tab", "home")
when (defaultTab) {
when (PreferenceHelper.getString(this, "default_tab", "home")) {
"home" -> navController.navigate(R.id.home2)
"subscriptions" -> navController.navigate(R.id.subscriptions)
"library" -> navController.navigate(R.id.library)

View File

@ -21,7 +21,7 @@ class RouterActivity : AppCompatActivity() {
handleSendText(uri!!)
} else {
// start app as normal if URI not in host list
ThemeHelper().restartMainActivity(this)
ThemeHelper.restartMainActivity(this)
}
}

View File

@ -19,7 +19,7 @@ class SettingsActivity : AppCompatActivity() {
val TAG = "SettingsActivity"
override fun onCreate(savedInstanceState: Bundle?) {
DynamicColors.applyToActivityIfAvailable(this)
ThemeHelper().updateTheme(this)
ThemeHelper.updateTheme(this)
// makes the preference dialogs use material dialogs
setTheme(R.style.MaterialAlertDialog)
@ -54,7 +54,7 @@ class SettingsActivity : AppCompatActivity() {
val nManager =
this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
nManager.cancelAll()
ThemeHelper().restartMainActivity(this)
ThemeHelper.restartMainActivity(this)
ActivityCompat.finishAffinity(this)
} else {
super.onBackPressed()

View File

@ -19,11 +19,11 @@ import com.github.libretube.obj.CommentsPage
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class CommentsAdapter(
private val videoId: String,

View File

@ -1,7 +1,6 @@
package com.github.libretube.adapters
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.text.format.DateUtils
import android.util.Log
@ -18,13 +17,14 @@ import com.github.libretube.dialogs.VideoOptionsDialog
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.PlaylistId
import com.github.libretube.obj.StreamItem
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class PlaylistAdapter(
private val videoFeed: MutableList<StreamItem>,
@ -81,11 +81,7 @@ class PlaylistAdapter(
val delete = holder.v.findViewById<ImageView>(R.id.delete_playlist)
delete.visibility = View.VISIBLE
delete.setOnClickListener {
val sharedPref = holder.v.context.getSharedPreferences(
"token",
Context.MODE_PRIVATE
)
val token = sharedPref?.getString("token", "")!!
val token = PreferenceHelper.getToken(holder.v.context)
removeFromPlaylist(token, position)
}
}

View File

@ -1,7 +1,6 @@
package com.github.libretube.adapters
import android.app.Activity
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.View
@ -14,13 +13,14 @@ import com.github.libretube.MainActivity
import com.github.libretube.R
import com.github.libretube.obj.PlaylistId
import com.github.libretube.obj.Playlists
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class PlaylistsAdapter(
private val playlists: MutableList<Playlists>,
@ -57,11 +57,7 @@ class PlaylistsAdapter(
builder.setTitle(R.string.deletePlaylist)
builder.setMessage(R.string.areYouSure)
builder.setPositiveButton(R.string.yes) { _, _ ->
val sharedPref = holder.v.context.getSharedPreferences(
"token",
Context.MODE_PRIVATE
)
val token = sharedPref?.getString("token", "")!!
val token = PreferenceHelper.getToken(holder.v.context)
deletePlaylist(playlist.id!!, token, position)
}
builder.setNegativeButton(R.string.cancel) { _, _ ->
@ -96,10 +92,6 @@ class PlaylistsAdapter(
playlists.removeAt(position)
// FIXME: This needs to run on UI thread?
activity.runOnUiThread { notifyDataSetChanged() }
/*if(playlists.isEmpty()){
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
}*/
}
} catch (e: Exception) {
Log.e(TAG, e.toString())

View File

@ -85,10 +85,11 @@ class SearchViewHolder(
val viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else ""
val uploadDate = if (item.uploadedDate != null) item.uploadedDate else ""
views.text =
if (viewsString != "" && uploadDate != "")
if (viewsString != "" && uploadDate != "") {
"$viewsString$uploadDate"
else
} else {
viewsString + uploadDate
}
val channelName = v.findViewById<TextView>(R.id.search_channel_name)
channelName.text = item.uploaderName
v.setOnClickListener {
@ -145,9 +146,10 @@ class SearchViewHolder(
val playlistChannelName = v.findViewById<TextView>(R.id.search_name)
playlistChannelName.text = item.uploaderName
val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos)
if (item.videos?.toInt() != -1)
if (item.videos?.toInt() != -1) {
playlistVideosNumber.text =
v.context.getString(R.string.videoCount, item.videos.toString())
}
v.setOnClickListener {
// playlist clicked
val activity = v.context as MainActivity

View File

@ -5,12 +5,12 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.fragments.SearchFragment
import com.google.android.material.imageview.ShapeableImageView
import com.github.libretube.util.PreferenceHelper
class SearchHistoryAdapter(
private val context: Context,
@ -34,10 +34,9 @@ class SearchHistoryAdapter(
val history = historyList[position]
holder.v.findViewById<TextView>(R.id.history_text).text = history
holder.v.findViewById<ShapeableImageView>(R.id.delete_history).setOnClickListener {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
holder.v.findViewById<ImageView>(R.id.delete_history).setOnClickListener {
historyList = historyList - history
sharedPreferences.edit().putStringSet("search_history", HashSet(historyList)).apply()
PreferenceHelper.saveHistory(context, historyList)
notifyDataSetChanged()
}

View File

@ -34,8 +34,9 @@ class SubscriptionAdapter(
fun updateItems() {
// limitedVideoFeed.add("")
i += 10
if (i > videoFeed.size)
if (i > videoFeed.size) {
i = videoFeed.size
}
notifyDataSetChanged()
}

View File

@ -13,13 +13,14 @@ import com.github.libretube.MainActivity
import com.github.libretube.R
import com.github.libretube.obj.Subscribe
import com.github.libretube.obj.Subscription
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscription>) :
RecyclerView.Adapter<SubscriptionChannelViewHolder>() {
@ -70,10 +71,9 @@ class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscrip
fun run() {
CoroutineScope(Dispatchers.IO).launch {
val response = try {
val sharedPref = context
.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(context)
RetrofitInstance.api.subscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channelId)
)
} catch (e: IOException) {
@ -93,10 +93,9 @@ class SubscriptionChannelAdapter(private val subscriptions: MutableList<Subscrip
fun run() {
CoroutineScope(Dispatchers.IO).launch {
val response = try {
val sharedPref =
context.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(context)
RetrofitInstance.api.unsubscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channelId)
)
} catch (e: IOException) {

View File

@ -1,7 +1,6 @@
package com.github.libretube.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
@ -17,10 +16,11 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.obj.PlaylistId
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class AddtoPlaylistDialog : DialogFragment() {
private val TAG = "AddToPlaylistDialog"
@ -34,8 +34,7 @@ class AddtoPlaylistDialog : DialogFragment() {
val builder = MaterialAlertDialogBuilder(it)
// Get the layout inflater
val inflater = requireActivity().layoutInflater
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
token = sharedPref?.getString("token", "")!!
token = PreferenceHelper.getToken(requireContext())
var view: View = inflater.inflate(R.layout.dialog_addtoplaylist, null)
spinner = view.findViewById(R.id.playlists_spinner)
button = view.findViewById(R.id.addToPlaylist)

View File

@ -1,7 +1,6 @@
package com.github.libretube.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
@ -9,18 +8,18 @@ import android.view.View
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.fragments.Library
import com.github.libretube.obj.Playlists
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class CreatePlaylistDialog : DialogFragment() {
val TAG = "CreatePlaylistDialog"
@ -46,8 +45,7 @@ class CreatePlaylistDialog : DialogFragment() {
dismiss()
}
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
token = sharedPref?.getString("token", "")!!
token = PreferenceHelper.getToken(requireContext())
val playlistName = view.findViewById<TextInputEditText>(R.id.playlist_name)
val createPlaylistBtn = view.findViewById<Button>(R.id.create_new_playlist)
@ -88,8 +86,13 @@ class CreatePlaylistDialog : DialogFragment() {
Toast.makeText(context, getString(R.string.unknown_error), Toast.LENGTH_SHORT)
.show()
}
// tell the Subscription Activity to fetch the playlists again
setFragmentResult("fetchPlaylists", bundleOf("" to ""))
// refresh the playlists in the library
try {
val parent = parentFragment as Library
parent.fetchPlaylists()
} catch (e: Exception) {
Log.e(TAG, e.toString())
}
dismiss()
}
}

View File

@ -9,8 +9,9 @@ import android.widget.TextView
import android.widget.Toast
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import com.github.libretube.R
import com.github.libretube.obj.CustomInstance
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import java.net.URL
@ -36,29 +37,38 @@ class CustomInstanceDialog : DialogFragment() {
}
addInstanceButton.setOnClickListener {
val instanceName = instanceNameEditText.text.toString()
val instanceApiUrl = instanceApiUrlEditText.text.toString()
val instanceFrontendUrl = instanceFrontendUrlEditText.text.toString()
val customInstance = CustomInstance()
customInstance.name = instanceNameEditText.text.toString()
customInstance.apiUrl = instanceApiUrlEditText.text.toString()
customInstance.frontendUrl = instanceFrontendUrlEditText.text.toString()
if (instanceName != "" && instanceApiUrl != "" && instanceFrontendUrl != "") {
if (
customInstance.name != "" &&
customInstance.apiUrl != "" &&
customInstance.frontendUrl != ""
) {
try {
// check whether the URL is valid, otherwise catch
URL(instanceApiUrl).toURI()
URL(instanceFrontendUrl).toURI()
URL(customInstance.apiUrl).toURI()
URL(customInstance.frontendUrl).toURI()
saveCustomInstance(instanceName, instanceApiUrl, instanceFrontendUrl)
PreferenceHelper.saveCustomInstance(requireContext(), customInstance)
activity?.recreate()
dismiss()
} catch (e: Exception) {
// invalid URL
Toast.makeText(
context, getString(R.string.invalid_url), Toast.LENGTH_SHORT
context,
getString(R.string.invalid_url),
Toast.LENGTH_SHORT
).show()
}
} else {
// at least one empty input
Toast.makeText(
context, context?.getString(R.string.empty_instance), Toast.LENGTH_SHORT
context,
context?.getString(R.string.empty_instance),
Toast.LENGTH_SHORT
).show()
}
}
@ -76,49 +86,4 @@ class CustomInstanceDialog : DialogFragment() {
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
private fun saveCustomInstance(
instanceName: String,
instanceApiUrl: String,
instanceFrontendApiUrl: String
) {
val sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(requireContext())
// get the names of the other custom instances
var customInstancesNames = try {
sharedPreferences
.getStringSet("custom_instances_name", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// get the api urls of the other custom instances
var customInstancesUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// get the frontend urls of the other custom instances
var customInstancesFrontendUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// append new instance to the list
customInstancesNames += instanceName
customInstancesUrls += instanceApiUrl
customInstancesFrontendUrls += instanceFrontendApiUrl
// save them to the shared preferences
sharedPreferences.edit()
.putStringSet("custom_instances_name", HashSet(customInstancesNames))
.putStringSet("custom_instances_url", HashSet(customInstancesUrls))
.putStringSet("custom_instances_frontend_url", HashSet(customInstancesFrontendUrls))
.apply()
}
}

View File

@ -0,0 +1,82 @@
package com.github.libretube.dialogs
import android.app.Dialog
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.obj.DeleteUserRequest
import com.github.libretube.requireMainActivityRestart
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class DeleteAccountDialog : DialogFragment() {
private val TAG = "DeleteAccountDialog"
lateinit var username: EditText
lateinit var password: EditText
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let {
val builder = MaterialAlertDialogBuilder(it)
val inflater = requireActivity().layoutInflater
val view = inflater.inflate(R.layout.dialog_delete_account, null)
view.findViewById<Button>(R.id.cancel_button).setOnClickListener {
dialog?.dismiss()
}
password = view.findViewById(R.id.delete_password)
view.findViewById<Button>(R.id.delete_account_confirm).setOnClickListener {
if (password.text.toString() != "") {
deleteAccount(password.text.toString())
} else {
Toast.makeText(context, R.string.empty, Toast.LENGTH_SHORT).show()
}
}
val typedValue = TypedValue()
this.requireActivity().theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true)
val hexColor = String.format("#%06X", (0xFFFFFF and typedValue.data))
val appName = HtmlCompat.fromHtml(
"Libre<span style='color:$hexColor';>Tube</span>",
HtmlCompat.FROM_HTML_MODE_COMPACT
)
view.findViewById<TextView>(R.id.title).text = appName
builder.setView(view)
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
private fun deleteAccount(password: String) {
fun run() {
lifecycleScope.launchWhenCreated {
val token = PreferenceHelper.getToken(requireContext())
try {
RetrofitInstance.api.deleteAccount(token, DeleteUserRequest(password))
} catch (e: Exception) {
Log.e(TAG, e.toString())
Toast.makeText(context, R.string.unknown_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
}
requireMainActivityRestart = true
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
logout()
dialog?.dismiss()
}
}
run()
}
private fun logout() {
PreferenceHelper.setToken(requireContext(), "")
}
}

View File

@ -1,7 +1,6 @@
package com.github.libretube.dialogs
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
@ -15,10 +14,11 @@ import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope
import com.github.libretube.R
import com.github.libretube.obj.Login
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class LoginDialog : DialogFragment() {
private val TAG = "LoginDialog"
@ -29,23 +29,17 @@ class LoginDialog : DialogFragment() {
val builder = MaterialAlertDialogBuilder(it)
// Get the layout inflater
val inflater = requireActivity().layoutInflater
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = sharedPref?.getString("token", "")
val token = PreferenceHelper.getToken(requireContext())
var view: View
Log.e("dafaq", token!!)
if (token != "") {
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE)
val user = sharedPref2?.getString("username", "")
val user = PreferenceHelper.getUsername(requireContext())
view = inflater.inflate(R.layout.dialog_logout, null)
view.findViewById<TextView>(R.id.user).text =
view.findViewById<TextView>(R.id.user).text.toString() + " (" + user + ")"
view.findViewById<Button>(R.id.logout).setOnClickListener {
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
with(sharedPref!!.edit()) {
putString("token", "")
apply()
}
PreferenceHelper.setToken(requireContext(), "")
dialog?.dismiss()
}
} else {
@ -99,24 +93,15 @@ class LoginDialog : DialogFragment() {
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
} catch (e: Exception) {
Log.e(TAG, "dafaq?" + e.toString())
Log.e(TAG, "dafaq?$e")
return@launchWhenCreated
}
if (response.error != null) {
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
} else if (response.token != null) {
Toast.makeText(context, R.string.loggedIn, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
with(sharedPref!!.edit()) {
putString("token", response.token)
apply()
}
val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE)
with(sharedPref2!!.edit()) {
putString("username", login.username)
apply()
}
PreferenceHelper.setToken(requireContext(), response.token!!)
PreferenceHelper.setUsername(requireContext(), login.username!!)
dialog?.dismiss()
}
}
@ -139,24 +124,15 @@ class LoginDialog : DialogFragment() {
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated
} catch (e: Exception) {
Log.e(TAG, "dafaq?" + e.toString())
Log.e(TAG, "dafaq?$e")
return@launchWhenCreated
}
if (response.error != null) {
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
} else if (response.token != null) {
Toast.makeText(context, R.string.registered, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
with(sharedPref!!.edit()) {
putString("token", response.token)
apply()
}
val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE)
with(sharedPref2!!.edit()) {
putString("username", login.username)
apply()
}
PreferenceHelper.setToken(requireContext(), response.token!!)
PreferenceHelper.setUsername(requireContext(), login.username!!)
dialog?.dismiss()
}
}

View File

@ -9,13 +9,14 @@ import android.widget.Toast
import androidx.fragment.app.DialogFragment
import com.github.libretube.R
import com.github.libretube.obj.PlaylistId
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class PlaylistOptionsDialog(
private val playlistId: String,
@ -43,9 +44,7 @@ class PlaylistOptionsDialog(
when (which) {
// Clone the playlist to the users Piped account
0 -> {
val sharedPref =
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = sharedPref?.getString("token", "")
val token = PreferenceHelper.getToken(requireContext())
if (token != "") {
importPlaylist(token!!, playlistId)
} else {

View File

@ -4,8 +4,8 @@ import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import com.github.libretube.R
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
class ShareDialog(
@ -54,35 +54,19 @@ class ShareDialog(
// get the frontend url if it's a custom instance
private fun getCustomInstanceFrontendUrl(): String {
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
val instancePref = sharedPreferences.getString(
val instancePref = PreferenceHelper.getString(
requireContext(),
"selectInstance",
"https://pipedapi.kavin.rocks"
)
// get the api urls of the other custom instances
var customInstancesUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
// get the frontend urls of the other custom instances
var customInstancesFrontendUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
val customInstances = PreferenceHelper.getCustomInstances(requireContext())
// return the custom instance frontend url if available
return if (customInstancesUrls.contains(instancePref)) {
val index = customInstancesUrls.indexOf(instancePref)
return customInstancesFrontendUrls[index]
} else {
""
customInstances.forEach { instance ->
if (instance.apiUrl == instancePref) return instance.apiUrl
}
return ""
}
}

View File

@ -8,6 +8,7 @@ import android.widget.Toast
import androidx.fragment.app.DialogFragment
import com.github.libretube.BackgroundMode
import com.github.libretube.R
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
/**
@ -50,11 +51,7 @@ class VideoOptionsDialog(private val videoId: String, context: Context) : Dialog
}
// Add Video to Playlist Dialog
1 -> {
val sharedPref = context?.getSharedPreferences(
"token",
Context.MODE_PRIVATE
)
val token = sharedPref?.getString("token", "")
val token = PreferenceHelper.getToken(requireContext())
if (token != "") {
val newFragment = AddtoPlaylistDialog()
val bundle = Bundle()

View File

@ -1,7 +1,6 @@
package com.github.libretube.fragments
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@ -18,12 +17,13 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R
import com.github.libretube.adapters.ChannelAdapter
import com.github.libretube.obj.Subscribe
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort
import com.google.android.material.button.MaterialButton
import com.squareup.picasso.Picasso
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class ChannelFragment : Fragment() {
@ -63,9 +63,8 @@ class ChannelFragment : Fragment() {
val refreshChannel = {
refreshLayout?.isRefreshing = true
fetchChannel(view)
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val subButton = view.findViewById<MaterialButton>(R.id.channel_subscribe)
if (sharedPref?.getString("token", "") != "") {
if (PreferenceHelper.getToken(requireContext()) != "") {
isSubscribed(subButton)
}
}
@ -95,10 +94,10 @@ class ChannelFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.isSubscribed(
channel_id!!,
sharedPref?.getString("token", "")!!
token
)
} catch (e: IOException) {
println(e)
@ -135,9 +134,9 @@ class ChannelFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.subscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channel_id)
)
} catch (e: IOException) {
@ -158,9 +157,9 @@ class ChannelFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.unsubscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channel_id)
)
} catch (e: IOException) {
@ -201,7 +200,10 @@ class ChannelFragment : Fragment() {
channelName.text = response.name
if (response.verified) {
channelName.setCompoundDrawablesWithIntrinsicBounds(
0, 0, R.drawable.ic_verified, 0
0,
0,
R.drawable.ic_verified,
0
)
}
view.findViewById<TextView>(R.id.channel_subs).text = resources.getString(
@ -231,7 +233,6 @@ class ChannelFragment : Fragment() {
private fun fetchNextPage() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
RetrofitInstance.api.getChannelNextPage(channel_id!!, nextPage!!)

View File

@ -9,15 +9,15 @@ import android.widget.ProgressBar
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R
import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class Home : Fragment() {
@ -34,7 +34,6 @@ class Home : Fragment() {
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
@ -42,8 +41,8 @@ class Home : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val recyclerView = view.findViewById<RecyclerView>(R.id.recview)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val grid = sharedPreferences.getString(
val grid = PreferenceHelper.getString(
requireContext(),
"grid",
resources.getInteger(R.integer.grid_items).toString()
)!!
@ -62,9 +61,8 @@ class Home : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
RetrofitInstance.api.getTrending(sharedPreferences.getString("region", "US")!!)
val region = PreferenceHelper.getString(requireContext(), "region", "US")
RetrofitInstance.api.getTrending(region!!)
} catch (e: IOException) {
println(e)
Log.e(TAG, "IOException, you might not have internet connection")

View File

@ -1,6 +1,5 @@
package com.github.libretube.fragments
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@ -17,10 +16,11 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R
import com.github.libretube.adapters.PlaylistsAdapter
import com.github.libretube.dialogs.CreatePlaylistDialog
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class Library : Fragment() {
@ -28,6 +28,7 @@ class Library : Fragment() {
lateinit var token: String
private lateinit var playlistRecyclerView: RecyclerView
private lateinit var refreshLayout: SwipeRefreshLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
@ -47,33 +48,37 @@ class Library : Fragment() {
super.onViewCreated(view, savedInstanceState)
playlistRecyclerView = view.findViewById(R.id.playlist_recView)
playlistRecyclerView.layoutManager = LinearLayoutManager(view.context)
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
token = sharedPref?.getString("token", "")!!
token = PreferenceHelper.getToken(requireContext())
refreshLayout = view.findViewById(R.id.playlist_refresh)
if (token != "") {
view.findViewById<ImageView>(R.id.boogh2).visibility = View.GONE
view.findViewById<TextView>(R.id.textLike2).visibility = View.GONE
fetchPlaylists(view)
fetchPlaylists()
refreshLayout.isEnabled = true
refreshLayout.setOnRefreshListener {
Log.d(TAG, "hmm")
fetchPlaylists(view)
fetchPlaylists()
}
view.findViewById<com.google.android.material.floatingactionbutton
.FloatingActionButton>(R.id.create_playlist).setOnClickListener {
val createPlaylistButton = view.findViewById<FloatingActionButton>(R.id.create_playlist)
createPlaylistButton.setOnClickListener {
val newFragment = CreatePlaylistDialog()
newFragment.show(childFragmentManager, "Create Playlist")
}
childFragmentManager.setFragmentResultListener("fetchPlaylists", this) { _, _ ->
fetchPlaylists(view)
}
} else {
refreshLayout.isEnabled = false
view.findViewById<FloatingActionButton>(R.id.create_playlist).visibility = View.GONE
}
}
private fun fetchPlaylists(view: View) {
override fun onResume() {
// optimize CreatePlaylistFab bottom margin if miniPlayer active
val createPlaylistButton = view?.findViewById<FloatingActionButton>(R.id.create_playlist)
val layoutParams = createPlaylistButton?.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.bottomMargin = if (isMiniPlayerVisible) 180 else 64
createPlaylistButton?.layoutParams = layoutParams
super.onResume()
}
fun fetchPlaylists() {
fun run() {
refreshLayout.isRefreshing = true
lifecycleScope.launchWhenCreated {
@ -93,12 +98,8 @@ class Library : Fragment() {
}
if (response.isNotEmpty()) {
runOnUiThread {
with(view.findViewById<ImageView>(R.id.boogh2)) {
visibility = View.GONE
}
with(view.findViewById<TextView>(R.id.textLike2)) {
visibility = View.GONE
}
view?.findViewById<ImageView>(R.id.boogh2)?.visibility = View.GONE
view?.findViewById<TextView>(R.id.textLike2)?.visibility = View.GONE
}
val playlistsAdapter = PlaylistsAdapter(
response.toMutableList(),
@ -107,13 +108,13 @@ class Library : Fragment() {
playlistRecyclerView.adapter = playlistsAdapter
} else {
runOnUiThread {
with(view.findViewById<ImageView>(R.id.boogh2)) {
visibility = View.VISIBLE
setImageResource(R.drawable.ic_list)
view?.findViewById<ImageView>(R.id.boogh2).apply {
this?.visibility = View.VISIBLE
this?.setImageResource(R.drawable.ic_list)
}
with(view.findViewById<TextView>(R.id.textLike2)) {
visibility = View.VISIBLE
text = getString(R.string.emptyList)
view?.findViewById<TextView>(R.id.textLike2).apply {
this?.visibility = View.VISIBLE
this?.text = getString(R.string.emptyList)
}
}
}

View File

@ -2,6 +2,7 @@ package com.github.libretube.fragments
import android.annotation.SuppressLint
import android.app.NotificationManager
import android.app.PictureInPictureParams
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
@ -18,6 +19,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.ImageView
@ -33,7 +35,6 @@ import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -51,12 +52,13 @@ import com.github.libretube.obj.ChapterSegment
import com.github.libretube.obj.PipedStream
import com.github.libretube.obj.Segment
import com.github.libretube.obj.Segments
import com.github.libretube.obj.SponsorBlockPrefs
import com.github.libretube.obj.StreamItem
import com.github.libretube.obj.Streams
import com.github.libretube.obj.Subscribe
import com.github.libretube.preferences.SponsorBlockSettings
import com.github.libretube.util.CronetHelper
import com.github.libretube.util.DescriptionAdapter
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.formatShort
import com.google.android.exoplayer2.C
@ -84,13 +86,14 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.card.MaterialCardView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.squareup.picasso.Picasso
import org.chromium.net.CronetEngine
import retrofit2.HttpException
import java.io.IOException
import java.util.concurrent.Executors
import kotlin.math.abs
import org.chromium.net.CronetEngine
import retrofit2.HttpException
var isFullScreen = false
var isMiniPlayerVisible = false
class PlayerFragment : Fragment() {
@ -118,6 +121,7 @@ class PlayerFragment : Fragment() {
private lateinit var segmentData: Segments
private var relatedStreams: List<StreamItem>? = arrayListOf()
private var relatedStreamsEnabled = true
private var isPlayerLocked: Boolean = false
private lateinit var relDownloadVideo: LinearLayout
@ -128,6 +132,7 @@ class PlayerFragment : Fragment() {
private lateinit var title: String
private lateinit var uploader: String
private lateinit var thumbnailUrl: String
private val sponsorBlockPrefs = SponsorBlockPrefs()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -149,6 +154,7 @@ class PlayerFragment : Fragment() {
super.onViewCreated(view, savedInstanceState)
hideKeyboard()
setSponsorBlockPrefs()
initializeTransitionLayout(view)
fetchJsonAndInitPlayer(view)
}
@ -182,6 +188,7 @@ class PlayerFragment : Fragment() {
val mainMotionLayout =
mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
mainMotionLayout.progress = abs(progress)
exoPlayerView.hideController()
eId = endId
sId = startId
}
@ -192,13 +199,13 @@ class PlayerFragment : Fragment() {
val mainMotionLayout =
mainActivity.findViewById<MotionLayout>(R.id.mainMotionLayout)
if (currentId == eId) {
exoPlayerView.hideController()
isMiniPlayerVisible = true
exoPlayerView.useController = false
mainMotionLayout.progress = 1.toFloat()
mainMotionLayout.progress = 1F
} else if (currentId == sId) {
exoPlayerView.showController()
isMiniPlayerVisible = false
exoPlayerView.useController = true
mainMotionLayout.progress = 0.toFloat()
mainMotionLayout.progress = 0F
}
}
@ -215,6 +222,7 @@ class PlayerFragment : Fragment() {
playerMotionLayout.transitionToStart()
view.findViewById<ImageView>(R.id.close_imageView).setOnClickListener {
isMiniPlayerVisible = false
motionLayout.transitionToEnd()
val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
@ -223,6 +231,7 @@ class PlayerFragment : Fragment() {
.commit()
}
view.findViewById<ImageButton>(R.id.close_imageButton).setOnClickListener {
isMiniPlayerVisible = false
motionLayout.transitionToEnd()
val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
@ -258,30 +267,42 @@ class PlayerFragment : Fragment() {
toggleComments()
}
val fullScreenButton = view.findViewById<ImageButton>(R.id.fullscreen)
val exoTitle = view.findViewById<TextView>(R.id.exo_title)
val mainContainer = view.findViewById<ConstraintLayout>(R.id.main_container)
val linLayout = view.findViewById<LinearLayout>(R.id.linLayout)
// FullScreen button trigger
view.findViewById<ImageButton>(R.id.fullscreen).setOnClickListener {
// remember to hide everything when new thing added
fullScreenButton.setOnClickListener {
exoPlayerView.hideController()
if (!isFullScreen) {
with(motionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, -1)
enableTransition(R.id.yt_transition, false)
}
view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = true
view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.GONE
mainContainer.isClickable = true
linLayout.visibility = View.GONE
fullScreenButton.setImageResource(R.drawable.ic_fullscreen_exit)
exoTitle.visibility = View.VISIBLE
val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
isFullScreen = true
} else {
with(motionLayout) {
getConstraintSet(R.id.start).constrainHeight(R.id.player, 0)
enableTransition(R.id.yt_transition, true)
}
view.findViewById<ConstraintLayout>(R.id.main_container).isClickable = false
view.findViewById<LinearLayout>(R.id.linLayout).visibility = View.VISIBLE
mainContainer.isClickable = false
linLayout.visibility = View.VISIBLE
fullScreenButton.setImageResource(R.drawable.ic_fullscreen)
exoTitle.visibility = View.INVISIBLE
val mainActivity = activity as MainActivity
mainActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
isFullScreen = false
}
isFullScreen = !isFullScreen
}
// switching between original aspect ratio (black bars) and zoomed to fill device screen
@ -295,6 +316,23 @@ class PlayerFragment : Fragment() {
}
}
// lock and unlock the player
val lockPlayerButton = view.findViewById<ImageButton>(R.id.lock_player)
lockPlayerButton.setOnClickListener {
// change the locked/unlocked icon
if (!isPlayerLocked) {
lockPlayerButton.setImageResource(R.drawable.ic_locked)
} else {
lockPlayerButton.setImageResource(R.drawable.ic_unlocked)
}
// show/hide all the controls
lockPlayer(isPlayerLocked)
// change locked status
isPlayerLocked = !isPlayerLocked
}
val scrollView = view.findViewById<ScrollView>(R.id.player_scrollView)
scrollView.viewTreeObserver
.addOnScrollChangedListener {
@ -326,9 +364,11 @@ class PlayerFragment : Fragment() {
override fun onPause() {
// pause the player if the screen is turned off
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val pausePlayerOnScreenOffEnabled = sharedPreferences
.getBoolean("pause_screen_off", false)
val pausePlayerOnScreenOffEnabled = PreferenceHelper.getBoolean(
requireContext(),
"pause_screen_off",
false
)
// check whether the screen is on
val pm = context?.getSystemService(Context.POWER_SERVICE) as PowerManager
@ -358,19 +398,20 @@ class PlayerFragment : Fragment() {
}
private fun checkForSegments() {
if (!exoPlayer.isPlaying || !SponsorBlockSettings.sponsorBlockEnabled) return
if (!exoPlayer.isPlaying || !sponsorBlockPrefs.sponsorBlockEnabled) return
exoPlayerView.postDelayed(this::checkForSegments, 100)
if (!::segmentData.isInitialized || segmentData.segments.isEmpty())
if (!::segmentData.isInitialized || segmentData.segments.isEmpty()) {
return
}
segmentData.segments.forEach { segment: Segment ->
val segmentStart = (segment.segment!![0] * 1000.0f).toLong()
val segmentEnd = (segment.segment[1] * 1000.0f).toLong()
val currentPosition = exoPlayer.currentPosition
if (currentPosition in segmentStart until segmentEnd) {
if (SponsorBlockSettings.sponsorNotificationsEnabled) {
if (sponsorBlockPrefs.sponsorNotificationsEnabled) {
Toast.makeText(context, R.string.segment_skipped, Toast.LENGTH_SHORT).show()
}
exoPlayer.seekTo(segmentEnd)
@ -399,27 +440,29 @@ class PlayerFragment : Fragment() {
thumbnailUrl = response.thumbnailUrl!!
// check whether related streams and autoplay are enabled
val sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(requireContext())
autoplay = sharedPreferences.getBoolean("autoplay", false)
relatedStreamsEnabled = sharedPreferences.getBoolean("related_streams_toggle", true)
autoplay = PreferenceHelper.getBoolean(requireContext(), "autoplay", false)
relatedStreamsEnabled =
PreferenceHelper.getBoolean(requireContext(), "related_streams_toggle", true)
// save related streams for autoplay
relatedStreams = response.relatedStreams
runOnUiThread {
createExoPlayer(view)
prepareExoPlayerView()
if (response.chapters != null) initializeChapters(response.chapters)
// set media sources for the player
setResolutionAndSubtitles(view, response)
exoPlayer.prepare()
initializePlayerView(view, response)
// support for time stamped links
if (arguments?.getLong("timeStamp") != null) {
val position = arguments?.getLong("timeStamp")!! * 1000
exoPlayer.seekTo(position)
}
exoPlayer.prepare()
exoPlayer.play()
initializePlayerView(view, response)
exoPlayerView.useController = true
initializePlayerNotification(requireContext())
fetchSponsorBlockSegments()
// show comments if related streams disabled
if (!relatedStreamsEnabled) toggleComments()
}
}
@ -427,38 +470,60 @@ class PlayerFragment : Fragment() {
run()
}
private fun setSponsorBlockPrefs() {
sponsorBlockPrefs.sponsorBlockEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_enabled_key", true)
sponsorBlockPrefs.sponsorNotificationsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sb_notifications_key", true)
sponsorBlockPrefs.introEnabled =
PreferenceHelper.getBoolean(requireContext(), "intro_category_key", false)
sponsorBlockPrefs.selfPromoEnabled =
PreferenceHelper.getBoolean(requireContext(), "selfpromo_category_key", false)
sponsorBlockPrefs.interactionEnabled =
PreferenceHelper.getBoolean(requireContext(), "interaction_category_key", false)
sponsorBlockPrefs.sponsorsEnabled =
PreferenceHelper.getBoolean(requireContext(), "sponsors_category_key", true)
sponsorBlockPrefs.outroEnabled =
PreferenceHelper.getBoolean(requireContext(), "outro_category_key", false)
sponsorBlockPrefs.fillerEnabled =
PreferenceHelper.getBoolean(requireContext(), "filler_category_key", false)
sponsorBlockPrefs.musicOffTopicEnabled =
PreferenceHelper.getBoolean(requireContext(), "music_offtopic_category_key", false)
sponsorBlockPrefs.previewEnabled =
PreferenceHelper.getBoolean(requireContext(), "preview_category_key", false)
}
private fun fetchSponsorBlockSegments() {
fun run() {
lifecycleScope.launchWhenCreated {
if (SponsorBlockSettings.sponsorBlockEnabled) {
if (sponsorBlockPrefs.sponsorBlockEnabled) {
val categories: ArrayList<String> = arrayListOf()
if (SponsorBlockSettings.introEnabled) {
if (sponsorBlockPrefs.introEnabled) {
categories.add("intro")
}
if (SponsorBlockSettings.selfPromoEnabled) {
if (sponsorBlockPrefs.selfPromoEnabled) {
categories.add("selfpromo")
}
if (SponsorBlockSettings.interactionEnabled) {
if (sponsorBlockPrefs.interactionEnabled) {
categories.add("interaction")
}
if (SponsorBlockSettings.sponsorsEnabled) {
if (sponsorBlockPrefs.sponsorsEnabled) {
categories.add("sponsor")
}
if (SponsorBlockSettings.outroEnabled) {
if (sponsorBlockPrefs.outroEnabled) {
categories.add("outro")
}
if (SponsorBlockSettings.fillerEnabled) {
if (sponsorBlockPrefs.fillerEnabled) {
categories.add("filler")
}
if (SponsorBlockSettings.musicOfftopicEnabled) {
if (sponsorBlockPrefs.musicOffTopicEnabled) {
categories.add("music_offtopic")
}
if (SponsorBlockSettings.previewEnabled) {
if (sponsorBlockPrefs.previewEnabled) {
categories.add("preview")
}
if (categories.size > 0) {
segmentData = try {
RetrofitInstance.api.getSegments(
videoId!!,
"[\"" + TextUtils.join("\",\"", categories) + "\"]"
@ -490,6 +555,7 @@ class PlayerFragment : Fragment() {
setRepeatToggleModes(RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL)
// controllerShowTimeoutMs = 1500
controllerHideOnTouch = true
useController = false
player = exoPlayer
}
}
@ -507,10 +573,12 @@ class PlayerFragment : Fragment() {
view.findViewById<TextView>(R.id.player_title).text = response.title
view.findViewById<TextView>(R.id.player_description).text = response.description
view.findViewById<TextView>(R.id.exo_title).text = response.title
// Listener for play and pause icon change
exoPlayer.addListener(object : Player.Listener {
override fun onIsPlayingChanged(isPlaying: Boolean) {
if (isPlaying && SponsorBlockSettings.sponsorBlockEnabled) {
if (isPlaying && sponsorBlockPrefs.sponsorBlockEnabled) {
exoPlayerView.postDelayed(
this@PlayerFragment::checkForSegments,
100
@ -523,7 +591,6 @@ class PlayerFragment : Fragment() {
playWhenReady: Boolean,
playbackState: Int
) {
exoPlayerView.keepScreenOn = !(
playbackState == Player.STATE_IDLE ||
playbackState == Player.STATE_ENDED ||
@ -627,15 +694,14 @@ class PlayerFragment : Fragment() {
}
view.findViewById<RelativeLayout>(R.id.player_channel).setOnClickListener {
val activity = view.context as MainActivity
val bundle = bundleOf("channel_id" to response.uploaderUrl)
activity.navController.navigate(R.id.channel, bundle)
activity.findViewById<MotionLayout>(R.id.mainMotionLayout).transitionToEnd()
view.findViewById<MotionLayout>(R.id.playerMotionLayout).transitionToEnd()
}
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
if (sharedPref?.getString("token", "") != "") {
val token = PreferenceHelper.getToken(requireContext())
if (token != "") {
val channelId = response.uploaderUrl?.replace("/channel/", "")
val subButton = view.findViewById<MaterialButton>(R.id.player_subscribe)
isSubscribed(subButton, channelId!!)
@ -698,14 +764,12 @@ class PlayerFragment : Fragment() {
}
private fun setResolutionAndSubtitles(view: View, response: Streams) {
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
val videoFormatPreference = sharedPreferences.getString("player_video_format", "WEBM")
val defres = sharedPreferences.getString("default_res", "")!!
val videoFormatPreference =
PreferenceHelper.getString(requireContext(), "player_video_format", "WEBM")
val defres = PreferenceHelper.getString(requireContext(), "default_res", "")!!
val qualityText = view.findViewById<TextView>(R.id.quality_text)
val qualitySelect = view.findViewById<ImageButton>(R.id.quality_select)
val qualitySelect = view.findViewById<LinearLayout>(R.id.quality_linLayout)
var videosNameArray: Array<CharSequence> = arrayOf()
var videosUrlArray: Array<Uri> = arrayOf()
@ -717,7 +781,6 @@ class PlayerFragment : Fragment() {
}
for (vid in response.videoStreams!!) {
Log.e(TAG, vid.toString())
// append quality to list if it has the preferred format (e.g. MPEG)
if (vid.format.equals(videoFormatPreference)) { // preferred format
videosNameArray += vid.quality!!
@ -817,11 +880,13 @@ class PlayerFragment : Fragment() {
}
private fun createExoPlayer(view: View) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val playbackSpeed = sharedPreferences.getString("playback_speed", "1F")?.toFloat()
val playbackSpeed =
PreferenceHelper.getString(requireContext(), "playback_speed", "1F")?.toFloat()
// multiply by thousand: s -> ms
val bufferingGoal = sharedPreferences.getString("buffering_goal", "50")?.toInt()!! * 1000
val seekIncrement = sharedPreferences.getString("seek_increment", "5")?.toLong()!! * 1000
val bufferingGoal =
PreferenceHelper.getString(requireContext(), "buffering_goal", "50")?.toInt()!! * 1000
val seekIncrement =
PreferenceHelper.getString(requireContext(), "seek_increment", "5")?.toLong()!! * 1000
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine()
val cronetDataSourceFactory: CronetDataSource.Factory =
@ -863,7 +928,6 @@ class PlayerFragment : Fragment() {
}
private fun initializePlayerNotification(c: Context) {
mediaSession = MediaSessionCompat(c, this.javaClass.name)
mediaSession.apply {
isActive = true
@ -887,15 +951,26 @@ class PlayerFragment : Fragment() {
}
}
private fun lockPlayer(isLocked: Boolean) {
val visibility = if (isLocked) View.VISIBLE else View.INVISIBLE
exoPlayerView.findViewById<LinearLayout>(R.id.exo_top_bar_right).visibility = visibility
exoPlayerView.findViewById<ImageButton>(R.id.exo_play_pause).visibility = visibility
exoPlayerView.findViewById<Button>(R.id.exo_ffwd_with_amount).visibility = visibility
exoPlayerView.findViewById<Button>(R.id.exo_rew_with_amount).visibility = visibility
exoPlayerView.findViewById<FrameLayout>(R.id.exo_bottom_bar).visibility = visibility
exoPlayerView.findViewById<TextView>(R.id.exo_title).visibility =
if (isLocked && isFullScreen) View.VISIBLE else View.INVISIBLE
}
private fun isSubscribed(button: MaterialButton, channel_id: String) {
@SuppressLint("ResourceAsColor")
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.isSubscribed(
channel_id,
sharedPref?.getString("token", "")!!
token
)
} catch (e: IOException) {
println(e)
@ -932,9 +1007,9 @@ class PlayerFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.subscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channel_id)
)
} catch (e: IOException) {
@ -955,9 +1030,9 @@ class PlayerFragment : Fragment() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.unsubscribe(
sharedPref?.getString("token", "")!!,
token,
Subscribe(channel_id)
)
} catch (e: IOException) {
@ -1072,7 +1147,11 @@ class PlayerFragment : Fragment() {
isFullScreen
)
) {
requireActivity().enterPictureInPictureMode()
activity?.enterPictureInPictureMode(updatePipParams())
}
}
private fun updatePipParams() = PictureInPictureParams.Builder()
.setActions(emptyList())
.build()
}

View File

@ -1,6 +1,5 @@
package com.github.libretube.fragments
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@ -15,9 +14,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
import com.github.libretube.adapters.PlaylistAdapter
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class PlaylistFragment : Fragment() {
private val TAG = "PlaylistFragment"
@ -75,9 +75,7 @@ class PlaylistFragment : Fragment() {
view.findViewById<TextView>(R.id.playlist_uploader).text = response.uploader
view.findViewById<TextView>(R.id.playlist_totVideos).text =
getString(R.string.videoCount, response.videos.toString())
val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE)
val user = sharedPref2?.getString("username", "")
val user = PreferenceHelper.getUsername(requireContext())
var isOwner = false
if (response.uploaderUrl == null && response.uploader.equals(user, true)) {
isOwner = true
@ -113,7 +111,6 @@ class PlaylistFragment : Fragment() {
private fun fetchNextPage() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
RetrofitInstance.api.getPlaylistNextPage(playlistId!!, nextPage!!)

View File

@ -18,7 +18,6 @@ import android.widget.TextView.OnEditorActionListener
import android.widget.TextView.VISIBLE
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -27,12 +26,13 @@ import com.github.libretube.adapters.SearchAdapter
import com.github.libretube.adapters.SearchHistoryAdapter
import com.github.libretube.adapters.SearchSuggestionsAdapter
import com.github.libretube.hideKeyboard
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import retrofit2.HttpException
import java.io.IOException
class SearchFragment : Fragment() {
private val TAG = "SearchFragment"
@ -94,7 +94,7 @@ class SearchFragment : Fragment() {
tempSelectedItem = id
}
.setPositiveButton(
getString(R.string.okay),
getString(R.string.okay)
) { _, _ ->
selectedFilter = tempSelectedItem
apiSearchFilter = when (selectedFilter) {
@ -266,7 +266,7 @@ class SearchFragment : Fragment() {
private fun showHistory() {
searchRecView.visibility = GONE
val historyList = getHistory()
val historyList = PreferenceHelper.getHistory(requireContext())
if (historyList.isNotEmpty()) {
historyRecView.adapter =
SearchHistoryAdapter(requireContext(), historyList, autoTextView, this)
@ -275,10 +275,10 @@ class SearchFragment : Fragment() {
}
private fun addToHistory(query: String) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val searchHistoryEnabled = sharedPreferences.getBoolean("search_history_toggle", true)
val searchHistoryEnabled =
PreferenceHelper.getBoolean(requireContext(), "search_history_toggle", true)
if (searchHistoryEnabled) {
var historyList = getHistory()
var historyList = PreferenceHelper.getHistory(requireContext())
if ((historyList.isNotEmpty() && historyList.contains(query)) || query == "") {
return
@ -290,20 +290,7 @@ class SearchFragment : Fragment() {
historyList = historyList.takeLast(10)
}
val set: Set<String> = HashSet(historyList)
sharedPreferences.edit().putStringSet("search_history", set)
.apply()
}
}
private fun getHistory(): List<String> {
return try {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val set: Set<String> = sharedPreferences.getStringSet("search_history", HashSet())!!
set.toList()
} catch (e: Exception) {
emptyList()
PreferenceHelper.saveHistory(requireContext(), historyList)
}
}
}

View File

@ -1,6 +1,5 @@
package com.github.libretube.fragments
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
@ -15,7 +14,6 @@ import android.widget.Toast
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@ -23,9 +21,10 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.libretube.R
import com.github.libretube.adapters.SubscriptionAdapter
import com.github.libretube.adapters.SubscriptionChannelAdapter
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import java.io.IOException
import retrofit2.HttpException
import java.io.IOException
class Subscriptions : Fragment() {
val TAG = "SubFragment"
@ -50,8 +49,7 @@ class Subscriptions : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
token = sharedPref?.getString("token", "")!!
token = PreferenceHelper.getToken(requireContext())
refreshLayout = view.findViewById(R.id.sub_refresh)
if (token != "") {
view.findViewById<RelativeLayout>(R.id.loginOrRegister).visibility = View.GONE
@ -63,9 +61,10 @@ class Subscriptions : Fragment() {
var channelRecView = view.findViewById<RecyclerView>(R.id.sub_channels)
var feedRecView = view.findViewById<RecyclerView>(R.id.sub_feed)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val grid = sharedPreferences.getString(
"grid", resources.getInteger(R.integer.grid_items).toString()
val grid = PreferenceHelper.getString(
requireContext(),
"grid",
resources.getInteger(R.integer.grid_items).toString()
)!!
feedRecView.layoutManager = GridLayoutManager(view.context, grid.toInt())
fetchFeed(feedRecView, progressBar, view)

View File

@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
data class CommentsPage(
val comments: MutableList<Comment> = arrayListOf(),
val disabled: Boolean? = null,
val nextpage: String? = "",
val nextpage: String? = ""
) {
constructor() : this(arrayListOf(), null, "")
}

View File

@ -0,0 +1,7 @@
package com.github.libretube.obj
class CustomInstance(
var name: String = "",
var apiUrl: String = "",
var frontendUrl: String = ""
)

View File

@ -0,0 +1,5 @@
package com.github.libretube.obj
data class DeleteUserRequest(
var password: String? = null
)

View File

@ -12,5 +12,5 @@ data class Playlist(
var uploaderUrl: String? = null,
var uploaderAvatar: String? = null,
var videos: Int? = 0,
var relatedStreams: List<StreamItem>? = null,
var relatedStreams: List<StreamItem>? = null
)

View File

@ -6,5 +6,5 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
data class PlaylistId(
var playlistId: String? = null,
var videoId: String? = null,
var index: Int = -1,
var index: Int = -1
)

View File

@ -7,5 +7,5 @@ data class Playlists(
var id: String? = null,
var name: String? = null,
var shortDescription: String? = null,
var thumbnail: String? = null,
var thumbnail: String? = null
)

View File

@ -0,0 +1,14 @@
package com.github.libretube.obj
class SponsorBlockPrefs(
var sponsorBlockEnabled: Boolean = false,
var sponsorNotificationsEnabled: Boolean = false,
var sponsorsEnabled: Boolean = false,
var selfPromoEnabled: Boolean = false,
var interactionEnabled: Boolean = false,
var introEnabled: Boolean = false,
var outroEnabled: Boolean = false,
var fillerEnabled: Boolean = false,
var musicOffTopicEnabled: Boolean = false,
var previewEnabled: Boolean = false
)

View File

@ -1,15 +1,13 @@
package com.github.libretube.preferences
import android.content.Context
import android.os.Bundle
import android.widget.TextView
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.github.libretube.R
import com.github.libretube.requireMainActivityRestart
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.chromium.base.CommandLine.reset
class AdvancedSettings : PreferenceFragmentCompat() {
val TAG = "AdvancedSettings"
@ -22,9 +20,7 @@ class AdvancedSettings : PreferenceFragmentCompat() {
val clearHistory = findPreference<Preference>("clear_history")
clearHistory?.setOnPreferenceClickListener {
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
sharedPreferences.edit().remove("search_history").commit()
PreferenceHelper.removePreference(requireContext(), "search_history")
true
}
@ -39,14 +35,10 @@ class AdvancedSettings : PreferenceFragmentCompat() {
MaterialAlertDialogBuilder(requireContext())
.setPositiveButton(R.string.reset) { _, _ ->
// clear default preferences
val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext())
sharedPreferences.edit().clear().commit()
PreferenceHelper.clearPreferences(requireContext())
// clear login token
val sharedPrefToken =
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
sharedPrefToken?.edit()?.clear()?.commit()
PreferenceHelper.setToken(requireContext(), "")
requireMainActivityRestart = true
activity?.recreate()

View File

@ -21,7 +21,7 @@ class AppearanceSettings : PreferenceFragmentCompat() {
val themeToggle = findPreference<ListPreference>("theme_togglee")
themeToggle?.setOnPreferenceChangeListener { _, _ ->
requireMainActivityRestart = true
ThemeHelper().restartMainActivity(requireContext())
ThemeHelper.restartMainActivity(requireContext())
true
}
@ -34,7 +34,7 @@ class AppearanceSettings : PreferenceFragmentCompat() {
val iconChange = findPreference<ListPreference>("icon_change")
iconChange?.setOnPreferenceChangeListener { _, newValue ->
ThemeHelper().changeIcon(requireContext(), newValue.toString())
ThemeHelper.changeIcon(requireContext(), newValue.toString())
true
}

View File

@ -2,7 +2,6 @@ package com.github.libretube.preferences
import android.Manifest
import android.content.ContentResolver
import android.content.Context
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
@ -19,19 +18,20 @@ import androidx.lifecycle.lifecycleScope
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.github.libretube.R
import com.github.libretube.dialogs.CustomInstanceDialog
import com.github.libretube.dialogs.DeleteAccountDialog
import com.github.libretube.dialogs.LoginDialog
import com.github.libretube.requireMainActivityRestart
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance
import org.json.JSONObject
import org.json.JSONTokener
import retrofit2.HttpException
import java.io.IOException
import java.io.InputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import org.json.JSONObject
import org.json.JSONTokener
import retrofit2.HttpException
class InstanceSettings : PreferenceFragmentCompat() {
val TAG = "InstanceSettings"
@ -59,8 +59,8 @@ class InstanceSettings : PreferenceFragmentCompat() {
val jsonObject = JSONTokener(json).nextValue() as JSONObject
Log.e(TAG, jsonObject.getJSONArray("subscriptions").toString())
for (
i in 0 until jsonObject.getJSONArray("subscriptions")
.length()
i in 0 until jsonObject.getJSONArray("subscriptions")
.length()
) {
var url =
jsonObject.getJSONArray("subscriptions").getJSONObject(i)
@ -85,8 +85,9 @@ class InstanceSettings : PreferenceFragmentCompat() {
inputStream?.bufferedReader()?.readLines()?.forEach {
if (it.isNotBlank()) {
val channelId = it.substringBefore(",")
if (channelId.length == 24)
if (channelId.length == 24) {
channels.add(channelId)
}
}
}
}
@ -132,11 +133,7 @@ class InstanceSettings : PreferenceFragmentCompat() {
val clearCustomInstances = findPreference<Preference>("clearCustomInstances")
clearCustomInstances?.setOnPreferenceClickListener {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
sharedPreferences.edit()
.remove("custom_instances_name")
.remove("custom_instances_url")
.commit()
PreferenceHelper.removePreference(requireContext(), "customInstances")
activity?.recreate()
true
}
@ -149,10 +146,21 @@ class InstanceSettings : PreferenceFragmentCompat() {
true
}
val deleteAccount = findPreference<Preference>("delete_account")
deleteAccount?.setOnPreferenceClickListener {
val token = PreferenceHelper.getToken(requireContext())
if (token != "") {
val newFragment = DeleteAccountDialog()
newFragment.show(childFragmentManager, "DeleteAccountDialog")
} else {
Toast.makeText(context, R.string.login_first, Toast.LENGTH_SHORT).show()
}
true
}
val importFromYt = findPreference<Preference>("import_from_yt")
importFromYt?.setOnPreferenceClickListener {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = sharedPref?.getString("token", "")!!
val token = PreferenceHelper.getToken(requireContext())
// check StorageAccess
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Log.d("myz", "" + Build.VERSION.SDK_INT)
@ -204,27 +212,15 @@ class InstanceSettings : PreferenceFragmentCompat() {
}
private fun initCustomInstances() {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
val customInstances = PreferenceHelper.getCustomInstances(requireContext())
// get the names of the custom instances
val customInstancesNames = try {
sharedPreferences
.getStringSet("custom_instances_name", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
var instanceNames = resources.getStringArray(R.array.instances)
var instanceValues = resources.getStringArray(R.array.instancesValue)
customInstances.forEach { instance ->
instanceNames += instance.name
instanceValues += instance.apiUrl
}
// get the urls of the custom instances
val customInstancesUrls = try {
sharedPreferences
.getStringSet("custom_instances_url", HashSet())!!.toList()
} catch (e: Exception) {
emptyList()
}
val instanceNames = resources.getStringArray(R.array.instances) + customInstancesNames
val instanceValues = resources.getStringArray(R.array.instancesValue) + customInstancesUrls
// add custom instances to the list preference
val instance = findPreference<ListPreference>("selectInstance")
instance?.entries = instanceNames
@ -241,15 +237,7 @@ class InstanceSettings : PreferenceFragmentCompat() {
}
private fun logout() {
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = sharedPref?.getString("token", "")
if (token != "") {
with(sharedPref!!.edit()) {
putString("token", "")
apply()
}
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
}
PreferenceHelper.setToken(requireContext(), "")
}
private fun fetchInstance() {
@ -305,11 +293,10 @@ class InstanceSettings : PreferenceFragmentCompat() {
fun run() {
lifecycleScope.launchWhenCreated {
val response = try {
val sharedPref =
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
val token = PreferenceHelper.getToken(requireContext())
RetrofitInstance.api.importSubscriptions(
false,
sharedPref?.getString("token", "")!!,
token,
channels
)
} catch (e: IOException) {

View File

@ -31,7 +31,7 @@ class MainSettings : PreferenceFragmentCompat() {
val language = findPreference<ListPreference>("language")
language?.setOnPreferenceChangeListener { _, _ ->
ThemeHelper().restartMainActivity(requireContext())
ThemeHelper.restartMainActivity(requireContext())
true
}

View File

@ -3,88 +3,15 @@ package com.github.libretube.preferences
import android.os.Bundle
import android.widget.TextView
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.github.libretube.R
class SponsorBlockSettings : PreferenceFragmentCompat() {
private val TAG = "SponsorBlockSettings"
companion object {
var sponsorBlockEnabled: Boolean = false
var sponsorNotificationsEnabled: Boolean = false
var sponsorsEnabled: Boolean = false
var selfPromoEnabled: Boolean = false
var interactionEnabled: Boolean = false
var introEnabled: Boolean = false
var outroEnabled: Boolean = false
var fillerEnabled: Boolean = false
var musicOfftopicEnabled: Boolean = false
var previewEnabled: Boolean = false
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.sponsorblock_settings, rootKey)
val topBarTextView = activity?.findViewById<TextView>(R.id.topBar_textView)
topBarTextView?.text = getString(R.string.sponsorblock)
val sponsorBlockToggle = findPreference<SwitchPreferenceCompat>("sb_enabled_key")
sponsorBlockToggle?.setOnPreferenceChangeListener { _, newValue ->
sponsorBlockEnabled = newValue as Boolean
true
}
val notificationsToggle = findPreference<SwitchPreferenceCompat>("sb_notifications_key")
notificationsToggle?.setOnPreferenceChangeListener { _, newValue ->
sponsorNotificationsEnabled = newValue as Boolean
true
}
val sponsorToggle = findPreference<SwitchPreferenceCompat>("sponsors_category_key")
sponsorToggle?.setOnPreferenceChangeListener { _, newValue ->
sponsorsEnabled = newValue as Boolean
true
}
val selfPromoToggle = findPreference<SwitchPreferenceCompat>("selfpromo_category_key")
selfPromoToggle?.setOnPreferenceChangeListener { _, newValue ->
selfPromoEnabled = newValue as Boolean
true
}
val interactionToggle = findPreference<SwitchPreferenceCompat>("interaction_category_key")
interactionToggle?.setOnPreferenceChangeListener { _, newValue ->
interactionEnabled = newValue as Boolean
true
}
val introToggle = findPreference<SwitchPreferenceCompat>("intro_category_key")
introToggle?.setOnPreferenceChangeListener { _, newValue ->
introEnabled = newValue as Boolean
true
}
val outroToggle = findPreference<SwitchPreferenceCompat>("outro_category_key")
outroToggle?.setOnPreferenceChangeListener { _, newValue ->
outroEnabled = newValue as Boolean
true
}
val fillerToggle = findPreference<SwitchPreferenceCompat>("filler_category_key")
fillerToggle?.setOnPreferenceChangeListener { _, newValue ->
fillerEnabled = newValue as Boolean
true
}
val musicToggle = findPreference<SwitchPreferenceCompat>("music_offtopic_category_key")
musicToggle?.setOnPreferenceChangeListener { _, newValue ->
musicOfftopicEnabled = newValue as Boolean
true
}
val previewToggle = findPreference<SwitchPreferenceCompat>("preview_category_key")
previewToggle?.setOnPreferenceChangeListener { _, newValue ->
previewEnabled = newValue as Boolean
true
}
}
}

View File

@ -82,7 +82,10 @@ class DescriptionAdapter(
*/
return try {
val resizedBitmap = Bitmap.createScaledBitmap(
bitmap, 1080, 1080, false
bitmap,
1080,
1080,
false
)
resizedBitmap
} catch (e: Exception) {

View File

@ -2,14 +2,12 @@ package com.github.libretube.util
import android.content.Context
import android.os.Build
import androidx.preference.PreferenceManager
import java.util.*
class LocaleHelper {
object LocaleHelper {
fun updateLanguage(context: Context) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val languageName = sharedPreferences.getString("language", "sys")
val languageName = PreferenceHelper.getString(context, "language", "en")
if (languageName != "") {
setLanguage(context, languageName!!)
}

View File

@ -2,6 +2,7 @@ package com.github.libretube.util
import com.github.libretube.obj.Channel
import com.github.libretube.obj.CommentsPage
import com.github.libretube.obj.DeleteUserRequest
import com.github.libretube.obj.Instances
import com.github.libretube.obj.Login
import com.github.libretube.obj.Message
@ -86,6 +87,12 @@ interface PipedApi {
@POST("register")
suspend fun register(@Body login: Login): Token
@POST("user/delete")
suspend fun deleteAccount(
@Header("Authorization") token: String,
@Body password: DeleteUserRequest
)
@GET("feed")
suspend fun getFeed(@Query("authToken") token: String?): List<StreamItem>

View File

@ -0,0 +1,132 @@
package com.github.libretube.util
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.github.libretube.obj.CustomInstance
import com.google.common.reflect.TypeToken
import com.google.gson.Gson
import java.lang.reflect.Type
object PreferenceHelper {
fun setString(context: Context, key: String?, value: String?) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.putString(key, value)
editor.apply()
}
fun setInt(context: Context, key: String?, value: Int) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.putInt(key, value)
editor.apply()
}
fun setLong(context: Context, key: String?, value: Long) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.putLong(key, value)
editor.apply()
}
fun setBoolean(context: Context, key: String?, value: Boolean) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.putBoolean(key, value)
editor.apply()
}
fun getString(context: Context, key: String?, defValue: String?): String? {
val settings: SharedPreferences = getDefaultSharedPreferences(context)
return settings.getString(key, defValue)
}
fun getInt(context: Context, key: String?, defValue: Int): Int {
val settings: SharedPreferences = getDefaultSharedPreferences(context)
return settings.getInt(key, defValue)
}
fun getLong(context: Context, key: String?, defValue: Long): Long {
val settings: SharedPreferences = getDefaultSharedPreferences(context)
return settings.getLong(key, defValue)
}
fun getBoolean(context: Context, key: String?, defValue: Boolean): Boolean {
val settings: SharedPreferences = getDefaultSharedPreferences(context)
return settings.getBoolean(key, defValue)
}
fun clearPreferences(context: Context) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.clear().apply()
}
fun removePreference(context: Context, value: String?) {
val editor = getDefaultSharedPreferencesEditor(context)
editor.remove(value).apply()
}
fun getToken(context: Context): String {
val sharedPref = context.getSharedPreferences("token", Context.MODE_PRIVATE)
return sharedPref?.getString("token", "")!!
}
fun setToken(context: Context, newValue: String) {
val editor = context.getSharedPreferences("token", Context.MODE_PRIVATE).edit()
editor.putString("token", newValue).apply()
}
fun getUsername(context: Context): String {
val sharedPref = context.getSharedPreferences("username", Context.MODE_PRIVATE)
return sharedPref.getString("username", "")!!
}
fun setUsername(context: Context, newValue: String) {
val editor = context.getSharedPreferences("username", Context.MODE_PRIVATE).edit()
editor.putString("username", newValue).apply()
}
fun saveCustomInstance(context: Context, customInstance: CustomInstance) {
val editor = getDefaultSharedPreferencesEditor(context)
val gson = Gson()
val customInstancesList = getCustomInstances(context)
customInstancesList += customInstance
val json = gson.toJson(customInstancesList)
editor.putString("customInstances", json).apply()
}
fun getCustomInstances(context: Context): ArrayList<CustomInstance> {
val settings = getDefaultSharedPreferences(context)
val gson = Gson()
val json: String = settings.getString("customInstances", "")!!
val type: Type = object : TypeToken<List<CustomInstance?>?>() {}.type
return try {
gson.fromJson(json, type)
} catch (e: Exception) {
arrayListOf()
}
}
fun getHistory(context: Context): List<String> {
return try {
val settings = getDefaultSharedPreferences(context)
val set: Set<String> = settings.getStringSet("search_history", HashSet())!!
set.toList()
} catch (e: Exception) {
emptyList()
}
}
fun saveHistory(context: Context, historyList: List<String>) {
val editor = getDefaultSharedPreferencesEditor(context)
val set: Set<String> = HashSet(historyList)
editor.putStringSet("search_history", set).apply()
}
private fun getDefaultSharedPreferences(context: Context): SharedPreferences {
return PreferenceManager.getDefaultSharedPreferences(context)
}
private fun getDefaultSharedPreferencesEditor(context: Context): SharedPreferences.Editor {
return getDefaultSharedPreferences(context).edit()
}
}

View File

@ -7,20 +7,17 @@ import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import com.github.libretube.R
class ThemeHelper {
object ThemeHelper {
fun updateTheme(context: Context) {
updateAccentColor(context)
updateThemeMode(context)
}
fun updateAccentColor(context: Context) {
val colorAccent =
PreferenceManager.getDefaultSharedPreferences(context).getString("accent_color", "red")
when (colorAccent) {
private fun updateAccentColor(context: Context) {
when (PreferenceHelper.getString(context, "accent_color", "red")) {
"my" -> context.setTheme(R.style.Theme_MY)
"red" -> context.setTheme(R.style.Theme_Red)
"blue" -> context.setTheme(R.style.Theme_Blue)
@ -30,10 +27,8 @@ class ThemeHelper {
}
}
fun updateThemeMode(context: Context) {
val themeMode =
PreferenceManager.getDefaultSharedPreferences(context).getString("theme_togglee", "A")
when (themeMode) {
private fun updateThemeMode(context: Context) {
when (PreferenceHelper.getString(context, "theme_togglee", "A")) {
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)

View File

@ -7,12 +7,12 @@ import com.github.libretube.GITHUB_API_URL
import com.github.libretube.dialogs.NoUpdateAvailableDialog
import com.github.libretube.dialogs.UpdateAvailableDialog
import com.github.libretube.obj.UpdateInfo
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.URL
import javax.net.ssl.HttpsURLConnection
import org.json.JSONArray
import org.json.JSONObject
fun checkUpdate(childFragmentManager: FragmentManager) {
var updateInfo: UpdateInfo? = UpdateInfo("", "")

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorSurface"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorSurface">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7.41,8.59L12,13.17l4.59,-4.58L18,10l-6,6 -6,-6 1.41,-1.41z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="14dp"
android:width="14dp"
android:viewportHeight="160"
android:height="14dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="160"
android:tint="?attr/colorControlNormal">
android:viewportHeight="160">
<path
android:fillColor="#FF000000"
android:pathData="M30.24,64.96C27.52,67.61 23.16,67.55 20.51,64.82 17.86,62.1 17.92,57.74 20.64,55.09L75.43,1.97 80.23,6.9 75.42,1.95c2.74,-2.65 7.1,-2.58 9.76,0.15 0.08,0.08 0.15,0.16 0.23,0.24L139.36,55.1c2.72,2.65 2.78,7.01 0.13,9.73 -2.65,2.72 -7,2.78 -9.73,0.14L80.21,16.5Z" />

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M19,17.59L17.59,19L7,8.41V15H5V5H15V7H8.41L19,17.59Z" />
</vector>

View File

@ -1,9 +1,9 @@
<vector android:height="24dp"
android:tint="#FFFFFF"
android:viewportHeight="24"
android:viewportWidth="24"
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,12h-2v3h-3v2h5v-5zM7,9h3L10,7L5,7v5h2L7,9zM21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,19.01L3,19.01L3,4.99h18v14.02z" />

View File

@ -4,7 +4,7 @@
android:viewportWidth="18"
android:viewportHeight="20">
<path
android:pathData="M8.625,0H9.375C9.5821,0 9.75,0.1679 9.75,0.375C9.75,0.5821 9.9179,0.75 10.125,0.75C10.3321,0.75 10.5,0.9179 10.5,1.125V1.875C10.5,2.4963 11.0088,3.0566 11.5685,3.3265C12.4353,3.7446 13.5132,4.5489 14.0889,5.6503C14.2067,5.8758 14.25,6.1307 14.25,6.3852V12.0512C14.25,12.9156 14.8488,13.6151 15.5614,14.1044C15.8681,14.315 16.102,14.5525 16.3642,14.8462C16.4522,14.9448 16.5,15.0728 16.5,15.2049C16.5,15.506 16.256,15.75 15.955,15.75H2.051C1.7467,15.75 1.5,15.5033 1.5,15.199C1.5,15.0704 1.5445,14.9452 1.6287,14.848C1.8916,14.5448 2.1396,14.3062 2.4619,14.0946C3.1737,13.6273 3.75,12.9293 3.75,12.0778V6.3852C3.75,6.1307 3.7933,5.8758 3.9111,5.6503C4.4868,4.5489 5.5648,3.7446 6.4316,3.3265C6.9912,3.0566 7.5,2.4963 7.5,1.875V1.125C7.5,0.9179 7.6679,0.75 7.875,0.75C8.0821,0.75 8.25,0.5821 8.25,0.375C8.25,0.1679 8.4179,0 8.625,0ZM9,19.4998C7.7574,19.4998 6.7501,18.4925 6.75,17.2499H11.25C11.2499,18.4925 10.2426,19.4998 9,19.4998ZM0.0558,7.5132C-0.1246,6.2857 0.1356,5.034 0.7902,3.9801C1.4447,2.9262 2.4513,2.1382 3.6315,1.7557L3.9552,2.7546C3.0111,3.0605 2.2058,3.691 1.6821,4.5341C1.1585,5.3772 0.9503,6.3786 1.0946,7.3605L0.0558,7.5132ZM17.1808,3.934C16.5153,2.8869 15.5006,2.1094 14.3165,1.7392L14.0032,2.7414C14.9504,3.0375 15.7623,3.6596 16.2946,4.4972C16.827,5.3348 17.0455,6.334 16.9115,7.3174L17.9519,7.4592C18.1194,6.2299 17.8463,4.981 17.1808,3.934Z"
android:fillColor="#E6E1E5"
android:fillType="evenOdd" />
android:fillType="evenOdd"
android:pathData="M8.625,0H9.375C9.5821,0 9.75,0.1679 9.75,0.375C9.75,0.5821 9.9179,0.75 10.125,0.75C10.3321,0.75 10.5,0.9179 10.5,1.125V1.875C10.5,2.4963 11.0088,3.0566 11.5685,3.3265C12.4353,3.7446 13.5132,4.5489 14.0889,5.6503C14.2067,5.8758 14.25,6.1307 14.25,6.3852V12.0512C14.25,12.9156 14.8488,13.6151 15.5614,14.1044C15.8681,14.315 16.102,14.5525 16.3642,14.8462C16.4522,14.9448 16.5,15.0728 16.5,15.2049C16.5,15.506 16.256,15.75 15.955,15.75H2.051C1.7467,15.75 1.5,15.5033 1.5,15.199C1.5,15.0704 1.5445,14.9452 1.6287,14.848C1.8916,14.5448 2.1396,14.3062 2.4619,14.0946C3.1737,13.6273 3.75,12.9293 3.75,12.0778V6.3852C3.75,6.1307 3.7933,5.8758 3.9111,5.6503C4.4868,4.5489 5.5648,3.7446 6.4316,3.3265C6.9912,3.0566 7.5,2.4963 7.5,1.875V1.125C7.5,0.9179 7.6679,0.75 7.875,0.75C8.0821,0.75 8.25,0.5821 8.25,0.375C8.25,0.1679 8.4179,0 8.625,0ZM9,19.4998C7.7574,19.4998 6.7501,18.4925 6.75,17.2499H11.25C11.2499,18.4925 10.2426,19.4998 9,19.4998ZM0.0558,7.5132C-0.1246,6.2857 0.1356,5.034 0.7902,3.9801C1.4447,2.9262 2.4513,2.1382 3.6315,1.7557L3.9552,2.7546C3.0111,3.0605 2.2058,3.691 1.6821,4.5341C1.1585,5.3772 0.9503,6.3786 1.0946,7.3605L0.0558,7.5132ZM17.1808,3.934C16.5153,2.8869 15.5006,2.1094 14.3165,1.7392L14.0032,2.7414C14.9504,3.0375 15.7623,3.6596 16.2946,4.4972C16.827,5.3348 17.0455,6.334 16.9115,7.3174L17.9519,7.4592C18.1194,6.2299 17.8463,4.981 17.1808,3.934Z" />
</vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="18"
android:viewportHeight="20">
<path
android:pathData="M8.625,0H9.375C9.5821,0 9.75,0.1679 9.75,0.375C9.75,0.5821 9.9179,0.75 10.125,0.75C10.3321,0.75 10.5,0.9179 10.5,1.125V1.875C10.5,2.4963 11.0088,3.0566 11.5685,3.3265C12.4353,3.7446 13.5132,4.5489 14.0889,5.6503C14.2067,5.8758 14.25,6.1307 14.25,6.3852V12.0512C14.25,12.9156 14.8488,13.6151 15.5614,14.1044C15.8681,14.315 16.102,14.5525 16.3642,14.8462C16.4522,14.9448 16.5,15.0728 16.5,15.2049C16.5,15.506 16.256,15.75 15.955,15.75H2.051C1.7467,15.75 1.5,15.5033 1.5,15.199C1.5,15.0704 1.5445,14.9452 1.6287,14.848C1.8916,14.5448 2.1396,14.3062 2.4619,14.0946C3.1737,13.6273 3.75,12.9293 3.75,12.0778V6.3852C3.75,6.1307 3.7933,5.8758 3.9111,5.6503C4.4868,4.5489 5.5648,3.7446 6.4316,3.3265C6.9912,3.0566 7.5,2.4963 7.5,1.875V1.125C7.5,0.9179 7.6679,0.75 7.875,0.75C8.0821,0.75 8.25,0.5821 8.25,0.375C8.25,0.1679 8.4179,0 8.625,0ZM9,19.4998C7.7574,19.4998 6.7501,18.4925 6.75,17.2499H11.25C11.2499,18.4925 10.2426,19.4998 9,19.4998ZM0.0558,7.5132C-0.1246,6.2857 0.1356,5.034 0.7902,3.9801C1.4447,2.9262 2.4513,2.1382 3.6315,1.7557L3.9552,2.7546C3.0111,3.0605 2.2058,3.691 1.6821,4.5341C1.1585,5.3772 0.9503,6.3786 1.0946,7.3605L0.0558,7.5132ZM17.1808,3.934C16.5153,2.8869 15.5006,2.1094 14.3165,1.7392L14.0032,2.7414C14.9504,3.0375 15.7623,3.6596 16.2946,4.4972C16.827,5.3348 17.0455,6.334 16.9115,7.3174L17.9519,7.4592C18.1194,6.2299 17.8463,4.981 17.1808,3.934Z"
android:fillColor="#E6E1E5"
android:fillType="evenOdd" />
android:fillType="evenOdd"
android:pathData="M8.625,0H9.375C9.5821,0 9.75,0.1679 9.75,0.375C9.75,0.5821 9.9179,0.75 10.125,0.75C10.3321,0.75 10.5,0.9179 10.5,1.125V1.875C10.5,2.4963 11.0088,3.0566 11.5685,3.3265C12.4353,3.7446 13.5132,4.5489 14.0889,5.6503C14.2067,5.8758 14.25,6.1307 14.25,6.3852V12.0512C14.25,12.9156 14.8488,13.6151 15.5614,14.1044C15.8681,14.315 16.102,14.5525 16.3642,14.8462C16.4522,14.9448 16.5,15.0728 16.5,15.2049C16.5,15.506 16.256,15.75 15.955,15.75H2.051C1.7467,15.75 1.5,15.5033 1.5,15.199C1.5,15.0704 1.5445,14.9452 1.6287,14.848C1.8916,14.5448 2.1396,14.3062 2.4619,14.0946C3.1737,13.6273 3.75,12.9293 3.75,12.0778V6.3852C3.75,6.1307 3.7933,5.8758 3.9111,5.6503C4.4868,4.5489 5.5648,3.7446 6.4316,3.3265C6.9912,3.0566 7.5,2.4963 7.5,1.875V1.125C7.5,0.9179 7.6679,0.75 7.875,0.75C8.0821,0.75 8.25,0.5821 8.25,0.375C8.25,0.1679 8.4179,0 8.625,0ZM9,19.4998C7.7574,19.4998 6.7501,18.4925 6.75,17.2499H11.25C11.2499,18.4925 10.2426,19.4998 9,19.4998ZM0.0558,7.5132C-0.1246,6.2857 0.1356,5.034 0.7902,3.9801C1.4447,2.9262 2.4513,2.1382 3.6315,1.7557L3.9552,2.7546C3.0111,3.0605 2.2058,3.691 1.6821,4.5341C1.1585,5.3772 0.9503,6.3786 1.0946,7.3605L0.0558,7.5132ZM17.1808,3.934C16.5153,2.8869 15.5006,2.1094 14.3165,1.7392L14.0032,2.7414C14.9504,3.0375 15.7623,3.6596 16.2946,4.4972C16.827,5.3348 17.0455,6.334 16.9115,7.3174L17.9519,7.4592C18.1194,6.2299 17.8463,4.981 17.1808,3.934Z" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,22.7994C11.55,22.7994 11.1,22.7094 10.74,22.4394 4.89,18.8394 1.29,12.6294 1.2,5.7894 1.2,4.8894 1.65,3.9894 2.46,3.5394 8.4,0.3894 15.6,0.3894 21.54,3.6294 22.35,3.9894 22.8,4.8894 22.8,5.7894 22.71,12.6294 19.11,18.8394 13.35,22.4394 12.9,22.7094 12.45,22.7994 12,22.7994ZM12,1.9194c-3.15,0 -6.3,0.81 -9.18,2.34 -0.54,0.27 -0.9,0.9 -0.9,1.53 0.09,6.57 3.51,12.51 9.18,16.02 0.54,0.36 1.26,0.36 1.8,0C18.57,18.3894 21.9,12.3594 22.08,5.7894 22.08,5.1594 21.72,4.5294 21.18,4.2594 18.3,2.7294 15.15,1.9194 12,1.9194Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,11v2h4v-2h-4zM16,17.61c0.96,0.71 2.21,1.65 3.2,2.39 0.4,-0.53 0.8,-1.07 1.2,-1.6 -0.99,-0.74 -2.24,-1.68 -3.2,-2.4 -0.4,0.54 -0.8,1.08 -1.2,1.61zM20.4,5.6c-0.4,-0.53 -0.8,-1.07 -1.2,-1.6 -0.99,0.74 -2.24,1.68 -3.2,2.4 0.4,0.53 0.8,1.07 1.2,1.6 0.96,-0.72 2.21,-1.65 3.2,-2.4zM4,9c-1.1,0 -2,0.9 -2,2v2c0,1.1 0.9,2 2,2h1v4h2v-4h1l5,3L13,6L8,9L4,9zM15.5,12c0,-1.33 -0.58,-2.53 -1.5,-3.35v6.69c0.92,-0.81 1.5,-2.01 1.5,-3.34z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M24,44Q19.9,44 16.25,42.425Q12.6,40.85 9.875,38.125Q7.15,35.4 5.575,31.75Q4,28.1 4,24Q4,19.8 5.6,16.15Q7.2,12.5 9.975,9.8Q12.75,7.1 16.475,5.55Q20.2,4 24.45,4Q28.4,4 31.95,5.325Q35.5,6.65 38.175,9Q40.85,11.35 42.425,14.575Q44,17.8 44,21.65Q44,27.05 40.85,30.175Q37.7,33.3 32.5,33.3H28.75Q27.85,33.3 27.2,34Q26.55,34.7 26.55,35.55Q26.55,36.55 27.275,37.45Q28,38.35 28,39.6Q28,40.9 26.775,42.45Q25.55,44 24,44ZM12.35,25.3Q13.35,25.3 14.1,24.55Q14.85,23.8 14.85,22.8Q14.85,21.8 14.1,21.05Q13.35,20.3 12.35,20.3Q11.35,20.3 10.6,21.05Q9.85,21.8 9.85,22.8Q9.85,23.8 10.6,24.55Q11.35,25.3 12.35,25.3ZM18.65,16.8Q19.65,16.8 20.4,16.05Q21.15,15.3 21.15,14.3Q21.15,13.3 20.4,12.55Q19.65,11.8 18.65,11.8Q17.65,11.8 16.9,12.55Q16.15,13.3 16.15,14.3Q16.15,15.3 16.9,16.05Q17.65,16.8 18.65,16.8ZM29.35,16.8Q30.35,16.8 31.1,16.05Q31.85,15.3 31.85,14.3Q31.85,13.3 31.1,12.55Q30.35,11.8 29.35,11.8Q28.35,11.8 27.6,12.55Q26.85,13.3 26.85,14.3Q26.85,15.3 27.6,16.05Q28.35,16.8 29.35,16.8ZM35.9,25.3Q36.9,25.3 37.65,24.55Q38.4,23.8 38.4,22.8Q38.4,21.8 37.65,21.05Q36.9,20.3 35.9,20.3Q34.9,20.3 34.15,21.05Q33.4,21.8 33.4,22.8Q33.4,23.8 34.15,24.55Q34.9,25.3 35.9,25.3Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M24,32.1 L13.9,22.05 16.35,19.6 22.3,25.55V7.15H25.7V25.55L31.65,19.6L34.1,22.05ZM10.8,40.55Q9.45,40.55 8.425,39.55Q7.4,38.55 7.4,37.15V29.45H10.8V37.15Q10.8,37.15 10.8,37.15Q10.8,37.15 10.8,37.15H37.15Q37.15,37.15 37.15,37.15Q37.15,37.15 37.15,37.15V29.45H40.55V37.15Q40.55,38.55 39.55,39.55Q38.55,40.55 37.15,40.55Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="300"
android:viewportHeight="300"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="300">
<path
android:fillColor="#FF000000"
android:pathData="M149.99,0C67.16,0 0,67.16 0,150c0,82.84 67.16,150 149.99,150s150,-67.16 150,-150C300,67.16 232.83,0 149.99,0zM110.97,105.36c2.08,-2.08 4.79,-3.11 7.51,-3.11c2.72,0 5.43,1.04 7.51,3.11l13.3,13.3v-3.91V62.48c0,-5.87 4.75,-10.62 10.62,-10.62s10.62,4.75 10.62,10.62v52.26v4.63l4.63,-4.63l9.39,-9.38c2.08,-2.08 4.79,-3.11 7.51,-3.11s5.44,1.04 7.51,3.11c2.55,2.55 3.52,6.08 2.93,9.38c0,0 -0,0 -0,0.01c-0.04,0.24 -0.12,0.47 -0.18,0.7c-0.09,0.37 -0.19,0.73 -0.32,1.08c-0.09,0.24 -0.19,0.47 -0.3,0.7c-0.17,0.37 -0.36,0.73 -0.57,1.08c-0.11,0.19 -0.22,0.37 -0.34,0.55c-0.36,0.52 -0.76,1.03 -1.23,1.5l-15.11,15.11l-16.59,16.59c-2.08,2.08 -4.79,3.11 -7.51,3.11c-0.03,0 -0.05,0 -0.08,0s-0.05,0 -0.08,0c-2.71,0 -5.43,-1.03 -7.51,-3.11l-16.59,-16.59l-15.11,-15.11c-0.47,-0.47 -0.86,-0.97 -1.22,-1.5c-0.13,-0.18 -0.23,-0.37 -0.34,-0.56c-0.21,-0.35 -0.4,-0.7 -0.56,-1.07c-0.11,-0.24 -0.21,-0.47 -0.3,-0.72c-0.13,-0.35 -0.22,-0.7 -0.31,-1.06c-0.06,-0.25 -0.14,-0.49 -0.19,-0.73C107.44,111.44 108.41,107.91 110.97,105.36zM231.57,209.32h-0c0,14.34 -14.06,25.57 -32.01,25.57h-99.13c-17.94,0 -32.01,-11.23 -32.01,-25.57V140.31c0,-12.12 10.06,-21.99 24,-24.76c0.6,5.98 3.22,11.53 7.53,15.83l4.11,4.11h-3.64c-7.26,0 -11.26,3.62 -11.26,4.82v69c0,1.2 3.99,4.82 11.26,4.82h99.14c7.26,0 11.26,-3.62 11.26,-4.82V140.31c0,-1.2 -3.99,-4.82 -11.26,-4.82h-3.12l4.11,-4.11c4.28,-4.28 6.89,-9.79 7.52,-15.73c13.68,2.91 23.5,12.69 23.5,24.66V209.32z" />

View File

@ -1,11 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="143dp"
android:height="144dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="143"
android:viewportHeight="144"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="144">
<path
android:fillColor="#120807"
android:pathData="M35.74,87.66L35.74,41.39c0,-1.44 0.54,-2.7 1.61,-3.78 1.07,-1.08 2.32,-1.62 3.75,-1.62h45.95v5.4L41.11,41.39L41.11,87.66ZM46.47,98.47L46.47,52.2c0,-1.44 0.54,-2.7 1.61,-3.78 1.07,-1.08 2.32,-1.62 3.75,-1.62h45.95v5.4L51.83,52.2L51.83,98.47ZM101.89,108.01L62.56,108.01c-1.43,0 -2.68,-0.54 -3.75,-1.62 -1.07,-1.08 -1.61,-2.34 -1.61,-3.78L57.2,63c0,-1.44 0.54,-2.7 1.61,-3.78 1.07,-1.08 2.32,-1.62 3.75,-1.62h39.33c1.43,0 2.68,0.54 3.75,1.62 1.07,1.08 1.61,2.34 1.61,3.78v39.61c0,1.44 -0.54,2.7 -1.61,3.78 -1.07,1.08 -2.32,1.62 -3.75,1.62zM101.89,102.61L101.89,63L62.56,63L62.56,102.61ZM62.56,63v39.61z"
android:strokeWidth="1"
android:fillColor="#120807" />
android:strokeWidth="1" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M10,18h4v-2h-4v2zM3,6v2h18L21,6L3,6zM6,13h12v-2L6,11v2z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M13.05,21.7 L24.05,4 35.05,21.7ZM35.3,44Q31.6,44 29.1,41.5Q26.6,39 26.6,35.3Q26.6,31.6 29.1,29.1Q31.6,26.6 35.3,26.6Q39,26.6 41.5,29.1Q44,31.6 44,35.3Q44,39 41.5,41.5Q39,44 35.3,44ZM6,42.75V27.55H21.2V42.75Z" />

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-5z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M5,21Q4.175,21 3.587,20.413Q3,19.825 3,19V5Q3,4.175 3.587,3.587Q4.175,3 5,3H11V21ZM13,21V12H21V19Q21,19.825 20.413,20.413Q19.825,21 19,21ZM13,10V3H19Q19.825,3 20.413,3.587Q21,4.175 21,5V10Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M12,30.15H14.5V25.7H19.5V30.15H22V17.85H19.5V23.2H14.5V17.85H12ZM26,30.15H33.5Q34.5,30.15 35.25,29.4Q36,28.65 36,27.65V20.35Q36,19.35 35.25,18.6Q34.5,17.85 33.5,17.85H26ZM28.5,27.65V20.35H33.5Q33.5,20.35 33.5,20.35Q33.5,20.35 33.5,20.35V27.65Q33.5,27.65 33.5,27.65Q33.5,27.65 33.5,27.65ZM7,40Q5.8,40 4.9,39.1Q4,38.2 4,37V11Q4,9.8 4.9,8.9Q5.8,8 7,8H41Q42.2,8 43.1,8.9Q44,9.8 44,11V37Q44,38.2 43.1,39.1Q42.2,40 41,40Z" />

View File

@ -4,6 +4,6 @@
android:viewportWidth="66.911"
android:viewportHeight="66.911">
<path
android:pathData="M66.911,22.831c0,-10.563 -8.558,-19.122 -19.118,-19.122c-5.658,0 -10.721,2.473 -14.223,6.377c-0.037,0.043 -0.076,0.085 -0.113,0.128c-3.5,-3.98 -8.618,-6.505 -14.334,-6.505C8.561,3.709 0.005,12.268 0,22.831c0,5.834 2.629,11.059 6.758,14.565H6.751l27.104,25.806l26.308,-25.806h-0.012C64.279,33.89 66.911,28.669 66.911,22.831z"
android:fillColor="#E34326" />
android:fillColor="#E34326"
android:pathData="M66.911,22.831c0,-10.563 -8.558,-19.122 -19.118,-19.122c-5.658,0 -10.721,2.473 -14.223,6.377c-0.037,0.043 -0.076,0.085 -0.113,0.128c-3.5,-3.98 -8.618,-6.505 -14.334,-6.505C8.561,3.709 0.005,12.268 0,22.831c0,5.834 2.629,11.059 6.758,14.565H6.751l27.104,25.806l26.308,-25.806h-0.012C64.279,33.89 66.911,28.669 66.911,22.831z" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,2c5.523,0 10,4.477 10,10s-4.477,10 -10,10c-1.702,0 -3.305,-0.425 -4.708,-1.175L2,22l1.176,-5.29C2.426,15.306 2,13.703 2,12 2,6.477 6.477,2 12,2zM13,7h-2v7h6v-2h-4L13,7z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportWidth="48"
android:width="24dp"
android:viewportHeight="48"
android:tint="?attr/colorControlNormal">
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="#FF000000"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M24,44Q19.75,44 16.1,42.475Q12.45,40.95 9.75,38.25Q7.05,35.55 5.525,31.9Q4,28.25 4,24Q4,19.8 5.525,16.15Q7.05,12.5 9.75,9.8Q12.45,7.1 16.1,5.55Q19.75,4 24,4Q28.2,4 31.85,5.55Q35.5,7.1 38.2,9.8Q40.9,12.5 42.45,16.15Q44,19.8 44,24Q44,28.25 42.45,31.9Q40.9,35.55 38.2,38.25Q35.5,40.95 31.85,42.475Q28.2,44 24,44ZM24,18.3Q24.7,18.3 25.175,17.85Q25.65,17.4 25.65,16.7Q25.65,16 25.175,15.5Q24.7,15 24,15Q23.3,15 22.825,15.5Q22.35,16 22.35,16.7Q22.35,17.4 22.825,17.85Q23.3,18.3 24,18.3ZM22.65,34H25.65V22H22.65Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportWidth="48"
android:width="24dp"
android:viewportHeight="48"
android:tint="?attr/colorControlNormal">
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="#FF000000"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="96"
android:viewportHeight="96"
android:tint="?attr/colorControlNormal">
android:viewportHeight="96">
<path
android:fillColor="#FF000000"
android:fillType="evenOdd"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M1,21h4L5,9L1,9v12zM23,10c0,-1.1 -0.9,-2 -2,-2h-6.31l0.95,-4.57 0.03,-0.32c0,-0.41 -0.17,-0.79 -0.44,-1.06L14.17,1 7.59,7.59C7.22,7.95 7,8.45 7,9v10c0,1.1 0.9,2 2,2h9c0.83,0 1.54,-0.5 1.84,-1.22l3.02,-7.05c0.09,-0.23 0.14,-0.47 0.14,-0.73v-2z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/black"
android:pathData="M4,14h4v-4L4,10v4zM4,19h4v-4L4,15v4zM4,9h4L8,5L4,5v4zM9,14h12v-4L9,10v4zM9,19h12v-4L9,15v4zM9,5v4h12L21,5L9,5z" />

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="@android:color/holo_green_dark"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z" />
</vector>

View File

@ -1,14 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="24">
<path
android:pathData="M9,3h8a2,2 0,0 1,2 2v14a2,2 0,0 1,-2 2H9m6,-9 l-4,-4m4,4 l-4,4m4,-4H5"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:pathData="M9,3h8a2,2 0,0 1,2 2v14a2,2 0,0 1,-2 2H9m6,-9 l-4,-4m4,4 l-4,4m4,-4H5"
android:strokeWidth="2"
android:strokeColor="@android:color/black"
android:strokeLineCap="round" />
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M10,11H4V3a1,1 0,0 1,1 -1h14a1,1 0,0 1,1 1v18a1,1 0,0 1,-1 1H5a1,1 0,0 1,-1 -1v-8h6v3l5,-4 -5,-4v3z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M22.99,9C19.15,5.16 13.8,3.76 8.84,4.78l2.52,2.52c3.47,-0.17 6.99,1.05 9.63,3.7l2,-2zM18.99,13c-1.29,-1.29 -2.84,-2.13 -4.49,-2.56l3.53,3.53 0.96,-0.97zM2,3.05L5.07,6.1C3.6,6.82 2.22,7.78 1,9l1.99,2c1.24,-1.24 2.67,-2.16 4.2,-2.77l2.24,2.24C7.81,10.89 6.27,11.73 5,13v0.01L6.99,15c1.36,-1.36 3.14,-2.04 4.92,-2.06L18.98,20l1.27,-1.26L3.29,1.79 2,3.05zM9,17l3,3 3,-3c-1.65,-1.66 -4.34,-1.66 -6,0z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="300"
android:viewportHeight="300"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="300">
<path
android:fillColor="#FF000000"
android:pathData="M150,0c-82.84,0 -150,67.16 -150,150c0,82.84 67.16,150 150,150c82.84,0 150,-67.17 150,-150C300,67.16 232.85,0 150,0zM134.41,194.54c0,9.5 -7.7,17.2 -17.2,17.2s-17.2,-7.7 -17.2,-17.2V105.46c0,-9.5 7.7,-17.2 17.2,-17.2s17.2,7.7 17.2,17.2V194.54zM198.96,194.54c0,9.5 -7.7,17.2 -17.2,17.2c-9.5,0 -17.2,-7.7 -17.2,-17.2V105.46c0,-9.5 7.7,-17.2 17.2,-17.2s17.2,7.7 17.2,17.2V194.54z" />

View File

@ -1,11 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16,9V4l1,0c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1H7C6.45,2 6,2.45 6,3v0c0,0.55 0.45,1 1,1l1,0v5c0,1.66 -1.34,3 -3,3h0v2h5.97v7l1,1l1,-1v-7H19v-2h0C17.34,12 16,10.66 16,9z"
android:fillType="evenOdd" />
android:fillType="evenOdd"
android:pathData="M16,9V4l1,0c0.55,0 1,-0.45 1,-1v0c0,-0.55 -0.45,-1 -1,-1H7C6.45,2 6,2.45 6,3v0c0,0.55 0.45,1 1,1l1,0v5c0,1.66 -1.34,3 -3,3h0v2h5.97v7l1,1l1,-1v-7H19v-2h0C17.34,12 16,10.66 16,9z" />
</vector>

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="485.74"
android:viewportHeight="485.74"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="485.74">
<path
android:fillColor="#FF000000"
android:pathData="M242.87,0C108.73,0 0,108.74 0,242.86c0,134.14 108.73,242.88 242.87,242.88c134.14,0 242.86,-108.74 242.86,-242.88C485.74,108.74 377.01,0 242.87,0zM338.41,263.94l-134.36,92.73c-16.78,11.59 -30.58,4.25 -30.58,-16.32V145.38c0,-20.56 13.81,-27.9 30.58,-16.31l134.32,92.73C355.14,233.38 355.18,252.35 338.41,263.94z" />

View File

@ -1,9 +1,9 @@
<vector android:height="24dp"
android:tint="#FFFFFF"
android:viewportHeight="24"
android:viewportWidth="24"
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M4,10h12v2L4,12zM4,6h12v2L4,8zM4,14h8v2L4,16zM14,14v6l5,-3z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M14,10L2,10v2h12v-2zM14,6L2,6v2h12L14,6zM18,14v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2,16h8v-2L2,14v2z" />

View File

@ -1,9 +1,9 @@
<vector android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="?attr/colorControlNormal"
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M7.7,23.3Q6.95,23.3 6.475,22.7Q6,22.1 6,21.25V7.8Q6,7 6.475,6.525Q6.95,6.05 7.7,6.05H40.25Q41.05,6.05 41.525,6.525Q42,7 42,7.8V21.25Q42,22.1 41.525,22.7Q41.05,23.3 40.25,23.3ZM14.35,17.15Q15.4,17.15 16.125,16.425Q16.85,15.7 16.85,14.65Q16.85,13.6 16.125,12.875Q15.4,12.15 14.35,12.15Q13.3,12.15 12.575,12.875Q11.85,13.6 11.85,14.65Q11.85,15.7 12.575,16.425Q13.3,17.15 14.35,17.15ZM7.95,44Q7.15,44 6.575,43.475Q6,42.95 6,41.95V28.75Q6,27.95 6.475,27.325Q6.95,26.7 7.7,26.7H40.05Q40.8,26.7 41.4,27.325Q42,27.95 42,28.75V41.95Q42,42.95 41.4,43.475Q40.8,44 40.05,44ZM14.35,37.85Q15.4,37.85 16.125,37.125Q16.85,36.4 16.85,35.35Q16.85,34.3 16.125,33.575Q15.4,32.85 14.35,32.85Q13.3,32.85 12.575,33.575Q11.85,34.3 11.85,35.35Q11.85,36.4 12.575,37.125Q13.3,37.85 14.35,37.85Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M36.35,44Q34,44 32.325,42.325Q30.65,40.65 30.65,38.3Q30.65,37.95 30.725,37.475Q30.8,37 30.95,36.6L15.8,27.8Q15.05,28.65 13.95,29.175Q12.85,29.7 11.7,29.7Q9.35,29.7 7.675,28.025Q6,26.35 6,24Q6,21.6 7.675,19.95Q9.35,18.3 11.7,18.3Q12.85,18.3 13.9,18.75Q14.95,19.2 15.8,20.05L30.95,11.35Q30.8,11 30.725,10.55Q30.65,10.1 30.65,9.7Q30.65,7.3 32.325,5.65Q34,4 36.35,4Q38.75,4 40.4,5.65Q42.05,7.3 42.05,9.7Q42.05,12.05 40.4,13.725Q38.75,15.4 36.35,15.4Q35.2,15.4 34.125,15.025Q33.05,14.65 32.3,13.8L17.15,22.2Q17.25,22.6 17.325,23.125Q17.4,23.65 17.4,24Q17.4,24.35 17.325,24.75Q17.25,25.15 17.15,25.55L32.3,34.15Q33.05,33.45 34.05,33.025Q35.05,32.6 36.35,32.6Q38.75,32.6 40.4,34.25Q42.05,35.9 42.05,38.3Q42.05,40.65 40.4,42.325Q38.75,44 36.35,44Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="32"
android:viewportHeight="32"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="32">
<path
android:fillColor="#111918"
android:pathData="M20.164,16 L5.098,28.555V3.445ZM12.631,3.445V8.088L22.125,16 12.631,23.912v4.643L27.697,16Z"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="512"
android:viewportHeight="512"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="512">
<path
android:fillColor="#FF000000"
android:pathData="M430.87,128.99l11.91,-11.91c6.38,-6.38 6.38,-16.73 0,-23.11c-6.38,-6.38 -16.73,-6.38 -23.11,0l-11.9,11.9c-36.81,-32.03 -83.82,-52.64 -135.43,-56.26V32.68h4.36c9.02,0 16.34,-7.32 16.34,-16.34c0,-9.02 -7.32,-16.34 -16.34,-16.34h-41.4c-9.02,0 -16.34,7.32 -16.34,16.34c0,9.02 7.32,16.34 16.34,16.34h4.36v16.92c-51.62,3.62 -98.62,24.22 -135.43,56.26L92.33,93.97c-6.38,-6.38 -16.73,-6.38 -23.11,0c-6.38,6.38 -6.38,16.73 0,23.11l11.91,11.91c-35.26,40.63 -56.62,93.63 -56.62,151.52C24.51,408.15 128.36,512 256,512s231.49,-103.85 231.49,-231.49C487.49,222.62 466.13,169.62 430.87,128.99zM256,323.54c-23.73,0 -43.03,-19.3 -43.03,-43.03c0,-17.94 11.04,-33.35 26.69,-39.8v-77.31c0,-9.02 7.32,-16.34 16.34,-16.34c9.02,0 16.34,7.32 16.34,16.34v77.31c15.65,6.45 26.69,21.85 26.69,39.8C299.03,304.24 279.73,323.54 256,323.54z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,22.7994C11.55,22.7994 11.1,22.7094 10.74,22.4394 4.89,18.8394 1.29,12.6294 1.2,5.7894 1.2,4.8894 1.65,3.9894 2.46,3.5394 8.4,0.3894 15.6,0.3894 21.54,3.6294 22.35,3.9894 22.8,4.8894 22.8,5.7894 22.71,12.6294 19.11,18.8394 13.35,22.4394 12.9,22.7094 12.45,22.7994 12,22.7994ZM12,1.9194c-3.15,0 -6.3,0.81 -9.18,2.34 -0.54,0.27 -0.9,0.9 -0.9,1.53 0.09,6.57 3.51,12.51 9.18,16.02 0.54,0.36 1.26,0.36 1.8,0C18.57,18.3894 21.9,12.3594 22.08,5.7894 22.08,5.1594 21.72,4.5294 21.18,4.2594 18.3,2.7294 15.15,1.9194 12,1.9194Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportWidth="48"
android:width="24dp"
android:viewportHeight="48"
android:tint="?attr/colorControlNormal">
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48">
<path
android:fillColor="#FF000000"

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="48">
<path
android:fillColor="#FF000000"
android:pathData="M24,42Q16.5,42 11.25,36.75Q6,31.5 6,24Q6,16.5 11.25,11.25Q16.5,6 24,6Q24.4,6 24.85,6.025Q25.3,6.05 26,6.1Q24.2,7.7 23.2,10.05Q22.2,12.4 22.2,15Q22.2,19.5 25.35,22.65Q28.5,25.8 33,25.8Q35.6,25.8 37.95,24.875Q40.3,23.95 41.9,22.3Q41.95,22.9 41.975,23.275Q42,23.65 42,24Q42,31.5 36.75,36.75Q31.5,42 24,42Z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M1,21h4L5,9L1,9v12zM23,10c0,-1.1 -0.9,-2 -2,-2h-6.31l0.95,-4.57 0.03,-0.32c0,-0.41 -0.17,-0.79 -0.44,-1.06L14.17,1 7.59,7.59C7.22,7.95 7,8.45 7,9v10c0,1.1 0.9,2 2,2h9c0.83,0 1.54,-0.5 1.84,-1.22l3.02,-7.05c0.09,-0.23 0.14,-0.47 0.14,-0.73v-2z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="60"
android:viewportHeight="60"
android:tint="?android:attr/colorControlNormal">
android:viewportHeight="60">
<path
android:fillColor="#FF000000"
android:pathData="M30,0.061c-16.542,0 -30,13.458 -30,30s13.458,29.879 30,29.879s30,-13.337 30,-29.879S46.542,0.061 30,0.061zM32,30.939c0,1.104 -0.896,2 -2,2H14c-1.104,0 -2,-0.896 -2,-2s0.896,-2 2,-2h14v-22c0,-1.104 0.896,-2 2,-2s2,0.896 2,2V30.939z" />

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="#FF000000"

Some files were not shown because too many files have changed in this diff Show More