diff --git a/.github/tg.py b/.github/tg.py
new file mode 100644
index 000000000..045443816
--- /dev/null
+++ b/.github/tg.py
@@ -0,0 +1,22 @@
+import telegram
+from tgconfig import TG_TOKEN
+from json import load
+from time import sleep
+
+f = open('commit.json')
+data = load(f)
+f.close()
+
+TG_CHAT_ID = "-1001537505605"
+bot = telegram.Bot(TG_TOKEN)
+
+bot.send_photo(TG_CHAT_ID, open('alpha.png', 'rb'), f'''*Libretube {data['sha'][0:7]} // Alpha*
+
+{data['commit']['message']}
+
+Signed-off-by: {data['commit']['author']['name']}
+''', parse_mode=telegram.ParseMode.MARKDOWN)
+bot.send_document(TG_CHAT_ID, open('app-arm64-v8a-debug.apk', 'rb'))
+bot.send_document(TG_CHAT_ID, open('app-armeabi-v7a-debug.apk', 'rb'))
+bot.send_document(TG_CHAT_ID, open('app-x86_64-debug.apk', 'rb'))
+bot.send_document(TG_CHAT_ID, open('app-x86-debug.apk', 'rb'))
\ No newline at end of file
diff --git a/.github/workflows/tg-bot.yml b/.github/workflows/tg-bot.yml
new file mode 100644
index 000000000..7ca78bb81
--- /dev/null
+++ b/.github/workflows/tg-bot.yml
@@ -0,0 +1,42 @@
+name: Telegram Builder
+
+on:
+ workflow_dispatch:
+ push:
+ paths-ignore:
+ - "README*.md"
+ - "fastlane/**"
+ - "assets/**"
+ - ".github/**/*.md"
+
+jobs:
+ debug-builds:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: gradle/wrapper-validation-action@v1
+ - uses: actions/setup-python@v3
+ with:
+ python-version: '3.x' # Version range or exact version of a Python version to use, using SemVer's version range syntax
+ architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
+
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: 11
+ distribution: "temurin"
+ cache: "gradle"
+
+ - name: Build debug APK and run jvm tests
+ run: ./gradlew assembleDebug
+
+ - name: Telegram Bot
+ run: |
+ mv app/build/outputs/apk/debug/*.apk .github/
+ cd .github
+ curl https://libre-tube.github.io/assets/LibreAlpha.png --output alpha.png
+ echo "TG_TOKEN = '${{ secrets.TG_TOKEN }}'" > tgconfig.py
+ curl https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }} > commit.json
+ python -m pip install --upgrade pip
+ pip install python-telegram-bot
+ python tg.py
diff --git a/README.md b/README.md
index 43afb4231..ea9c659f7 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@
[![Reddit](https://libre-tube.github.io/assets/rd-widget.svg)](https://www.reddit.com/r/Libretube/)
[](https://f-droid.org/en/packages/com.github.libretube/)
+[](https://apt.izzysoft.de/fdroid/index/apk/com.github.libretube)
[](https://github.com/libre-tube/LibreTube/releases/latest)
[](https://t.me/LibreTube)
@@ -49,6 +50,8 @@ WARNING: THIS IS A BETA VERSION, THEREFORE YOU MAY ENCOUNTER BUGS. IF YOU DO, OP
### Donate
+[![Support us on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dlibretubeteam%26type%3Dpatrons&style=for-the-badge)](https://patreon.com/libretubeteam)
+
**BTC:** `bc1q0hk2smc74ej8fxupfrp05wk867e54e2zztnxfc`
**XMR:** `44txdmy4E5bDzMYQJh1ZSoHbrp1sWfpGa2FYg26L2ya8EaRejPsh42yVrYhepW9P4YWvrqmTZvms35z5FDgqy1xcVewk18d`
diff --git a/app/src/main/java/com/github/libretube/MainActivity.kt b/app/src/main/java/com/github/libretube/MainActivity.kt
index a20f7971d..183fe853f 100644
--- a/app/src/main/java/com/github/libretube/MainActivity.kt
+++ b/app/src/main/java/com/github/libretube/MainActivity.kt
@@ -53,7 +53,7 @@ class MainActivity : AppCompatActivity() {
CronetHelper.initCronet(this.applicationContext)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
RetrofitInstance.url =
- sharedPreferences.getString("instance", "https://pipedapi.kavin.rocks/")!!
+ sharedPreferences.getString("selectInstance", "https://pipedapi.kavin.rocks/")!!
SponsorBlockSettings.sponsorBlockEnabled =
sharedPreferences.getBoolean("sb_enabled_key", false)
SponsorBlockSettings.sponsorNotificationsEnabled =
diff --git a/app/src/main/java/com/github/libretube/adapters/ChannelAdapter.kt b/app/src/main/java/com/github/libretube/adapters/ChannelAdapter.kt
index 5b8f70bc8..28f716ac1 100644
--- a/app/src/main/java/com/github/libretube/adapters/ChannelAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/ChannelAdapter.kt
@@ -10,9 +10,9 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
-import com.github.libretube.formatShort
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.StreamItem
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
class ChannelAdapter(private val videoFeed: MutableList) :
diff --git a/app/src/main/java/com/github/libretube/adapters/CommentsAdapter.kt b/app/src/main/java/com/github/libretube/adapters/CommentsAdapter.kt
index 7740c7e58..efce52157 100644
--- a/app/src/main/java/com/github/libretube/adapters/CommentsAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/CommentsAdapter.kt
@@ -14,10 +14,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.MainActivity
import com.github.libretube.R
-import com.github.libretube.formatShort
import com.github.libretube.obj.Comment
import com.github.libretube.obj.CommentsPage
import com.github.libretube.util.RetrofitInstance
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
diff --git a/app/src/main/java/com/github/libretube/adapters/RepliesAdapter.kt b/app/src/main/java/com/github/libretube/adapters/RepliesAdapter.kt
index de06907ae..7cd46cfc8 100644
--- a/app/src/main/java/com/github/libretube/adapters/RepliesAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/RepliesAdapter.kt
@@ -10,8 +10,8 @@ import androidx.core.os.bundleOf
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.MainActivity
import com.github.libretube.R
-import com.github.libretube.formatShort
import com.github.libretube.obj.Comment
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
class RepliesAdapter(
diff --git a/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt b/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt
index d1fa29523..75fedea49 100644
--- a/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/SearchAdapter.kt
@@ -14,9 +14,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.MainActivity
import com.github.libretube.R
import com.github.libretube.dialogs.VideoOptionsDialog
-import com.github.libretube.formatShort
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.SearchItem
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
class SearchAdapter(
diff --git a/app/src/main/java/com/github/libretube/adapters/SearchHistoryAdapter.kt b/app/src/main/java/com/github/libretube/adapters/SearchHistoryAdapter.kt
index 2de707573..7dfdeaa72 100644
--- a/app/src/main/java/com/github/libretube/adapters/SearchHistoryAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/SearchHistoryAdapter.kt
@@ -4,17 +4,19 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.AutoCompleteTextView
+import android.widget.EditText
import android.widget.TextView
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.R
+import com.github.libretube.fragments.SearchFragment
import com.google.android.material.imageview.ShapeableImageView
class SearchHistoryAdapter(
private val context: Context,
private var historyList: List,
- private val editText: AutoCompleteTextView
+ private val editText: EditText,
+ private val searchFragment: SearchFragment
) :
RecyclerView.Adapter() {
@@ -34,17 +36,14 @@ class SearchHistoryAdapter(
holder.v.findViewById(R.id.delete_history).setOnClickListener {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
-
historyList = historyList - history
-
- sharedPreferences.edit().putStringSet("search_history", HashSet(historyList))
- .apply()
-
+ sharedPreferences.edit().putStringSet("search_history", HashSet(historyList)).apply()
notifyDataSetChanged()
}
holder.v.setOnClickListener {
editText.setText(history)
+ searchFragment.fetchSearch(history)
}
}
}
diff --git a/app/src/main/java/com/github/libretube/adapters/SearchSuggestionsAdapter.kt b/app/src/main/java/com/github/libretube/adapters/SearchSuggestionsAdapter.kt
new file mode 100644
index 000000000..fb899db41
--- /dev/null
+++ b/app/src/main/java/com/github/libretube/adapters/SearchSuggestionsAdapter.kt
@@ -0,0 +1,43 @@
+package com.github.libretube.adapters
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.EditText
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.github.libretube.R
+import com.github.libretube.fragments.SearchFragment
+
+class SearchSuggestionsAdapter(
+ private var suggestionsList: List,
+ private var editText: EditText,
+ private val searchFragment: SearchFragment
+) :
+ RecyclerView.Adapter() {
+
+ override fun getItemCount(): Int {
+ return suggestionsList.size
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchSuggestionsViewHolder {
+ val layoutInflater = LayoutInflater.from(parent.context)
+ val cell = layoutInflater.inflate(R.layout.searchsuggestion_row, parent, false)
+ return SearchSuggestionsViewHolder(cell)
+ }
+
+ override fun onBindViewHolder(holder: SearchSuggestionsViewHolder, position: Int) {
+ val suggestion = suggestionsList[position]
+ val suggestionTextView = holder.v.findViewById(R.id.suggestion_text)
+ suggestionTextView.text = suggestion
+ holder.v.setOnClickListener {
+ editText.setText(suggestion)
+ searchFragment.fetchSearch(editText.text.toString())
+ }
+ }
+}
+
+class SearchSuggestionsViewHolder(val v: View) : RecyclerView.ViewHolder(v) {
+ init {
+ }
+}
diff --git a/app/src/main/java/com/github/libretube/adapters/SubscriptionAdapter.kt b/app/src/main/java/com/github/libretube/adapters/SubscriptionAdapter.kt
index 3e37fd814..0db923b83 100644
--- a/app/src/main/java/com/github/libretube/adapters/SubscriptionAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/SubscriptionAdapter.kt
@@ -15,9 +15,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.MainActivity
import com.github.libretube.R
import com.github.libretube.dialogs.VideoOptionsDialog
-import com.github.libretube.formatShort
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.StreamItem
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
class SubscriptionAdapter(
diff --git a/app/src/main/java/com/github/libretube/adapters/TrendingAdapter.kt b/app/src/main/java/com/github/libretube/adapters/TrendingAdapter.kt
index 376171c9e..0d223e54d 100644
--- a/app/src/main/java/com/github/libretube/adapters/TrendingAdapter.kt
+++ b/app/src/main/java/com/github/libretube/adapters/TrendingAdapter.kt
@@ -15,9 +15,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.MainActivity
import com.github.libretube.R
import com.github.libretube.dialogs.VideoOptionsDialog
-import com.github.libretube.formatShort
import com.github.libretube.fragments.PlayerFragment
import com.github.libretube.obj.StreamItem
+import com.github.libretube.util.formatShort
import com.squareup.picasso.Picasso
class TrendingAdapter(
diff --git a/app/src/main/java/com/github/libretube/dialogs/CustomInstanceDialog.kt b/app/src/main/java/com/github/libretube/dialogs/CustomInstanceDialog.kt
new file mode 100644
index 000000000..945a3f405
--- /dev/null
+++ b/app/src/main/java/com/github/libretube/dialogs/CustomInstanceDialog.kt
@@ -0,0 +1,106 @@
+package com.github.libretube.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import android.util.Log
+import android.util.TypedValue
+import android.view.View
+import android.widget.Button
+import android.widget.TextView
+import android.widget.Toast
+import androidx.core.text.HtmlCompat
+import androidx.fragment.app.DialogFragment
+import androidx.preference.PreferenceManager
+import com.github.libretube.R
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.textfield.TextInputEditText
+import java.net.URL
+
+class CustomInstanceDialog : DialogFragment() {
+ val TAG = "CustomInstanceDialog"
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return activity?.let {
+ val builder = MaterialAlertDialogBuilder(it)
+ val inflater = requireActivity().layoutInflater
+ val view: View = inflater.inflate(R.layout.dialog_custom_instance, null)
+
+ val instanceNameEditText = view.findViewById(R.id.instanceName)
+ val instanceApiUrlEditText = view.findViewById(R.id.instanceApiUrl)
+ val addInstanceButton = view.findViewById