Use searchable dialog for tag and aspect/contact list

* Remove seperate fragments for both cases
* Make use of opoc/SearchOrCustomTextDialog
* Basically also removes all fragment swaps
  * Only two fragments are stream and podselection
  * Pod logout restarts app
  * Thus long known Android Supportlib bug can't occur

* Fixes #198
This commit is contained in:
Gregor Santner 2018-07-25 01:59:25 +02:00
parent 918adcf358
commit dbbd3cef35
13 changed files with 358 additions and 457 deletions

View File

@ -1,208 +0,0 @@
/*
This file is part of the dandelion*.
dandelion* is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dandelion* is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.listener.OnSomethingClickListener;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Fragment that shows a list of the Aspects
*/
public class AspectListFragment extends ThemedFragment implements OnSomethingClickListener<Object> {
public static final String TAG = "com.github.dfa.diaspora_android.AspectListFragment";
@BindView(R.id.fragment_list__recycler_view)
public RecyclerView aspectsRecyclerView;
@BindView(R.id.fragment_list__spacer)
public View space;
@BindView(R.id.fragment_list__root)
public RelativeLayout rootView;
protected App app;
protected DiasporaUrlHelper urls;
@Override
protected int getLayoutResId() {
return R.layout.recycler_list__fragment;
}
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
app = (App) getActivity().getApplication();
AppSettings appSettings = app.getSettings();
urls = new DiasporaUrlHelper(appSettings);
aspectsRecyclerView.setHasFixedSize(true);
aspectsRecyclerView.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
aspectsRecyclerView.setLayoutManager(layoutManager);
final AspectAdapter adapter = new AspectAdapter(appSettings, this);
aspectsRecyclerView.setAdapter(adapter);
//Set window title
getActivity().setTitle(R.string.nav_aspects);
}
@Override
public String getFragmentTag() {
return TAG;
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public void onSomethingClicked(Object null1, Integer null2, String aspectId) {
((MainActivity) getActivity()).openDiasporaUrl(urls.getAspectUrl(aspectId));
}
@Override
protected void applyColorToViews() {
aspectsRecyclerView.invalidate();
if (getAppSettings().isAmoledColorMode()) {
rootView.setBackgroundColor(Color.BLACK);
space.setBackgroundColor(Color.BLACK);
}
}
public static class AspectAdapter extends RecyclerView.Adapter<AspectAdapter.ViewHolder> {
private boolean isAmoledColorMode;
private final AppSettings appSettings;
private final DiasporaAspect[] aspectList;
private final List<String> aspectFavsList;
private final OnSomethingClickListener<Object> aspectClickedListener;
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.recycler_view__list_item__text)
public TextView title;
@BindView(R.id.recycler_view__list_item__favourite)
AppCompatImageView favouriteImage;
@BindView(R.id.recycler_view__list_item__root)
RelativeLayout root;
ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
AspectAdapter(AppSettings appSettings, OnSomethingClickListener<Object> aspectClickedListener) {
this.appSettings = appSettings;
this.aspectList = appSettings.getAspects();
this.aspectFavsList = new ArrayList<>(Arrays.asList(appSettings.getAspectFavs()));
this.aspectClickedListener = aspectClickedListener;
this.isAmoledColorMode = appSettings.isAmoledColorMode();
}
@Override
public int getItemCount() {
return aspectList.length;
}
@Override
public AspectAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_list__list_item_with_fav, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// Alternating colors
final Context c = holder.root.getContext();
final DiasporaAspect aspect = aspectList[position];
holder.title.setText(aspect.name);
if (position % 2 == 1) {
holder.root.setBackgroundColor(isAmoledColorMode ? Color.BLACK : ContextUtils.get().rcolor(R.color.alternate_row_color));
holder.title.setTextColor(isAmoledColorMode ? Color.GRAY : Color.BLACK);
} else {
holder.root.setBackgroundColor(isAmoledColorMode ? Color.BLACK : Color.WHITE);
holder.title.setTextColor(isAmoledColorMode ? Color.GRAY : Color.BLACK);
}
// Favourite (Star) Image
applyFavouriteImage(holder.favouriteImage, isAspectFaved(aspect.name));
// Click on fav button
holder.favouriteImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (isAspectFaved(aspect.name)) {
aspectFavsList.remove(aspectFavsList.indexOf(aspect.name));
} else {
aspectFavsList.add(aspect.name);
}
appSettings.setAspectFavs(aspectFavsList);
applyFavouriteImage(holder.favouriteImage, isAspectFaved(aspect.name));
}
});
holder.root.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
aspectClickedListener.onSomethingClicked(null, null, aspect.id + "");
}
});
}
private boolean isAspectFaved(String tag) {
return aspectFavsList.contains(tag);
}
private void applyFavouriteImage(AppCompatImageView imageView, boolean isFaved) {
imageView.setImageResource(isFaved ? R.drawable.ic_star_filled_48px : R.drawable.ic_star_border_black_48px);
imageView.setColorFilter(isFaved ? appSettings.getAccentColor() : (isAmoledColorMode ? Color.GRAY : 0), PorterDuff.Mode.SRC_ATOP);
}
}
}

