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) ## Mirrors (read-only)
<a href="https://gitlab.com/libretube/LibreTube">GitLab</a></p> <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 { dependencies {
//debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' //debugImplementation libs.square.leakcanary
implementation 'androidx.appcompat:appcompat:1.4.1' implementation libs.androidx.appcompat
implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation libs.androidx.constraintlayout
implementation 'com.google.android.material:material:1.6.0' implementation libs.androidx.legacySupport
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.2' implementation libs.androidx.multidex
implementation 'androidx.navigation:navigation-ui-ktx:2.4.2' implementation libs.androidx.navigation.fragment
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation libs.androidx.navigation.ui
implementation 'androidx.preference:preference-ktx:1.2.0' implementation libs.androidx.preference
androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation libs.androidx.test.junit
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' androidTestImplementation libs.androidx.test.espressoCore
implementation 'com.squareup.picasso:picasso:2.8' implementation libs.circleimageview
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 'com.squareup.retrofit2:retrofit:2.9.0' implementation libs.material
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0' implementation libs.exoplayer
//do not update jackson annotations! it does not supports <api26 implementation(libs.exoplayer.extension.cronet) { exclude group: 'com.google.android.gms' }
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.3' 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' coreLibraryDesugaring libs.desugaring
implementation('com.google.android.exoplayer:extension-cronet:2.17.1') { exclude group: 'com.google.android.gms' } implementation libs.cronet.embedded
implementation 'org.chromium.net:cronet-embedded:101.4951.41' implementation libs.gson
} }

View File

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

View File

