mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Library search support
This commit is contained in:
@@ -63,6 +63,7 @@ import com.futo.platformplayer.fragment.mainactivity.main.LibraryArtistFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryArtistsFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryFilesFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibrarySearchFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryVideosFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.MainFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PlaylistFragment
|
||||
@@ -194,6 +195,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
||||
lateinit var _fragLibraryArtists: LibraryArtistsFragment;
|
||||
lateinit var _fragLibraryArtist: LibraryArtistFragment;
|
||||
lateinit var _fragLibraryVideos: LibraryVideosFragment;
|
||||
lateinit var _fragLibrarySearch: LibrarySearchFragment;
|
||||
lateinit var _fragLibraryFiles: LibraryFilesFragment;
|
||||
|
||||
lateinit var _fragBrowser: BrowserFragment;
|
||||
@@ -374,6 +376,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
||||
_fragLibraryArtist = LibraryArtistFragment.newInstance();
|
||||
_fragLibraryVideos = LibraryVideosFragment.newInstance();
|
||||
_fragLibraryFiles = LibraryFilesFragment.newInstance();
|
||||
_fragLibrarySearch = LibrarySearchFragment.newInstance();
|
||||
|
||||
_fragBrowser = BrowserFragment.newInstance();
|
||||
|
||||
@@ -512,6 +515,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
||||
_fragLibraryArtist.topBar = _fragTopBarNavigation;
|
||||
_fragLibraryVideos.topBar = _fragTopBarNavigation;
|
||||
_fragLibraryFiles.topBar = _fragTopBarFiles;
|
||||
_fragLibrarySearch.topBar = _fragTopBarSearch;
|
||||
|
||||
_fragBrowser.topBar = _fragTopBarNavigation;
|
||||
|
||||
@@ -1323,6 +1327,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
|
||||
LibraryArtistFragment::class -> _fragLibraryArtist as T;
|
||||
LibraryVideosFragment::class -> _fragLibraryVideos as T;
|
||||
LibraryFilesFragment::class -> _fragLibraryFiles as T;
|
||||
LibrarySearchFragment::class -> _fragLibrarySearch as T;
|
||||
else -> throw IllegalArgumentException("Fragment type ${T::class.java.name} is not available in MainActivity");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -120,8 +120,8 @@ class LibraryAlbumFragment : MainFragment() {
|
||||
holder.onClick.subscribe { c ->
|
||||
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
val index = playlist?.videos?.indexOfFirst { it.name == c.name } ?: -1;
|
||||
if (playlist != null) {
|
||||
val index = playlist.videos.indexOf(c);
|
||||
if (index == -1)
|
||||
return@subscribe;
|
||||
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ class LibraryFragment : MainFragment() {
|
||||
this.fragment = fragment;
|
||||
recycler = findViewById(R.id.recycler);
|
||||
sectionArtists = LibrarySection(context)//findViewById<LibrarySection>(R.id.section_artists);
|
||||
sectionArtists.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 155.dp(resources)).apply {
|
||||
sectionArtists.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 140.dp(resources)).apply {
|
||||
this.setMargins(0,10.dp(resources), 0, 0);
|
||||
}
|
||||
sectionAlbums = LibrarySection(context)//findViewById(R.id.section_albums);
|
||||
|
||||
+39
-16
@@ -106,16 +106,18 @@ class LibrarySearchFragment : MainFragment() {
|
||||
val pillSongs: PillV2;
|
||||
val pills: List<PillV2>;
|
||||
|
||||
val textMetadata: TextView;
|
||||
|
||||
val recycler: RecyclerView;
|
||||
|
||||
val adapterArtists: AnyAdapterView<Artist, LibraryArtistsFragment.ArtistViewHolder>;
|
||||
val adapterSongs: AnyAdapterView<IPlatformContent, TrackViewHolder>;
|
||||
val adapterAlbums: AnyAdapterView<Album, AlbumTileViewHolder>;
|
||||
val adapterAlbums: AnyAdapterView<Album, LibraryAlbumsFragment.AlbumViewHolder>;
|
||||
|
||||
|
||||
|
||||
constructor(fragment: LibrarySearchFragment) : super(fragment.requireContext()) {
|
||||
inflate(context, R.layout.fragview_library, this);
|
||||
inflate(context, R.layout.fragview_library_search, this);
|
||||
this.fragment = fragment;
|
||||
|
||||
pillArtist = findViewById(R.id.pill_artist);
|
||||
@@ -123,6 +125,8 @@ class LibrarySearchFragment : MainFragment() {
|
||||
pillSongs = findViewById(R.id.pill_songs);
|
||||
pills = listOf(pillArtist, pillAlbums, pillSongs);
|
||||
|
||||
textMetadata = findViewById(R.id.text_metadata);
|
||||
|
||||
pillArtist.onClick.subscribe {
|
||||
pills.forEach { it.setIsEnabled(false) };
|
||||
pillArtist.setIsEnabled(true);
|
||||
@@ -146,7 +150,7 @@ class LibrarySearchFragment : MainFragment() {
|
||||
fragment.navigate<LibraryArtistFragment>(it);
|
||||
}
|
||||
});
|
||||
adapterAlbums = recycler.asAny<Album, AlbumTileViewHolder>(RecyclerView.VERTICAL, false, {
|
||||
adapterAlbums = recycler.asAny<Album, LibraryAlbumsFragment.AlbumViewHolder>(RecyclerView.VERTICAL, false, {
|
||||
it.onClick.subscribe {
|
||||
if(it != null)
|
||||
fragment.navigate<LibraryAlbumFragment>(it);
|
||||
@@ -173,38 +177,57 @@ class LibrarySearchFragment : MainFragment() {
|
||||
|
||||
fun loadArtists(){
|
||||
recycler.adapter = adapterArtists.adapter.adapter;
|
||||
fragment.topBar?.let {
|
||||
if(it is SearchTopBarFragment)
|
||||
search(it.getSearchText());
|
||||
}
|
||||
}
|
||||
fun loadAlbums() {
|
||||
recycler.adapter = adapterAlbums.adapter.adapter;
|
||||
fragment.topBar?.let {
|
||||
if(it is SearchTopBarFragment)
|
||||
search(it.getSearchText());
|
||||
}
|
||||
}
|
||||
fun loadSongs() {
|
||||
recycler.adapter = adapterSongs.adapter.adapter;
|
||||
fragment.topBar?.let {
|
||||
if(it is SearchTopBarFragment)
|
||||
search(it.getSearchText());
|
||||
}
|
||||
}
|
||||
|
||||
fun search(str: String) {
|
||||
if(recycler.adapter == adapterArtists.adapter.adapter) {
|
||||
if(str.isNullOrBlank())
|
||||
adapterArtists.adapter.setData(listOf());
|
||||
else
|
||||
adapterArtists.setData(StateLibrary.instance.searchArtists(str));
|
||||
val data = if(!str.isNullOrBlank())
|
||||
StateLibrary.instance.searchArtists(str)
|
||||
else listOf();
|
||||
adapterArtists.setData(data);
|
||||
textMetadata.text = "${data.size} artists";
|
||||
}
|
||||
else if(recycler.adapter == adapterAlbums.adapter.adapter) {
|
||||
if(str.isNullOrBlank())
|
||||
adapterAlbums.adapter.setData(listOf());
|
||||
else
|
||||
adapterAlbums.setData(StateLibrary.instance.searchAlbums(str));
|
||||
val data = if(!str.isNullOrBlank())
|
||||
StateLibrary.instance.searchAlbums(str)
|
||||
else listOf();
|
||||
adapterAlbums.setData(data);
|
||||
textMetadata.text = "${data.size} albums";
|
||||
}
|
||||
else if(recycler.adapter == adapterSongs.adapter.adapter) {
|
||||
if(str.isNullOrBlank())
|
||||
adapterSongs.adapter.setData(listOf());
|
||||
else
|
||||
adapterSongs.setData(StateLibrary.instance.searchTracks(str));
|
||||
val data = if(!str.isNullOrBlank())
|
||||
StateLibrary.instance.searchTracks(str)
|
||||
else listOf();
|
||||
|
||||
adapterSongs.setData(data);
|
||||
textMetadata.text = "${data.size} songs";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun onShown() {
|
||||
|
||||
fragment.topBar?.let {
|
||||
if(it is SearchTopBarFragment)
|
||||
it.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -9,6 +9,8 @@ import android.widget.ImageView
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.UIDialogs
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.CreatorsFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibrarySearchFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PlaylistFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.PlaylistsFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.SuggestionsFragment
|
||||
@@ -46,6 +48,8 @@ class GeneralTopBarFragment : TopFragment() {
|
||||
navigate<SuggestionsFragment>(SuggestionsFragmentData("", SearchType.CREATOR));
|
||||
} else if (currentMain is PlaylistsFragment || currentMain is PlaylistFragment) {
|
||||
navigate<SuggestionsFragment>(SuggestionsFragmentData("", SearchType.PLAYLIST));
|
||||
} else if (currentMain is LibraryFragment) {
|
||||
navigate<LibrarySearchFragment>();
|
||||
} else {
|
||||
navigate<SuggestionsFragment>(SuggestionsFragmentData("", SearchType.VIDEO));
|
||||
}
|
||||
|
||||
+11
-1
@@ -18,6 +18,7 @@ import com.futo.platformplayer.Settings
|
||||
import com.futo.platformplayer.UIDialogs
|
||||
import com.futo.platformplayer.constructs.Event0
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibrarySearchFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.SuggestionsFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.SuggestionsFragmentData
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
@@ -112,7 +113,10 @@ class SearchTopBarFragment : TopFragment() {
|
||||
}
|
||||
fun clear() {
|
||||
_editSearch?.text?.clear();
|
||||
if (currentMain !is SuggestionsFragment) {
|
||||
if(currentMain is LibrarySearchFragment) {
|
||||
onSearch.emit("");
|
||||
}
|
||||
else if (currentMain !is SuggestionsFragment) {
|
||||
navigate<SuggestionsFragment>(SuggestionsFragmentData("", _searchType), false);
|
||||
} else {
|
||||
onSearch.emit("");
|
||||
@@ -190,6 +194,12 @@ class SearchTopBarFragment : TopFragment() {
|
||||
_buttonFilter?.visibility = if (visible) View.VISIBLE else View.GONE;
|
||||
}
|
||||
|
||||
fun getSearchText(): String {
|
||||
return _editSearch?.let {
|
||||
it.text.toString();
|
||||
} ?: "";
|
||||
}
|
||||
|
||||
private fun onDone() {
|
||||
val editSearch = _editSearch
|
||||
if (editSearch != null) {
|
||||
|
||||
@@ -90,6 +90,8 @@ class StateLibrary {
|
||||
|
||||
|
||||
fun searchTracks(str: String): List<IPlatformVideo> {
|
||||
if(str.isNullOrBlank())
|
||||
return listOf();
|
||||
val resolver = StateApp.instance.contextOrNull?.contentResolver;
|
||||
if(resolver == null) {
|
||||
Logger.w(TAG, "Album contentResolver not found");
|
||||
@@ -97,7 +99,7 @@ class StateLibrary {
|
||||
}
|
||||
val cursor = resolver?.query(
|
||||
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, StateLibrary.PROJECTION_MEDIA,
|
||||
"LOWER(" + MediaStore.Audio.Media.DISPLAY_NAME + ") LIKE ? ", arrayOf(str.trim().lowercase()),
|
||||
"LOWER(" + MediaStore.Audio.Media.DISPLAY_NAME + ") LIKE ? ", arrayOf("%" + str.trim().lowercase() + "%"),
|
||||
null) ?: return listOf();
|
||||
cursor.moveToFirst();
|
||||
val list = mutableListOf<IPlatformVideo>()
|
||||
@@ -118,7 +120,9 @@ class StateLibrary {
|
||||
return null;
|
||||
}
|
||||
fun searchAlbums(str: String): List<Album> {
|
||||
return Album.getAlbums("LOWER(" + MediaStore.Audio.Albums.ALBUM + ") LIKE ? ", arrayOf(str.trim().lowercase()));
|
||||
if(str.isNullOrBlank())
|
||||
return listOf();
|
||||
return Album.getAlbums("LOWER(" + MediaStore.Audio.Albums.ALBUM + ") LIKE ? ", arrayOf("%" + str.trim().lowercase() + "%"));
|
||||
}
|
||||
|
||||
fun getAlbum(id: Long): Album? {
|
||||
@@ -135,7 +139,9 @@ class StateLibrary {
|
||||
return null;
|
||||
}
|
||||
fun searchArtists(str: String): List<Artist> {
|
||||
return Artist.getArtists(ArtistOrdering.TrackCount, "LOWER(" + MediaStore.Audio.Artists.ARTIST + ") LIKE ? ", arrayOf(str.trim().lowercase()));
|
||||
if(str.isNullOrBlank())
|
||||
return listOf();
|
||||
return Artist.getArtists(ArtistOrdering.TrackCount, "LOWER(" + MediaStore.Audio.Artists.ARTIST + ") LIKE ? ", arrayOf("%" + str.trim().lowercase() + "%"));
|
||||
}
|
||||
|
||||
fun getArtist(id: Long): Artist? {
|
||||
|
||||
@@ -50,7 +50,9 @@
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="3dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13sp"
|
||||
android:textColor="#D0D0D0"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
@@ -17,6 +18,7 @@
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_4dp"
|
||||
app:srcCompat="@drawable/placeholder_video_thumbnail"
|
||||
android:background="@drawable/video_thumbnail_outline"
|
||||
android:layout_marginLeft="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
@@ -36,7 +38,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintBottom_toTopOf="@id/text_metadata"
|
||||
android:layout_marginStart="10dp" />
|
||||
android:layout_marginStart="15dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
@@ -53,7 +55,7 @@
|
||||
app:layout_constraintLeft_toRightOf="@id/image_thumbnail"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="10dp" />
|
||||
android:layout_marginStart="15dp" />
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="86dp"
|
||||
android:layout_width="71dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
@@ -14,12 +14,12 @@
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_thumbnail"
|
||||
android:layout_height="66dp"
|
||||
android:layout_width="66dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_width="50dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_33dp"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_25dp"
|
||||
app:srcCompat="@drawable/unknown_music"
|
||||
android:background="@drawable/video_thumbnail_outline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@@ -29,7 +29,7 @@
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
android:textAlignment="center"
|
||||
@@ -45,7 +45,7 @@
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textSize="10sp"
|
||||
android:textColor="#75FFFFFF"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
android:textAlignment="center"
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">33dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_25dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">25dp</item>
|
||||
</style>
|
||||
<style name="roundedCorners_40dp" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">40dp</item>
|
||||
|
||||
Reference in New Issue
Block a user