View File

@ -36,6 +36,7 @@ import android.support.customtabs.CustomTabsSession;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
@ -61,8 +62,8 @@ import android.widget.TextView;
import android.widget.Toast;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.BuildConfig;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.data.DiasporaPodList;
import com.github.dfa.diaspora_android.data.DiasporaUserProfile;
import com.github.dfa.diaspora_android.listener.DiasporaUserProfileChangedListener;
@ -71,6 +72,7 @@ import com.github.dfa.diaspora_android.receiver.OpenExternalLinkReceiver;
import com.github.dfa.diaspora_android.receiver.UpdateTitleReceiver;
import com.github.dfa.diaspora_android.ui.BadgeDrawable;
import com.github.dfa.diaspora_android.ui.PodSelectionDialog;
import com.github.dfa.diaspora_android.ui.SearchOrCustomTextDialogCreator;
import com.github.dfa.diaspora_android.ui.theme.ThemeHelper;
import com.github.dfa.diaspora_android.ui.theme.ThemedActivity;
import com.github.dfa.diaspora_android.ui.theme.ThemedAlertDialogBuilder;
@ -306,14 +308,6 @@ public class MainActivity extends ThemedActivity
BrowserFragment bf = new BrowserFragment();
fm.beginTransaction().add(bf, fragmentTag).commit();
return bf;
case TagListFragment.TAG:
TagListFragment hlf = new TagListFragment();
fm.beginTransaction().add(hlf, fragmentTag).commit();
return hlf;
case AspectListFragment.TAG:
AspectListFragment alf = new AspectListFragment();
fm.beginTransaction().add(alf, fragmentTag).commit();
return alf;
case PodSelectionFragment.TAG:
PodSelectionFragment psf = new PodSelectionFragment();
fm.beginTransaction().add(psf, fragmentTag).commit();
@ -370,6 +364,13 @@ public class MainActivity extends ThemedActivity
* @param fragment Fragment to show
*/
protected void showFragment(ThemedFragment fragment) {
if (PodSelectionFragment.TAG.equals(fragment.getTag())) {
Fragment fragment1 = fm.findFragmentByTag(DiasporaStreamFragment.TAG);
if (fragment1 != null) {
new net.gsantner.opoc.util.ContextUtils(this).restartApp(MainActivity.class);
}
}
AppLog.v(this, "showFragment()");
ThemedFragment currentTop = (ThemedFragment) fm.findFragmentById(R.id.fragment_container);
if (currentTop == null || !currentTop.getFragmentTag().equals(fragment.getFragmentTag())) {
@ -457,7 +458,7 @@ public class MainActivity extends ThemedActivity
navMenu.findItem(R.id.nav_statistics).setVisible(_appSettings.isVisibleInNavStatistics());
navMenu.findItem(R.id.nav_reports).setVisible(_appSettings.isVisibleInNavReports());
navMenu.findItem(R.id.nav_toggle_desktop_page).setVisible(_appSettings.isVisibleInNavToggleMobileDesktop());
navMenu.findItem(R.id.nav_dandelion).setVisible(_appSettings.isVisibleInNavDandelionAccount());
navMenu.findItem(R.id.nav_product_support).setVisible(_appSettings.isVisibleInNavGsantnerAccount());
// Hide whole group (for logged in use) if no pod was selected
@ -561,16 +562,18 @@ public class MainActivity extends ThemedActivity
} else if ("sc_new_post".equals(action)) {
openDiasporaUrl(urls.getNewPostUrl());
return;
} else if ("sc_nav_followed_tags".equals(action)) {
showFragment(getFragment(TagListFragment.TAG));
return;
} else if ("sc_aspects".equals(action)) {
showFragment(getFragment(AspectListFragment.TAG));
return;
} else if ("sc_activities".equals(action)) {
openDiasporaUrl(urls.getActivityUrl());
return;
}
else if ("sc_contacts".equals(action)) {
onNavigationItemSelected(navView.getMenu().findItem(R.id.nav_aspects));
return;
}
else if ("sc_tags".equals(action)) {
onNavigationItemSelected(navView.getMenu().findItem(R.id.nav_followed_tags));
return;
}
//Catch split screen recreation
if (action != null && action.equals(Intent.ACTION_MAIN) && getTopFragment() != null) {
return;
@ -1062,12 +1065,39 @@ public class MainActivity extends ThemedActivity
break;
case R.id.nav_followed_tags: {
showFragment(getFragment(TagListFragment.TAG));
SearchOrCustomTextDialogCreator.showDiasporaTagsDialog(this, arg -> {
if (arg.startsWith(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX)) {
arg = arg.replace(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX, "").trim();
if (arg.equals(getString(R.string.pref_title__manage_tags))) {
openDiasporaUrl(urls.getManageTagsUrl());
} else {
openDiasporaUrl(urls.getAllFollowedTagsUrl());
}
} else {
openDiasporaUrl(urls.getSearchTagsUrl(arg));
}
});
}
break;
case R.id.nav_aspects: {
showFragment(getFragment(AspectListFragment.TAG));
SearchOrCustomTextDialogCreator.showDiasporaAspectsDialog(this, arg -> {
if (arg.startsWith(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX)) {
arg = arg.replace(SearchOrCustomTextDialogCreator.SPECIAL_PREFIX, "").trim();
if (arg.equals(getString(R.string.pref_desc__manage_contacts))) {
openDiasporaUrl(urls.getContactsUrl());
} else if (arg.equals(getString(R.string.nav_profile))) {
openDiasporaUrl(urls.getProfileUrl());
}
} else {
for (DiasporaAspect daspect : _appSettings.getAspects()) {
if (arg.equals(daspect.name)) {
openDiasporaUrl(urls.getAspectUrl(Long.toString(daspect.id)));
break;
}
}
}
});
}
break;
@ -1148,8 +1178,8 @@ public class MainActivity extends ThemedActivity
}
break;
case R.id.nav_dandelion: {
openDiasporaUrl(urls.getProfileUrl("48b78420923501341ef3782bcb452bd5"));
case R.id.nav_product_support: {
openDiasporaUrl(urls.getProfileUrl("d1cbdd70095301341e834860008dbc6c"));
}
break;

View File

@ -483,11 +483,7 @@ public class SettingsActivity extends ThemedActivity implements SharedPreference
public void onClick(DialogInterface dialogInterface, int i) {
appSettings.resetAppSettings();
appSettings.resetPodSettings();
Intent restartActivity = new Intent(getActivity(), MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getActivity(), 12374, restartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
System.exit(0);
new net.gsantner.opoc.util.ContextUtils(appSettings.getContext()).restartApp(MainActivity.class);
}
}).setNegativeButton(android.R.string.cancel, null)
.create().show();

View File

@ -1,206 +0,0 @@
/*
This file is part of the dandelion*.
dandelion* is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dandelion* is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the dandelion*.
If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.dfa.diaspora_android.activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.github.dfa.diaspora_android.App;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.listener.OnSomethingClickListener;
import com.github.dfa.diaspora_android.ui.theme.ThemedFragment;
import com.github.dfa.diaspora_android.util.AppSettings;
import com.github.dfa.diaspora_android.util.ContextUtils;
import com.github.dfa.diaspora_android.util.DiasporaUrlHelper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Fragment that shows a list of the HashTags the user follows
*/
public class TagListFragment extends ThemedFragment implements OnSomethingClickListener<Object> {
public static final String TAG = "com.github.dfa.diaspora_android.TagListFragment";
@BindView(R.id.fragment_list__recycler_view)
public RecyclerView followedTagsRecyclerView;
@BindView(R.id.fragment_list__spacer)
public View space;
@BindView(R.id.fragment_list__root)
public RelativeLayout rootView;
protected App app;
protected DiasporaUrlHelper urls;
@Override
protected int getLayoutResId() {
return R.layout.recycler_list__fragment;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
app = (App) getActivity().getApplication();
AppSettings appSettings = app.getSettings();
urls = new DiasporaUrlHelper(appSettings);
followedTagsRecyclerView.setHasFixedSize(true);
followedTagsRecyclerView.setNestedScrollingEnabled(false);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
followedTagsRecyclerView.setLayoutManager(layoutManager);
final FollowedTagsAdapter adapter = new FollowedTagsAdapter(appSettings, this);
followedTagsRecyclerView.setAdapter(adapter);
//Set window title
getActivity().setTitle(R.string.nav_followed_tags);
}
@Override
public String getFragmentTag() {
return TAG;
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public void onSomethingClicked(Object null1, Integer null2, String tag) {
((MainActivity) getActivity()).openDiasporaUrl(urls.getSearchTagsUrl(tag));
}
@Override
protected void applyColorToViews() {
followedTagsRecyclerView.invalidate();
if (getAppSettings().isAmoledColorMode()) {
rootView.setBackgroundColor(Color.BLACK);
space.setBackgroundColor(Color.BLACK);
}
}
public static class FollowedTagsAdapter extends RecyclerView.Adapter<FollowedTagsAdapter.ViewHolder> {
private boolean isAmoledColorMode;
private AppSettings appSettings;
private String[] followedTagsList;
private List<String> followedTagsFavsList;
private OnSomethingClickListener<Object> tagClickedListener;
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.recycler_view__list_item__text)
public TextView title;
@BindView(R.id.recycler_view__list_item__favourite)
AppCompatImageView favouriteImage;
@BindView(R.id.recycler_view__list_item__root)
RelativeLayout root;
ViewHolder(View v) {
super(v);
ButterKnife.bind(this, v);
}
}
FollowedTagsAdapter(AppSettings appSettings, OnSomethingClickListener<Object> tagClickedListener) {
this.appSettings = appSettings;
this.followedTagsList = appSettings.getFollowedTags();
this.followedTagsFavsList = new ArrayList<>(Arrays.asList(appSettings.getFollowedTagsFavs()));
this.tagClickedListener = tagClickedListener;
this.isAmoledColorMode = appSettings.isAmoledColorMode();
}
@Override
public int getItemCount() {
return followedTagsList.length;
}
@Override
public FollowedTagsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_list__list_item_with_fav, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// Alternating colors
final Context c = holder.root.getContext();
final String tag = followedTagsList[position];
holder.title.setText(tag);
if (position % 2 == 1) {
holder.root.setBackgroundColor(isAmoledColorMode ? Color.BLACK : ContextUtils.get().rcolor(R.color.alternate_row_color));
holder.title.setTextColor(isAmoledColorMode ? Color.GRAY : Color.BLACK);
} else {
holder.root.setBackgroundColor(isAmoledColorMode ? Color.BLACK : Color.WHITE);
holder.title.setTextColor(isAmoledColorMode ? Color.GRAY : Color.BLACK);
}
// Favourite (Star) Image
applyFavouriteImage(holder.favouriteImage, isFollowedTagFaved(tag));
// Click on fav button
holder.favouriteImage.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (isFollowedTagFaved(tag)) {
followedTagsFavsList.remove(followedTagsFavsList.indexOf(tag));
} else {
followedTagsFavsList.add(tag);
}
appSettings.setFollowedTagsFavs(followedTagsFavsList);
applyFavouriteImage(holder.favouriteImage, isFollowedTagFaved(tag));
}
});
holder.root.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
tagClickedListener.onSomethingClicked(null, null, tag);
}
});
}
private boolean isFollowedTagFaved(String tag) {
return followedTagsFavsList.contains(tag);
}
private void applyFavouriteImage(AppCompatImageView imageView, boolean isFaved) {
imageView.setImageResource(isFaved ? R.drawable.ic_star_filled_48px : R.drawable.ic_star_border_black_48px);
imageView.setColorFilter(isFaved ? appSettings.getAccentColor() : (isAmoledColorMode ? Color.GRAY : 0), PorterDuff.Mode.SRC_ATOP);
}
}
}