@ -17,8 +17,8 @@ import android.os.IBinder
import android.util.Log import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.preference.PreferenceManager
import com.arthenica.ffmpegkit.FFmpegKit import com.arthenica.ffmpegkit.FFmpegKit
import com.github.libretube.util.PreferenceHelper
import java.io.File import java.io.File
var IS_DOWNLOAD_RUNNING = false var IS_DOWNLOAD_RUNNING = false
@ -48,8 +48,7 @@ class DownloadService : Service() {
videoUrl = intent.getStringExtra("videoUrl")!! videoUrl = intent.getStringExtra("videoUrl")!!
audioUrl = intent.getStringExtra("audioUrl")!! audioUrl = intent.getStringExtra("audioUrl")!!
duration = intent.getIntExtra("duration", 1) duration = intent.getIntExtra("duration", 1)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) extension = PreferenceHelper.getString(this, "video_format", ".mp4")!!
extension = sharedPreferences.getString("video_format", ".mp4")!!
downloadType = if (audioUrl != "" && videoUrl != "") "mux" downloadType = if (audioUrl != "" && videoUrl != "") "mux"
else if (audioUrl != "") "audio" else if (audioUrl != "") "audio"
else if (videoUrl != "") "video" else if (videoUrl != "") "video"
@ -69,7 +68,6 @@ class DownloadService : Service() {
} }
private fun downloadManager() { private fun downloadManager() {
// create folder for temporary files // create folder for temporary files
tempDir = File( tempDir = File(
applicationContext.getExternalFilesDir(DIRECTORY_DOWNLOADS), applicationContext.getExternalFilesDir(DIRECTORY_DOWNLOADS),
@ -84,9 +82,8 @@ class DownloadService : Service() {
Log.e(TAG, "Directory already have") Log.e(TAG, "Directory already have")
} }
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) val downloadLocationPref = PreferenceHelper.getString(this, "download_location", "")
val downloadLocationPref = sharedPreferences.getString("download_location", "") val folderName = PreferenceHelper.getString(this, "download_folder", "LibreTube")
val folderName = sharedPreferences.getString("download_folder", "")
val location = when (downloadLocationPref) { val location = when (downloadLocationPref) {
"downloads" -> Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS) "downloads" -> Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS)
@ -255,10 +252,11 @@ class DownloadService : Service() {
if (returnCode.toString() != "0") downloadFailedNotification() if (returnCode.toString() != "0") downloadFailedNotification()
else downloadSucceededNotification() else downloadSucceededNotification()
onDestroy() 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 // CALLED WHEN SESSION GENERATES STATISTICS
Log.e(TAG + "stat", it.time.toString()) 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.NavController
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.github.libretube.fragments.PlayerFragment import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.fragments.isFullScreen import com.github.libretube.fragments.isFullScreen
import com.github.libretube.preferences.SponsorBlockSettings
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.github.libretube.util.LocaleHelper import com.github.libretube.util.LocaleHelper
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.github.libretube.util.ThemeHelper import com.github.libretube.util.ThemeHelper
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
@ -54,32 +53,12 @@ class MainActivity : AppCompatActivity() {
DynamicColors.applyToActivityIfAvailable(this) DynamicColors.applyToActivityIfAvailable(this)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
CronetHelper.initCronet(this.applicationContext) 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) RetrofitInstance.url =
LocaleHelper().updateLanguage(this) PreferenceHelper.getString(this, "selectInstance", "https://pipedapi.kavin.rocks/")!!
ThemeHelper.updateTheme(this)
LocaleHelper.updateLanguage(this)
// show noInternet Activity if no internet available on app startup // show noInternet Activity if no internet available on app startup
if (!isNetworkAvailable(this)) { if (!isNetworkAvailable(this)) {
@ -100,12 +79,11 @@ class MainActivity : AppCompatActivity() {
bottomNavigationView.setupWithNavController(navController) bottomNavigationView.setupWithNavController(navController)
// hide the trending page if enabled // 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 if (hideTrendingPage) bottomNavigationView.menu.findItem(R.id.home2).isVisible = false
// navigate to the default start tab // navigate to the default start tab
val defaultTab = sharedPreferences.getString("default_tab", "home") when (PreferenceHelper.getString(this, "default_tab", "home")) {
when (defaultTab) {
"home" -> navController.navigate(R.id.home2) "home" -> navController.navigate(R.id.home2)
"subscriptions" -> navController.navigate(R.id.subscriptions) "subscriptions" -> navController.navigate(R.id.subscriptions)
"library" -> navController.navigate(R.id.library) "library" -> navController.navigate(R.id.library)

View File

@ -21,7 +21,7 @@ class RouterActivity : AppCompatActivity() {
handleSendText(uri!!) handleSendText(uri!!)
} else { } else {
// start app as normal if URI not in host list // 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" val TAG = "SettingsActivity"
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
DynamicColors.applyToActivityIfAvailable(this) DynamicColors.applyToActivityIfAvailable(this)
ThemeHelper().updateTheme(this) ThemeHelper.updateTheme(this)
// makes the preference dialogs use material dialogs // makes the preference dialogs use material dialogs
setTheme(R.style.MaterialAlertDialog) setTheme(R.style.MaterialAlertDialog)
@ -54,7 +54,7 @@ class SettingsActivity : AppCompatActivity() {
val nManager = val nManager =
this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
nManager.cancelAll() nManager.cancelAll()
ThemeHelper().restartMainActivity(this) ThemeHelper.restartMainActivity(this)
ActivityCompat.finishAffinity(this) ActivityCompat.finishAffinity(this)
} else { } else {
super.onBackPressed() 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.RetrofitInstance
import com.github.libretube.util.formatShort import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class CommentsAdapter( class CommentsAdapter(
private val videoId: String, private val videoId: String,

View File

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

View File

@ -1,7 +1,6 @@
package com.github.libretube.adapters package com.github.libretube.adapters
import android.app.Activity import android.app.Activity
import android.content.Context
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -14,13 +13,14 @@ import com.github.libretube.MainActivity
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.obj.PlaylistId import com.github.libretube.obj.PlaylistId
import com.github.libretube.obj.Playlists import com.github.libretube.obj.Playlists
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.squareup.picasso.Picasso import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class PlaylistsAdapter( class PlaylistsAdapter(
private val playlists: MutableList<Playlists>, private val playlists: MutableList<Playlists>,
@ -57,11 +57,7 @@ class PlaylistsAdapter(
builder.setTitle(R.string.deletePlaylist) builder.setTitle(R.string.deletePlaylist)
builder.setMessage(R.string.areYouSure) builder.setMessage(R.string.areYouSure)
builder.setPositiveButton(R.string.yes) { _, _ -> builder.setPositiveButton(R.string.yes) { _, _ ->
val sharedPref = holder.v.context.getSharedPreferences( val token = PreferenceHelper.getToken(holder.v.context)
"token",
Context.MODE_PRIVATE
)
val token = sharedPref?.getString("token", "")!!
deletePlaylist(playlist.id!!, token, position) deletePlaylist(playlist.id!!, token, position)
} }
builder.setNegativeButton(R.string.cancel) { _, _ -> builder.setNegativeButton(R.string.cancel) { _, _ ->
@ -96,10 +92,6 @@ class PlaylistsAdapter(
playlists.removeAt(position) playlists.removeAt(position)
// FIXME: This needs to run on UI thread? // FIXME: This needs to run on UI thread?
activity.runOnUiThread { notifyDataSetChanged() } activity.runOnUiThread { notifyDataSetChanged() }
/*if(playlists.isEmpty()){
view.findViewById<ImageView>(R.id.boogh2).visibility=View.VISIBLE
}*/
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, e.toString()) 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 viewsString = if (item.views?.toInt() != -1) item.views.formatShort() else ""
val uploadDate = if (item.uploadedDate != null) item.uploadedDate else "" val uploadDate = if (item.uploadedDate != null) item.uploadedDate else ""
views.text = views.text =
if (viewsString != "" && uploadDate != "") if (viewsString != "" && uploadDate != "") {
"$viewsString$uploadDate" "$viewsString$uploadDate"
else } else {
viewsString + uploadDate viewsString + uploadDate
}
val channelName = v.findViewById<TextView>(R.id.search_channel_name) val channelName = v.findViewById<TextView>(R.id.search_channel_name)
channelName.text = item.uploaderName channelName.text = item.uploaderName
v.setOnClickListener { v.setOnClickListener {
@ -145,9 +146,10 @@ class SearchViewHolder(
val playlistChannelName = v.findViewById<TextView>(R.id.search_name) val playlistChannelName = v.findViewById<TextView>(R.id.search_name)
playlistChannelName.text = item.uploaderName playlistChannelName.text = item.uploaderName
val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos) val playlistVideosNumber = v.findViewById<TextView>(R.id.search_playlist_videos)
if (item.videos?.toInt() != -1) if (item.videos?.toInt() != -1) {
playlistVideosNumber.text = playlistVideosNumber.text =
v.context.getString(R.string.videoCount, item.videos.toString()) v.context.getString(R.string.videoCount, item.videos.toString())
}
v.setOnClickListener { v.setOnClickListener {
// playlist clicked // playlist clicked
val activity = v.context as MainActivity val activity = v.context as MainActivity

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,8 +9,9 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import com.github.libretube.R 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.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import java.net.URL import java.net.URL
@ -36,29 +37,38 @@ class CustomInstanceDialog : DialogFragment() {
} }
addInstanceButton.setOnClickListener { addInstanceButton.setOnClickListener {
val instanceName = instanceNameEditText.text.toString() val customInstance = CustomInstance()
val instanceApiUrl = instanceApiUrlEditText.text.toString() customInstance.name = instanceNameEditText.text.toString()
val instanceFrontendUrl = instanceFrontendUrlEditText.text.toString() customInstance.apiUrl = instanceApiUrlEditText.text.toString()
customInstance.frontendUrl = instanceFrontendUrlEditText.text.toString()
if (instanceName != "" && instanceApiUrl != "" && instanceFrontendUrl != "") { if (
customInstance.name != "" &&
customInstance.apiUrl != "" &&
customInstance.frontendUrl != ""
) {
try { try {
// check whether the URL is valid, otherwise catch // check whether the URL is valid, otherwise catch
URL(instanceApiUrl).toURI() URL(customInstance.apiUrl).toURI()
URL(instanceFrontendUrl).toURI() URL(customInstance.frontendUrl).toURI()
saveCustomInstance(instanceName, instanceApiUrl, instanceFrontendUrl) PreferenceHelper.saveCustomInstance(requireContext(), customInstance)
activity?.recreate() activity?.recreate()
dismiss() dismiss()
} catch (e: Exception) { } catch (e: Exception) {
// invalid URL // invalid URL
Toast.makeText( Toast.makeText(
context, getString(R.string.invalid_url), Toast.LENGTH_SHORT context,
getString(R.string.invalid_url),
Toast.LENGTH_SHORT
).show() ).show()
} }
} else { } else {
// at least one empty input // at least one empty input
Toast.makeText( Toast.makeText(
context, context?.getString(R.string.empty_instance), Toast.LENGTH_SHORT context,
context?.getString(R.string.empty_instance),
Toast.LENGTH_SHORT
).show() ).show()
} }
} }
@ -76,49 +86,4 @@ class CustomInstanceDialog : DialogFragment() {
builder.create() builder.create()
} ?: throw IllegalStateException("Activity cannot be null") } ?: 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 package com.github.libretube.dialogs
import android.app.Dialog import android.app.Dialog
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.util.TypedValue import android.util.TypedValue
@ -15,10 +14,11 @@ import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.obj.Login import com.github.libretube.obj.Login
import com.github.libretube.util.PreferenceHelper
import com.github.libretube.util.RetrofitInstance import com.github.libretube.util.RetrofitInstance
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.IOException
import retrofit2.HttpException import retrofit2.HttpException
import java.io.IOException
class LoginDialog : DialogFragment() { class LoginDialog : DialogFragment() {
private val TAG = "LoginDialog" private val TAG = "LoginDialog"
@ -29,23 +29,17 @@ class LoginDialog : DialogFragment() {
val builder = MaterialAlertDialogBuilder(it) val builder = MaterialAlertDialogBuilder(it)
// Get the layout inflater // Get the layout inflater
val inflater = requireActivity().layoutInflater val inflater = requireActivity().layoutInflater
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) val token = PreferenceHelper.getToken(requireContext())
val token = sharedPref?.getString("token", "")
var view: View var view: View
Log.e("dafaq", token!!) Log.e("dafaq", token!!)
if (token != "") { if (token != "") {
val sharedPref2 = context?.getSharedPreferences("username", Context.MODE_PRIVATE) val user = PreferenceHelper.getUsername(requireContext())
val user = sharedPref2?.getString("username", "")
view = inflater.inflate(R.layout.dialog_logout, null) view = inflater.inflate(R.layout.dialog_logout, null)
view.findViewById<TextView>(R.id.user).text = view.findViewById<TextView>(R.id.user).text =
view.findViewById<TextView>(R.id.user).text.toString() + " (" + user + ")" view.findViewById<TextView>(R.id.user).text.toString() + " (" + user + ")"
view.findViewById<Button>(R.id.logout).setOnClickListener { view.findViewById<Button>(R.id.logout).setOnClickListener {
Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.loggedout, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) PreferenceHelper.setToken(requireContext(), "")
with(sharedPref!!.edit()) {
putString("token", "")
apply()
}
dialog?.dismiss() dialog?.dismiss()
} }
} else { } else {
@ -99,24 +93,15 @@ class LoginDialog : DialogFragment() {
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated return@launchWhenCreated
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "dafaq?" + e.toString()) Log.e(TAG, "dafaq?$e")
return@launchWhenCreated return@launchWhenCreated
} }
if (response.error != null) { if (response.error != null) {
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show() Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
} else if (response.token != null) { } else if (response.token != null) {
Toast.makeText(context, R.string.loggedIn, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.loggedIn, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) PreferenceHelper.setToken(requireContext(), response.token!!)
with(sharedPref!!.edit()) { PreferenceHelper.setUsername(requireContext(), login.username!!)
putString("token", response.token)
apply()
}
val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE)
with(sharedPref2!!.edit()) {
putString("username", login.username)
apply()
}
dialog?.dismiss() dialog?.dismiss()
} }
} }
@ -139,24 +124,15 @@ class LoginDialog : DialogFragment() {
Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.server_error, Toast.LENGTH_SHORT).show()
return@launchWhenCreated return@launchWhenCreated
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "dafaq?" + e.toString()) Log.e(TAG, "dafaq?$e")
return@launchWhenCreated return@launchWhenCreated
} }
if (response.error != null) { if (response.error != null) {
Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show() Toast.makeText(context, response.error, Toast.LENGTH_SHORT).show()
} else if (response.token != null) { } else if (response.token != null) {
Toast.makeText(context, R.string.registered, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.registered, Toast.LENGTH_SHORT).show()
val sharedPref = context?.getSharedPreferences("token", Context.MODE_PRIVATE) PreferenceHelper.setToken(requireContext(), response.token!!)
with(sharedPref!!.edit()) { PreferenceHelper.setUsername(requireContext(), login.username!!)
putString("token", response.token)
apply()
}
val sharedPref2 =
context?.getSharedPreferences("username", Context.MODE_PRIVATE)
with(sharedPref2!!.edit()) {
putString("username", login.username)
apply()
}
dialog?.dismiss() dialog?.dismiss()
} }
} }

View File

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

View File

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

View File

@ -8,6 +8,7 @@ import android.widget.Toast
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.github.libretube.BackgroundMode import com.github.libretube.BackgroundMode
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder 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 // Add Video to Playlist Dialog
1 -> { 1 -> {
val sharedPref = context?.getSharedPreferences( val token = PreferenceHelper.getToken(requireContext())
"token",
Context.MODE_PRIVATE
)
val token = sharedPref?.getString("token", "")
if (token != "") { if (token != "") {
val newFragment = AddtoPlaylistDialog() val newFragment = AddtoPlaylistDialog()
val bundle = Bundle() val bundle = Bundle()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties
data class CommentsPage( data class CommentsPage(
val comments: MutableList<Comment> = arrayListOf(), val comments: MutableList<Comment> = arrayListOf(),
val disabled: Boolean? = null, val disabled: Boolean? = null,
val nextpage: String? = "", val nextpage: String? = ""
) { ) {
constructor() : this(arrayListOf(), null, "") 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 uploaderUrl: String? = null,
var uploaderAvatar: String? = null, var uploaderAvatar: String? = null,
var videos: Int? = 0, 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( data class PlaylistId(
var playlistId: String? = null, var playlistId: String? = null,
var videoId: 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 id: String? = null,
var name: String? = null, var name: String? = null,
var shortDescription: 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 package com.github.libretube.preferences
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.requireMainActivityRestart import com.github.libretube.requireMainActivityRestart
import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.chromium.base.CommandLine.reset
class AdvancedSettings : PreferenceFragmentCompat() { class AdvancedSettings : PreferenceFragmentCompat() {
val TAG = "AdvancedSettings" val TAG = "AdvancedSettings"
@ -22,9 +20,7 @@ class AdvancedSettings : PreferenceFragmentCompat() {
val clearHistory = findPreference<Preference>("clear_history") val clearHistory = findPreference<Preference>("clear_history")
clearHistory?.setOnPreferenceClickListener { clearHistory?.setOnPreferenceClickListener {
val sharedPreferences = PreferenceHelper.removePreference(requireContext(), "search_history")
PreferenceManager.getDefaultSharedPreferences(requireContext())
sharedPreferences.edit().remove("search_history").commit()
true true
} }
@ -39,14 +35,10 @@ class AdvancedSettings : PreferenceFragmentCompat() {
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setPositiveButton(R.string.reset) { _, _ -> .setPositiveButton(R.string.reset) { _, _ ->
// clear default preferences // clear default preferences
val sharedPreferences = PreferenceHelper.clearPreferences(requireContext())
PreferenceManager.getDefaultSharedPreferences(requireContext())
sharedPreferences.edit().clear().commit()
// clear login token // clear login token
val sharedPrefToken = PreferenceHelper.setToken(requireContext(), "")
context?.getSharedPreferences("token", Context.MODE_PRIVATE)
sharedPrefToken?.edit()?.clear()?.commit()
requireMainActivityRestart = true requireMainActivityRestart = true
activity?.recreate() activity?.recreate()

View File

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

View File

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

View File

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

View File

@ -3,88 +3,15 @@ package com.github.libretube.preferences
import android.os.Bundle import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
import com.github.libretube.R import com.github.libretube.R
class SponsorBlockSettings : PreferenceFragmentCompat() { class SponsorBlockSettings : PreferenceFragmentCompat() {
private val TAG = "SponsorBlockSettings" 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?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.sponsorblock_settings, rootKey) setPreferencesFromResource(R.xml.sponsorblock_settings, rootKey)
val topBarTextView = activity?.findViewById<TextView>(R.id.topBar_textView) val topBarTextView = activity?.findViewById<TextView>(R.id.topBar_textView)
topBarTextView?.text = getString(R.string.sponsorblock) 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 { return try {
val resizedBitmap = Bitmap.createScaledBitmap( val resizedBitmap = Bitmap.createScaledBitmap(
bitmap, 1080, 1080, false bitmap,
1080,
1080,
false
) )
resizedBitmap resizedBitmap
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -2,14 +2,12 @@ package com.github.libretube.util
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import androidx.preference.PreferenceManager
import java.util.* import java.util.*
class LocaleHelper { object LocaleHelper {
fun updateLanguage(context: Context) { fun updateLanguage(context: Context) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) val languageName = PreferenceHelper.getString(context, "language", "en")
val languageName = sharedPreferences.getString("language", "sys")
if (languageName != "") { if (languageName != "") {
setLanguage(context, 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.Channel
import com.github.libretube.obj.CommentsPage import com.github.libretube.obj.CommentsPage
import com.github.libretube.obj.DeleteUserRequest
import com.github.libretube.obj.Instances import com.github.libretube.obj.Instances
import com.github.libretube.obj.Login import com.github.libretube.obj.Login
import com.github.libretube.obj.Message import com.github.libretube.obj.Message
@ -86,6 +87,12 @@ interface PipedApi {
@POST("register") @POST("register")
suspend fun register(@Body login: Login): Token suspend fun register(@Body login: Login): Token
@POST("user/delete")
suspend fun deleteAccount(
@Header("Authorization") token: String,
@Body password: DeleteUserRequest
)
@GET("feed") @GET("feed")
suspend fun getFeed(@Query("authToken") token: String?): List<StreamItem> 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 android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager
import com.github.libretube.R import com.github.libretube.R
class ThemeHelper { object ThemeHelper {
fun updateTheme(context: Context) { fun updateTheme(context: Context) {
updateAccentColor(context) updateAccentColor(context)
updateThemeMode(context) updateThemeMode(context)
} }
fun updateAccentColor(context: Context) { private fun updateAccentColor(context: Context) {
val colorAccent = when (PreferenceHelper.getString(context, "accent_color", "red")) {
PreferenceManager.getDefaultSharedPreferences(context).getString("accent_color", "red")
when (colorAccent) {
"my" -> context.setTheme(R.style.Theme_MY) "my" -> context.setTheme(R.style.Theme_MY)
"red" -> context.setTheme(R.style.Theme_Red) "red" -> context.setTheme(R.style.Theme_Red)
"blue" -> context.setTheme(R.style.Theme_Blue) "blue" -> context.setTheme(R.style.Theme_Blue)
@ -30,10 +27,8 @@ class ThemeHelper {
} }
} }
fun updateThemeMode(context: Context) { private fun updateThemeMode(context: Context) {
val themeMode = when (PreferenceHelper.getString(context, "theme_togglee", "A")) {
PreferenceManager.getDefaultSharedPreferences(context).getString("theme_togglee", "A")
when (themeMode) {
"A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) "A" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
"L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) "L" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
"D" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) "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.NoUpdateAvailableDialog
import com.github.libretube.dialogs.UpdateAvailableDialog import com.github.libretube.dialogs.UpdateAvailableDialog
import com.github.libretube.obj.UpdateInfo import com.github.libretube.obj.UpdateInfo
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStreamReader import java.io.InputStreamReader
import java.net.URL import java.net.URL
import javax.net.ssl.HttpsURLConnection import javax.net.ssl.HttpsURLConnection
import org.json.JSONArray
import org.json.JSONObject
fun checkUpdate(childFragmentManager: FragmentManager) { fun checkUpdate(childFragmentManager: FragmentManager) {
var updateInfo: UpdateInfo? = UpdateInfo("", "") var updateInfo: UpdateInfo? = UpdateInfo("", "")

View File

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

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="14dp"
android:width="14dp" android:width="14dp"
android:viewportHeight="160" android:height="14dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="160" android:viewportWidth="160"
android:tint="?attr/colorControlNormal"> android:viewportHeight="160">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" 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 <path
android:fillColor="@android:color/white" 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" /> 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:viewportWidth="18"
android:viewportHeight="20"> android:viewportHeight="20">
<path <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: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> </vector>

View File

@ -4,7 +4,7 @@
android:viewportWidth="18" android:viewportWidth="18"
android:viewportHeight="20"> android:viewportHeight="20">
<path <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: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> </vector>

View File

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

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48" android:viewportWidth="48"
android:viewportHeight="48" android:viewportHeight="48">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="300" android:viewportWidth="300"
android:viewportHeight="300" android:viewportHeight="300">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="143dp" android:width="143dp"
android:height="144dp" android:height="144dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="143" android:viewportWidth="143"
android:viewportHeight="144" android:viewportHeight="144">
android:tint="?android:attr/colorControlNormal">
<path <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: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:strokeWidth="1" />
android:fillColor="#120807" />
</vector> </vector>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/black" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?android:attr/colorControlNormal">
<path <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: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:strokeColor="@android:color/black"
android:strokeLineCap="round" /> android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector> </vector>

View File

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

View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="485.74" android:viewportWidth="485.74"
android:viewportHeight="485.74" android:viewportHeight="485.74">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:tint="#FFFFFF"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" 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 <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M4,10h12v2L4,12zM4,6h12v2L4,8zM4,14h8v2L4,16zM14,14v6l5,-3z" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="@android:color/white" android:fillColor="@android:color/white"
android:pathData="M14,10L2,10v2h12v-2zM14,6L2,6v2h12L14,6zM18,14v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zM2,16h8v-2L2,14v2z" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="?attr/colorControlNormal"
android:width="24dp" 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 <path
android:fillColor="@android:color/white" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48" android:viewportWidth="48"
android:viewportHeight="48" android:viewportHeight="48">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="48" android:viewportWidth="48"
android:viewportHeight="48" android:viewportHeight="48">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="32" android:viewportWidth="32"
android:viewportHeight="32" android:viewportHeight="32">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#111918" 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" 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="512" android:viewportWidth="512"
android:viewportHeight="512" android:viewportHeight="512">
android:tint="?android:attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24" android:viewportWidth="24"
android:viewportHeight="24" android:viewportHeight="24">
android:tint="?attr/colorControlNormal">
<path <path
android:fillColor="#FF000000" 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" /> 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" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:viewportWidth="48"
android:width="24dp" android:width="24dp"
android:viewportHeight="48" android:height="24dp"
android:tint="?attr/colorControlNormal"> android:tint="?attr/colorControlNormal"
android:viewportWidth="48"
android:viewportHeight="48">
<path <path
android:fillColor="#FF000000" android:fillColor="#FF000000"

View File

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

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