Skip to content

Commit

Permalink
Add auto-complete to discovery country selection (#6139)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pinkolik committed Oct 15, 2022
1 parent 8ff9dd8 commit 4c30d8f
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 113 deletions.
177 changes: 104 additions & 73 deletions app/src/main/java/de/danoeh/antennapod/fragment/DiscoveryFragment.java
@@ -1,46 +1,52 @@
package de.danoeh.antennapod.fragment;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.NonNull;
import com.google.android.material.appbar.MaterialToolbar;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;

import de.danoeh.antennapod.net.discovery.ItunesTopListLoader;
import de.danoeh.antennapod.net.discovery.PodcastSearchResult;
import org.greenrobot.eventbus.EventBus;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.textfield.MaterialAutoCompleteTextView;
import com.google.android.material.textfield.TextInputLayout;

import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
import de.danoeh.antennapod.event.DiscoveryDefaultUpdateEvent;
import io.reactivex.disposables.Disposable;
import org.apache.commons.lang3.StringUtils;
import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static android.content.Context.MODE_PRIVATE;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
import de.danoeh.antennapod.adapter.itunes.ItunesAdapter;
import de.danoeh.antennapod.event.DiscoveryDefaultUpdateEvent;
import de.danoeh.antennapod.net.discovery.ItunesTopListLoader;
import de.danoeh.antennapod.net.discovery.PodcastSearchResult;
import io.reactivex.disposables.Disposable;

/**
* Searches iTunes store for top podcasts and displays results in a list.
*/
public class DiscoveryFragment extends Fragment {
public class DiscoveryFragment extends Fragment implements Toolbar.OnMenuItemClickListener {

private static final String TAG = "ItunesSearchFragment";
private SharedPreferences prefs;
Expand All @@ -62,9 +68,16 @@ public class DiscoveryFragment extends Fragment {
private List<PodcastSearchResult> topList;
private Disposable disposable;
private String countryCode = "US";
private boolean hidden;
private MaterialToolbar toolbar;

public DiscoveryFragment() {
// Required empty public constructor
}

/**
* Replace adapter data with provided search results from SearchTask.
*
* @param result List of Podcast objects containing search results
*/
private void updateData(List<PodcastSearchResult> result) {
Expand All @@ -83,28 +96,28 @@ private void updateData(List<PodcastSearchResult> result) {
}
}

public DiscoveryFragment() {
// Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE);
prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, Context.MODE_PRIVATE);
countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, Locale.getDefault().getCountry());
hidden = prefs.getBoolean(ItunesTopListLoader.PREF_KEY_HIDDEN_DISCOVERY_COUNTRY, false);
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
gridView.setAdapter(adapter);

MaterialToolbar toolbar = root.findViewById(R.id.toolbar);
toolbar = root.findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(v -> getParentFragmentManager().popBackStack());
toolbar.inflateMenu(R.menu.countries_menu);
MenuItem discoverHideItem = toolbar.getMenu().findItem(R.id.discover_hide_item);
discoverHideItem.setChecked(hidden);
toolbar.setOnMenuItemClickListener(this);

//Show information about the podcast when the list item is clicked
gridView.setOnItemClickListener((parent, view1, position, id) -> {
Expand All @@ -117,57 +130,6 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
startActivity(intent);
});

List<String> countryCodeArray = new ArrayList<String>(Arrays.asList(Locale.getISOCountries()));
HashMap<String, String> countryCodeNames = new HashMap<String, String>();
for (String code: countryCodeArray) {
Locale locale = new Locale("", code);
String countryName = locale.getDisplayCountry();
if (countryName != null) {
countryCodeNames.put(code, countryName);
}
}

List<String> countryNamesSort = new ArrayList<String>(countryCodeNames.values());
Collections.sort(countryNamesSort);
countryNamesSort.add(0, getResources().getString(R.string.discover_hide));

Spinner countrySpinner = root.findViewById(R.id.spinner_country);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this.getContext(),
android.R.layout.simple_spinner_item,
countryNamesSort);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
countrySpinner.setAdapter(dataAdapter);
int pos = countryNamesSort.indexOf(countryCodeNames.get(countryCode));
countrySpinner.setSelection(pos);

countrySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> countrySpinner, View view, int position, long id) {
String countryName = (String) countrySpinner.getItemAtPosition(position);

if (countryName.equals(getResources().getString(R.string.discover_hide))) {
countryCode = ItunesTopListLoader.DISCOVER_HIDE_FAKE_COUNTRY_CODE;
} else {
for (Object o : countryCodeNames.keySet()) {
if (countryCodeNames.get(o).equals(countryName)) {
countryCode = o.toString();
break;
}
}
}

prefs.edit()
.putString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, countryCode)
.apply();

EventBus.getDefault().post(new DiscoveryDefaultUpdateEvent());
loadToplist(countryCode);
}

@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
progressBar = root.findViewById(R.id.progressBar);
txtvError = root.findViewById(R.id.txtvError);
butRetry = root.findViewById(R.id.butRetry);
Expand Down Expand Up @@ -197,7 +159,7 @@ private void loadToplist(String country) {
txtvEmpty.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);

if (country.equals(ItunesTopListLoader.DISCOVER_HIDE_FAKE_COUNTRY_CODE)) {
if (hidden) {
gridView.setVisibility(View.GONE);
txtvError.setVisibility(View.VISIBLE);
txtvError.setText(getResources().getString(R.string.discover_is_hidden));
Expand All @@ -221,4 +183,73 @@ private void loadToplist(String country) {
});
}
}