View File

@ -0,0 +1,85 @@
package com.github.dfa.diaspora_android.ui;
import android.app.Activity;
import android.support.v4.content.ContextCompat;
import com.github.dfa.diaspora_android.R;
import com.github.dfa.diaspora_android.data.DiasporaAspect;
import com.github.dfa.diaspora_android.util.AppSettings;
import net.gsantner.opoc.ui.SearchOrCustomTextDialog;
import net.gsantner.opoc.util.Callback;
import java.util.ArrayList;
import java.util.Arrays;
public class SearchOrCustomTextDialogCreator {
public static final String SPECIAL_PREFIX = "\uD83D\uDCA0";
public static void showDiasporaTagsDialog(final Activity activity, final Callback.a1<String> callback) {
SearchOrCustomTextDialog.DialogOptions dopt = new SearchOrCustomTextDialog.DialogOptions();
baseConf(activity, dopt);
dopt.callback = callback;
dopt.isSearchEnabled = true;
dopt.searchHintText = R.string.search;
dopt.titleText = R.string.tags;
new Thread(() -> {
AppSettings appSettings = AppSettings.get();
ArrayList<String> hl = new ArrayList<>();
ArrayList<String> data = new ArrayList<>(Arrays.asList(appSettings.getFollowedTags()));
if (data.size() > 0) {
String highlighted = surroundString(data.remove(0));
data.add(0, highlighted);
hl.add(highlighted);
}
for (int strid : new int[]{R.string.pref_title__manage_tags}) {
String special = surroundString(appSettings.rstr(strid));
data.add(0, special);
hl.add(special);
}
dopt.data = data;
dopt.highlightData = hl;
activity.runOnUiThread(() -> SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt));
}).start();
}
private static String surroundString(String text) {
return SPECIAL_PREFIX + " " + text + " ";
}
public static void showDiasporaAspectsDialog(final Activity activity, final Callback.a1<String> callback) {
SearchOrCustomTextDialog.DialogOptions dopt = new SearchOrCustomTextDialog.DialogOptions();
baseConf(activity, dopt);
dopt.callback = callback;
dopt.isSearchEnabled = false;
dopt.titleText = R.string.contacts;
new Thread(() -> {
AppSettings appSettings = AppSettings.get();
ArrayList<String> hl = new ArrayList<>();
ArrayList<String> data = new ArrayList<>();
for (DiasporaAspect aspect : AppSettings.get().getAspects()) {
data.add(aspect.name);
}
for (int strid : new int[]{R.string.nav_profile, R.string.pref_desc__manage_contacts}) {
String special = surroundString(appSettings.rstr(strid));
data.add(0, special);
hl.add(special);
}
dopt.data = data;
dopt.highlightData = hl;
activity.runOnUiThread(() -> SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt));
}).start();
}
private static void baseConf(Activity activity, SearchOrCustomTextDialog.DialogOptions dopt) {
AppSettings as = new AppSettings(activity);
dopt.isDarkDialog = as.isAmoledColorMode();
dopt.textColor = ContextCompat.getColor(activity, dopt.isDarkDialog ? R.color.white : R.color.primary_text);
dopt.highlightColor = as.getAccentColor();
}
}

View File

@ -347,8 +347,8 @@ public class AppSettings extends SharedPreferencesPropertyBackend {
return getBool(R.string.pref_key__visibility_nav__reports, false);
}
public boolean isVisibleInNavDandelionAccount() {
return getBool(R.string.pref_key__visibility_nav__dandelion_account, false);
public boolean isVisibleInNavGsantnerAccount() {
return getBool(R.string.pref_key__visibility_nav__gsantner_account, false);
}
public boolean isVisibleInNavToggleMobileDesktop() {

View File

@ -229,6 +229,15 @@ public class DiasporaUrlHelper {
return getPodUrl() + SUBURL_SEARCH_TAGS + query;
}
/**
* Return a url that queries posts for the given hashtag query
*
* @return https://(pod-domain.tld)/followed_tags
*/
public String getAllFollowedTagsUrl() {
return getPodUrl() + SUBURL_FOLOWED_TAGS;
}
/**
* Return a url that queries user accounts for query
*

View File

@ -0,0 +1,189 @@
/*#######################################################
*
* Maintained by Gregor Santner, 2017-
* https://gsantner.net/
*
* License: Apache 2.0
* https://github.com/gsantner/opoc/#licensing
* https://www.apache.org/licenses/LICENSE-2.0
*
#########################################################*/
package net.gsantner.opoc.ui;
import android.app.Activity;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import net.gsantner.opoc.util.Callback;
import net.gsantner.opoc.util.ContextUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@SuppressWarnings("WeakerAccess")
public class SearchOrCustomTextDialog {
public static class DialogOptions {
public Callback.a1<String> callback;
public List<? extends CharSequence> data = new ArrayList<>();
public List<? extends CharSequence> highlightData = new ArrayList<>();
public String messageText = "";
public boolean isSearchEnabled = true;
public boolean isDarkDialog = false;
@ColorInt
public int textColor = 0xFF000000;
@ColorInt
public int highlightColor = 0xFF00FF00;
@StringRes
public int cancelButtonText = android.R.string.cancel;
@StringRes
public int okButtonText = android.R.string.ok;
@StringRes
public int titleText = android.R.string.untitled;
@StringRes
public int searchHintText = android.R.string.search_go;
}
public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activity, final DialogOptions dopt) {
final List<CharSequence> allItems = new ArrayList<>(dopt.data);
final List<CharSequence> filteredItems = new ArrayList<>(allItems);
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, dopt.isDarkDialog
? android.support.v7.appcompat.R.style.Theme_AppCompat_Dialog
: android.support.v7.appcompat.R.style.Theme_AppCompat_Light_Dialog
);
final ArrayAdapter<CharSequence> listAdapter = new ArrayAdapter<CharSequence>(activity, android.R.layout.simple_list_item_1, filteredItems) {
@NonNull
@Override
public View getView(int pos, @Nullable View convertView, @NonNull ViewGroup parent) {
TextView textView = (TextView) super.getView(pos, convertView, parent);
String text = textView.getText().toString();
textView.setTextColor(dopt.textColor);
if (dopt.highlightData.contains(text)) {
textView.setTextColor(dopt.highlightColor);
}
return textView;
}
@Override
public Filter getFilter() {
return new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(final CharSequence constraint, final FilterResults results) {
filteredItems.clear();
filteredItems.addAll((List<String>) results.values);
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(final CharSequence constraint) {
final FilterResults res = new FilterResults();
final ArrayList<CharSequence> resList = new ArrayList<>();
final String fil = constraint.toString();
for (final CharSequence str : allItems) {
if ("".equals(fil) || str.toString().toLowerCase(Locale.getDefault()).contains(fil.toLowerCase(Locale.getDefault()))) {
resList.add(str);
}
}
res.values = resList;
res.count = resList.size();
return res;
}
};
}
};
final AppCompatEditText searchEditText = new AppCompatEditText(activity);
searchEditText.setSingleLine(true);
searchEditText.setMaxLines(1);
searchEditText.setTextColor(dopt.textColor);
searchEditText.setHintTextColor((dopt.textColor & 0x00FFFFFF) | 0x99000000);
searchEditText.setHint(dopt.searchHintText);
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(final Editable arg0) {
listAdapter.getFilter().filter(searchEditText.getText());
}
@Override
public void onTextChanged(final CharSequence arg0, final int arg1, final int arg2, final int arg3) {
}
@Override
public void beforeTextChanged(final CharSequence arg0, final int arg1, final int arg2, final int arg3) {
}
});
final ListView listView = new ListView(activity);
final LinearLayout linearLayout = new LinearLayout(activity);
listView.setAdapter(listAdapter);
linearLayout.setOrientation(LinearLayout.VERTICAL);
if (dopt.isSearchEnabled) {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
ContextUtils cu = new net.gsantner.opoc.util.ContextUtils(listView.getContext());
int px = (int) (new net.gsantner.opoc.util.ContextUtils(listView.getContext()).convertDpToPx(8));
lp.setMargins(px, px / 2, px, px / 2);
linearLayout.addView(searchEditText, lp);
}
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
layoutParams.weight = 1;
linearLayout.addView(listView, layoutParams);
if (!TextUtils.isEmpty(dopt.messageText)) {
dialogBuilder.setMessage(dopt.messageText);
}
dialogBuilder.setView(linearLayout)
.setTitle(dopt.titleText)
.setOnCancelListener(null)
.setNegativeButton(dopt.cancelButtonText, null);
if (dopt.isSearchEnabled) {
dialogBuilder.setPositiveButton(dopt.okButtonText, (dialogInterface, i) -> {
dialogInterface.dismiss();
if (dopt.callback != null && !TextUtils.isEmpty(searchEditText.getText().toString())) {
dopt.callback.callback(searchEditText.getText().toString());
}
});
}
final AlertDialog dialog = dialogBuilder.create();
listView.setOnItemClickListener((parent, view, position, id) -> {
dialog.dismiss();
if (dopt.callback != null) {
dopt.callback.callback(filteredItems.get(position).toString());
}
});
searchEditText.setOnKeyListener((keyView, keyCode, keyEvent) -> {
if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
dialog.dismiss();
if (dopt.callback != null && !TextUtils.isEmpty(searchEditText.getText().toString())) {
dopt.callback.callback(searchEditText.getText().toString());
}
return true;
}
return false;
});
dialog.show();
}
}