@Override
public boolean onMenuItemClick(MenuItem item) {
if (super.onOptionsItemSelected(item)) {
return true;
}
final int itemId = item.getItemId();
if (itemId == R.id.discover_hide_item) {
item.setChecked(!item.isChecked());
hidden = item.isChecked();
prefs.edit().putBoolean(ItunesTopListLoader.PREF_KEY_HIDDEN_DISCOVERY_COUNTRY, hidden).apply();

EventBus.getDefault().post(new DiscoveryDefaultUpdateEvent());
loadToplist(countryCode);
return true;
} else if (itemId == R.id.discover_countries_item) {

LayoutInflater inflater = getLayoutInflater();
View selectCountryDialogView = inflater.inflate(R.layout.select_country_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(selectCountryDialogView);

List<String> countryCodeArray = new ArrayList<>(Arrays.asList(Locale.getISOCountries()));
Map<String, String> countryCodeNames = new HashMap<>();
Map<String, String> countryNameCodes = new HashMap<>();
for (String code : countryCodeArray) {
Locale locale = new Locale("", code);
String countryName = locale.getDisplayCountry();
countryCodeNames.put(code, countryName);
countryNameCodes.put(countryName, code);
}

List<String> countryNamesSort = new ArrayList<>(countryCodeNames.values());
Collections.sort(countryNamesSort);

ArrayAdapter<String> dataAdapter =
new ArrayAdapter<>(this.getContext(), android.R.layout.simple_list_item_1, countryNamesSort);
TextInputLayout textInput = selectCountryDialogView.findViewById(R.id.country_text_input);
MaterialAutoCompleteTextView editText = (MaterialAutoCompleteTextView) textInput.getEditText();
editText.setAdapter(dataAdapter);
editText.setText(countryCodeNames.get(countryCode));
editText.setOnClickListener(view -> {
if (StringUtils.isEmpty(editText.getText().toString())) {
return;
}
editText.getText().clear();
editText.postDelayed(editText::showDropDown, 100);
});

builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
String countryName = editText.getText().toString();
if (countryNameCodes.containsKey(countryName)) {
countryCode = countryNameCodes.get(countryName);
MenuItem discoverHideItem = toolbar.getMenu().findItem(R.id.discover_hide_item);
discoverHideItem.setChecked(false);
hidden = false;
}

prefs.edit().putBoolean(ItunesTopListLoader.PREF_KEY_HIDDEN_DISCOVERY_COUNTRY, hidden).apply();
prefs.edit().putString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE, countryCode).apply();

EventBus.getDefault().post(new DiscoveryDefaultUpdateEvent());
loadToplist(countryCode);
});
builder.show();
return true;
}
return false;
}
}
Expand Up @@ -3,22 +3,26 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import android.widget.AbsListView;
import com.google.android.material.appbar.MaterialToolbar;
import androidx.fragment.app.Fragment;
import androidx.appcompat.widget.SearchView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment;

import com.google.android.material.appbar.MaterialToolbar;

import java.util.ArrayList;
import java.util.List;

import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
Expand All @@ -28,11 +32,6 @@
import de.danoeh.antennapod.net.discovery.PodcastSearcherRegistry;
import io.reactivex.disposables.Disposable;

import java.util.ArrayList;
import java.util.List;

import static android.view.View.INVISIBLE;

public class OnlineSearchFragment extends Fragment {

private static final String TAG = "FyydSearchFragment";
Expand Down Expand Up @@ -95,7 +94,6 @@ public void onCreate(Bundle savedInstanceState) {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_itunes_search, container, false);
root.findViewById(R.id.spinner_country).setVisibility(INVISIBLE);
gridView = root.findViewById(R.id.gridView);
adapter = new ItunesAdapter(getActivity(), new ArrayList<>());
gridView.setAdapter(adapter);
Expand Down
Expand Up @@ -114,7 +114,8 @@ private void loadToplist() {
SharedPreferences prefs = getActivity().getSharedPreferences(ItunesTopListLoader.PREFS, MODE_PRIVATE);
String countryCode = prefs.getString(ItunesTopListLoader.PREF_KEY_COUNTRY_CODE,
Locale.getDefault().getCountry());
if (countryCode.equals(ItunesTopListLoader.DISCOVER_HIDE_FAKE_COUNTRY_CODE)) {
boolean hidden = prefs.getBoolean(ItunesTopListLoader.PREF_KEY_HIDDEN_DISCOVERY_COUNTRY, false);
if (hidden) {
errorTextView.setText(R.string.discover_is_hidden);
errorView.setVisibility(View.VISIBLE);
discoverGridLayout.setVisibility(View.GONE);
Expand Down
34 changes: 8 additions & 26 deletions app/src/main/res/layout/fragment_itunes_search.xml
Expand Up @@ -7,40 +7,22 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<LinearLayout
android:id="@+id/browsing"
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
android:orientation="horizontal"
android:layout_alignParentTop="true">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:navigationIcon="?homeAsUpIndicator"
app:title="@string/discover" />

<android.widget.Spinner
android:id="@+id/spinner_country"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:gravity="right|end"
android:isScrollContainer="true"
android:minHeight="?attr/actionBarSize"
android:spinnerMode="dropdown"
android:textAlignment="textEnd" />

</LinearLayout>
android:theme="?attr/actionBarTheme"
app:navigationIcon="?homeAsUpIndicator"
app:title="@string/discover" />

<GridView
android:id="@+id/gridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/browsing"
android:layout_below="@id/toolbar"
android:clipToPadding="false"
android:columnWidth="400dp"
android:gravity="center"
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/res/layout/select_country_dialog.xml
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/country_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:hint="@string/country"
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu">

<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</com.google.android.material.textfield.TextInputLayout>

</LinearLayout>

0 comments on commit 4c30d8f

Please sign in to comment.