View File

@ -11,6 +11,7 @@
package net.gsantner.opoc.util;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
@ -380,6 +381,9 @@ public class ContextUtils {
Intent inte = new Intent(_context, classToStart);
PendingIntent inteP = PendingIntent.getActivity(_context, 555, inte, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) _context.getSystemService(Context.ALARM_SERVICE);
if (_context instanceof Activity) {
((Activity) _context).finish();
}
if (mgr != null) {
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, inteP);
} else {

View File

@ -17,7 +17,7 @@
<item
android:id="@+id/nav_followed_tags"
android:icon="@drawable/ic_local_offer_black_48px"
android:title="@string/nav_followed_tags" />
android:title="@string/tags" />
<item
android:id="@+id/nav_aspects"
android:icon="@drawable/ic_group_black_48px"
@ -54,9 +54,9 @@
android:title="@string/nav_public_activities" />
<item
android:id="@+id/nav_dandelion"
android:id="@+id/nav_product_support"
android:icon="@drawable/ic_person_black_24px"
android:title="@string/dandelion" />
android:title="@string/gsantner" />
<item
android:id="@+id/nav_statistics"

View File

@ -9,6 +9,7 @@
*via [dandelion*](/people?q=dandelion00%40diasp.org) client [(Source)](https://github.com/gsantner/dandelion)*</string>
<string name="tags" translatable="false">Tags</string>
<string name="tor" translatable="false">Tor</string>
<string name="HTTP" translatable="false">HTTP</string>
@ -116,7 +117,7 @@
<string name="pref_key__visibility_nav__reports" translatable="false">pref_key__visibility_nav__reports</string>
<string name="pref_key__visibility_nav__statistics" translatable="false">pref_key__visibility_nav__statistics</string>
<string name="pref_key__visibility_nav__toggle_mobile_desktop" translatable="false">pref_key__visibility_nav__toggle_mobile_desktop</string>
<string name="pref_key__visibility_nav__dandelion_account" translatable="false">pref_key__visibility_nav__dandelion_account</string>
<string name="pref_key__visibility_nav__gsantner_account" translatable="false">pref_key__visibility_nav__gsantner_account</string>
<string name="pref_key__podprofile_avatar_url" translatable="false">pref_key__podprofile_avatar_url</string>
<string name="pref_key__podprofile_name" translatable="false">pref_key__podprofile_name</string>
<string name="pref_key__podprofile_id" translatable="false">pref_key__podprofile_id</string>
@ -146,4 +147,5 @@
<string name="pref_key__recreate_main_activity" translatable="false">pref_key__recreate_main_activity</string>
<string name="pref_key__show_title" translatable="false">pref_key__show_title</string>
<string name="pdf" translatable="false">PDF</string>
<string name="gsantner" translatable="false">gsantner</string>
</resources>

View File

@ -35,14 +35,14 @@
</shortcut>
<shortcut
android:shortcutId="sc_aspects"
android:shortcutId="sc_contacts"
android:enabled="true"
android:icon="@drawable/sc_aspect"
android:shortcutShortLabel="@string/aspects"
android:shortcutLongLabel="@string/aspects"
android:shortcutDisabledMessage="@string/aspects">
android:shortcutShortLabel="@string/contacts"
android:shortcutLongLabel="@string/contacts"
android:shortcutDisabledMessage="@string/contacts">
<intent
android:action="sc_aspects"
android:action="sc_contacts"
android:targetPackage="com.github.dfa.diaspora_android"
android:targetClass="com.github.dfa.diaspora_android.activity.MainActivity" />
<!-- If your shortcut is associated with multiple intents, include them
@ -52,14 +52,14 @@
</shortcut>
<shortcut
android:shortcutId="sc_nav_followed_tags"
android:shortcutId="sc_tags"
android:enabled="true"
android:icon="@drawable/sc_tags"
android:shortcutShortLabel="@string/nav_followed_tags"
android:shortcutLongLabel="@string/nav_followed_tags"
android:shortcutDisabledMessage="@string/nav_followed_tags">
android:shortcutShortLabel="@string/tags"
android:shortcutLongLabel="@string/tags"
android:shortcutDisabledMessage="@string/tags">
<intent
android:action="sc_nav_followed_tags"
android:action="sc_tags"
android:targetPackage="com.github.dfa.diaspora_android"
android:targetClass="com.github.dfa.diaspora_android.activity.MainActivity" />
<!-- If your shortcut is associated with multiple intents, include them

View File

@ -42,8 +42,8 @@
android:title="@string/nav_public_activities"/>
<com.github.dfa.diaspora_android.ui.theme.ThemedVisibilityPreference
android:defaultValue="false"
android:key="@string/pref_key__visibility_nav__dandelion_account"
android:title="@string/dandelion"/>
android:key="@string/pref_key__visibility_nav__gsantner_account"
android:title="@string/gsantner"/>
</com.github.dfa.diaspora_android.ui.theme.ThemedPreferenceCategory>