diff --git a/app/src/main/java/me/ccrama/redditslide/Activities/Crosspost.java b/app/src/main/java/me/ccrama/redditslide/Activities/Crosspost.java index 2377831eb..099aee45e 100644 --- a/app/src/main/java/me/ccrama/redditslide/Activities/Crosspost.java +++ b/app/src/main/java/me/ccrama/redditslide/Activities/Crosspost.java @@ -1,245 +1,245 @@ -package me.ccrama.redditslide.Activities; - -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.EditText; - -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.SwitchCompat; - -import com.google.android.material.floatingactionbutton.FloatingActionButton; - -import net.dean.jraw.ApiException; -import net.dean.jraw.managers.AccountManager; -import net.dean.jraw.models.Submission; -import net.dean.jraw.models.Subreddit; - -import java.util.List; - -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.OpenRedditLink; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SpoilerRobotoTextView; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Views.CommentOverflow; -import me.ccrama.redditslide.util.SubmissionParser; -import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; - - -/** - * Created by ccrama on 3/5/2015. - */ -public class Crosspost extends BaseActivity { - - public static Submission toCrosspost; - private SwitchCompat inboxReplies; - - AsyncTask tchange; - - public void onCreate(Bundle savedInstanceState) { - disableSwipeBackLayout(); - super.onCreate(savedInstanceState); - applyColorTheme(); - setContentView(R.layout.activity_crosspost); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = this.getWindow(); - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - } - setupAppBar(R.id.toolbar, R.string.title_crosspost, true, true); - - inboxReplies = (SwitchCompat) findViewById(R.id.replies); - - final AutoCompleteTextView subredditText = - ((AutoCompleteTextView) findViewById(R.id.subreddittext)); - - ((EditText) findViewById(R.id.crossposttext)).setText(toCrosspost.getTitle() - + getString(R.string.submission_properties_seperator) - + "/u/" - + toCrosspost.getAuthor()); - findViewById(R.id.crossposttext).setEnabled(false); - ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, - UserSubscriptions.getAllSubreddits(this)); - - subredditText.setAdapter(adapter); - subredditText.setThreshold(2); - - subredditText.addTextChangedListener(new SimpleTextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (tchange != null) { - tchange.cancel(true); - } - findViewById(R.id.submittext).setVisibility(View.GONE); - } - }); - - subredditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - findViewById(R.id.submittext).setVisibility(View.GONE); - if (!hasFocus) { - tchange = new AsyncTask() { - @Override - protected Subreddit doInBackground(Void... params) { - try { - return Authentication.reddit.getSubreddit( - subredditText.getText().toString()); - } catch (Exception ignored) { - - } - return null; - } - - @Override - protected void onPostExecute(Subreddit s) { - - if (s != null) { - String text = s.getDataNode().get("submit_text_html").asText(); - if (text != null && !text.isEmpty() && !text.equals("null")) { - findViewById(R.id.submittext).setVisibility(View.VISIBLE); - setViews(text, subredditText.getText().toString(), - (SpoilerRobotoTextView) findViewById(R.id.submittext), - (CommentOverflow) findViewById(R.id.commentOverflow)); - } - if (s.getSubredditType().equals("RESTRICTED")) { - subredditText.setText(""); - new AlertDialog.Builder(Crosspost.this) - .setTitle(R.string.err_submit_restricted) - .setMessage(R.string.err_submit_restricted_text) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } - } else { - findViewById(R.id.submittext).setVisibility(View.GONE); - } - } - }; - tchange.execute(); - } - } - }); - - ((EditText) findViewById(R.id.titletext)).setText(toCrosspost.getTitle()); - - findViewById(R.id.suggest).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ((EditText) findViewById(R.id.titletext)).setText(toCrosspost.getTitle()); - } - }); - - findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - ((FloatingActionButton) findViewById(R.id.send)).hide(); - new AsyncDo().execute(); - } - }); - - - } - - public void setViews(String rawHTML, String subredditName, SpoilerRobotoTextView firstTextView, - CommentOverflow commentOverflow) { - if (rawHTML.isEmpty()) { - return; - } - - List blocks = SubmissionParser.getBlocks(rawHTML); - - int startIndex = 0; - // the
case is when the body contains a table or code block first - if (!blocks.get(0).equals("
")) { - firstTextView.setVisibility(View.VISIBLE); - firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); - startIndex = 1; - } else { - firstTextView.setText(""); - firstTextView.setVisibility(View.GONE); - } - - if (blocks.size() > 1) { - if (startIndex == 0) { - commentOverflow.setViews(blocks, subredditName); - } else { - commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); - } - } else { - commentOverflow.removeAllViews(); - } - } - - - private class AsyncDo extends AsyncTask { - - @Override - protected Void doInBackground(Void... voids) { - try { - try { - Submission s = new AccountManager(Authentication.reddit).crosspost(toCrosspost, - ((AutoCompleteTextView) findViewById(R.id.subreddittext)).getText() - .toString(), - ((EditText) findViewById(R.id.titletext)).getText().toString(), null, - ""); - new AccountManager(Authentication.reddit).sendRepliesToInbox(s, - inboxReplies.isChecked()); - OpenRedditLink.openUrl(Crosspost.this, - "reddit.com/r/" - + ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString() - + "/comments/" - + s.getFullName().substring(3), true); - Crosspost.this.finish(); - } catch (final ApiException e) { - e.printStackTrace(); - - runOnUiThread(new Runnable() { - @Override - public void run() { - showErrorRetryDialog(getString(R.string.misc_err) - + ": " - + e.getExplanation() - + "\n" - + getString(R.string.misc_retry)); - } - }); - } - } catch (Exception e) { - e.printStackTrace(); - - runOnUiThread(new Runnable() { - @Override - public void run() { - showErrorRetryDialog(getString(R.string.misc_retry)); - } - }); - } - return null; - } - - - } - - - private void showErrorRetryDialog(String message) { - new AlertDialog.Builder(Crosspost.this) - .setTitle(R.string.err_title) - .setMessage(message) - .setNegativeButton(R.string.btn_no, (dialogInterface, i) -> - finish()) - .setPositiveButton(R.string.btn_yes, (dialogInterface, i) -> - ((FloatingActionButton) findViewById(R.id.send)).show()) - .setOnDismissListener(dialog -> - ((FloatingActionButton) findViewById(R.id.send)).show()) - .create() - .show(); - } -} +package me.ccrama.redditslide.Activities; + +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.EditText; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import net.dean.jraw.ApiException; +import net.dean.jraw.managers.AccountManager; +import net.dean.jraw.models.Submission; +import net.dean.jraw.models.Subreddit; + +import java.util.List; + +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.OpenRedditLink; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SpoilerRobotoTextView; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Views.CommentOverflow; +import me.ccrama.redditslide.util.SubmissionParser; +import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; + + +/** + * Created by ccrama on 3/5/2015. + */ +public class Crosspost extends BaseActivity { + + public static Submission toCrosspost; + private SwitchCompat inboxReplies; + + AsyncTask tchange; + + public void onCreate(Bundle savedInstanceState) { + disableSwipeBackLayout(); + super.onCreate(savedInstanceState); + applyColorTheme(); + setContentView(R.layout.activity_crosspost); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = this.getWindow(); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + } + setupAppBar(R.id.toolbar, R.string.title_crosspost, true, true); + + inboxReplies = (SwitchCompat) findViewById(R.id.replies); + + final AutoCompleteTextView subredditText = + ((AutoCompleteTextView) findViewById(R.id.subreddittext)); + + ((EditText) findViewById(R.id.crossposttext)).setText(toCrosspost.getTitle() + + getString(R.string.submission_properties_seperator) + + "/u/" + + toCrosspost.getAuthor()); + findViewById(R.id.crossposttext).setEnabled(false); + ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, + UserSubscriptions.getAllSubreddits(this)); + + subredditText.setAdapter(adapter); + subredditText.setThreshold(2); + + subredditText.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (tchange != null) { + tchange.cancel(true); + } + findViewById(R.id.submittext).setVisibility(View.GONE); + } + }); + + subredditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + findViewById(R.id.submittext).setVisibility(View.GONE); + if (!hasFocus) { + tchange = new AsyncTask() { + @Override + protected Subreddit doInBackground(Void... params) { + try { + return Authentication.reddit.getSubreddit( + subredditText.getText().toString()); + } catch (Exception ignored) { + + } + return null; + } + + @Override + protected void onPostExecute(Subreddit s) { + + if (s != null) { + String text = s.getDataNode().get("submit_text_html").asText(); + if (text != null && !text.isEmpty() && !text.equals("null")) { + findViewById(R.id.submittext).setVisibility(View.VISIBLE); + setViews(text, subredditText.getText().toString(), + (SpoilerRobotoTextView) findViewById(R.id.submittext), + (CommentOverflow) findViewById(R.id.commentOverflow)); + } + if (s.getSubredditType().equals("RESTRICTED")) { + subredditText.setText(""); + new AlertDialog.Builder(Crosspost.this) + .setTitle(R.string.err_submit_restricted) + .setMessage(R.string.err_submit_restricted_text) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } + } else { + findViewById(R.id.submittext).setVisibility(View.GONE); + } + } + }; + tchange.execute(); + } + } + }); + + ((EditText) findViewById(R.id.titletext)).setText(toCrosspost.getTitle()); + + findViewById(R.id.suggest).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ((EditText) findViewById(R.id.titletext)).setText(toCrosspost.getTitle()); + } + }); + + findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ((FloatingActionButton) findViewById(R.id.send)).hide(); + new AsyncDo().execute(); + } + }); + + + } + + public void setViews(String rawHTML, String subredditName, SpoilerRobotoTextView firstTextView, + CommentOverflow commentOverflow) { + if (rawHTML.isEmpty()) { + return; + } + + List blocks = SubmissionParser.getBlocks(rawHTML); + + int startIndex = 0; + // the
case is when the body contains a table or code block first + if (!blocks.get(0).equals("
")) { + firstTextView.setVisibility(View.VISIBLE); + firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); + startIndex = 1; + } else { + firstTextView.setText(""); + firstTextView.setVisibility(View.GONE); + } + + if (blocks.size() > 1) { + if (startIndex == 0) { + commentOverflow.setViews(blocks, subredditName); + } else { + commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); + } + } else { + commentOverflow.removeAllViews(); + } + } + + + private class AsyncDo extends AsyncTask { + + @Override + protected Void doInBackground(Void... voids) { + try { + try { + Submission s = new AccountManager(Authentication.reddit).crosspost(toCrosspost, + ((AutoCompleteTextView) findViewById(R.id.subreddittext)).getText() + .toString(), + ((EditText) findViewById(R.id.titletext)).getText().toString(), null, + ""); + new AccountManager(Authentication.reddit).sendRepliesToInbox(s, + inboxReplies.isChecked()); + OpenRedditLink.openUrl(Crosspost.this, + "reddit.com/r/" + + ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString() + + "/comments/" + + s.getFullName().substring(3), true); + Crosspost.this.finish(); + } catch (final ApiException e) { + e.printStackTrace(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + showErrorRetryDialog(getString(R.string.misc_err) + + ": " + + e.getExplanation() + + "\n" + + getString(R.string.misc_retry)); + } + }); + } + } catch (Exception e) { + e.printStackTrace(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + showErrorRetryDialog(getString(R.string.misc_retry)); + } + }); + } + return null; + } + + + } + + + private void showErrorRetryDialog(String message) { + new AlertDialog.Builder(Crosspost.this) + .setTitle(R.string.err_title) + .setMessage(message) + .setNegativeButton(R.string.btn_no, (dialogInterface, i) -> + finish()) + .setPositiveButton(R.string.btn_yes, (dialogInterface, i) -> + ((FloatingActionButton) findViewById(R.id.send)).show()) + .setOnDismissListener(dialog -> + ((FloatingActionButton) findViewById(R.id.send)).show()) + .create() + .show(); + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/Activities/MultiredditOverview.java b/app/src/main/java/me/ccrama/redditslide/Activities/MultiredditOverview.java index 501df3367..51e9237df 100644 --- a/app/src/main/java/me/ccrama/redditslide/Activities/MultiredditOverview.java +++ b/app/src/main/java/me/ccrama/redditslide/Activities/MultiredditOverview.java @@ -1,748 +1,748 @@ -package me.ccrama.redditslide.Activities; - -import android.app.Activity; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.text.Spannable; -import android.util.Log; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.animation.LinearInterpolator; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.PopupMenu; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.viewpager.widget.ViewPager; - -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; -import com.google.android.material.tabs.TabLayout; - -import net.dean.jraw.models.MultiReddit; -import net.dean.jraw.models.MultiSubreddit; -import net.dean.jraw.models.Submission; -import net.dean.jraw.paginators.Sorting; -import net.dean.jraw.paginators.TimePeriod; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.CaseInsensitiveArrayList; -import me.ccrama.redditslide.Fragments.MultiredditView; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Views.CatchStaggeredGridLayoutManager; -import me.ccrama.redditslide.Views.PreCachingLayoutManager; -import me.ccrama.redditslide.Visuals.ColorPreferences; -import me.ccrama.redditslide.Visuals.Palette; -import me.ccrama.redditslide.util.BlendModeUtil; -import me.ccrama.redditslide.util.LogUtil; -import me.ccrama.redditslide.util.ProUtil; -import me.ccrama.redditslide.util.SortingUtil; - -/** - * Created by ccrama on 9/17/2015. - */ -public class MultiredditOverview extends BaseActivityAnim { - - public static final String EXTRA_PROFILE = "profile"; - public static final String EXTRA_MULTI = "multi"; - - public static Activity multiActivity; - - public static MultiReddit searchMulti; - public MultiredditOverviewPagerAdapter adapter; - private ViewPager pager; - private String profile; - private TabLayout tabs; - private List usedArray; - private String initialMulti; - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.menu_multireddits, menu); - - if (!profile.isEmpty()) { - menu.findItem(R.id.action_edit).setVisible(false); - menu.findItem(R.id.create).setVisible(false); - } - - // if (mShowInfoButton) menu.findItem(R.id.action_info).setVisible(true); - // else menu.findItem(R.id.action_info).setVisible(false); - - return true; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - /* removed for now - int keyCode = event.getKeyCode(); - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - return ((MultiredditView) adapter.getCurrentFragment()).onKeyDown(keyCode); - case KeyEvent.KEYCODE_VOLUME_DOWN: - return ((MultiredditView) adapter.getCurrentFragment()).onKeyDown(keyCode); - default: - return super.dispatchKeyEvent(event); - }*/ - return super.dispatchKeyEvent(event); - } - - public int getCurrentPage() { - int position = 0; - int currentOrientation = getResources().getConfiguration().orientation; - if (((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof LinearLayoutManager - && currentOrientation == Configuration.ORIENTATION_LANDSCAPE) { - position = - ((LinearLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) - .findFirstVisibleItemPosition() - 1; - } else if (((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof CatchStaggeredGridLayoutManager) { - int[] firstVisibleItems = null; - firstVisibleItems = - ((CatchStaggeredGridLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv - .getLayoutManager()).findFirstVisibleItemPositions(firstVisibleItems); - if (firstVisibleItems != null && firstVisibleItems.length > 0) { - position = firstVisibleItems[0] - 1; - } - } else { - position = - ((PreCachingLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) - .findFirstVisibleItemPosition() - 1; - } - return position; - } - - String term; - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - - case android.R.id.home: - try { - onBackPressed(); - } catch (Exception ignored) { - - } - return true; - case R.id.action_edit: { - if (profile.isEmpty() - && (UserSubscriptions.multireddits != null) - && !UserSubscriptions.multireddits.isEmpty()) { - Intent i = new Intent(MultiredditOverview.this, CreateMulti.class); - i.putExtra(CreateMulti.EXTRA_MULTI, UserSubscriptions.multireddits - .get(pager.getCurrentItem()) - .getDisplayName()); - startActivity(i); - } - } - return true; - case R.id.search: { - - UserSubscriptions.MultiCallback m = new UserSubscriptions.MultiCallback() { - @Override - public void onComplete(List multireddits) { - if ((multireddits != null) && !multireddits.isEmpty()) { - searchMulti = multireddits.get(pager.getCurrentItem()); - MaterialDialog.Builder builder = - new MaterialDialog.Builder(MultiredditOverview.this).title(R.string.search_title) - .alwaysCallInputCallback() - .input(getString(R.string.search_msg), "", - new MaterialDialog.InputCallback() { - @Override - public void onInput( - MaterialDialog materialDialog, - CharSequence charSequence) { - term = charSequence.toString(); - } - }); - - //Add "search current sub" if it is not frontpage/all/random - builder.positiveText(getString(R.string.search_subreddit, - "/m/" + searchMulti.getDisplayName())) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(@NonNull MaterialDialog materialDialog, - @NonNull DialogAction dialogAction) { - Intent i = new Intent(MultiredditOverview.this, - Search.class); - i.putExtra(Search.EXTRA_TERM, term); - i.putExtra(Search.EXTRA_MULTIREDDIT, - searchMulti.getDisplayName()); - startActivity(i); - } - }); - - builder.show(); - } - } - }; - - if (profile.isEmpty()) { - UserSubscriptions.getMultireddits(m); - } else { - UserSubscriptions.getPublicMultireddits(m, profile); - } - } - return true; - case R.id.create: - if (profile.isEmpty()) { - Intent i2 = new Intent(MultiredditOverview.this, CreateMulti.class); - startActivity(i2); - } - return true; - case R.id.action_sort: - openPopup(); - return true; - - case R.id.subs: - ((DrawerLayout) findViewById(R.id.drawer_layout)).openDrawer(Gravity.RIGHT); - return true; - case R.id.gallery: - if (SettingValues.isPro) { - List posts = - ((MultiredditView) adapter.getCurrentFragment()).posts.posts; - if (posts != null && !posts.isEmpty()) { - Intent i2 = new Intent(this, Gallery.class); - i2.putExtra(Gallery.EXTRA_PROFILE, profile); - i2.putExtra(Gallery.EXTRA_MULTIREDDIT, - ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit.getDisplayName()); - startActivity(i2); - } - } else { - final AlertDialog.Builder b = - ProUtil.proUpgradeMsg(this, R.string.general_gallerymode_ispro) - .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> - dialog.dismiss()); - if (SettingValues.previews > 0) { - b.setNeutralButton(getString(R.string.pro_previews, SettingValues.previews), - (dialog, which) -> { - SettingValues.prefs.edit() - .putInt(SettingValues.PREVIEWS_LEFT, - SettingValues.previews - 1) - .apply(); - SettingValues.previews = SettingValues.prefs.getInt( - SettingValues.PREVIEWS_LEFT, 10); - List posts = - ((MultiredditView) adapter.getCurrentFragment()).posts.posts; - if (posts != null && !posts.isEmpty()) { - Intent i2 = new Intent(MultiredditOverview.this, - Gallery.class); - i2.putExtra(Gallery.EXTRA_PROFILE, profile); - i2.putExtra(Gallery.EXTRA_MULTIREDDIT, - ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit - .getDisplayName()); - startActivity(i2); - } - }); - } - b.show(); - } - return true; - case R.id.action_shadowbox: - if (SettingValues.isPro) { - List posts = - ((MultiredditView) adapter.getCurrentFragment()).posts.posts; - if (posts != null && !posts.isEmpty()) { - Intent i = new Intent(this, Shadowbox.class); - i.putExtra(Shadowbox.EXTRA_PAGE, getCurrentPage()); - i.putExtra(Shadowbox.EXTRA_PROFILE, profile); - i.putExtra(Shadowbox.EXTRA_MULTIREDDIT, - ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit.getDisplayName()); - startActivity(i); - } - } else { - final AlertDialog.Builder b = - ProUtil.proUpgradeMsg(this, R.string.general_shadowbox_ispro) - .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> - dialog.dismiss()); - if (SettingValues.previews > 0 - && adapter != null - && ((MultiredditView) adapter.getCurrentFragment()).posts != null - && ((MultiredditView) adapter.getCurrentFragment()).posts.posts != null - && !((MultiredditView) adapter.getCurrentFragment()).posts.posts.isEmpty()) { - b.setNeutralButton(getString(R.string.pro_previews, SettingValues.previews), - (dialog, which) -> { - SettingValues.prefs.edit() - .putInt(SettingValues.PREVIEWS_LEFT, - SettingValues.previews - 1) - .apply(); - SettingValues.previews = SettingValues.prefs.getInt( - SettingValues.PREVIEWS_LEFT, 10); - List posts = - ((MultiredditView) adapter.getCurrentFragment()).posts.posts; - if (posts != null && !posts.isEmpty()) { - Intent i = new Intent(MultiredditOverview.this, - Shadowbox.class); - i.putExtra(Shadowbox.EXTRA_PAGE, getCurrentPage()); - i.putExtra(Shadowbox.EXTRA_PROFILE, profile); - i.putExtra(Shadowbox.EXTRA_MULTIREDDIT, - ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit - .getDisplayName()); - startActivity(i); - } - }); - } - b.show(); - } - return true; - default: - return false; - } - } - - private void buildDialog() { - buildDialog(false); - } - - private void buildDialog(boolean wasException) { - try { - final AlertDialog.Builder b = - new AlertDialog.Builder(MultiredditOverview.this) - .setCancelable(false) - .setOnDismissListener(dialog -> - finish()); - if (wasException) { - b.setTitle(R.string.err_title) - .setMessage(R.string.err_loading_content) - .setPositiveButton(R.string.btn_ok, (dialog, which) -> - finish()); - } else if (profile.isEmpty()) { - b.setTitle(R.string.multireddit_err_title) - .setMessage(R.string.multireddit_err_msg) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> { - Intent i = new Intent(MultiredditOverview.this, CreateMulti.class); - startActivity(i); - }) - .setNegativeButton(R.string.btn_no, (dialog, which) -> - finish()); - } else { - b.setTitle(R.string.public_multireddit_err_title) - .setMessage(R.string.public_multireddit_err_msg) - .setNegativeButton(R.string.btn_go_back, (dialog, which) -> - finish()); - } - b.show(); - } catch (Exception e) { - - } - } - - @Override - public void onCreate(Bundle savedInstance) { - overrideSwipeFromAnywhere(); - - multiActivity = this; - - super.onCreate(savedInstance); - - applyColorTheme(""); - setContentView(R.layout.activity_multireddits); - setupAppBar(R.id.toolbar, R.string.title_multireddits, true, false); - - findViewById(R.id.header).setBackgroundColor(Palette.getDefaultColor()); - tabs = (TabLayout) findViewById(R.id.sliding_tabs); - tabs.setTabMode(TabLayout.MODE_SCROLLABLE); - - pager = (ViewPager) findViewById(R.id.content_view); - mToolbar.setPopupTheme(new ColorPreferences(this).getFontStyle().getBaseId()); - - profile = ""; - initialMulti = ""; - if (getIntent().getExtras() != null) { - profile = getIntent().getExtras().getString(EXTRA_PROFILE, ""); - initialMulti = getIntent().getExtras().getString(EXTRA_MULTI, ""); - } - if (profile.equalsIgnoreCase(Authentication.name)) { - profile = ""; - } - - UserSubscriptions.MultiCallback callback = new UserSubscriptions.MultiCallback() { - @Override - public void onComplete(List multiReddits) { - if (multiReddits != null && !multiReddits.isEmpty()) { - setDataSet(multiReddits); - } else { - buildDialog(); - } - } - }; - - if (profile.isEmpty()) { - UserSubscriptions.getMultireddits(callback); - } else { - UserSubscriptions.getPublicMultireddits(callback, profile); - } - } - - - public void openPopup() { - PopupMenu popup = - new PopupMenu(MultiredditOverview.this, findViewById(R.id.anchor), Gravity.RIGHT); - String id = - ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()).getCurrentFragment())).posts.multiReddit - .getDisplayName() - .toLowerCase(Locale.ENGLISH); - final Spannable[] base = SortingUtil.getSortingSpannables("multi" + id); - for (Spannable s : base) { - // Do not add option for "Best" in any subreddit except for the frontpage. - if (s.toString().equals(getString(R.string.sorting_best))) { - continue; - } - MenuItem m = popup.getMenu().add(s); - } - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - int i = 0; - for (Spannable s : base) { - if (s.equals(item.getTitle())) { - break; - } - i++; - } - LogUtil.v("Chosen is " + i); - if (pager.getAdapter() != null) { - switch (i) { - case 0: - SortingUtil.setSorting("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), Sorting.HOT); - reloadSubs(); - break; - case 1: - SortingUtil.setSorting("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), Sorting.NEW); - reloadSubs(); - break; - case 2: - SortingUtil.setSorting("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), Sorting.RISING); - reloadSubs(); - break; - case 3: - SortingUtil.setSorting("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), Sorting.TOP); - openPopupTime(); - break; - case 4: - SortingUtil.setSorting("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), Sorting.CONTROVERSIAL); - openPopupTime(); - break; - } - } - return true; - } - }); - popup.show(); - - - } - - public void openPopupTime() { - PopupMenu popup = - new PopupMenu(MultiredditOverview.this, findViewById(R.id.anchor), Gravity.RIGHT); - String id = - ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()).getCurrentFragment())).posts.multiReddit - .getDisplayName() - .toLowerCase(Locale.ENGLISH); - final Spannable[] base = SortingUtil.getSortingTimesSpannables("multi" + id); - for (Spannable s : base) { - MenuItem m = popup.getMenu().add(s); - } - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - int i = 0; - for (Spannable s : base) { - if (s.equals(item.getTitle())) { - break; - } - i++; - } - LogUtil.v("Chosen is " + i); - if (pager.getAdapter() != null) { - switch (i) { - case 0: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.HOUR); - reloadSubs(); - break; - case 1: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.DAY); - reloadSubs(); - break; - case 2: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.WEEK); - reloadSubs(); - break; - case 3: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.MONTH); - reloadSubs(); - break; - case 4: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.YEAR); - reloadSubs(); - break; - case 5: - SortingUtil.setTime("multi" - + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) - .getCurrentFragment())).posts.multiReddit.getDisplayName() - .toLowerCase(Locale.ENGLISH), TimePeriod.ALL); - reloadSubs(); - break; - } - } - return true; - } - }); - popup.show(); - - - } - - private void reloadSubs() { - int current = pager.getCurrentItem(); - adapter = new MultiredditOverviewPagerAdapter(getSupportFragmentManager()); - pager.setAdapter(adapter); - pager.setCurrentItem(current); - } - - private void setDataSet(List data) { - try { - usedArray = data; - - if (usedArray.isEmpty()) { - buildDialog(); - } else { - - if (adapter == null) { - adapter = new MultiredditOverviewPagerAdapter(getSupportFragmentManager()); - } else { - adapter.notifyDataSetChanged(); - } - pager.setAdapter(adapter); - pager.setOffscreenPageLimit(1); - tabs.setupWithViewPager(pager); - if (!initialMulti.isEmpty()) { - for (int i = 0; i < usedArray.size(); i++) { - if (usedArray.get(i).getDisplayName().equalsIgnoreCase(initialMulti)) { - pager.setCurrentItem(i); - break; - } - } - } - tabs.setSelectedTabIndicatorColor( - new ColorPreferences(MultiredditOverview.this).getColor( - usedArray.get(0).getDisplayName())); - doDrawerSubs(0); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = this.getWindow(); - window.setStatusBarColor( - Palette.getDarkerColor(usedArray.get(0).getDisplayName())); - } - final View header = findViewById(R.id.header); - tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) { - @Override - public void onTabReselected(TabLayout.Tab tab) { - super.onTabReselected(tab); - int pastVisiblesItems = 0; - int[] firstVisibleItems = - ((CatchStaggeredGridLayoutManager) (((MultiredditView) adapter.getCurrentFragment()).rv - .getLayoutManager())).findFirstVisibleItemPositions(null); - if (firstVisibleItems != null && firstVisibleItems.length > 0) { - for (int firstVisibleItem : firstVisibleItems) { - pastVisiblesItems = firstVisibleItem; - } - } - if (pastVisiblesItems > 8) { - ((MultiredditView) adapter.getCurrentFragment()).rv.scrollToPosition(0); - if (header != null) { - header.animate() - .translationY(header.getHeight()) - .setInterpolator(new LinearInterpolator()) - .setDuration(0); - } - } else { - ((MultiredditView) adapter.getCurrentFragment()).rv.smoothScrollToPosition( - 0); - } - } - }); - findViewById(R.id.header).setBackgroundColor( - Palette.getColor(usedArray.get(0).getDisplayName())); - } - } catch (NullPointerException e) { - buildDialog(true); - Log.e(LogUtil.getTag(), "Cannot load multis:\n" + e); - } - - } - - public void doDrawerSubs(int position) { - MultiReddit current = usedArray.get(position); - LinearLayout l = (LinearLayout) findViewById(R.id.sidebar_scroll); - l.removeAllViews(); - - CaseInsensitiveArrayList toSort = new CaseInsensitiveArrayList(); - - for (MultiSubreddit s : current.getSubreddits()) { - toSort.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); - } - - for (String sub : UserSubscriptions.sortNoExtras(toSort)) { - final View convertView = getLayoutInflater().inflate(R.layout.subforsublist, l, false); - - final String subreddit = sub; - final TextView t = convertView.findViewById(R.id.name); - t.setText(subreddit); - - final View colorView = convertView.findViewById(R.id.color); - colorView.setBackgroundResource(R.drawable.circle); - BlendModeUtil.tintDrawableAsModulate(colorView.getBackground(), Palette.getColor(subreddit)); - convertView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent inte = new Intent(MultiredditOverview.this, SubredditView.class); - inte.putExtra(SubredditView.EXTRA_SUBREDDIT, subreddit); - MultiredditOverview.this.startActivityForResult(inte, 4); - } - }); - l.addView(convertView); - } - } - - private class MultiredditOverviewPagerAdapter extends FragmentStatePagerAdapter { - - MultiredditOverviewPagerAdapter(FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - findViewById(R.id.header).animate() - .translationY(0) - .setInterpolator(new LinearInterpolator()) - .setDuration(180); - findViewById(R.id.header).setBackgroundColor( - Palette.getColor(usedArray.get(position).getDisplayName())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = getWindow(); - window.setStatusBarColor( - Palette.getDarkerColor(usedArray.get(position).getDisplayName())); - } - tabs.setSelectedTabIndicatorColor( - new ColorPreferences(MultiredditOverview.this).getColor( - usedArray.get(position).getDisplayName())); - doDrawerSubs(position); - } - }); - } - - @NonNull - @Override - public Fragment getItem(int i) { - Fragment f = new MultiredditView(); - Bundle args = new Bundle(); - - args.putInt("id", i); - args.putString(EXTRA_PROFILE, profile); - - f.setArguments(args); - - return f; - } - - private Fragment mCurrentFragment; - - Fragment getCurrentFragment() { - return mCurrentFragment; - } - - @Override - public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) { - if (mCurrentFragment != object) { - mCurrentFragment = (Fragment) object; - } - super.setPrimaryItem(container, position, object); - } - - @Override - public int getCount() { - if (usedArray == null) { - return 1; - } else { - return usedArray.size(); - } - } - - @Override - public CharSequence getPageTitle(int position) { - return usedArray.get(position).getFullName(); - } - } - - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == 940 && adapter != null && adapter.getCurrentFragment() != null) { - if (resultCode == RESULT_OK) { - LogUtil.v("Doing hide posts"); - ArrayList posts = data.getIntegerArrayListExtra("seen"); - ((MultiredditView) adapter.getCurrentFragment()).adapter.refreshView(posts); - if (data.hasExtra("lastPage") - && data.getIntExtra("lastPage", 0) != 0 - && ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof LinearLayoutManager) { - ((LinearLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) - .scrollToPositionWithOffset(data.getIntExtra("lastPage", 0) + 1, - mToolbar.getHeight()); - } - } else { - ((MultiredditView) adapter.getCurrentFragment()).adapter.refreshView(); - } - } - - } - -} +package me.ccrama.redditslide.Activities; + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.text.Spannable; +import android.util.Log; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.animation.LinearInterpolator; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.PopupMenu; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.viewpager.widget.ViewPager; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.google.android.material.tabs.TabLayout; + +import net.dean.jraw.models.MultiReddit; +import net.dean.jraw.models.MultiSubreddit; +import net.dean.jraw.models.Submission; +import net.dean.jraw.paginators.Sorting; +import net.dean.jraw.paginators.TimePeriod; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.CaseInsensitiveArrayList; +import me.ccrama.redditslide.Fragments.MultiredditView; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Views.CatchStaggeredGridLayoutManager; +import me.ccrama.redditslide.Views.PreCachingLayoutManager; +import me.ccrama.redditslide.Visuals.ColorPreferences; +import me.ccrama.redditslide.Visuals.Palette; +import me.ccrama.redditslide.util.BlendModeUtil; +import me.ccrama.redditslide.util.LogUtil; +import me.ccrama.redditslide.util.ProUtil; +import me.ccrama.redditslide.util.SortingUtil; + +/** + * Created by ccrama on 9/17/2015. + */ +public class MultiredditOverview extends BaseActivityAnim { + + public static final String EXTRA_PROFILE = "profile"; + public static final String EXTRA_MULTI = "multi"; + + public static Activity multiActivity; + + public static MultiReddit searchMulti; + public MultiredditOverviewPagerAdapter adapter; + private ViewPager pager; + private String profile; + private TabLayout tabs; + private List usedArray; + private String initialMulti; + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_multireddits, menu); + + if (!profile.isEmpty()) { + menu.findItem(R.id.action_edit).setVisible(false); + menu.findItem(R.id.create).setVisible(false); + } + + // if (mShowInfoButton) menu.findItem(R.id.action_info).setVisible(true); + // else menu.findItem(R.id.action_info).setVisible(false); + + return true; + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + /* removed for now + int keyCode = event.getKeyCode(); + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + return ((MultiredditView) adapter.getCurrentFragment()).onKeyDown(keyCode); + case KeyEvent.KEYCODE_VOLUME_DOWN: + return ((MultiredditView) adapter.getCurrentFragment()).onKeyDown(keyCode); + default: + return super.dispatchKeyEvent(event); + }*/ + return super.dispatchKeyEvent(event); + } + + public int getCurrentPage() { + int position = 0; + int currentOrientation = getResources().getConfiguration().orientation; + if (((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof LinearLayoutManager + && currentOrientation == Configuration.ORIENTATION_LANDSCAPE) { + position = + ((LinearLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) + .findFirstVisibleItemPosition() - 1; + } else if (((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof CatchStaggeredGridLayoutManager) { + int[] firstVisibleItems = null; + firstVisibleItems = + ((CatchStaggeredGridLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv + .getLayoutManager()).findFirstVisibleItemPositions(firstVisibleItems); + if (firstVisibleItems != null && firstVisibleItems.length > 0) { + position = firstVisibleItems[0] - 1; + } + } else { + position = + ((PreCachingLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) + .findFirstVisibleItemPosition() - 1; + } + return position; + } + + String term; + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + + case android.R.id.home: + try { + onBackPressed(); + } catch (Exception ignored) { + + } + return true; + case R.id.action_edit: { + if (profile.isEmpty() + && (UserSubscriptions.multireddits != null) + && !UserSubscriptions.multireddits.isEmpty()) { + Intent i = new Intent(MultiredditOverview.this, CreateMulti.class); + i.putExtra(CreateMulti.EXTRA_MULTI, UserSubscriptions.multireddits + .get(pager.getCurrentItem()) + .getDisplayName()); + startActivity(i); + } + } + return true; + case R.id.search: { + + UserSubscriptions.MultiCallback m = new UserSubscriptions.MultiCallback() { + @Override + public void onComplete(List multireddits) { + if ((multireddits != null) && !multireddits.isEmpty()) { + searchMulti = multireddits.get(pager.getCurrentItem()); + MaterialDialog.Builder builder = + new MaterialDialog.Builder(MultiredditOverview.this).title(R.string.search_title) + .alwaysCallInputCallback() + .input(getString(R.string.search_msg), "", + new MaterialDialog.InputCallback() { + @Override + public void onInput( + MaterialDialog materialDialog, + CharSequence charSequence) { + term = charSequence.toString(); + } + }); + + //Add "search current sub" if it is not frontpage/all/random + builder.positiveText(getString(R.string.search_subreddit, + "/m/" + searchMulti.getDisplayName())) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog materialDialog, + @NonNull DialogAction dialogAction) { + Intent i = new Intent(MultiredditOverview.this, + Search.class); + i.putExtra(Search.EXTRA_TERM, term); + i.putExtra(Search.EXTRA_MULTIREDDIT, + searchMulti.getDisplayName()); + startActivity(i); + } + }); + + builder.show(); + } + } + }; + + if (profile.isEmpty()) { + UserSubscriptions.getMultireddits(m); + } else { + UserSubscriptions.getPublicMultireddits(m, profile); + } + } + return true; + case R.id.create: + if (profile.isEmpty()) { + Intent i2 = new Intent(MultiredditOverview.this, CreateMulti.class); + startActivity(i2); + } + return true; + case R.id.action_sort: + openPopup(); + return true; + + case R.id.subs: + ((DrawerLayout) findViewById(R.id.drawer_layout)).openDrawer(Gravity.RIGHT); + return true; + case R.id.gallery: + if (SettingValues.isPro) { + List posts = + ((MultiredditView) adapter.getCurrentFragment()).posts.posts; + if (posts != null && !posts.isEmpty()) { + Intent i2 = new Intent(this, Gallery.class); + i2.putExtra(Gallery.EXTRA_PROFILE, profile); + i2.putExtra(Gallery.EXTRA_MULTIREDDIT, + ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit.getDisplayName()); + startActivity(i2); + } + } else { + final AlertDialog.Builder b = + ProUtil.proUpgradeMsg(this, R.string.general_gallerymode_ispro) + .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> + dialog.dismiss()); + if (SettingValues.previews > 0) { + b.setNeutralButton(getString(R.string.pro_previews, SettingValues.previews), + (dialog, which) -> { + SettingValues.prefs.edit() + .putInt(SettingValues.PREVIEWS_LEFT, + SettingValues.previews - 1) + .apply(); + SettingValues.previews = SettingValues.prefs.getInt( + SettingValues.PREVIEWS_LEFT, 10); + List posts = + ((MultiredditView) adapter.getCurrentFragment()).posts.posts; + if (posts != null && !posts.isEmpty()) { + Intent i2 = new Intent(MultiredditOverview.this, + Gallery.class); + i2.putExtra(Gallery.EXTRA_PROFILE, profile); + i2.putExtra(Gallery.EXTRA_MULTIREDDIT, + ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit + .getDisplayName()); + startActivity(i2); + } + }); + } + b.show(); + } + return true; + case R.id.action_shadowbox: + if (SettingValues.isPro) { + List posts = + ((MultiredditView) adapter.getCurrentFragment()).posts.posts; + if (posts != null && !posts.isEmpty()) { + Intent i = new Intent(this, Shadowbox.class); + i.putExtra(Shadowbox.EXTRA_PAGE, getCurrentPage()); + i.putExtra(Shadowbox.EXTRA_PROFILE, profile); + i.putExtra(Shadowbox.EXTRA_MULTIREDDIT, + ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit.getDisplayName()); + startActivity(i); + } + } else { + final AlertDialog.Builder b = + ProUtil.proUpgradeMsg(this, R.string.general_shadowbox_ispro) + .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> + dialog.dismiss()); + if (SettingValues.previews > 0 + && adapter != null + && ((MultiredditView) adapter.getCurrentFragment()).posts != null + && ((MultiredditView) adapter.getCurrentFragment()).posts.posts != null + && !((MultiredditView) adapter.getCurrentFragment()).posts.posts.isEmpty()) { + b.setNeutralButton(getString(R.string.pro_previews, SettingValues.previews), + (dialog, which) -> { + SettingValues.prefs.edit() + .putInt(SettingValues.PREVIEWS_LEFT, + SettingValues.previews - 1) + .apply(); + SettingValues.previews = SettingValues.prefs.getInt( + SettingValues.PREVIEWS_LEFT, 10); + List posts = + ((MultiredditView) adapter.getCurrentFragment()).posts.posts; + if (posts != null && !posts.isEmpty()) { + Intent i = new Intent(MultiredditOverview.this, + Shadowbox.class); + i.putExtra(Shadowbox.EXTRA_PAGE, getCurrentPage()); + i.putExtra(Shadowbox.EXTRA_PROFILE, profile); + i.putExtra(Shadowbox.EXTRA_MULTIREDDIT, + ((MultiredditView) adapter.getCurrentFragment()).posts.multiReddit + .getDisplayName()); + startActivity(i); + } + }); + } + b.show(); + } + return true; + default: + return false; + } + } + + private void buildDialog() { + buildDialog(false); + } + + private void buildDialog(boolean wasException) { + try { + final AlertDialog.Builder b = + new AlertDialog.Builder(MultiredditOverview.this) + .setCancelable(false) + .setOnDismissListener(dialog -> + finish()); + if (wasException) { + b.setTitle(R.string.err_title) + .setMessage(R.string.err_loading_content) + .setPositiveButton(R.string.btn_ok, (dialog, which) -> + finish()); + } else if (profile.isEmpty()) { + b.setTitle(R.string.multireddit_err_title) + .setMessage(R.string.multireddit_err_msg) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> { + Intent i = new Intent(MultiredditOverview.this, CreateMulti.class); + startActivity(i); + }) + .setNegativeButton(R.string.btn_no, (dialog, which) -> + finish()); + } else { + b.setTitle(R.string.public_multireddit_err_title) + .setMessage(R.string.public_multireddit_err_msg) + .setNegativeButton(R.string.btn_go_back, (dialog, which) -> + finish()); + } + b.show(); + } catch (Exception e) { + + } + } + + @Override + public void onCreate(Bundle savedInstance) { + overrideSwipeFromAnywhere(); + + multiActivity = this; + + super.onCreate(savedInstance); + + applyColorTheme(""); + setContentView(R.layout.activity_multireddits); + setupAppBar(R.id.toolbar, R.string.title_multireddits, true, false); + + findViewById(R.id.header).setBackgroundColor(Palette.getDefaultColor()); + tabs = (TabLayout) findViewById(R.id.sliding_tabs); + tabs.setTabMode(TabLayout.MODE_SCROLLABLE); + + pager = (ViewPager) findViewById(R.id.content_view); + mToolbar.setPopupTheme(new ColorPreferences(this).getFontStyle().getBaseId()); + + profile = ""; + initialMulti = ""; + if (getIntent().getExtras() != null) { + profile = getIntent().getExtras().getString(EXTRA_PROFILE, ""); + initialMulti = getIntent().getExtras().getString(EXTRA_MULTI, ""); + } + if (profile.equalsIgnoreCase(Authentication.name)) { + profile = ""; + } + + UserSubscriptions.MultiCallback callback = new UserSubscriptions.MultiCallback() { + @Override + public void onComplete(List multiReddits) { + if (multiReddits != null && !multiReddits.isEmpty()) { + setDataSet(multiReddits); + } else { + buildDialog(); + } + } + }; + + if (profile.isEmpty()) { + UserSubscriptions.getMultireddits(callback); + } else { + UserSubscriptions.getPublicMultireddits(callback, profile); + } + } + + + public void openPopup() { + PopupMenu popup = + new PopupMenu(MultiredditOverview.this, findViewById(R.id.anchor), Gravity.RIGHT); + String id = + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()).getCurrentFragment())).posts.multiReddit + .getDisplayName() + .toLowerCase(Locale.ENGLISH); + final Spannable[] base = SortingUtil.getSortingSpannables("multi" + id); + for (Spannable s : base) { + // Do not add option for "Best" in any subreddit except for the frontpage. + if (s.toString().equals(getString(R.string.sorting_best))) { + continue; + } + MenuItem m = popup.getMenu().add(s); + } + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + int i = 0; + for (Spannable s : base) { + if (s.equals(item.getTitle())) { + break; + } + i++; + } + LogUtil.v("Chosen is " + i); + if (pager.getAdapter() != null) { + switch (i) { + case 0: + SortingUtil.setSorting("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), Sorting.HOT); + reloadSubs(); + break; + case 1: + SortingUtil.setSorting("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), Sorting.NEW); + reloadSubs(); + break; + case 2: + SortingUtil.setSorting("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), Sorting.RISING); + reloadSubs(); + break; + case 3: + SortingUtil.setSorting("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), Sorting.TOP); + openPopupTime(); + break; + case 4: + SortingUtil.setSorting("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), Sorting.CONTROVERSIAL); + openPopupTime(); + break; + } + } + return true; + } + }); + popup.show(); + + + } + + public void openPopupTime() { + PopupMenu popup = + new PopupMenu(MultiredditOverview.this, findViewById(R.id.anchor), Gravity.RIGHT); + String id = + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()).getCurrentFragment())).posts.multiReddit + .getDisplayName() + .toLowerCase(Locale.ENGLISH); + final Spannable[] base = SortingUtil.getSortingTimesSpannables("multi" + id); + for (Spannable s : base) { + MenuItem m = popup.getMenu().add(s); + } + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + int i = 0; + for (Spannable s : base) { + if (s.equals(item.getTitle())) { + break; + } + i++; + } + LogUtil.v("Chosen is " + i); + if (pager.getAdapter() != null) { + switch (i) { + case 0: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.HOUR); + reloadSubs(); + break; + case 1: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.DAY); + reloadSubs(); + break; + case 2: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.WEEK); + reloadSubs(); + break; + case 3: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.MONTH); + reloadSubs(); + break; + case 4: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.YEAR); + reloadSubs(); + break; + case 5: + SortingUtil.setTime("multi" + + ((MultiredditView) (((MultiredditOverviewPagerAdapter) pager.getAdapter()) + .getCurrentFragment())).posts.multiReddit.getDisplayName() + .toLowerCase(Locale.ENGLISH), TimePeriod.ALL); + reloadSubs(); + break; + } + } + return true; + } + }); + popup.show(); + + + } + + private void reloadSubs() { + int current = pager.getCurrentItem(); + adapter = new MultiredditOverviewPagerAdapter(getSupportFragmentManager()); + pager.setAdapter(adapter); + pager.setCurrentItem(current); + } + + private void setDataSet(List data) { + try { + usedArray = data; + + if (usedArray.isEmpty()) { + buildDialog(); + } else { + + if (adapter == null) { + adapter = new MultiredditOverviewPagerAdapter(getSupportFragmentManager()); + } else { + adapter.notifyDataSetChanged(); + } + pager.setAdapter(adapter); + pager.setOffscreenPageLimit(1); + tabs.setupWithViewPager(pager); + if (!initialMulti.isEmpty()) { + for (int i = 0; i < usedArray.size(); i++) { + if (usedArray.get(i).getDisplayName().equalsIgnoreCase(initialMulti)) { + pager.setCurrentItem(i); + break; + } + } + } + tabs.setSelectedTabIndicatorColor( + new ColorPreferences(MultiredditOverview.this).getColor( + usedArray.get(0).getDisplayName())); + doDrawerSubs(0); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = this.getWindow(); + window.setStatusBarColor( + Palette.getDarkerColor(usedArray.get(0).getDisplayName())); + } + final View header = findViewById(R.id.header); + tabs.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager) { + @Override + public void onTabReselected(TabLayout.Tab tab) { + super.onTabReselected(tab); + int pastVisiblesItems = 0; + int[] firstVisibleItems = + ((CatchStaggeredGridLayoutManager) (((MultiredditView) adapter.getCurrentFragment()).rv + .getLayoutManager())).findFirstVisibleItemPositions(null); + if (firstVisibleItems != null && firstVisibleItems.length > 0) { + for (int firstVisibleItem : firstVisibleItems) { + pastVisiblesItems = firstVisibleItem; + } + } + if (pastVisiblesItems > 8) { + ((MultiredditView) adapter.getCurrentFragment()).rv.scrollToPosition(0); + if (header != null) { + header.animate() + .translationY(header.getHeight()) + .setInterpolator(new LinearInterpolator()) + .setDuration(0); + } + } else { + ((MultiredditView) adapter.getCurrentFragment()).rv.smoothScrollToPosition( + 0); + } + } + }); + findViewById(R.id.header).setBackgroundColor( + Palette.getColor(usedArray.get(0).getDisplayName())); + } + } catch (NullPointerException e) { + buildDialog(true); + Log.e(LogUtil.getTag(), "Cannot load multis:\n" + e); + } + + } + + public void doDrawerSubs(int position) { + MultiReddit current = usedArray.get(position); + LinearLayout l = (LinearLayout) findViewById(R.id.sidebar_scroll); + l.removeAllViews(); + + CaseInsensitiveArrayList toSort = new CaseInsensitiveArrayList(); + + for (MultiSubreddit s : current.getSubreddits()) { + toSort.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); + } + + for (String sub : UserSubscriptions.sortNoExtras(toSort)) { + final View convertView = getLayoutInflater().inflate(R.layout.subforsublist, l, false); + + final String subreddit = sub; + final TextView t = convertView.findViewById(R.id.name); + t.setText(subreddit); + + final View colorView = convertView.findViewById(R.id.color); + colorView.setBackgroundResource(R.drawable.circle); + BlendModeUtil.tintDrawableAsModulate(colorView.getBackground(), Palette.getColor(subreddit)); + convertView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent inte = new Intent(MultiredditOverview.this, SubredditView.class); + inte.putExtra(SubredditView.EXTRA_SUBREDDIT, subreddit); + MultiredditOverview.this.startActivityForResult(inte, 4); + } + }); + l.addView(convertView); + } + } + + private class MultiredditOverviewPagerAdapter extends FragmentStatePagerAdapter { + + MultiredditOverviewPagerAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + findViewById(R.id.header).animate() + .translationY(0) + .setInterpolator(new LinearInterpolator()) + .setDuration(180); + findViewById(R.id.header).setBackgroundColor( + Palette.getColor(usedArray.get(position).getDisplayName())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = getWindow(); + window.setStatusBarColor( + Palette.getDarkerColor(usedArray.get(position).getDisplayName())); + } + tabs.setSelectedTabIndicatorColor( + new ColorPreferences(MultiredditOverview.this).getColor( + usedArray.get(position).getDisplayName())); + doDrawerSubs(position); + } + }); + } + + @NonNull + @Override + public Fragment getItem(int i) { + Fragment f = new MultiredditView(); + Bundle args = new Bundle(); + + args.putInt("id", i); + args.putString(EXTRA_PROFILE, profile); + + f.setArguments(args); + + return f; + } + + private Fragment mCurrentFragment; + + Fragment getCurrentFragment() { + return mCurrentFragment; + } + + @Override + public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) { + if (mCurrentFragment != object) { + mCurrentFragment = (Fragment) object; + } + super.setPrimaryItem(container, position, object); + } + + @Override + public int getCount() { + if (usedArray == null) { + return 1; + } else { + return usedArray.size(); + } + } + + @Override + public CharSequence getPageTitle(int position) { + return usedArray.get(position).getFullName(); + } + } + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 940 && adapter != null && adapter.getCurrentFragment() != null) { + if (resultCode == RESULT_OK) { + LogUtil.v("Doing hide posts"); + ArrayList posts = data.getIntegerArrayListExtra("seen"); + ((MultiredditView) adapter.getCurrentFragment()).adapter.refreshView(posts); + if (data.hasExtra("lastPage") + && data.getIntExtra("lastPage", 0) != 0 + && ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager() instanceof LinearLayoutManager) { + ((LinearLayoutManager) ((MultiredditView) adapter.getCurrentFragment()).rv.getLayoutManager()) + .scrollToPositionWithOffset(data.getIntExtra("lastPage", 0) + 1, + mToolbar.getHeight()); + } + } else { + ((MultiredditView) adapter.getCurrentFragment()).adapter.refreshView(); + } + } + + } + +} diff --git a/app/src/main/java/me/ccrama/redditslide/Activities/Submit.java b/app/src/main/java/me/ccrama/redditslide/Activities/Submit.java index eecefc572..028c5dcac 100644 --- a/app/src/main/java/me/ccrama/redditslide/Activities/Submit.java +++ b/app/src/main/java/me/ccrama/redditslide/Activities/Submit.java @@ -1,732 +1,732 @@ -package me.ccrama.redditslide.Activities; - -import android.app.Dialog; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.RadioButton; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.SwitchCompat; - -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import net.dean.jraw.ApiException; -import net.dean.jraw.http.HttpRequest; -import net.dean.jraw.managers.AccountManager; -import net.dean.jraw.models.Submission; -import net.dean.jraw.models.Subreddit; - -import org.json.JSONObject; - -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import gun0912.tedbottompicker.TedBottomPicker; -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.Drafts; -import me.ccrama.redditslide.Flair.RichFlair; -import me.ccrama.redditslide.ImgurAlbum.UploadImgur; -import me.ccrama.redditslide.ImgurAlbum.UploadImgurAlbum; -import me.ccrama.redditslide.OpenRedditLink; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.Reddit; -import me.ccrama.redditslide.SpoilerRobotoTextView; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Views.CommentOverflow; -import me.ccrama.redditslide.Views.DoEditorActions; -import me.ccrama.redditslide.Views.ImageInsertEditText; -import me.ccrama.redditslide.util.HttpUtil; -import me.ccrama.redditslide.util.KeyboardUtil; -import me.ccrama.redditslide.util.LogUtil; -import me.ccrama.redditslide.util.SubmissionParser; -import me.ccrama.redditslide.util.TitleExtractor; -import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; -import okhttp3.OkHttpClient; -import okhttp3.Request; - -/** - * Created by ccrama on 3/5/2015. - */ -public class Submit extends BaseActivity { - - private boolean sent; - private String trying; - private String URL; - private String selectedFlairID; - private SwitchCompat inboxReplies; - private View image; - private View link; - private View self; - public static final String EXTRA_SUBREDDIT = "subreddit"; - public static final String EXTRA_BODY = "body"; - public static final String EXTRA_IS_SELF = "is_self"; - - AsyncTask tchange; - private OkHttpClient client; - private Gson gson; - - @Override - public void onDestroy() { - super.onDestroy(); - try { - String text = ((EditText) findViewById(R.id.bodytext)).getText().toString(); - if (!text.isEmpty() && sent) { - Drafts.addDraft(text); - Toast.makeText(getApplicationContext(), R.string.msg_save_draft, Toast.LENGTH_LONG) - .show(); - } - } catch (Exception e) { - - } - } - - public void onCreate(Bundle savedInstanceState) { - disableSwipeBackLayout(); - super.onCreate(savedInstanceState); - applyColorTheme(); - setContentView(R.layout.activity_submit); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = this.getWindow(); - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - } - setupAppBar(R.id.toolbar, R.string.title_submit_post, true, true); - - inboxReplies = (SwitchCompat) findViewById(R.id.replies); - - Intent intent = getIntent(); - final String subreddit = intent.getStringExtra(EXTRA_SUBREDDIT); - final String initialBody = intent.getStringExtra(EXTRA_BODY); - - self = findViewById(R.id.selftext); - final AutoCompleteTextView subredditText = - ((AutoCompleteTextView) findViewById(R.id.subreddittext)); - image = findViewById(R.id.image); - link = findViewById(R.id.url); - - image.setVisibility(View.GONE); - link.setVisibility(View.GONE); - - if (subreddit != null - && !subreddit.equals("frontpage") - && !subreddit.equals("all") - && !subreddit.equals("friends") - && !subreddit.equals("mod") - && !subreddit.contains("/m/") - && !subreddit.contains("+")) { - subredditText.setText(subreddit); - } - if (initialBody != null) { - ((ImageInsertEditText) self.findViewById(R.id.bodytext)).setText(initialBody); - } - ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, - UserSubscriptions.getAllSubreddits(this)); - - subredditText.setAdapter(adapter); - subredditText.setThreshold(2); - - subredditText.addTextChangedListener(new SimpleTextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (tchange != null) { - tchange.cancel(true); - } - findViewById(R.id.submittext).setVisibility(View.GONE); - } - }); - - subredditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - findViewById(R.id.submittext).setVisibility(View.GONE); - if (!hasFocus) { - tchange = new AsyncTask() { - @Override - protected Subreddit doInBackground(Void... params) { - try { - return Authentication.reddit.getSubreddit( - subredditText.getText().toString()); - } catch (Exception ignored) { - - } - return null; - } - - @Override - protected void onPostExecute(Subreddit s) { - - if (s != null) { - String text = s.getDataNode().get("submit_text_html").asText(); - if (text != null && !text.isEmpty() && !text.equals("null")) { - findViewById(R.id.submittext).setVisibility(View.VISIBLE); - setViews(text, subredditText.getText().toString(), - (SpoilerRobotoTextView) findViewById(R.id.submittext), - (CommentOverflow) findViewById(R.id.commentOverflow)); - } - if (s.getSubredditType().equals("RESTRICTED")) { - subredditText.setText(""); - new AlertDialog.Builder(Submit.this) - .setTitle(R.string.err_submit_restricted) - .setMessage(R.string.err_submit_restricted_text) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } - } else { - findViewById(R.id.submittext).setVisibility(View.GONE); - } - } - }; - tchange.execute(); - } - } - }); - - findViewById(R.id.selftextradio).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - self.setVisibility(View.VISIBLE); - - image.setVisibility(View.GONE); - link.setVisibility(View.GONE); - } - }); - findViewById(R.id.imageradio).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - self.setVisibility(View.GONE); - image.setVisibility(View.VISIBLE); - link.setVisibility(View.GONE); - } - }); - findViewById(R.id.linkradio).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - self.setVisibility(View.GONE); - image.setVisibility(View.GONE); - link.setVisibility(View.VISIBLE); - } - }); - findViewById(R.id.flair).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - showFlairChooser(); - } - }); - - findViewById(R.id.suggest).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new AsyncTask() { - Dialog d; - - @Override - protected String doInBackground(String... params) { - try { - return TitleExtractor.getPageTitle(params[0]); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPreExecute() { - d = new MaterialDialog.Builder(Submit.this).progress(true, 100) - .title(R.string.editor_finding_title) - .content(R.string.misc_please_wait) - .show(); - } - - @Override - protected void onPostExecute(String s) { - if (s != null) { - ((EditText) findViewById(R.id.titletext)).setText(s); - d.dismiss(); - } else { - d.dismiss(); - new AlertDialog.Builder(Submit.this) - .setTitle(R.string.title_not_found) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } - } - }.execute(((EditText) findViewById(R.id.urltext)).getText().toString()); - } - }); - findViewById(R.id.selImage).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - TedBottomPicker tedBottomPicker = - new TedBottomPicker.Builder(Submit.this).setOnImageSelectedListener( - Submit.this::handleImageIntent) - .setLayoutResource(R.layout.image_sheet_dialog) - .setTitle("Choose a photo") - .create(); - - tedBottomPicker.show(getSupportFragmentManager()); - KeyboardUtil.hideKeyboard(Submit.this, findViewById(R.id.bodytext).getWindowToken(), 0); - } - }); - - DoEditorActions.doActions(((EditText) findViewById(R.id.bodytext)), - findViewById(R.id.selftext), getSupportFragmentManager(), Submit.this, null, null); - if (intent.hasExtra(Intent.EXTRA_TEXT) && !intent.getExtras() - .getString(Intent.EXTRA_TEXT, "") - .isEmpty() && !intent.getBooleanExtra(EXTRA_IS_SELF, false)) { - String data = intent.getStringExtra(Intent.EXTRA_TEXT); - if (data.contains("\n")) { - ((EditText) findViewById(R.id.titletext)).setText( - data.substring(0, data.indexOf("\n"))); - ((EditText) findViewById(R.id.urltext)).setText(data.substring(data.indexOf("\n"))); - } else { - ((EditText) findViewById(R.id.urltext)).setText(data); - } - self.setVisibility(View.GONE); - image.setVisibility(View.GONE); - link.setVisibility(View.VISIBLE); - ((RadioButton) findViewById(R.id.linkradio)).setChecked(true); - - } else if (intent.hasExtra(Intent.EXTRA_STREAM)) { - final Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); - if (imageUri != null) { - handleImageIntent(new ArrayList() {{ - add(imageUri); - }}); - self.setVisibility(View.GONE); - image.setVisibility(View.VISIBLE); - link.setVisibility(View.GONE); - ((RadioButton) findViewById(R.id.imageradio)).setChecked(true); - } - } - if (intent.hasExtra(Intent.EXTRA_SUBJECT) && !intent.getExtras() - .getString(Intent.EXTRA_SUBJECT, "") - .isEmpty()) { - String data = intent.getStringExtra(Intent.EXTRA_SUBJECT); - ((EditText) findViewById(R.id.titletext)).setText(data); - } - findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - ((FloatingActionButton) findViewById(R.id.send)).hide(); - new AsyncDo().execute(); - } - }); - - } - - private void setImage(final String URL) { - this.URL = URL; - - runOnUiThread(new Runnable() { - @Override - public void run() { - findViewById(R.id.imagepost).setVisibility(View.VISIBLE); - ((Reddit) getApplication()).getImageLoader() - .displayImage(URL, ((ImageView) findViewById(R.id.imagepost))); - } - }); - } - - private void showFlairChooser() { - client = Reddit.client; - gson = new Gson(); - - String subreddit = ((EditText) findViewById(R.id.subreddittext)).getText().toString(); - - final Dialog d = - new MaterialDialog.Builder(Submit.this).title(R.string.submit_findingflairs) - .cancelable(true) - .content(R.string.misc_please_wait) - .progress(true, 100) - .show(); - new AsyncTask() { - ArrayList flairs; - - @Override - protected JsonArray doInBackground(Void... params) { - flairs = new ArrayList<>(); - HttpRequest r = Authentication.reddit.request() - .path("/r/" + subreddit + "/api/link_flair_v2.json") - .get() - .build(); - - Request request = new Request.Builder() - .headers(r.getHeaders().newBuilder().set("User-Agent", "Slide flair search").build()) - .url(r.getUrl()) - .build(); - - return HttpUtil.getJsonArray(client, gson, request); - } - - @Override - protected void onPostExecute(final JsonArray result) { - if (result == null) { - LogUtil.v("Error loading content"); - d.dismiss(); - } else { - try { - final HashMap flairs = new HashMap<>(); - for(JsonElement object : result) { - RichFlair choice = new ObjectMapper().disable( - DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).readValue(object.toString(), RichFlair.class); - String title = choice.getText(); - flairs.put(title, choice); - } - d.dismiss(); - - ArrayList allKeys = new ArrayList<>(flairs.keySet()); - - new MaterialDialog.Builder(Submit.this).title( - getString(R.string.submit_flairchoices, subreddit)) - .items(allKeys) - .itemsCallback(new MaterialDialog.ListCallback() { - @Override - public void onSelection(MaterialDialog dialog, - View itemView, int which, CharSequence text) { - RichFlair selected = flairs.get(allKeys.get(which)); - selectedFlairID = selected.getId(); - ((TextView) findViewById(R.id.flair)).setText(getString(R.string.submit_selected_flair, selected.getText())); - } - }) - .show(); - } catch(Exception e) { - LogUtil.v(e.toString()); - d.dismiss(); - LogUtil.v("Error parsing flairs"); - } - } - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - public void setViews(String rawHTML, String subredditName, SpoilerRobotoTextView firstTextView, - CommentOverflow commentOverflow) { - if (rawHTML.isEmpty()) { - return; - } - - List blocks = SubmissionParser.getBlocks(rawHTML); - - int startIndex = 0; - // the
case is when the body contains a table or code block first - if (!blocks.get(0).equals("
")) { - firstTextView.setVisibility(View.VISIBLE); - firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); - startIndex = 1; - } else { - firstTextView.setText(""); - firstTextView.setVisibility(View.GONE); - } - - if (blocks.size() > 1) { - if (startIndex == 0) { - commentOverflow.setViews(blocks, subredditName); - } else { - commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); - } - } else { - commentOverflow.removeAllViews(); - } - } - - public void handleImageIntent(List uris) { - if (uris.size() == 1) { - // Get the Image from data (single image) - try { - new UploadImgurSubmit(this, uris.get(0)); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - //Multiple images - try { - new UploadImgurAlbumSubmit(this, uris.toArray(new Uri[0])); - } catch (Exception e) { - e.printStackTrace(); - - } - } - } - - private class AsyncDo extends AsyncTask { - - @Override - protected Void doInBackground(Void... voids) { - try { - if (self.getVisibility() == View.VISIBLE) { - final String text = - ((EditText) findViewById(R.id.bodytext)).getText().toString(); - try { - AccountManager.SubmissionBuilder builder = new AccountManager.SubmissionBuilder( - ((EditText) findViewById(R.id.bodytext)).getText() - .toString(), ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString(), - ((EditText) findViewById(R.id.titletext)).getText() - .toString()); - - if(selectedFlairID != null) { - builder.flairID(selectedFlairID); - } - - Submission s = new AccountManager(Authentication.reddit).submit(builder); - new AccountManager(Authentication.reddit).sendRepliesToInbox(s, - inboxReplies.isChecked()); - OpenRedditLink.openUrl(Submit.this, - "reddit.com/r/" + ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString() + "/comments/" + s - .getFullName() - .substring(3), true); - Submit.this.finish(); - } catch (final ApiException e) { - Drafts.addDraft(text); - e.printStackTrace(); - - runOnUiThread(new Runnable() { - @Override - public void run() { - showErrorRetryDialog(getString(R.string.misc_err) - + ": " - + e.getExplanation() - + "\n" - + getString(R.string.misc_retry_draft)); - } - }); - } - } else if (link.getVisibility() == View.VISIBLE) { - try { - Submission s = new AccountManager(Authentication.reddit).submit( - new AccountManager.SubmissionBuilder( - new URL(((EditText) findViewById(R.id.urltext)).getText() - .toString()), ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString(), - ((EditText) findViewById(R.id.titletext)).getText() - .toString())); - new AccountManager(Authentication.reddit).sendRepliesToInbox(s, - inboxReplies.isChecked()); - OpenRedditLink.openUrl(Submit.this, - "reddit.com/r/" + ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString() + "/comments/" + s - .getFullName() - .substring(3), true); - - Submit.this.finish(); - } catch (final ApiException e) { - e.printStackTrace(); - - runOnUiThread(new Runnable() { - @Override - public void run() { - - if (e instanceof ApiException) { - showErrorRetryDialog(getString(R.string.misc_err) - + ": " - + e.getExplanation() - + "\n" - + getString(R.string.misc_retry)); - } else { - showErrorRetryDialog( - getString(R.string.misc_err) + ": " + getString( - R.string.err_invalid_url) + "\n" + getString( - R.string.misc_retry)); - } - } - }); - } - } else if (image.getVisibility() == View.VISIBLE) { - try { - Submission s = new AccountManager(Authentication.reddit).submit( - new AccountManager.SubmissionBuilder(new URL(URL), - ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString(), - ((EditText) findViewById(R.id.titletext)).getText() - .toString())); - new AccountManager(Authentication.reddit).sendRepliesToInbox(s, - inboxReplies.isChecked()); - OpenRedditLink.openUrl(Submit.this, - "reddit.com/r/" + ((AutoCompleteTextView) findViewById( - R.id.subreddittext)).getText().toString() + "/comments/" + s - .getFullName() - .substring(3), true); - - Submit.this.finish(); - } catch (final Exception e) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (e instanceof ApiException) { - showErrorRetryDialog( - getString(R.string.misc_err) + ": " + ((ApiException) e) - .getExplanation() + "\n" + getString( - R.string.misc_retry)); - } else { - showErrorRetryDialog( - getString(R.string.misc_err) + ": " + getString( - R.string.err_invalid_url) + "\n" + getString( - R.string.misc_retry)); - } - } - }); - } - } - } catch (Exception e) { - e.printStackTrace(); - - runOnUiThread(new Runnable() { - @Override - public void run() { - showErrorRetryDialog(getString(R.string.misc_retry)); - } - }); - } - return null; - } - } - - private class UploadImgurSubmit extends UploadImgur { - - private final Uri uri; - - public UploadImgurSubmit(Context c, Uri u) { - this.c = c; - this.uri = u; - - dialog = new MaterialDialog.Builder(c).title( - c.getString(R.string.editor_uploading_image)) - .progress(false, 100) - .cancelable(false) - .autoDismiss(false) - .build(); - - new MaterialDialog.Builder(c).title(c.getString(R.string.editor_upload_image_question)) - .cancelable(false) - .autoDismiss(false) - .positiveText(c.getString(R.string.btn_upload)) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(MaterialDialog d, DialogAction w) { - d.dismiss(); - dialog.show(); - execute(uri); - } - }) - .negativeText(c.getString(R.string.btn_cancel)) - .onNegative(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(MaterialDialog d, DialogAction w) { - d.dismiss(); - } - }) - .show(); - } - - @Override - protected void onPostExecute(final JSONObject result) { - dialog.dismiss(); - try { - final String url = result.getJSONObject("data").getString("link"); - setImage(url); - - } catch (Exception e) { - new AlertDialog.Builder(c) - .setTitle(R.string.err_title) - .setMessage(R.string.editor_err_msg) - .setPositiveButton(R.string.btn_ok, null) - .show(); - e.printStackTrace(); - } - } - } - - private class UploadImgurAlbumSubmit extends UploadImgurAlbum { - - private final Uri[] uris; - - public UploadImgurAlbumSubmit(Context c, Uri... u) { - this.c = c; - this.uris = u; - - dialog = new MaterialDialog.Builder(c).title( - c.getString(R.string.editor_uploading_image)) - .progress(false, 100) - .cancelable(false) - .build(); - - new MaterialDialog.Builder(c).title(c.getString(R.string.editor_upload_image_question)) - .cancelable(false) - .autoDismiss(false) - .positiveText(c.getString(R.string.btn_upload)) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(MaterialDialog d, DialogAction w) { - d.dismiss(); - dialog.show(); - execute(uris); - } - }) - .negativeText(c.getString(R.string.btn_cancel)) - .onNegative(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(MaterialDialog d, DialogAction w) { - d.dismiss(); - } - }) - .show(); - } - - @Override - protected void onPostExecute(final String result) { - dialog.dismiss(); - try { - ((RadioButton) findViewById(R.id.linkradio)).setChecked(true); - link.setVisibility(View.VISIBLE); - ((EditText) findViewById(R.id.urltext)).setText(finalUrl); - } catch (Exception e) { - new AlertDialog.Builder(c) - .setTitle(R.string.err_title) - .setMessage(R.string.editor_err_msg) - .setPositiveButton(R.string.btn_ok, null) - .show(); - e.printStackTrace(); - } - } - } - - private void showErrorRetryDialog(String message) { - new AlertDialog.Builder(Submit.this) - .setTitle(R.string.err_title) - .setMessage(message) - .setNegativeButton(R.string.btn_no, (dialogInterface, i) -> - finish()) - .setPositiveButton(R.string.btn_yes, (dialogInterface, i) -> - ((FloatingActionButton) findViewById(R.id.send)).show()) - .setOnDismissListener(dialog -> - ((FloatingActionButton) findViewById(R.id.send)).show()) - .create() - .show(); - } - -} +package me.ccrama.redditslide.Activities; + +import android.app.Dialog; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.RadioButton; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.dean.jraw.ApiException; +import net.dean.jraw.http.HttpRequest; +import net.dean.jraw.managers.AccountManager; +import net.dean.jraw.models.Submission; +import net.dean.jraw.models.Subreddit; + +import org.json.JSONObject; + +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import gun0912.tedbottompicker.TedBottomPicker; +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.Drafts; +import me.ccrama.redditslide.Flair.RichFlair; +import me.ccrama.redditslide.ImgurAlbum.UploadImgur; +import me.ccrama.redditslide.ImgurAlbum.UploadImgurAlbum; +import me.ccrama.redditslide.OpenRedditLink; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.Reddit; +import me.ccrama.redditslide.SpoilerRobotoTextView; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Views.CommentOverflow; +import me.ccrama.redditslide.Views.DoEditorActions; +import me.ccrama.redditslide.Views.ImageInsertEditText; +import me.ccrama.redditslide.util.HttpUtil; +import me.ccrama.redditslide.util.KeyboardUtil; +import me.ccrama.redditslide.util.LogUtil; +import me.ccrama.redditslide.util.SubmissionParser; +import me.ccrama.redditslide.util.TitleExtractor; +import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; +import okhttp3.OkHttpClient; +import okhttp3.Request; + +/** + * Created by ccrama on 3/5/2015. + */ +public class Submit extends BaseActivity { + + private boolean sent; + private String trying; + private String URL; + private String selectedFlairID; + private SwitchCompat inboxReplies; + private View image; + private View link; + private View self; + public static final String EXTRA_SUBREDDIT = "subreddit"; + public static final String EXTRA_BODY = "body"; + public static final String EXTRA_IS_SELF = "is_self"; + + AsyncTask tchange; + private OkHttpClient client; + private Gson gson; + + @Override + public void onDestroy() { + super.onDestroy(); + try { + String text = ((EditText) findViewById(R.id.bodytext)).getText().toString(); + if (!text.isEmpty() && sent) { + Drafts.addDraft(text); + Toast.makeText(getApplicationContext(), R.string.msg_save_draft, Toast.LENGTH_LONG) + .show(); + } + } catch (Exception e) { + + } + } + + public void onCreate(Bundle savedInstanceState) { + disableSwipeBackLayout(); + super.onCreate(savedInstanceState); + applyColorTheme(); + setContentView(R.layout.activity_submit); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = this.getWindow(); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + } + setupAppBar(R.id.toolbar, R.string.title_submit_post, true, true); + + inboxReplies = (SwitchCompat) findViewById(R.id.replies); + + Intent intent = getIntent(); + final String subreddit = intent.getStringExtra(EXTRA_SUBREDDIT); + final String initialBody = intent.getStringExtra(EXTRA_BODY); + + self = findViewById(R.id.selftext); + final AutoCompleteTextView subredditText = + ((AutoCompleteTextView) findViewById(R.id.subreddittext)); + image = findViewById(R.id.image); + link = findViewById(R.id.url); + + image.setVisibility(View.GONE); + link.setVisibility(View.GONE); + + if (subreddit != null + && !subreddit.equals("frontpage") + && !subreddit.equals("all") + && !subreddit.equals("friends") + && !subreddit.equals("mod") + && !subreddit.contains("/m/") + && !subreddit.contains("+")) { + subredditText.setText(subreddit); + } + if (initialBody != null) { + ((ImageInsertEditText) self.findViewById(R.id.bodytext)).setText(initialBody); + } + ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, + UserSubscriptions.getAllSubreddits(this)); + + subredditText.setAdapter(adapter); + subredditText.setThreshold(2); + + subredditText.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (tchange != null) { + tchange.cancel(true); + } + findViewById(R.id.submittext).setVisibility(View.GONE); + } + }); + + subredditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + findViewById(R.id.submittext).setVisibility(View.GONE); + if (!hasFocus) { + tchange = new AsyncTask() { + @Override + protected Subreddit doInBackground(Void... params) { + try { + return Authentication.reddit.getSubreddit( + subredditText.getText().toString()); + } catch (Exception ignored) { + + } + return null; + } + + @Override + protected void onPostExecute(Subreddit s) { + + if (s != null) { + String text = s.getDataNode().get("submit_text_html").asText(); + if (text != null && !text.isEmpty() && !text.equals("null")) { + findViewById(R.id.submittext).setVisibility(View.VISIBLE); + setViews(text, subredditText.getText().toString(), + (SpoilerRobotoTextView) findViewById(R.id.submittext), + (CommentOverflow) findViewById(R.id.commentOverflow)); + } + if (s.getSubredditType().equals("RESTRICTED")) { + subredditText.setText(""); + new AlertDialog.Builder(Submit.this) + .setTitle(R.string.err_submit_restricted) + .setMessage(R.string.err_submit_restricted_text) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } + } else { + findViewById(R.id.submittext).setVisibility(View.GONE); + } + } + }; + tchange.execute(); + } + } + }); + + findViewById(R.id.selftextradio).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + self.setVisibility(View.VISIBLE); + + image.setVisibility(View.GONE); + link.setVisibility(View.GONE); + } + }); + findViewById(R.id.imageradio).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + self.setVisibility(View.GONE); + image.setVisibility(View.VISIBLE); + link.setVisibility(View.GONE); + } + }); + findViewById(R.id.linkradio).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + self.setVisibility(View.GONE); + image.setVisibility(View.GONE); + link.setVisibility(View.VISIBLE); + } + }); + findViewById(R.id.flair).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + showFlairChooser(); + } + }); + + findViewById(R.id.suggest).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new AsyncTask() { + Dialog d; + + @Override + protected String doInBackground(String... params) { + try { + return TitleExtractor.getPageTitle(params[0]); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPreExecute() { + d = new MaterialDialog.Builder(Submit.this).progress(true, 100) + .title(R.string.editor_finding_title) + .content(R.string.misc_please_wait) + .show(); + } + + @Override + protected void onPostExecute(String s) { + if (s != null) { + ((EditText) findViewById(R.id.titletext)).setText(s); + d.dismiss(); + } else { + d.dismiss(); + new AlertDialog.Builder(Submit.this) + .setTitle(R.string.title_not_found) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } + } + }.execute(((EditText) findViewById(R.id.urltext)).getText().toString()); + } + }); + findViewById(R.id.selImage).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + TedBottomPicker tedBottomPicker = + new TedBottomPicker.Builder(Submit.this).setOnImageSelectedListener( + Submit.this::handleImageIntent) + .setLayoutResource(R.layout.image_sheet_dialog) + .setTitle("Choose a photo") + .create(); + + tedBottomPicker.show(getSupportFragmentManager()); + KeyboardUtil.hideKeyboard(Submit.this, findViewById(R.id.bodytext).getWindowToken(), 0); + } + }); + + DoEditorActions.doActions(((EditText) findViewById(R.id.bodytext)), + findViewById(R.id.selftext), getSupportFragmentManager(), Submit.this, null, null); + if (intent.hasExtra(Intent.EXTRA_TEXT) && !intent.getExtras() + .getString(Intent.EXTRA_TEXT, "") + .isEmpty() && !intent.getBooleanExtra(EXTRA_IS_SELF, false)) { + String data = intent.getStringExtra(Intent.EXTRA_TEXT); + if (data.contains("\n")) { + ((EditText) findViewById(R.id.titletext)).setText( + data.substring(0, data.indexOf("\n"))); + ((EditText) findViewById(R.id.urltext)).setText(data.substring(data.indexOf("\n"))); + } else { + ((EditText) findViewById(R.id.urltext)).setText(data); + } + self.setVisibility(View.GONE); + image.setVisibility(View.GONE); + link.setVisibility(View.VISIBLE); + ((RadioButton) findViewById(R.id.linkradio)).setChecked(true); + + } else if (intent.hasExtra(Intent.EXTRA_STREAM)) { + final Uri imageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (imageUri != null) { + handleImageIntent(new ArrayList() {{ + add(imageUri); + }}); + self.setVisibility(View.GONE); + image.setVisibility(View.VISIBLE); + link.setVisibility(View.GONE); + ((RadioButton) findViewById(R.id.imageradio)).setChecked(true); + } + } + if (intent.hasExtra(Intent.EXTRA_SUBJECT) && !intent.getExtras() + .getString(Intent.EXTRA_SUBJECT, "") + .isEmpty()) { + String data = intent.getStringExtra(Intent.EXTRA_SUBJECT); + ((EditText) findViewById(R.id.titletext)).setText(data); + } + findViewById(R.id.send).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ((FloatingActionButton) findViewById(R.id.send)).hide(); + new AsyncDo().execute(); + } + }); + + } + + private void setImage(final String URL) { + this.URL = URL; + + runOnUiThread(new Runnable() { + @Override + public void run() { + findViewById(R.id.imagepost).setVisibility(View.VISIBLE); + ((Reddit) getApplication()).getImageLoader() + .displayImage(URL, ((ImageView) findViewById(R.id.imagepost))); + } + }); + } + + private void showFlairChooser() { + client = Reddit.client; + gson = new Gson(); + + String subreddit = ((EditText) findViewById(R.id.subreddittext)).getText().toString(); + + final Dialog d = + new MaterialDialog.Builder(Submit.this).title(R.string.submit_findingflairs) + .cancelable(true) + .content(R.string.misc_please_wait) + .progress(true, 100) + .show(); + new AsyncTask() { + ArrayList flairs; + + @Override + protected JsonArray doInBackground(Void... params) { + flairs = new ArrayList<>(); + HttpRequest r = Authentication.reddit.request() + .path("/r/" + subreddit + "/api/link_flair_v2.json") + .get() + .build(); + + Request request = new Request.Builder() + .headers(r.getHeaders().newBuilder().set("User-Agent", "Slide flair search").build()) + .url(r.getUrl()) + .build(); + + return HttpUtil.getJsonArray(client, gson, request); + } + + @Override + protected void onPostExecute(final JsonArray result) { + if (result == null) { + LogUtil.v("Error loading content"); + d.dismiss(); + } else { + try { + final HashMap flairs = new HashMap<>(); + for(JsonElement object : result) { + RichFlair choice = new ObjectMapper().disable( + DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).readValue(object.toString(), RichFlair.class); + String title = choice.getText(); + flairs.put(title, choice); + } + d.dismiss(); + + ArrayList allKeys = new ArrayList<>(flairs.keySet()); + + new MaterialDialog.Builder(Submit.this).title( + getString(R.string.submit_flairchoices, subreddit)) + .items(allKeys) + .itemsCallback(new MaterialDialog.ListCallback() { + @Override + public void onSelection(MaterialDialog dialog, + View itemView, int which, CharSequence text) { + RichFlair selected = flairs.get(allKeys.get(which)); + selectedFlairID = selected.getId(); + ((TextView) findViewById(R.id.flair)).setText(getString(R.string.submit_selected_flair, selected.getText())); + } + }) + .show(); + } catch(Exception e) { + LogUtil.v(e.toString()); + d.dismiss(); + LogUtil.v("Error parsing flairs"); + } + } + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + public void setViews(String rawHTML, String subredditName, SpoilerRobotoTextView firstTextView, + CommentOverflow commentOverflow) { + if (rawHTML.isEmpty()) { + return; + } + + List blocks = SubmissionParser.getBlocks(rawHTML); + + int startIndex = 0; + // the
case is when the body contains a table or code block first + if (!blocks.get(0).equals("
")) { + firstTextView.setVisibility(View.VISIBLE); + firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); + startIndex = 1; + } else { + firstTextView.setText(""); + firstTextView.setVisibility(View.GONE); + } + + if (blocks.size() > 1) { + if (startIndex == 0) { + commentOverflow.setViews(blocks, subredditName); + } else { + commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); + } + } else { + commentOverflow.removeAllViews(); + } + } + + public void handleImageIntent(List uris) { + if (uris.size() == 1) { + // Get the Image from data (single image) + try { + new UploadImgurSubmit(this, uris.get(0)); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + //Multiple images + try { + new UploadImgurAlbumSubmit(this, uris.toArray(new Uri[0])); + } catch (Exception e) { + e.printStackTrace(); + + } + } + } + + private class AsyncDo extends AsyncTask { + + @Override + protected Void doInBackground(Void... voids) { + try { + if (self.getVisibility() == View.VISIBLE) { + final String text = + ((EditText) findViewById(R.id.bodytext)).getText().toString(); + try { + AccountManager.SubmissionBuilder builder = new AccountManager.SubmissionBuilder( + ((EditText) findViewById(R.id.bodytext)).getText() + .toString(), ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString(), + ((EditText) findViewById(R.id.titletext)).getText() + .toString()); + + if(selectedFlairID != null) { + builder.flairID(selectedFlairID); + } + + Submission s = new AccountManager(Authentication.reddit).submit(builder); + new AccountManager(Authentication.reddit).sendRepliesToInbox(s, + inboxReplies.isChecked()); + OpenRedditLink.openUrl(Submit.this, + "reddit.com/r/" + ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString() + "/comments/" + s + .getFullName() + .substring(3), true); + Submit.this.finish(); + } catch (final ApiException e) { + Drafts.addDraft(text); + e.printStackTrace(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + showErrorRetryDialog(getString(R.string.misc_err) + + ": " + + e.getExplanation() + + "\n" + + getString(R.string.misc_retry_draft)); + } + }); + } + } else if (link.getVisibility() == View.VISIBLE) { + try { + Submission s = new AccountManager(Authentication.reddit).submit( + new AccountManager.SubmissionBuilder( + new URL(((EditText) findViewById(R.id.urltext)).getText() + .toString()), ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString(), + ((EditText) findViewById(R.id.titletext)).getText() + .toString())); + new AccountManager(Authentication.reddit).sendRepliesToInbox(s, + inboxReplies.isChecked()); + OpenRedditLink.openUrl(Submit.this, + "reddit.com/r/" + ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString() + "/comments/" + s + .getFullName() + .substring(3), true); + + Submit.this.finish(); + } catch (final ApiException e) { + e.printStackTrace(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + + if (e instanceof ApiException) { + showErrorRetryDialog(getString(R.string.misc_err) + + ": " + + e.getExplanation() + + "\n" + + getString(R.string.misc_retry)); + } else { + showErrorRetryDialog( + getString(R.string.misc_err) + ": " + getString( + R.string.err_invalid_url) + "\n" + getString( + R.string.misc_retry)); + } + } + }); + } + } else if (image.getVisibility() == View.VISIBLE) { + try { + Submission s = new AccountManager(Authentication.reddit).submit( + new AccountManager.SubmissionBuilder(new URL(URL), + ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString(), + ((EditText) findViewById(R.id.titletext)).getText() + .toString())); + new AccountManager(Authentication.reddit).sendRepliesToInbox(s, + inboxReplies.isChecked()); + OpenRedditLink.openUrl(Submit.this, + "reddit.com/r/" + ((AutoCompleteTextView) findViewById( + R.id.subreddittext)).getText().toString() + "/comments/" + s + .getFullName() + .substring(3), true); + + Submit.this.finish(); + } catch (final Exception e) { + runOnUiThread(new Runnable() { + @Override + public void run() { + if (e instanceof ApiException) { + showErrorRetryDialog( + getString(R.string.misc_err) + ": " + ((ApiException) e) + .getExplanation() + "\n" + getString( + R.string.misc_retry)); + } else { + showErrorRetryDialog( + getString(R.string.misc_err) + ": " + getString( + R.string.err_invalid_url) + "\n" + getString( + R.string.misc_retry)); + } + } + }); + } + } + } catch (Exception e) { + e.printStackTrace(); + + runOnUiThread(new Runnable() { + @Override + public void run() { + showErrorRetryDialog(getString(R.string.misc_retry)); + } + }); + } + return null; + } + } + + private class UploadImgurSubmit extends UploadImgur { + + private final Uri uri; + + public UploadImgurSubmit(Context c, Uri u) { + this.c = c; + this.uri = u; + + dialog = new MaterialDialog.Builder(c).title( + c.getString(R.string.editor_uploading_image)) + .progress(false, 100) + .cancelable(false) + .autoDismiss(false) + .build(); + + new MaterialDialog.Builder(c).title(c.getString(R.string.editor_upload_image_question)) + .cancelable(false) + .autoDismiss(false) + .positiveText(c.getString(R.string.btn_upload)) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog d, DialogAction w) { + d.dismiss(); + dialog.show(); + execute(uri); + } + }) + .negativeText(c.getString(R.string.btn_cancel)) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog d, DialogAction w) { + d.dismiss(); + } + }) + .show(); + } + + @Override + protected void onPostExecute(final JSONObject result) { + dialog.dismiss(); + try { + final String url = result.getJSONObject("data").getString("link"); + setImage(url); + + } catch (Exception e) { + new AlertDialog.Builder(c) + .setTitle(R.string.err_title) + .setMessage(R.string.editor_err_msg) + .setPositiveButton(R.string.btn_ok, null) + .show(); + e.printStackTrace(); + } + } + } + + private class UploadImgurAlbumSubmit extends UploadImgurAlbum { + + private final Uri[] uris; + + public UploadImgurAlbumSubmit(Context c, Uri... u) { + this.c = c; + this.uris = u; + + dialog = new MaterialDialog.Builder(c).title( + c.getString(R.string.editor_uploading_image)) + .progress(false, 100) + .cancelable(false) + .build(); + + new MaterialDialog.Builder(c).title(c.getString(R.string.editor_upload_image_question)) + .cancelable(false) + .autoDismiss(false) + .positiveText(c.getString(R.string.btn_upload)) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog d, DialogAction w) { + d.dismiss(); + dialog.show(); + execute(uris); + } + }) + .negativeText(c.getString(R.string.btn_cancel)) + .onNegative(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog d, DialogAction w) { + d.dismiss(); + } + }) + .show(); + } + + @Override + protected void onPostExecute(final String result) { + dialog.dismiss(); + try { + ((RadioButton) findViewById(R.id.linkradio)).setChecked(true); + link.setVisibility(View.VISIBLE); + ((EditText) findViewById(R.id.urltext)).setText(finalUrl); + } catch (Exception e) { + new AlertDialog.Builder(c) + .setTitle(R.string.err_title) + .setMessage(R.string.editor_err_msg) + .setPositiveButton(R.string.btn_ok, null) + .show(); + e.printStackTrace(); + } + } + } + + private void showErrorRetryDialog(String message) { + new AlertDialog.Builder(Submit.this) + .setTitle(R.string.err_title) + .setMessage(message) + .setNegativeButton(R.string.btn_no, (dialogInterface, i) -> + finish()) + .setPositiveButton(R.string.btn_yes, (dialogInterface, i) -> + ((FloatingActionButton) findViewById(R.id.send)).show()) + .setOnDismissListener(dialog -> + ((FloatingActionButton) findViewById(R.id.send)).show()) + .create() + .show(); + } + +} diff --git a/app/src/main/java/me/ccrama/redditslide/Adapters/CommentAdapter.java b/app/src/main/java/me/ccrama/redditslide/Adapters/CommentAdapter.java index a375a80c3..d8080b43b 100644 --- a/app/src/main/java/me/ccrama/redditslide/Adapters/CommentAdapter.java +++ b/app/src/main/java/me/ccrama/redditslide/Adapters/CommentAdapter.java @@ -1,2372 +1,2372 @@ -package me.ccrama.redditslide.Adapters; - -/** - * Created by ccrama on 3/22/2015. - */ - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.app.Activity; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Handler; -import android.os.Looper; -import android.util.Log; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.FragmentManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.devspark.robototextview.RobotoTypefaces; -import com.lusfold.androidkeyvaluestore.KVStore; -import com.mikepenz.itemanimators.AlphaInAnimator; -import com.mikepenz.itemanimators.SlideRightAlphaAnimator; -import com.nostra13.universalimageloader.utils.DiskCacheUtils; - -import net.dean.jraw.ApiException; -import net.dean.jraw.RedditClient; -import net.dean.jraw.http.UserAgent; -import net.dean.jraw.managers.AccountManager; -import net.dean.jraw.models.Comment; -import net.dean.jraw.models.CommentNode; -import net.dean.jraw.models.Contribution; -import net.dean.jraw.models.Submission; -import net.dean.jraw.models.VoteDirection; - -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; - -import me.ccrama.redditslide.ActionStates; -import me.ccrama.redditslide.Activities.BaseActivity; -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.BuildConfig; -import me.ccrama.redditslide.Constants; -import me.ccrama.redditslide.Drafts; -import me.ccrama.redditslide.Fragments.CommentPage; -import me.ccrama.redditslide.HasSeen; -import me.ccrama.redditslide.ImageFlairs; -import me.ccrama.redditslide.LastComments; -import me.ccrama.redditslide.OpenRedditLink; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.Reddit; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.SpoilerRobotoTextView; -import me.ccrama.redditslide.SubmissionViews.PopulateSubmissionViewHolder; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Views.CommentOverflow; -import me.ccrama.redditslide.Views.DoEditorActions; -import me.ccrama.redditslide.Views.PreCachingLayoutManagerComments; -import me.ccrama.redditslide.Visuals.FontPreferences; -import me.ccrama.redditslide.Visuals.Palette; -import me.ccrama.redditslide.Vote; -import me.ccrama.redditslide.util.AnimatorUtil; -import me.ccrama.redditslide.util.BlendModeUtil; -import me.ccrama.redditslide.util.DisplayUtil; -import me.ccrama.redditslide.util.KeyboardUtil; -import me.ccrama.redditslide.util.LogUtil; -import me.ccrama.redditslide.util.OnSingleClickListener; -import me.ccrama.redditslide.util.SubmissionParser; -import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; - - -public class CommentAdapter extends RecyclerView.Adapter { - - final static int HEADER = 1; - private final int SPACER = 6; - public final Bitmap[] awardIcons; - public Context mContext; - public SubmissionComments dataSet; - public Submission submission; - public CommentViewHolder currentlySelected; - public CommentNode currentNode; - public String currentSelectedItem = ""; - public int shiftFrom; - public FragmentManager fm; - public int clickpos; - public int currentPos; - public CommentViewHolder isHolder; - public boolean isClicking; - public HashMap keys = new HashMap<>(); - public ArrayList currentComments; - public ArrayList deleted = new ArrayList<>(); - RecyclerView listView; - CommentPage mPage; - int shifted; - int toShiftTo; - HashSet hidden; - ArrayList hiddenPersons; - ArrayList toCollapse; - private String backedText = ""; - private String currentlyEditingId = ""; - public SubmissionViewHolder submissionViewHolder; - long lastSeen = 0; - public ArrayList approved = new ArrayList<>(); - public ArrayList removed = new ArrayList<>(); - - public CommentAdapter(CommentPage mContext, SubmissionComments dataSet, RecyclerView listView, - Submission submission, FragmentManager fm) { - this.mContext = mContext.getContext(); - mPage = mContext; - this.listView = listView; - this.dataSet = dataSet; - this.fm = fm; - - this.submission = submission; - hidden = new HashSet<>(); - currentComments = dataSet.comments; - if (currentComments != null) { - for (int i = 0; i < currentComments.size(); i++) { - keys.put(currentComments.get(i).getName(), i); - } - } - hiddenPersons = new ArrayList<>(); - toCollapse = new ArrayList<>(); - - shifted = 0; - - // As per reddit API gids: 0=silver, 1=gold, 2=platinum - awardIcons = new Bitmap[] { - BitmapFactory.decodeResource(mContext.getResources(), R.drawable.silver), - BitmapFactory.decodeResource(mContext.getResources(), R.drawable.gold), - BitmapFactory.decodeResource(mContext.getResources(), R.drawable.platinum), - }; - } - - public void reset(Context mContext, SubmissionComments dataSet, RecyclerView listView, - Submission submission, boolean reset) { - - doTimes(); - - this.mContext = mContext; - this.listView = listView; - this.dataSet = dataSet; - - this.submission = submission; - hidden = new HashSet<>(); - currentComments = dataSet.comments; - if (currentComments != null) { - for (int i = 0; i < currentComments.size(); i++) { - keys.put(currentComments.get(i).getName(), i); - } - } - - hiddenPersons = new ArrayList<>(); - toCollapse = new ArrayList<>(); - - - if (currentSelectedItem != null && !currentSelectedItem.isEmpty() && !reset) { - notifyDataSetChanged(); - } else { - if (currentComments != null && !reset) { - notifyItemRangeChanged(2, currentComments.size() + 1); - } else if (currentComments == null) { - currentComments = new ArrayList<>(); - notifyDataSetChanged(); - } else { - notifyDataSetChanged(); - } - } - - if (currentSelectedItem != null - && !currentSelectedItem.isEmpty() - && currentComments != null - && !currentComments.isEmpty()) { - int i = 2; - for (CommentObject n : currentComments) { - if (n instanceof CommentItem && n.comment.getComment() - .getFullName() - .contains(currentSelectedItem)) { - ((PreCachingLayoutManagerComments) listView.getLayoutManager()).scrollToPositionWithOffset( - i, mPage.headerHeight); - break; - } - i++; - } - mPage.resetScroll(true); - } - if (mContext instanceof BaseActivity) { - ((BaseActivity) mContext).setShareUrl("https://reddit.com" + submission.getPermalink()); - } - } - - @Override - public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { - switch (i) { - case SPACER: { - View v = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.spacer_post, viewGroup, false); - return new SpacerViewHolder(v); - } - case HEADER: { - View v = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.submission_fullscreen, viewGroup, false); - return new SubmissionViewHolder(v); - } - case 2: { - View v = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.comment, viewGroup, false); - return new CommentViewHolder(v); - } - default: { - View v = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.morecomment, viewGroup, false); - return new MoreCommentViewHolder(v); - } - } - - - } - - public static class SpacerViewHolder extends RecyclerView.ViewHolder { - public SpacerViewHolder(View itemView) { - super(itemView); - } - } - - public void expandAll() { - if (currentComments == null) return; - for (CommentObject o : currentComments) { - if (o.comment.isTopLevel()) { - hiddenPersons.remove(o.comment.getComment().getFullName()); - unhideAll(o.comment); - } - } - notifyItemChanged(2); - } - - - public void collapseAll() { - if (currentComments == null) return; - for (CommentObject o : currentComments) { - if (o.comment.isTopLevel()) { - if (!hiddenPersons.contains(o.comment.getComment().getFullName())) { - hiddenPersons.add(o.comment.getComment().getFullName()); - } - hideAll(o.comment); - } - } - notifyItemChanged(2); - } - - public void doScoreText(CommentViewHolder holder, Comment comment, CommentAdapter adapter) { - holder.content.setText( - CommentAdapterHelper.getScoreString(comment, mContext, holder, submission, - adapter)); - } - - public void doTimes() { - if (submission != null && SettingValues.commentLastVisit && !dataSet.single && ( - SettingValues.storeHistory - && (!submission.isNsfw() || SettingValues.storeNSFWHistory))) { - lastSeen = HasSeen.getSeenTime(submission); - String fullname = submission.getFullName(); - if (fullname.contains("t3_")) { - fullname = fullname.substring(3); - } - HasSeen.seenTimes.put(fullname, System.currentTimeMillis()); - KVStore.getInstance().insert(fullname, String.valueOf(System.currentTimeMillis())); - } - if (submission != null) { - if (SettingValues.storeHistory) { - if (submission.isNsfw() && !SettingValues.storeNSFWHistory) { - } else { - HasSeen.addSeen(submission.getFullName()); - } - LastComments.setComments(submission); - } - } - } - - - @Override - public void onBindViewHolder(final RecyclerView.ViewHolder firstHolder, int old) { - int pos = old != 0 ? old - 1 : old; - if (firstHolder instanceof CommentViewHolder) { - final CommentViewHolder holder = (CommentViewHolder) firstHolder; - int datasetPosition = pos - 1; - - datasetPosition = getRealPosition(datasetPosition); - - if (pos > toShiftTo) { - shifted = 0; - } - if (pos < shiftFrom) { - shifted = 0; - } - - final CommentNode baseNode = currentComments.get(datasetPosition).comment; - final Comment comment = baseNode.getComment(); - - if (pos == getItemCount() - 1) { - holder.itemView.setPadding(0, 0, 0, (int) mContext.getResources() - .getDimension(R.dimen.overview_top_padding_single)); - } else { - holder.itemView.setPadding(0, 0, 0, 0); - } - - doScoreText(holder, comment, this); - - //Long click listeners - View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (SettingValues.swap) { - doOnClick(holder, comment, baseNode); - } else { - doLongClick(holder, comment, baseNode); - } - return true; - } - }; - - holder.firstTextView.setOnLongClickListener(onLongClickListener); - holder.commentOverflow.setOnLongClickListener(onLongClickListener); - - holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if (!currentlyEditingId.equals(comment.getFullName())) { - if (SettingValues.swap) { - doOnClick(holder, comment, baseNode); - } else { - doLongClick(holder, comment, baseNode); - } - } - return true; - } - }); - - //Single click listeners - OnSingleClickListener singleClick = new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - if (!currentlyEditingId.equals(comment.getFullName())) { - if (SettingValues.swap) { - doLongClick(holder, comment, baseNode); - } else { - doOnClick(holder, comment, baseNode); - } - } - } - }; - holder.itemView.setOnClickListener(singleClick); - holder.commentOverflow.setOnClickListener(singleClick); - if (!toCollapse.contains(comment.getFullName()) || !SettingValues.collapseComments) { - setViews(comment.getDataNode().get("body_html").asText(), - submission.getSubredditName(), holder, singleClick, onLongClickListener); - } - - holder.firstTextView.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - SpoilerRobotoTextView SpoilerRobotoTextView = (SpoilerRobotoTextView) v; - if (SettingValues.swap) { - if (!SpoilerRobotoTextView.isSpoilerClicked()) { - doLongClick(holder, comment, baseNode); - } else if (SpoilerRobotoTextView.isSpoilerClicked()) { - SpoilerRobotoTextView.resetSpoilerClicked(); - } - } else if (!SpoilerRobotoTextView.isSpoilerClicked()) { - doOnClick(holder, comment, baseNode); - } else if (SpoilerRobotoTextView.isSpoilerClicked()) { - SpoilerRobotoTextView.resetSpoilerClicked(); - } - } - }); - if (ImageFlairs.isSynced(comment.getSubredditName()) - && comment.getAuthorFlair() != null - && comment.getAuthorFlair().getCssClass() != null - && !comment.getAuthorFlair().getCssClass().isEmpty()) { - boolean set = false; - for (String s : comment.getAuthorFlair().getCssClass().split(" ")) { - ImageFlairs.FlairImageLoader loader = ImageFlairs.getFlairImageLoader(mContext); - File file = DiskCacheUtils.findInCache( - comment.getSubredditName().toLowerCase(Locale.ENGLISH) - + ":" - + s.toLowerCase(Locale.ENGLISH), - loader.getDiskCache()); - if (file != null && file.exists()) { - set = true; - holder.imageFlair.setVisibility(View.VISIBLE); - String decodedImgUri = Uri.fromFile(file).toString(); - loader.displayImage(decodedImgUri, holder.imageFlair); - break; - } - } - if (!set) { - holder.imageFlair.setImageDrawable(null); - holder.imageFlair.setVisibility(View.GONE); - } - } else { - holder.imageFlair.setVisibility(View.GONE); - } - //Set typeface for body - int type = new FontPreferences(mContext).getFontTypeComment().getTypeface(); - Typeface typeface; - if (type >= 0) { - typeface = RobotoTypefaces.obtainTypeface(mContext, type); - } else { - typeface = Typeface.DEFAULT; - } - holder.firstTextView.setTypeface(typeface); - - - //Show padding on top - if (baseNode.isTopLevel()) { - holder.itemView.findViewById(R.id.next).setVisibility(View.VISIBLE); - } else if (holder.itemView.findViewById(R.id.next).getVisibility() == View.VISIBLE) { - holder.itemView.findViewById(R.id.next).setVisibility(View.GONE); - } - - //Should be collapsed? - if (hiddenPersons.contains(comment.getFullName()) || toCollapse.contains( - comment.getFullName())) { - int childnumber = getChildNumber(baseNode); - if (hiddenPersons.contains(comment.getFullName()) && childnumber > 0) { - holder.childrenNumber.setVisibility(View.VISIBLE); - holder.childrenNumber.setText("+" + childnumber); - } else { - holder.childrenNumber.setVisibility(View.GONE); - } - if (SettingValues.collapseComments && toCollapse.contains(comment.getFullName())) { - holder.firstTextView.setVisibility(View.GONE); - holder.commentOverflow.setVisibility(View.GONE); - } - } else { - holder.childrenNumber.setVisibility(View.GONE); - holder.commentOverflow.setVisibility(View.VISIBLE); - } - - - holder.dot.setVisibility(View.VISIBLE); - - int dwidth = (int) ((SettingValues.largeDepth ? 5 : 3) * Resources.getSystem() - .getDisplayMetrics().density); - int width = 0; - - //Padding on the left, starting with the third comment - for (int i = 2; i < baseNode.getDepth(); i++) { - width += dwidth; - } - RecyclerView.LayoutParams params = - (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); - params.setMargins(width, 0, 0, 0); - holder.itemView.setLayoutParams(params); - RelativeLayout.LayoutParams params2 = - (RelativeLayout.LayoutParams) holder.dot.getLayoutParams(); - params2.width = dwidth; - holder.dot.setLayoutParams(params2); - if (baseNode.getDepth() - 1 > 0) { - int i22 = baseNode.getDepth() - 2; - String commentOp = dataSet.commentOPs.get(comment.getId()); - if (SettingValues.highlightCommentOP - && commentOp != null - && comment != null - && commentOp.equals(comment.getAuthor())) { - holder.dot.setBackgroundColor( - ContextCompat.getColor(mContext, R.color.md_purple_500)); - - } else { - if (i22 % 5 == 0) { - holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, - !SettingValues.colorCommentDepth ? R.color.md_grey_700 - : R.color.md_blue_500)); - } else if (i22 % 4 == 0) { - holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, - !SettingValues.colorCommentDepth ? R.color.md_grey_600 - : R.color.md_green_500)); - } else if (i22 % 3 == 0) { - holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, - !SettingValues.colorCommentDepth ? R.color.md_grey_500 - : R.color.md_yellow_500)); - } else if (i22 % 2 == 0) { - holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, - !SettingValues.colorCommentDepth ? R.color.md_grey_400 - : R.color.md_orange_500)); - } else { - holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, - !SettingValues.colorCommentDepth ? R.color.md_grey_300 - : R.color.md_red_500)); - } - } - } else { - holder.dot.setVisibility(View.GONE); - } - - if (currentSelectedItem != null - && comment.getFullName().contains(currentSelectedItem) - && !currentSelectedItem.isEmpty() - && !currentlyEditingId.equals(comment.getFullName())) { - doHighlighted(holder, comment, baseNode, false); - } else if (!currentlyEditingId.equals(comment.getFullName())) { - setCommentStateUnhighlighted(holder, baseNode, false); - } - - if (deleted.contains(comment.getFullName())) { - holder.firstTextView.setText(R.string.comment_deleted); - holder.content.setText(R.string.comment_deleted); - } - - if (currentlyEditingId.equals(comment.getFullName())) { - setCommentStateUnhighlighted(holder, baseNode, false); - setCommentStateHighlighted(holder, comment, baseNode, true, false); - } - - if (SettingValues.collapseDeletedComments) { - if (comment.getBody().startsWith("[removed]") || comment.getBody().startsWith("[deleted]")) { - holder.firstTextView.setVisibility(View.GONE); - holder.commentOverflow.setVisibility(View.GONE); - } - } - - } else if (firstHolder instanceof SubmissionViewHolder && submission != null) { - submissionViewHolder = (SubmissionViewHolder) firstHolder; - new PopulateSubmissionViewHolder().populateSubmissionViewHolder( - (SubmissionViewHolder) firstHolder, submission, (Activity) mContext, true, true, - null, listView, false, false, null, this); - if (Authentication.isLoggedIn && Authentication.didOnline) { - if (submission.isArchived() || submission.isLocked()) { - firstHolder.itemView.findViewById(R.id.reply).setVisibility(View.GONE); - } else { - firstHolder.itemView.findViewById(R.id.reply) - .setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - doReplySubmission(firstHolder); - } - }); - firstHolder.itemView.findViewById(R.id.discard) - .setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - firstHolder.itemView.findViewById(R.id.innerSend) - .setVisibility(View.GONE); - currentlyEditing = null; - editingPosition = -1; - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - } - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - currentlyEditingId = ""; - backedText = ""; - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - } - }); - } - } else { - firstHolder.itemView.findViewById(R.id.innerSend).setVisibility(View.GONE); - firstHolder.itemView.findViewById(R.id.reply).setVisibility(View.GONE); - } - - firstHolder.itemView.findViewById(R.id.more) - .setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - firstHolder.itemView.findViewById(R.id.menu).callOnClick(); - } - }); - - - } else if (firstHolder instanceof MoreCommentViewHolder) { - final MoreCommentViewHolder holder = (MoreCommentViewHolder) firstHolder; - int nextPos = pos - 1; - - nextPos = getRealPosition(nextPos); - - final MoreChildItem baseNode = (MoreChildItem) currentComments.get(nextPos); - if (baseNode.children.getCount() > 0) { - try { - holder.content.setText(mContext.getString(R.string.comment_load_more_string_new, - baseNode.children.getLocalizedCount())); - } catch (Exception e) { - holder.content.setText(R.string.comment_load_more_number_unknown); - } - } else if (!baseNode.children.getChildrenIds().isEmpty()) { - holder.content.setText(R.string.comment_load_more_number_unknown); - } else { - holder.content.setText(R.string.thread_continue); - } - - int dwidth = (int) ((SettingValues.largeDepth ? 5 : 3) * Resources.getSystem() - .getDisplayMetrics().density); - int width = 0; - for (int i = 1; i < baseNode.comment.getDepth(); i++) { - width += dwidth; - } - - final View progress = holder.loading; - progress.setVisibility(View.GONE); - final int finalNextPos = nextPos; - holder.content.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - if (baseNode.children.getChildrenIds().isEmpty()) { - String toGoTo = "https://reddit.com" - + submission.getPermalink() - + baseNode.comment.getComment().getId() - + "?context=0"; - OpenRedditLink.openUrl(mContext, toGoTo, true); - } else if (progress.getVisibility() == View.GONE) { - progress.setVisibility(View.VISIBLE); - holder.content.setText(R.string.comment_loading_more); - currentLoading = - new AsyncLoadMore(getRealPosition(holder.getBindingAdapterPosition() - 2), - holder.getBindingAdapterPosition(), holder, finalNextPos, - baseNode.comment.getComment().getFullName()); - currentLoading.execute(baseNode); - } - } - }); - - RecyclerView.LayoutParams params = - (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); - params.setMargins(width, 0, 0, 0); - holder.itemView.setLayoutParams(params); - - } - if (firstHolder instanceof SpacerViewHolder) { - //Make a space the size of the toolbar minus 1 so there isn't a gap - firstHolder.itemView.findViewById(R.id.height) - .setLayoutParams( - new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ( - Constants.SINGLE_HEADER_VIEW_OFFSET - DisplayUtil.dpToPxVertical(1) - + mPage.shownHeaders))); - } - } - - AsyncLoadMore currentLoading; - String changedProfile; - - private void doReplySubmission(RecyclerView.ViewHolder submissionViewHolder) { - final View replyArea = submissionViewHolder.itemView.findViewById(R.id.innerSend); - if (replyArea.getVisibility() == View.GONE) { - expandSubmissionReply(replyArea); - EditText replyLine = submissionViewHolder.itemView.findViewById(R.id.replyLine); - DoEditorActions.doActions(replyLine, submissionViewHolder.itemView, fm, - (Activity) mContext, submission.isSelfPost() ? submission.getSelftext() : null, - new String[]{submission.getAuthor()}); - - currentlyEditing = submissionViewHolder.itemView.findViewById(R.id.replyLine); - - final TextView profile = submissionViewHolder.itemView.findViewById(R.id.profile); - changedProfile = Authentication.name; - profile.setText("/u/" + changedProfile); - profile.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final HashMap accounts = new HashMap<>(); - - for (String s : Authentication.authentication.getStringSet("accounts", - new HashSet())) { - if (s.contains(":")) { - accounts.put(s.split(":")[0], s.split(":")[1]); - } else { - accounts.put(s, ""); - } - } - final ArrayList keys = new ArrayList<>(accounts.keySet()); - final int i = keys.indexOf(changedProfile); - - new AlertDialog.Builder(mContext) - .setTitle(R.string.replies_switch_accounts) - .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { - changedProfile = keys.get(which); - profile.setText("/u/" + changedProfile); - }) - .setNegativeButton(R.string.btn_cancel, null) - .show(); - } - }); - currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - mPage.fastScroll.setVisibility(View.GONE); - if (mPage.fab != null) mPage.fab.setVisibility(View.GONE); - mPage.overrideFab = true; - } else if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - } - } - }); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - replyLine.setOnFocusChangeListener((v, b) -> { - if (b) { - v.postDelayed(() -> { - if (!v.hasFocus()) - v.requestFocus(); - }, 100); - } - }); - } - replyLine.requestFocus(); - KeyboardUtil.toggleKeyboard(mContext, - InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); - - editingPosition = submissionViewHolder.getBindingAdapterPosition(); - - submissionViewHolder.itemView.findViewById(R.id.send) - .setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - dataSet.refreshLayout.setRefreshing(true); - - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - } - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - if (currentlyEditing != null) { - String text = currentlyEditing.getText().toString(); - new ReplyTaskComment(submission, changedProfile).execute(text); - replyArea.setVisibility(View.GONE); - currentlyEditing.setText(""); - currentlyEditing = null; - editingPosition = -1; - //Hide soft keyboard - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - } - } - }); - } else { - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - collapseAndHide(replyArea); - } - } - - public void setViews(String rawHTML, String subredditName, - final SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow) { - if (rawHTML.isEmpty()) { - return; - } - - List blocks = SubmissionParser.getBlocks(rawHTML); - - int startIndex = 0; - // the
case is when the body contains a table or code block first - if (!blocks.get(0).equals("
")) { - firstTextView.setVisibility(View.VISIBLE); - firstTextView.setTextHtml(blocks.get(0), subredditName); - startIndex = 1; - } else { - firstTextView.setText(""); - } - - if (blocks.size() > 1) { - if (startIndex == 0) { - commentOverflow.setViews(blocks, subredditName); - } else { - commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); - } - } else { - commentOverflow.removeAllViews(); - } - - } - - public void setViews(String rawHTML, String subredditName, - final SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow, - View.OnClickListener click, View.OnLongClickListener onLongClickListener) { - if (rawHTML.isEmpty()) { - return; - } - - List blocks = SubmissionParser.getBlocks(rawHTML); - - int startIndex = 0; - // the
case is when the body contains a table or code block first - if (!blocks.get(0).equals("
")) { - firstTextView.setVisibility(View.VISIBLE); - firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); - startIndex = 1; - } else { - firstTextView.setText(""); - } - - if (blocks.size() > 1) { - if (startIndex == 0) { - commentOverflow.setViews(blocks, subredditName, click, onLongClickListener); - } else { - commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName, - click, onLongClickListener); - } - } else { - commentOverflow.removeAllViews(); - } - - } - - private void setViews(String rawHTML, String subredditName, CommentViewHolder holder) { - setViews(rawHTML, subredditName, holder.firstTextView, holder.commentOverflow); - } - - private void setViews(String rawHTML, String subredditName, CommentViewHolder holder, - View.OnClickListener click, View.OnLongClickListener longClickListener) { - setViews(rawHTML, subredditName, holder.firstTextView, holder.commentOverflow, click, - longClickListener); - } - - int editingPosition; - - private void collapseAndHide(final View v) { - int finalHeight = v.getHeight(); - - mAnimator = AnimatorUtil.slideAnimator(finalHeight, 0, v); - - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animator) { - //Height=0, but it set visibility to GONE - v.setVisibility(View.GONE); - } - - @Override - public void onAnimationCancel(Animator animation) { - v.setVisibility(View.GONE); - } - }); - mAnimator.start(); - } - - private void collapseAndRemove(final View v) { - int finalHeight = v.getHeight(); - - mAnimator = AnimatorUtil.slideAnimator(finalHeight, 0, v); - - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animator) { - //Height=0, but it set visibility to GONE - ((LinearLayout) v).removeAllViews(); - } - - @Override - public void onAnimationCancel(Animator animation) { - ((LinearLayout) v).removeAllViews(); - } - }); - mAnimator.start(); - } - - private void doShowMenu(final View l) { - l.setVisibility(View.VISIBLE); - - final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l.measure(widthSpec, heightSpec); - - - final View l2 = l.findViewById(R.id.menu); - final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l2.measure(widthSpec2, heightSpec2); - ValueAnimator mAnimator = AnimatorUtil.slideAnimator(l.getMeasuredHeight(), l2.getMeasuredHeight(), l); - - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - l2.setVisibility(View.VISIBLE); - } - - @Override - public void onAnimationCancel(Animator animation) { - l2.setVisibility(View.VISIBLE); - } - }); - mAnimator.start(); - } - - ValueAnimator mAnimator; - - private void expand(final View l) { - l.setVisibility(View.VISIBLE); - - final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l.measure(widthSpec, heightSpec); - - View l2 = l.findViewById(R.id.replyArea) == null ? l.findViewById(R.id.innerSend) - : l.findViewById(R.id.replyArea); - final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l2.measure(widthSpec2, heightSpec2); - - mAnimator = AnimatorUtil.slideAnimator(0, l.getMeasuredHeight() - l2.getMeasuredHeight(), l); - - mAnimator.start(); - } - - private void expandAndSetParams(final View l) { - l.setVisibility(View.VISIBLE); - - final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l.measure(widthSpec, heightSpec); - - View l2 = l.findViewById(R.id.replyArea) == null ? l.findViewById(R.id.innerSend) - : l.findViewById(R.id.replyArea); - final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l2.measure(widthSpec2, heightSpec2); - - mAnimator = AnimatorUtil.slideAnimator((l.getMeasuredHeight() - l2.getMeasuredHeight()), - l.getMeasuredHeight() - (l.getMeasuredHeight() - l2.getMeasuredHeight()), l); - - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - RelativeLayout.LayoutParams params = - (RelativeLayout.LayoutParams) l.getLayoutParams(); - params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - params.addRule(RelativeLayout.BELOW, R.id.commentOverflow); - l.setLayoutParams(params); - } - - @Override - public void onAnimationCancel(Animator animation) { - RelativeLayout.LayoutParams params = - (RelativeLayout.LayoutParams) l.getLayoutParams(); - params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - params.addRule(RelativeLayout.BELOW, R.id.commentOverflow); - l.setLayoutParams(params); - } - }); - mAnimator.start(); - } - - private void expandSubmissionReply(final View l) { - l.setVisibility(View.VISIBLE); - - final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l.measure(widthSpec, heightSpec); - - mAnimator = AnimatorUtil.slideAnimator(0, l.getMeasuredHeight(), l); - - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) l.getLayoutParams(); - params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - l.setLayoutParams(params); - } - - @Override - public void onAnimationCancel(Animator animation) { - LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) l.getLayoutParams(); - params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - l.setLayoutParams(params); - } - }); - mAnimator.start(); - } - - CommentNode currentBaseNode; - - public void setCommentStateHighlighted(final CommentViewHolder holder, final Comment n, - final CommentNode baseNode, boolean isReplying, boolean animate) { - if (currentlySelected != null && currentlySelected != holder) { - setCommentStateUnhighlighted(currentlySelected, currentBaseNode, true); - } - - if (mContext instanceof BaseActivity) { - ((BaseActivity) mContext).setShareUrl("https://reddit.com" - + submission.getPermalink() - + n.getFullName() - + "?context=3"); - } - - // If a comment is hidden and (Swap long press == true), then a single click will un-hide the comment - // and expand to show all children comments - if (SettingValues.swap - && holder.firstTextView.getVisibility() == View.GONE - && !isReplying) { - hiddenPersons.remove(n.getFullName()); - unhideAll(baseNode, holder.getBindingAdapterPosition() + 1); - if (toCollapse.contains(n.getFullName()) && SettingValues.collapseComments) { - setViews(n.getDataNode().get("body_html").asText(), submission.getSubredditName(), - holder); - } - CommentAdapterHelper.hideChildrenObject(holder.childrenNumber); - holder.commentOverflow.setVisibility(View.VISIBLE); - toCollapse.remove(n.getFullName()); - } else { - currentlySelected = holder; - currentBaseNode = baseNode; - int color = Palette.getColor(n.getSubredditName()); - currentSelectedItem = n.getFullName(); - currentNode = baseNode; - LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); - resetMenu(holder.menuArea, false); - final View baseView = inflater.inflate( - SettingValues.rightHandedCommentMenu ? - R.layout.comment_menu_right_handed : R.layout.comment_menu, holder.menuArea); - - if (!isReplying) { - baseView.setVisibility(View.GONE); - if (animate) { - expand(baseView); - } else { - baseView.setVisibility(View.VISIBLE); - final int widthSpec = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - baseView.measure(widthSpec, heightSpec); - View l2 = baseView.findViewById(R.id.replyArea) == null ? baseView.findViewById( - R.id.innerSend) : baseView.findViewById(R.id.replyArea); - final int widthSpec2 = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec2 = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l2.measure(widthSpec2, heightSpec2); - ViewGroup.LayoutParams layoutParams = baseView.getLayoutParams(); - layoutParams.height = baseView.getMeasuredHeight() - l2.getMeasuredHeight(); - baseView.setLayoutParams(layoutParams); - } - } - - RecyclerView.LayoutParams params = - (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); - params.setMargins(0, 0, 0, 0); - holder.itemView.setLayoutParams(params); - - View reply = baseView.findViewById(R.id.reply); - View send = baseView.findViewById(R.id.send); - - final View menu = baseView.findViewById(R.id.menu); - final View replyArea = baseView.findViewById(R.id.replyArea); - - final View more = baseView.findViewById(R.id.more); - final ImageView upvote = baseView.findViewById(R.id.upvote); - final ImageView downvote = baseView.findViewById(R.id.downvote); - View discard = baseView.findViewById(R.id.discard); - final EditText replyLine = baseView.findViewById(R.id.replyLine); - final ImageView mod = baseView.findViewById(R.id.mod); - - final Comment comment = baseNode.getComment(); - if (ActionStates.getVoteDirection(comment) == VoteDirection.UPVOTE) { - BlendModeUtil.tintImageViewAsModulate(upvote, holder.textColorUp); - upvote.setContentDescription(mContext.getResources().getString(R.string.btn_upvoted)); - } else if (ActionStates.getVoteDirection(comment) == VoteDirection.DOWNVOTE) { - BlendModeUtil.tintImageViewAsModulate(downvote, holder.textColorDown); - downvote.setContentDescription(mContext.getResources().getString(R.string.btn_downvoted)); - } else { - downvote.clearColorFilter(); - downvote.setContentDescription(mContext.getResources().getString(R.string.btn_downvote)); - upvote.clearColorFilter(); - upvote.setContentDescription(mContext.getResources().getString(R.string.btn_upvote)); - } - - try { - if (UserSubscriptions.modOf.contains(submission.getSubredditName())) { - //todo - mod.setVisibility(View.GONE); - } else { - mod.setVisibility(View.GONE); - } - } catch (Exception e) { - Log.d(LogUtil.getTag(), "Error loading mod " + e.toString()); - } - - if (UserSubscriptions.modOf != null && UserSubscriptions.modOf.contains( - submission.getSubredditName().toLowerCase(Locale.ENGLISH))) { - mod.setVisibility(View.VISIBLE); - final Map reports = comment.getUserReports(); - final Map reports2 = comment.getModeratorReports(); - if (reports.size() + reports2.size() > 0) { - BlendModeUtil.tintImageViewAsSrcAtop( - mod, ContextCompat.getColor(mContext, R.color.md_red_300)); - } else { - BlendModeUtil.tintImageViewAsSrcAtop(mod, Color.WHITE); - } - mod.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - CommentAdapterHelper.showModBottomSheet(CommentAdapter.this, mContext, - baseNode, comment, holder, reports, reports2); - } - }); - } else { - mod.setVisibility(View.GONE); - } - - final ImageView edit = baseView.findViewById(R.id.edit); - if (Authentication.name != null - && Authentication.name.toLowerCase(Locale.ENGLISH) - .equals(comment.getAuthor().toLowerCase(Locale.ENGLISH)) - && Authentication.didOnline) { - edit.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - CommentAdapterHelper.doCommentEdit(CommentAdapter.this, mContext, fm, - baseNode, baseNode.isTopLevel() ? submission.getSelftext() - : baseNode.getParent().getComment().getBody(), holder); - } - }); - } else { - edit.setVisibility(View.GONE); - } - - - final ImageView delete = baseView.findViewById(R.id.delete); - if (Authentication.name != null - && Authentication.name.toLowerCase(Locale.ENGLISH) - .equals(comment.getAuthor().toLowerCase(Locale.ENGLISH)) - && Authentication.didOnline) { - delete.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - CommentAdapterHelper.deleteComment(CommentAdapter.this, mContext, baseNode, - holder); - } - }); - } else { - delete.setVisibility(View.GONE); - } - - if (Authentication.isLoggedIn - && !submission.isArchived() - && !submission.isLocked() - && !(comment.getDataNode().has("locked") && comment.getDataNode().get("locked").asBoolean()) - && !deleted.contains(n.getFullName()) - && !comment.getAuthor().equals("[deleted]") - && Authentication.didOnline) { - if (isReplying) { - baseView.setVisibility(View.VISIBLE); - - final int widthSpec = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - baseView.measure(widthSpec, heightSpec); - - View l2 = baseView.findViewById(R.id.replyArea) == null ? baseView.findViewById( - R.id.innerSend) : baseView.findViewById(R.id.replyArea); - final int widthSpec2 = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - final int heightSpec2 = - View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - l2.measure(widthSpec2, heightSpec2); - RelativeLayout.LayoutParams params2 = - (RelativeLayout.LayoutParams) baseView.getLayoutParams(); - params2.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - params2.addRule(RelativeLayout.BELOW, R.id.commentOverflow); - baseView.setLayoutParams(params2); - replyArea.setVisibility(View.VISIBLE); - menu.setVisibility(View.GONE); - currentlyEditing = replyLine; - currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - mPage.fastScroll.setVisibility(View.GONE); - if (mPage.fab != null) { - mPage.fab.setVisibility(View.GONE); - } - mPage.overrideFab = true; - } else if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - if (mPage.fab != null) { - mPage.fab.setVisibility(View.VISIBLE); - } - mPage.overrideFab = false; - } - } - }); - final TextView profile = baseView.findViewById(R.id.profile); - changedProfile = Authentication.name; - profile.setText("/u/" + changedProfile); - profile.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final HashMap accounts = new HashMap<>(); - - for (String s : Authentication.authentication.getStringSet("accounts", - new HashSet())) { - if (s.contains(":")) { - accounts.put(s.split(":")[0], s.split(":")[1]); - } else { - accounts.put(s, ""); - } - } - final ArrayList keys = new ArrayList<>(accounts.keySet()); - final int i = keys.indexOf(changedProfile); - - new AlertDialog.Builder(mContext) - .setTitle(R.string.sorting_choose) - .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { - changedProfile = keys.get(which); - profile.setText("/u/" + changedProfile); - }) - .setNegativeButton(R.string.btn_cancel, null) - .show(); - } - }); - replyLine.requestFocus(); - KeyboardUtil.toggleKeyboard(mContext, - InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); - - currentlyEditingId = n.getFullName(); - replyLine.setText(backedText); - replyLine.addTextChangedListener(new SimpleTextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - backedText = s.toString(); - } - }); - editingPosition = holder.getBindingAdapterPosition(); - } - reply.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - expandAndSetParams(baseView); - - //If the base theme is Light or Sepia, tint the Editor actions to be white - if (SettingValues.currentTheme == 1 || SettingValues.currentTheme == 5) { - final ImageView saveDraft = (ImageView) replyArea.findViewById(R.id.savedraft); - final ImageView draft = (ImageView) replyArea.findViewById(R.id.draft); - final ImageView imagerep = (ImageView) replyArea.findViewById(R.id.imagerep); - final ImageView link = (ImageView) replyArea.findViewById(R.id.link); - final ImageView bold = (ImageView) replyArea.findViewById(R.id.bold); - final ImageView italics = (ImageView) replyArea.findViewById(R.id.italics); - final ImageView bulletlist = (ImageView) replyArea.findViewById(R.id.bulletlist); - final ImageView numlist = (ImageView) replyArea.findViewById(R.id.numlist); - final ImageView draw = (ImageView) replyArea.findViewById(R.id.draw); - final ImageView quote = (ImageView) replyArea.findViewById(R.id.quote); - final ImageView size = (ImageView) replyArea.findViewById(R.id.size); - final ImageView strike = (ImageView) replyArea.findViewById(R.id.strike); - final ImageView author = (ImageView) replyArea.findViewById(R.id.author); - final ImageView spoiler = (ImageView) replyArea.findViewById(R.id.spoiler); - final List imageViewSet = Arrays.asList( - saveDraft, draft, imagerep, link, bold, italics, bulletlist, - numlist, draw, quote, size, strike, author, spoiler); - BlendModeUtil.tintImageViewsAsSrcAtop(imageViewSet, Color.WHITE); - BlendModeUtil.tintDrawableAsSrcIn(replyLine.getBackground(), Color.WHITE); - } - - replyArea.setVisibility(View.VISIBLE); - menu.setVisibility(View.GONE); - currentlyEditing = replyLine; - DoEditorActions.doActions(currentlyEditing, replyArea, fm, - (Activity) mContext, comment.getBody(), getParents(baseNode)); - currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - mPage.fastScroll.setVisibility(View.GONE); - if (mPage.fab != null) mPage.fab.setVisibility(View.GONE); - mPage.overrideFab = true; - } else if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - } - } - }); - final TextView profile = baseView.findViewById(R.id.profile); - changedProfile = Authentication.name; - profile.setText("/u/" + changedProfile); - profile.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final HashMap accounts = new HashMap<>(); - - for (String s : Authentication.authentication.getStringSet( - "accounts", new HashSet())) { - if (s.contains(":")) { - accounts.put(s.split(":")[0], s.split(":")[1]); - } else { - accounts.put(s, ""); - } - } - final ArrayList keys = new ArrayList<>(accounts.keySet()); - final int i = keys.indexOf(changedProfile); - - new AlertDialog.Builder(mContext) - .setTitle(R.string.sorting_choose) - .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { - changedProfile = keys.get(which); - profile.setText("/u/" + changedProfile); - }) - .setNegativeButton(R.string.btn_cancel, null) - .show(); - } - }); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - replyLine.setOnFocusChangeListener((view, b) -> { - if (b) { - view.postDelayed(() -> { - if (!view.hasFocus()) - view.requestFocus(); - }, 100); - } - }); - } - replyLine.requestFocus(); // TODO: Not working when called a second time - KeyboardUtil.toggleKeyboard(mContext, - InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); - - currentlyEditingId = n.getFullName(); - replyLine.addTextChangedListener(new SimpleTextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - backedText = s.toString(); - } - }); - editingPosition = holder.getBindingAdapterPosition(); - } - }); - send.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - currentlyEditingId = ""; - backedText = ""; - - doShowMenu(baseView); - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - } - dataSet.refreshLayout.setRefreshing(true); - if (currentlyEditing != null) { - String text = currentlyEditing.getText().toString(); - new ReplyTaskComment(n, baseNode, holder, changedProfile).execute(text); - currentlyEditing = null; - editingPosition = -1; - } - //Hide soft keyboard - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - } - }); - discard.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - currentlyEditing = null; - editingPosition = -1; - currentlyEditingId = ""; - backedText = ""; - mPage.overrideFab = false; - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - doShowMenu(baseView); - } - }); - } else { - if (reply.getVisibility() == View.VISIBLE) { - reply.setVisibility(View.GONE); - } - if ((submission.isArchived() - || deleted.contains(n.getFullName()) - || comment.getAuthor().equals("[deleted]")) - && Authentication.isLoggedIn - && Authentication.didOnline - && upvote.getVisibility() == View.VISIBLE) { - upvote.setVisibility(View.GONE); - } - if ((submission.isArchived() - || deleted.contains(n.getFullName()) - || comment.getAuthor().equals("[deleted]")) - && Authentication.isLoggedIn - && Authentication.didOnline - && downvote.getVisibility() == View.VISIBLE) { - downvote.setVisibility(View.GONE); - } - } - - more.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - CommentAdapterHelper.showOverflowBottomSheet(CommentAdapter.this, mContext, - holder, baseNode); - } - }); - upvote.setOnClickListener(new OnSingleClickListener() { - - @Override - public void onSingleClick(View v) { - setCommentStateUnhighlighted(holder, comment, baseNode, true); - if (ActionStates.getVoteDirection(comment) == VoteDirection.UPVOTE) { - new Vote(v, mContext).execute(n); - ActionStates.setVoteDirection(comment, VoteDirection.NO_VOTE); - doScoreText(holder, n, CommentAdapter.this); - upvote.clearColorFilter(); - } else { - new Vote(true, v, mContext).execute(n); - ActionStates.setVoteDirection(comment, VoteDirection.UPVOTE); - downvote.clearColorFilter(); // reset colour - doScoreText(holder, n, CommentAdapter.this); - BlendModeUtil.tintImageViewAsModulate(upvote, holder.textColorUp); - } - } - }); - downvote.setOnClickListener(new OnSingleClickListener() { - - @Override - public void onSingleClick(View v) { - setCommentStateUnhighlighted(holder, comment, baseNode, true); - if (ActionStates.getVoteDirection(comment) == VoteDirection.DOWNVOTE) { - new Vote(v, mContext).execute(n); - ActionStates.setVoteDirection(comment, VoteDirection.NO_VOTE); - doScoreText(holder, n, CommentAdapter.this); - downvote.clearColorFilter(); - - } else { - new Vote(false, v, mContext).execute(n); - ActionStates.setVoteDirection(comment, VoteDirection.DOWNVOTE); - upvote.clearColorFilter(); // reset colour - doScoreText(holder, n, CommentAdapter.this); - BlendModeUtil.tintImageViewAsModulate(downvote, holder.textColorDown); - } - } - }); - menu.setBackgroundColor(color); - replyArea.setBackgroundColor(color); - - if (!isReplying) { - menu.setVisibility(View.VISIBLE); - replyArea.setVisibility(View.GONE); - } - - holder.itemView.findViewById(R.id.background) - .setBackgroundColor(Color.argb(50, Color.red(color), Color.green(color), - Color.blue(color))); - } - } - - public void doHighlighted(final CommentViewHolder holder, final Comment n, - final CommentNode baseNode, boolean animate) { - if (mAnimator != null && mAnimator.isRunning()) { - holder.itemView.postDelayed(new Runnable() { - @Override - public void run() { - setCommentStateHighlighted(holder, n, baseNode, false, true); - } - }, mAnimator.getDuration()); - } else { - setCommentStateHighlighted(holder, n, baseNode, false, animate); - } - } - - public EditText currentlyEditing; - - public void resetMenu(LinearLayout v, boolean collapsed) { - v.removeAllViews(); - RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams(); - if (collapsed) { - params.height = 0; - } else { - params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; - } - v.setLayoutParams(params); - } - - public void setCommentStateUnhighlighted(final CommentViewHolder holder, - final CommentNode baseNode, boolean animate) { - if (animate) { - collapseAndRemove(holder.menuArea); - } else { - resetMenu(holder.menuArea, true); - } - - int color; - - Comment c = baseNode.getComment(); - if (lastSeen != 0 - && lastSeen < c.getCreated().getTime() - && !dataSet.single - && SettingValues.commentLastVisit - && !Authentication.name.equals(c.getAuthor())) { - color = Palette.getColor(baseNode.getComment().getSubredditName()); - color = Color.argb(20, Color.red(color), Color.green(color), Color.blue(color)); - } else { - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = mContext.getTheme(); - theme.resolveAttribute(R.attr.card_background, typedValue, true); - color = typedValue.data; - } - int dwidth = (int) (3 * Resources.getSystem().getDisplayMetrics().density); - int width = 0; - - //Padding on the left, starting with the third comment - for (int i = 2; i < baseNode.getDepth(); i++) { - width += dwidth; - } - RecyclerView.LayoutParams params = - (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); - params.setMargins(width, 0, 0, 0); - holder.itemView.setLayoutParams(params); - - holder.itemView.findViewById(R.id.background).setBackgroundColor(color); - } - - public void setCommentStateUnhighlighted(final CommentViewHolder holder, final Comment comment, - final CommentNode baseNode, boolean animate) { - if (currentlyEditing != null - && !currentlyEditing.getText().toString().isEmpty() - && holder.getBindingAdapterPosition() <= editingPosition) { - new AlertDialog.Builder(mContext) - .setTitle(R.string.discard_comment_title) - .setMessage(R.string.comment_discard_msg) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> { - currentlyEditing = null; - editingPosition = -1; - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - } - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - currentlyEditingId = ""; - backedText = ""; - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - if (mContext instanceof BaseActivity) { - ((BaseActivity) mContext).setShareUrl( - "https://reddit.com" + submission.getPermalink()); - } - - setCommentStateUnhighlighted(holder, comment, baseNode, true); - - }) - .setNegativeButton(R.string.btn_no, null) - .show(); - } else { - if (mContext instanceof BaseActivity) { - ((BaseActivity) mContext).setShareUrl( - "https://freddit.com" + submission.getPermalink()); - } - currentlySelected = null; - currentSelectedItem = ""; - if (animate) { - collapseAndRemove(holder.menuArea); - } else { - resetMenu(holder.menuArea, true); - } - int dwidth = (int) (3 * Resources.getSystem().getDisplayMetrics().density); - int width = 0; - - //Padding on the left, starting with the third comment - for (int i = 2; i < baseNode.getDepth(); i++) { - width += dwidth; - } - RecyclerView.LayoutParams params = - (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); - params.setMargins(width, 0, 0, 0); - holder.itemView.setLayoutParams(params); - - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = mContext.getTheme(); - theme.resolveAttribute(R.attr.card_background, typedValue, true); - int color = typedValue.data; - holder.itemView.findViewById(R.id.background).setBackgroundColor(color); - } - } - - public void doLongClick(final CommentViewHolder holder, final Comment comment, - final CommentNode baseNode) { - if (currentlyEditing != null && !currentlyEditing.getText().toString().isEmpty()) { - new AlertDialog.Builder(mContext) - .setTitle(R.string.discard_comment_title) - .setMessage(R.string.comment_discard_msg) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> { - currentlyEditing = null; - editingPosition = -1; - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - } - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - currentlyEditingId = ""; - backedText = ""; - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - - doLongClick(holder, comment, baseNode); - }) - .setNegativeButton(R.string.btn_no, null) - .show(); - - } else { - if (currentSelectedItem != null && currentSelectedItem.contains( - comment.getFullName())) { - setCommentStateUnhighlighted(holder, comment, baseNode, true); - } else { - doHighlighted(holder, comment, baseNode, true); - } - } - } - - public void doOnClick(CommentViewHolder holder, Comment comment, CommentNode baseNode) { - if (currentSelectedItem != null && currentSelectedItem.contains(comment.getFullName())) { - if (SettingValues.swap) { - //If the comment is highlighted and the user is long pressing the comment, - //hide the comment. - doOnClick(holder, baseNode, comment); - } - setCommentStateUnhighlighted(holder, comment, baseNode, true); - } else { - doOnClick(holder, baseNode, comment); - } - } - - public void doOnClick(final CommentViewHolder holder, final CommentNode baseNode, - final Comment comment) { - if (currentlyEditing != null - && !currentlyEditing.getText().toString().isEmpty() - && holder.getBindingAdapterPosition() <= editingPosition) { - new AlertDialog.Builder(mContext) - .setTitle(R.string.discard_comment_title) - .setMessage(R.string.comment_discard_msg) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> { - currentlyEditing = null; - editingPosition = -1; - if (SettingValues.fastscroll) { - mPage.fastScroll.setVisibility(View.VISIBLE); - } - if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); - mPage.overrideFab = false; - currentlyEditingId = ""; - backedText = ""; - View view = ((Activity) mContext).findViewById(android.R.id.content); - if (view != null) { - KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); - } - - doOnClick(holder, baseNode, comment); - - }) - .setNegativeButton(R.string.btn_no, null) - .show(); - - } else { - if (isClicking) { - isClicking = false; - resetMenu(holder.menuArea, true); - isHolder.itemView.findViewById(R.id.menu).setVisibility(View.GONE); - } else { - if (hiddenPersons.contains(comment.getFullName())) { - hiddenPersons.remove(comment.getFullName()); - unhideAll(baseNode, holder.getBindingAdapterPosition() + 1); - - if (toCollapse.contains(comment.getFullName()) - && SettingValues.collapseComments) { - setViews(comment.getDataNode().get("body_html").asText(), - submission.getSubredditName(), holder); - } - - CommentAdapterHelper.hideChildrenObject(holder.childrenNumber); - if (!holder.firstTextView.getText().toString().isEmpty()) { - holder.firstTextView.setVisibility(View.VISIBLE); - } else { - holder.firstTextView.setVisibility(View.GONE); - } - holder.commentOverflow.setVisibility(View.VISIBLE); - - - toCollapse.remove(comment.getFullName()); - - } else { - int childNumber = getChildNumber(baseNode); - if (childNumber > 0) { - hideAll(baseNode, holder.getBindingAdapterPosition() + 1); - if (!hiddenPersons.contains(comment.getFullName())) { - hiddenPersons.add(comment.getFullName()); - } - if (childNumber > 0) { - CommentAdapterHelper.showChildrenObject(holder.childrenNumber); - holder.childrenNumber.setText("+" + childNumber); - } - } else { - if (!SettingValues.collapseComments) { - doLongClick(holder, comment, baseNode); - } - } - toCollapse.add(comment.getFullName()); - if ((holder.firstTextView.getVisibility() == View.VISIBLE - || holder.commentOverflow.getVisibility() == View.VISIBLE) - && SettingValues.collapseComments) { - holder.firstTextView.setVisibility(View.GONE); - holder.commentOverflow.setVisibility(View.GONE); - } else if (SettingValues.collapseComments) { - if (!holder.firstTextView.getText().toString().isEmpty()) { - holder.firstTextView.setVisibility(View.VISIBLE); - } else { - holder.firstTextView.setVisibility(View.GONE); - } - holder.commentOverflow.setVisibility(View.VISIBLE); - } - } - clickpos = holder.getBindingAdapterPosition() + 1; - } - } - } - - private int getChildNumber(CommentNode user) { - int i = 0; - for (CommentNode ignored : user.walkTree()) { - i++; - if (ignored.hasMoreComments() && dataSet.online) { - i++; - } - } - - return i - 1; - } - - @Override - public int getItemViewType(int position) { - if (position == 0 || (currentComments != null - && !currentComments.isEmpty() - && position == (currentComments.size() - hidden.size()) + 2) || (currentComments - != null && currentComments.isEmpty() && position == 2)) { - return SPACER; - } else { - position -= 1; - } - if (position == 0) { - return HEADER; - } - - return (currentComments.get(getRealPosition(position - 1)) instanceof CommentItem ? 2 : 3); - } - - @Override - public int getItemCount() { - if (currentComments == null) { - return 2; - } else { - return 3 + (currentComments.size() - hidden.size()); - } - } - - public void unhideAll(CommentNode n, int i) { - try { - int counter = unhideNumber(n, 0); - if (SettingValues.collapseComments) { - listView.setItemAnimator(null); - } else { - try { - listView.setItemAnimator(new AlphaInAnimator()); - } catch (Exception ignored) { - } - } - notifyItemRangeInserted(i, counter); - } catch (Exception ignored) { - - } - } - - public void unhideAll(CommentNode n) { - unhideNumber(n, 0); - if (SettingValues.collapseComments) { - listView.setItemAnimator(null); - } else { - listView.setItemAnimator(new AlphaInAnimator()); - } - notifyDataSetChanged(); - } - - public void hideAll(CommentNode n) { - - hideNumber(n, 0); - if (SettingValues.collapseComments) { - listView.setItemAnimator(null); - } else { - listView.setItemAnimator(new AlphaInAnimator()); - } - notifyDataSetChanged(); - - } - - public void hideAll(CommentNode n, int i) { - - int counter = hideNumber(n, 0); - if (SettingValues.collapseComments) { - listView.setItemAnimator(null); - } else { - listView.setItemAnimator(new AlphaInAnimator()); - } - notifyItemRangeRemoved(i, counter); - - } - - public boolean parentHidden(CommentNode n) { - n = n.getParent(); - while (n != null && n.getDepth() > 0) { - String name = n.getComment().getFullName(); - if (hiddenPersons.contains(name) || hidden.contains(name)) { - return true; - } - n = n.getParent(); - } - return false; - } - - public int unhideNumber(CommentNode n, int i) { - for (CommentNode ignored : n.getChildren()) { - - if (!ignored.getComment().getFullName().equals(n.getComment().getFullName())) { - boolean parentHidden = parentHidden(ignored); - - if (parentHidden) { - continue; - } - - String name = ignored.getComment().getFullName(); - - if (hidden.contains(name) || hiddenPersons.contains(name)) { - hidden.remove(name); - i++; - - if (ignored.hasMoreComments() - && !hiddenPersons.contains(name) - && dataSet.online) { - name = name + "more"; - if (hidden.contains(name)) { - hidden.remove(name); - toCollapse.remove(name); - i++; - } - } - } - i += unhideNumber(ignored, 0); - } - } - if (n.hasMoreComments() && !parentHidden(n) && !hiddenPersons.contains( - n.getComment().getFullName()) && dataSet.online) { - String fullname = n.getComment().getFullName() + "more"; - - if (hidden.contains(fullname)) { - i++; - hidden.remove(fullname); - } - } - return i; - } - - public int hideNumber(CommentNode n, int i) { - for (CommentNode ignored : n.getChildren()) { - if (!ignored.getComment().getFullName().equals(n.getComment().getFullName())) { - String fullname = ignored.getComment().getFullName(); - - if (!hidden.contains(fullname)) { - i++; - hidden.add(fullname); - } - if (ignored.hasMoreComments() && dataSet.online) { - if (currentLoading != null && currentLoading.fullname.equals(fullname)) { - currentLoading.cancel(true); - } - - fullname = fullname + "more"; - - if (!hidden.contains(fullname)) { - i++; - hidden.add(fullname); - } - } - i += hideNumber(ignored, 0); - } - - } - if (n.hasMoreComments() && dataSet.online) { - String fullname = n.getComment().getFullName() + "more"; - if (!hidden.contains(fullname)) { - i++; - hidden.add(fullname); - } - } - return i; - } - - public String[] getParents(CommentNode comment) { - String[] bodies = new String[comment.getDepth() + 1]; - bodies[0] = comment.getComment().getAuthor(); - - CommentNode parent = comment.getParent(); - int index = 1; - - while (parent != null) { - bodies[index] = parent.getComment().getAuthor(); - index++; - parent = parent.getParent(); - } - - bodies[index - 1] = submission.getAuthor(); - - //Reverse the array so Submission > Author > ... > Current OP - for (int i = 0; i < bodies.length / 2; i++) { - String temp = bodies[i]; - bodies[i] = bodies[bodies.length - i - 1]; - bodies[bodies.length - i - 1] = temp; - } - - - return bodies; - } - - public int getRealPosition(int position) { - int hElements = getHiddenCountUpTo(position); - int diff = 0; - for (int i = 0; i < hElements; i++) { - diff++; - if ((currentComments.size() > position + diff) && hidden.contains( - currentComments.get(position + diff).getName())) { - i--; - } - } - return (position + diff); - } - - private int getHiddenCountUpTo(int location) { - int count = 0; - for (int i = 0; (i <= location && i < currentComments.size()); i++) { - if (currentComments.size() > i && hidden.contains(currentComments.get(i).getName())) { - count++; - } - } - return count; - } - - public class AsyncLoadMore extends AsyncTask { - public MoreCommentViewHolder holder; - public int holderPos; - public int position; - public int dataPos; - public String fullname; - - public AsyncLoadMore(int position, int holderPos, MoreCommentViewHolder holder, int dataPos, - String fullname) { - this.holderPos = holderPos; - this.holder = holder; - this.position = position; - this.dataPos = dataPos; - this.fullname = fullname; - } - - @Override - public void onPostExecute(Integer data) { - currentLoading = null; - if (!isCancelled() && data != null) { - shifted += data; - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - currentComments.remove(position); - notifyItemRemoved(holderPos); - } - }); - int oldSize = currentComments.size(); - currentComments.addAll(position, finalData); - int newSize = currentComments.size(); - - for (int i2 = 0; i2 < currentComments.size(); i2++) { - keys.put(currentComments.get(i2).getName(), i2); - } - data = newSize - oldSize; - listView.setItemAnimator(new SlideRightAlphaAnimator()); - notifyItemRangeInserted(holderPos, data); - currentPos = holderPos; - toShiftTo = - ((LinearLayoutManager) listView.getLayoutManager()).findLastVisibleItemPosition(); - shiftFrom = - ((LinearLayoutManager) listView.getLayoutManager()).findFirstVisibleItemPosition(); - - } else if (data == null && currentComments.get(dataPos) instanceof MoreChildItem) { - final MoreChildItem baseNode = (MoreChildItem) currentComments.get(dataPos); - if (baseNode.children.getCount() > 0) { - holder.content.setText(mContext.getString(R.string.comment_load_more, - baseNode.children.getCount())); - } else if (!baseNode.children.getChildrenIds().isEmpty()) { - holder.content.setText(R.string.comment_load_more_number_unknown); - } else { - holder.content.setText(R.string.thread_continue); - } - holder.loading.setVisibility(View.GONE); - } - } - - ArrayList finalData; - - @Override - protected Integer doInBackground(MoreChildItem... params) { - finalData = new ArrayList<>(); - int i = 0; - if (params.length > 0) { - try { - CommentNode node = params[0].comment; - node.loadMoreComments(Authentication.reddit); - HashMap waiting = new HashMap<>(); - - for (CommentNode n : node.walkTree()) { - if (!keys.containsKey(n.getComment().getFullName())) { - - CommentObject obj = new CommentItem(n); - ArrayList removed = new ArrayList<>(); - Map map = - new TreeMap<>(Collections.reverseOrder()); - map.putAll(waiting); - - for (Integer i2 : map.keySet()) { - if (i2 >= n.getDepth()) { - finalData.add(waiting.get(i2)); - removed.add(i2); - waiting.remove(i2); - i++; - - } - } - - finalData.add(obj); - i++; - - if (n.hasMoreComments()) { - waiting.put(n.getDepth(), - new MoreChildItem(n, n.getMoreChildren())); - } - } - } - if (node.hasMoreComments()) { - finalData.add(new MoreChildItem(node, node.getMoreChildren())); - i++; - } - } catch (Exception e) { - Log.w(LogUtil.getTag(), "Cannot load more comments " + e); - Writer writer = new StringWriter(); - PrintWriter printWriter = new PrintWriter(writer); - e.printStackTrace(printWriter); - String stacktrace = writer.toString().replace(";", ","); - if (stacktrace.contains("UnknownHostException") || stacktrace.contains( - "SocketTimeoutException") || stacktrace.contains("ConnectException")) { - //is offline - final Handler mHandler = new Handler(Looper.getMainLooper()); - mHandler.post(new Runnable() { - @Override - public void run() { - try { - new AlertDialog.Builder(mContext) - .setTitle(R.string.err_title) - .setMessage(R.string.err_connection_failed_msg) - .setNegativeButton(R.string.btn_ok, null) - .show(); - } catch (Exception ignored) { - - } - } - } - - ); - } else if (stacktrace.contains("403 Forbidden") || stacktrace.contains( - "401 Unauthorized")) { - //Un-authenticated - final Handler mHandler = new Handler(Looper.getMainLooper()); - mHandler.post(new Runnable() { - @Override - public void run() { - try { - new AlertDialog.Builder(mContext) - .setTitle(R.string.err_title) - .setMessage(R.string.err_refused_request_msg) - .setNegativeButton(R.string.btn_no, null) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> - Reddit.authentication.updateToken(mContext)) - .show(); - } catch (Exception ignored) { - - } - } - }); - - } else if (stacktrace.contains("404 Not Found") || stacktrace.contains( - "400 Bad Request")) { - final Handler mHandler = new Handler(Looper.getMainLooper()); - mHandler.post(new Runnable() { - @Override - public void run() { - try { - new AlertDialog.Builder(mContext). - setTitle(R.string.err_title) - .setMessage(R.string.err_could_not_find_content_msg) - .setNegativeButton(R.string.btn_close, null) - .show(); - } catch (Exception ignored) { - - } - } - }); - } - return null; - } - } - return i; - } - } - - public class AsyncForceLoadChild extends AsyncTask { - CommentNode node; - public int holderPos; - public int position; - - - public AsyncForceLoadChild(int position, int holderPos, CommentNode baseNode) { - this.holderPos = holderPos; - this.node = baseNode; - this.position = position; - } - - @Override - public void onPostExecute(Integer data) { - if (data != -1) { - listView.setItemAnimator(new SlideRightAlphaAnimator()); - - notifyItemInserted(holderPos + 1); - - currentPos = holderPos + 1; - toShiftTo = - ((LinearLayoutManager) listView.getLayoutManager()).findLastVisibleItemPosition(); - shiftFrom = - ((LinearLayoutManager) listView.getLayoutManager()).findFirstVisibleItemPosition(); - - dataSet.refreshLayout.setRefreshing(false); - } else { - //Comment could not be found, force a reload - Handler handler2 = new Handler(); - handler2.postDelayed(new Runnable() { - public void run() { - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - dataSet.refreshLayout.setRefreshing(false); - dataSet.loadMoreReply(CommentAdapter.this); - } - }); - } - }, 2000); - } - } - - @Override - protected Integer doInBackground(String... params) { - - int i = 0; - - if (params.length > 0) { - try { - node.insertComment(Authentication.reddit, "t1_" + params[0]); - for (CommentNode n : node.walkTree()) { - if (n.getComment().getFullName().contains(params[0])) { - currentComments.add(position, new CommentItem(n)); - i++; - } - } - - } catch (Exception e) { - Log.w(LogUtil.getTag(), "Cannot load more comments " + e); - i = -1; - } - - shifted += i; - - if (currentComments != null) { - for (int i2 = 0; i2 < currentComments.size(); i2++) { - keys.put(currentComments.get(i2).getName(), i2); - } - } else { - i = -1; - } - } - return i; - } - } - - public void editComment(CommentNode n, CommentViewHolder holder) { - if (n == null) { - dataSet.loadMoreReply(this); - } else { - int position = getRealPosition(holder.getBindingAdapterPosition() - 1); - final int holderpos = holder.getBindingAdapterPosition(); - currentComments.remove(position - 1); - currentComments.add(position - 1, new CommentItem(n)); - listView.setItemAnimator(new SlideRightAlphaAnimator()); - ((Activity) mContext).runOnUiThread(new Runnable() { - @Override - public void run() { - notifyItemChanged(holderpos); - } - }); - } - } - - - public class ReplyTaskComment extends AsyncTask { - public Contribution sub; - CommentNode node; - CommentViewHolder holder; - boolean isSubmission; - String profileName; - - public ReplyTaskComment(Contribution n, CommentNode node, CommentViewHolder holder, - String profileName) { - sub = n; - this.holder = holder; - this.node = node; - this.profileName = profileName; - } - - public ReplyTaskComment(Contribution n, String profileName) { - sub = n; - isSubmission = true; - this.profileName = profileName; - } - - @Override - public void onPostExecute(final String s) { - if (s == null || s.isEmpty()) { - - if (commentBack != null && !commentBack.isEmpty()) { - Drafts.addDraft(commentBack); - try { - new AlertDialog.Builder(mContext) - .setTitle(R.string.err_comment_post) - .setMessage(((why == null) ? "" - : mContext.getString(R.string.err_comment_post_reason, why)) - + mContext.getString(R.string.err_comment_post_message)) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } catch (Exception ignored) { - - } - } else { - try { - new AlertDialog.Builder(mContext) - .setTitle(R.string.err_comment_post) - .setMessage(((why == null) ? "" - : mContext.getString(R.string.err_comment_post_reason, why)) - + mContext.getString(R.string.err_comment_post_nosave_message)) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } catch (Exception ignored) { - - } - } - } else { - if (isSubmission) { - new AsyncForceLoadChild(0, 0, submission.getComments()).execute(s); - } else { - new AsyncForceLoadChild(getRealPosition(holder.getBindingAdapterPosition() - 1), - holder.getBindingAdapterPosition(), node).execute(s); - } - } - } - - String why; - String commentBack; - - @Override - protected String doInBackground(String... comment) { - if (Authentication.me != null) { - try { - commentBack = comment[0]; - if (profileName.equals(Authentication.name)) { - return new AccountManager(Authentication.reddit).reply(sub, comment[0]); - } else { - LogUtil.v("Switching to " + profileName); - return new AccountManager(getAuthenticatedClient(profileName)).reply(sub, - comment[0]); - } - } catch (Exception e) { - if (e instanceof ApiException) { - why = ((ApiException) e).getExplanation(); - } - return null; - } - } else { - return null; - } - } - } - - private RedditClient getAuthenticatedClient(String profileName) { - String token; - RedditClient reddit = new RedditClient( - UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME)); - final HashMap accounts = new HashMap<>(); - - for (String s : Authentication.authentication.getStringSet("accounts", - new HashSet())) { - if (s.contains(":")) { - accounts.put(s.split(":")[0], s.split(":")[1]); - } else { - accounts.put(s, ""); - } - } - final ArrayList keys = new ArrayList<>(accounts.keySet()); - if (accounts.containsKey(profileName) && !accounts.get(profileName).isEmpty()) { - token = accounts.get(profileName); - } else { - ArrayList tokens = new ArrayList<>( - Authentication.authentication.getStringSet("tokens", new HashSet())); - int index = keys.indexOf(profileName); - if (keys.indexOf(profileName) > tokens.size()) { - index -= 1; - } - token = tokens.get(index); - } - Authentication.doVerify(token, reddit, true, mContext); - return reddit; - } -} +package me.ccrama.redditslide.Adapters; + +/** + * Created by ccrama on 3/22/2015. + */ + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Typeface; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.devspark.robototextview.RobotoTypefaces; +import com.lusfold.androidkeyvaluestore.KVStore; +import com.mikepenz.itemanimators.AlphaInAnimator; +import com.mikepenz.itemanimators.SlideRightAlphaAnimator; +import com.nostra13.universalimageloader.utils.DiskCacheUtils; + +import net.dean.jraw.ApiException; +import net.dean.jraw.RedditClient; +import net.dean.jraw.http.UserAgent; +import net.dean.jraw.managers.AccountManager; +import net.dean.jraw.models.Comment; +import net.dean.jraw.models.CommentNode; +import net.dean.jraw.models.Contribution; +import net.dean.jraw.models.Submission; +import net.dean.jraw.models.VoteDirection; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; + +import me.ccrama.redditslide.ActionStates; +import me.ccrama.redditslide.Activities.BaseActivity; +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.BuildConfig; +import me.ccrama.redditslide.Constants; +import me.ccrama.redditslide.Drafts; +import me.ccrama.redditslide.Fragments.CommentPage; +import me.ccrama.redditslide.HasSeen; +import me.ccrama.redditslide.ImageFlairs; +import me.ccrama.redditslide.LastComments; +import me.ccrama.redditslide.OpenRedditLink; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.Reddit; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.SpoilerRobotoTextView; +import me.ccrama.redditslide.SubmissionViews.PopulateSubmissionViewHolder; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Views.CommentOverflow; +import me.ccrama.redditslide.Views.DoEditorActions; +import me.ccrama.redditslide.Views.PreCachingLayoutManagerComments; +import me.ccrama.redditslide.Visuals.FontPreferences; +import me.ccrama.redditslide.Visuals.Palette; +import me.ccrama.redditslide.Vote; +import me.ccrama.redditslide.util.AnimatorUtil; +import me.ccrama.redditslide.util.BlendModeUtil; +import me.ccrama.redditslide.util.DisplayUtil; +import me.ccrama.redditslide.util.KeyboardUtil; +import me.ccrama.redditslide.util.LogUtil; +import me.ccrama.redditslide.util.OnSingleClickListener; +import me.ccrama.redditslide.util.SubmissionParser; +import me.ccrama.redditslide.util.stubs.SimpleTextWatcher; + + +public class CommentAdapter extends RecyclerView.Adapter { + + final static int HEADER = 1; + private final int SPACER = 6; + public final Bitmap[] awardIcons; + public Context mContext; + public SubmissionComments dataSet; + public Submission submission; + public CommentViewHolder currentlySelected; + public CommentNode currentNode; + public String currentSelectedItem = ""; + public int shiftFrom; + public FragmentManager fm; + public int clickpos; + public int currentPos; + public CommentViewHolder isHolder; + public boolean isClicking; + public HashMap keys = new HashMap<>(); + public ArrayList currentComments; + public ArrayList deleted = new ArrayList<>(); + RecyclerView listView; + CommentPage mPage; + int shifted; + int toShiftTo; + HashSet hidden; + ArrayList hiddenPersons; + ArrayList toCollapse; + private String backedText = ""; + private String currentlyEditingId = ""; + public SubmissionViewHolder submissionViewHolder; + long lastSeen = 0; + public ArrayList approved = new ArrayList<>(); + public ArrayList removed = new ArrayList<>(); + + public CommentAdapter(CommentPage mContext, SubmissionComments dataSet, RecyclerView listView, + Submission submission, FragmentManager fm) { + this.mContext = mContext.getContext(); + mPage = mContext; + this.listView = listView; + this.dataSet = dataSet; + this.fm = fm; + + this.submission = submission; + hidden = new HashSet<>(); + currentComments = dataSet.comments; + if (currentComments != null) { + for (int i = 0; i < currentComments.size(); i++) { + keys.put(currentComments.get(i).getName(), i); + } + } + hiddenPersons = new ArrayList<>(); + toCollapse = new ArrayList<>(); + + shifted = 0; + + // As per reddit API gids: 0=silver, 1=gold, 2=platinum + awardIcons = new Bitmap[] { + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.silver), + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.gold), + BitmapFactory.decodeResource(mContext.getResources(), R.drawable.platinum), + }; + } + + public void reset(Context mContext, SubmissionComments dataSet, RecyclerView listView, + Submission submission, boolean reset) { + + doTimes(); + + this.mContext = mContext; + this.listView = listView; + this.dataSet = dataSet; + + this.submission = submission; + hidden = new HashSet<>(); + currentComments = dataSet.comments; + if (currentComments != null) { + for (int i = 0; i < currentComments.size(); i++) { + keys.put(currentComments.get(i).getName(), i); + } + } + + hiddenPersons = new ArrayList<>(); + toCollapse = new ArrayList<>(); + + + if (currentSelectedItem != null && !currentSelectedItem.isEmpty() && !reset) { + notifyDataSetChanged(); + } else { + if (currentComments != null && !reset) { + notifyItemRangeChanged(2, currentComments.size() + 1); + } else if (currentComments == null) { + currentComments = new ArrayList<>(); + notifyDataSetChanged(); + } else { + notifyDataSetChanged(); + } + } + + if (currentSelectedItem != null + && !currentSelectedItem.isEmpty() + && currentComments != null + && !currentComments.isEmpty()) { + int i = 2; + for (CommentObject n : currentComments) { + if (n instanceof CommentItem && n.comment.getComment() + .getFullName() + .contains(currentSelectedItem)) { + ((PreCachingLayoutManagerComments) listView.getLayoutManager()).scrollToPositionWithOffset( + i, mPage.headerHeight); + break; + } + i++; + } + mPage.resetScroll(true); + } + if (mContext instanceof BaseActivity) { + ((BaseActivity) mContext).setShareUrl("https://reddit.com" + submission.getPermalink()); + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { + switch (i) { + case SPACER: { + View v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.spacer_post, viewGroup, false); + return new SpacerViewHolder(v); + } + case HEADER: { + View v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.submission_fullscreen, viewGroup, false); + return new SubmissionViewHolder(v); + } + case 2: { + View v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.comment, viewGroup, false); + return new CommentViewHolder(v); + } + default: { + View v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.morecomment, viewGroup, false); + return new MoreCommentViewHolder(v); + } + } + + + } + + public static class SpacerViewHolder extends RecyclerView.ViewHolder { + public SpacerViewHolder(View itemView) { + super(itemView); + } + } + + public void expandAll() { + if (currentComments == null) return; + for (CommentObject o : currentComments) { + if (o.comment.isTopLevel()) { + hiddenPersons.remove(o.comment.getComment().getFullName()); + unhideAll(o.comment); + } + } + notifyItemChanged(2); + } + + + public void collapseAll() { + if (currentComments == null) return; + for (CommentObject o : currentComments) { + if (o.comment.isTopLevel()) { + if (!hiddenPersons.contains(o.comment.getComment().getFullName())) { + hiddenPersons.add(o.comment.getComment().getFullName()); + } + hideAll(o.comment); + } + } + notifyItemChanged(2); + } + + public void doScoreText(CommentViewHolder holder, Comment comment, CommentAdapter adapter) { + holder.content.setText( + CommentAdapterHelper.getScoreString(comment, mContext, holder, submission, + adapter)); + } + + public void doTimes() { + if (submission != null && SettingValues.commentLastVisit && !dataSet.single && ( + SettingValues.storeHistory + && (!submission.isNsfw() || SettingValues.storeNSFWHistory))) { + lastSeen = HasSeen.getSeenTime(submission); + String fullname = submission.getFullName(); + if (fullname.contains("t3_")) { + fullname = fullname.substring(3); + } + HasSeen.seenTimes.put(fullname, System.currentTimeMillis()); + KVStore.getInstance().insert(fullname, String.valueOf(System.currentTimeMillis())); + } + if (submission != null) { + if (SettingValues.storeHistory) { + if (submission.isNsfw() && !SettingValues.storeNSFWHistory) { + } else { + HasSeen.addSeen(submission.getFullName()); + } + LastComments.setComments(submission); + } + } + } + + + @Override + public void onBindViewHolder(final RecyclerView.ViewHolder firstHolder, int old) { + int pos = old != 0 ? old - 1 : old; + if (firstHolder instanceof CommentViewHolder) { + final CommentViewHolder holder = (CommentViewHolder) firstHolder; + int datasetPosition = pos - 1; + + datasetPosition = getRealPosition(datasetPosition); + + if (pos > toShiftTo) { + shifted = 0; + } + if (pos < shiftFrom) { + shifted = 0; + } + + final CommentNode baseNode = currentComments.get(datasetPosition).comment; + final Comment comment = baseNode.getComment(); + + if (pos == getItemCount() - 1) { + holder.itemView.setPadding(0, 0, 0, (int) mContext.getResources() + .getDimension(R.dimen.overview_top_padding_single)); + } else { + holder.itemView.setPadding(0, 0, 0, 0); + } + + doScoreText(holder, comment, this); + + //Long click listeners + View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (SettingValues.swap) { + doOnClick(holder, comment, baseNode); + } else { + doLongClick(holder, comment, baseNode); + } + return true; + } + }; + + holder.firstTextView.setOnLongClickListener(onLongClickListener); + holder.commentOverflow.setOnLongClickListener(onLongClickListener); + + holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if (!currentlyEditingId.equals(comment.getFullName())) { + if (SettingValues.swap) { + doOnClick(holder, comment, baseNode); + } else { + doLongClick(holder, comment, baseNode); + } + } + return true; + } + }); + + //Single click listeners + OnSingleClickListener singleClick = new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + if (!currentlyEditingId.equals(comment.getFullName())) { + if (SettingValues.swap) { + doLongClick(holder, comment, baseNode); + } else { + doOnClick(holder, comment, baseNode); + } + } + } + }; + holder.itemView.setOnClickListener(singleClick); + holder.commentOverflow.setOnClickListener(singleClick); + if (!toCollapse.contains(comment.getFullName()) || !SettingValues.collapseComments) { + setViews(comment.getDataNode().get("body_html").asText(), + submission.getSubredditName(), holder, singleClick, onLongClickListener); + } + + holder.firstTextView.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + SpoilerRobotoTextView SpoilerRobotoTextView = (SpoilerRobotoTextView) v; + if (SettingValues.swap) { + if (!SpoilerRobotoTextView.isSpoilerClicked()) { + doLongClick(holder, comment, baseNode); + } else if (SpoilerRobotoTextView.isSpoilerClicked()) { + SpoilerRobotoTextView.resetSpoilerClicked(); + } + } else if (!SpoilerRobotoTextView.isSpoilerClicked()) { + doOnClick(holder, comment, baseNode); + } else if (SpoilerRobotoTextView.isSpoilerClicked()) { + SpoilerRobotoTextView.resetSpoilerClicked(); + } + } + }); + if (ImageFlairs.isSynced(comment.getSubredditName()) + && comment.getAuthorFlair() != null + && comment.getAuthorFlair().getCssClass() != null + && !comment.getAuthorFlair().getCssClass().isEmpty()) { + boolean set = false; + for (String s : comment.getAuthorFlair().getCssClass().split(" ")) { + ImageFlairs.FlairImageLoader loader = ImageFlairs.getFlairImageLoader(mContext); + File file = DiskCacheUtils.findInCache( + comment.getSubredditName().toLowerCase(Locale.ENGLISH) + + ":" + + s.toLowerCase(Locale.ENGLISH), + loader.getDiskCache()); + if (file != null && file.exists()) { + set = true; + holder.imageFlair.setVisibility(View.VISIBLE); + String decodedImgUri = Uri.fromFile(file).toString(); + loader.displayImage(decodedImgUri, holder.imageFlair); + break; + } + } + if (!set) { + holder.imageFlair.setImageDrawable(null); + holder.imageFlair.setVisibility(View.GONE); + } + } else { + holder.imageFlair.setVisibility(View.GONE); + } + //Set typeface for body + int type = new FontPreferences(mContext).getFontTypeComment().getTypeface(); + Typeface typeface; + if (type >= 0) { + typeface = RobotoTypefaces.obtainTypeface(mContext, type); + } else { + typeface = Typeface.DEFAULT; + } + holder.firstTextView.setTypeface(typeface); + + + //Show padding on top + if (baseNode.isTopLevel()) { + holder.itemView.findViewById(R.id.next).setVisibility(View.VISIBLE); + } else if (holder.itemView.findViewById(R.id.next).getVisibility() == View.VISIBLE) { + holder.itemView.findViewById(R.id.next).setVisibility(View.GONE); + } + + //Should be collapsed? + if (hiddenPersons.contains(comment.getFullName()) || toCollapse.contains( + comment.getFullName())) { + int childnumber = getChildNumber(baseNode); + if (hiddenPersons.contains(comment.getFullName()) && childnumber > 0) { + holder.childrenNumber.setVisibility(View.VISIBLE); + holder.childrenNumber.setText("+" + childnumber); + } else { + holder.childrenNumber.setVisibility(View.GONE); + } + if (SettingValues.collapseComments && toCollapse.contains(comment.getFullName())) { + holder.firstTextView.setVisibility(View.GONE); + holder.commentOverflow.setVisibility(View.GONE); + } + } else { + holder.childrenNumber.setVisibility(View.GONE); + holder.commentOverflow.setVisibility(View.VISIBLE); + } + + + holder.dot.setVisibility(View.VISIBLE); + + int dwidth = (int) ((SettingValues.largeDepth ? 5 : 3) * Resources.getSystem() + .getDisplayMetrics().density); + int width = 0; + + //Padding on the left, starting with the third comment + for (int i = 2; i < baseNode.getDepth(); i++) { + width += dwidth; + } + RecyclerView.LayoutParams params = + (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); + params.setMargins(width, 0, 0, 0); + holder.itemView.setLayoutParams(params); + RelativeLayout.LayoutParams params2 = + (RelativeLayout.LayoutParams) holder.dot.getLayoutParams(); + params2.width = dwidth; + holder.dot.setLayoutParams(params2); + if (baseNode.getDepth() - 1 > 0) { + int i22 = baseNode.getDepth() - 2; + String commentOp = dataSet.commentOPs.get(comment.getId()); + if (SettingValues.highlightCommentOP + && commentOp != null + && comment != null + && commentOp.equals(comment.getAuthor())) { + holder.dot.setBackgroundColor( + ContextCompat.getColor(mContext, R.color.md_purple_500)); + + } else { + if (i22 % 5 == 0) { + holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, + !SettingValues.colorCommentDepth ? R.color.md_grey_700 + : R.color.md_blue_500)); + } else if (i22 % 4 == 0) { + holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, + !SettingValues.colorCommentDepth ? R.color.md_grey_600 + : R.color.md_green_500)); + } else if (i22 % 3 == 0) { + holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, + !SettingValues.colorCommentDepth ? R.color.md_grey_500 + : R.color.md_yellow_500)); + } else if (i22 % 2 == 0) { + holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, + !SettingValues.colorCommentDepth ? R.color.md_grey_400 + : R.color.md_orange_500)); + } else { + holder.dot.setBackgroundColor(ContextCompat.getColor(mContext, + !SettingValues.colorCommentDepth ? R.color.md_grey_300 + : R.color.md_red_500)); + } + } + } else { + holder.dot.setVisibility(View.GONE); + } + + if (currentSelectedItem != null + && comment.getFullName().contains(currentSelectedItem) + && !currentSelectedItem.isEmpty() + && !currentlyEditingId.equals(comment.getFullName())) { + doHighlighted(holder, comment, baseNode, false); + } else if (!currentlyEditingId.equals(comment.getFullName())) { + setCommentStateUnhighlighted(holder, baseNode, false); + } + + if (deleted.contains(comment.getFullName())) { + holder.firstTextView.setText(R.string.comment_deleted); + holder.content.setText(R.string.comment_deleted); + } + + if (currentlyEditingId.equals(comment.getFullName())) { + setCommentStateUnhighlighted(holder, baseNode, false); + setCommentStateHighlighted(holder, comment, baseNode, true, false); + } + + if (SettingValues.collapseDeletedComments) { + if (comment.getBody().startsWith("[removed]") || comment.getBody().startsWith("[deleted]")) { + holder.firstTextView.setVisibility(View.GONE); + holder.commentOverflow.setVisibility(View.GONE); + } + } + + } else if (firstHolder instanceof SubmissionViewHolder && submission != null) { + submissionViewHolder = (SubmissionViewHolder) firstHolder; + new PopulateSubmissionViewHolder().populateSubmissionViewHolder( + (SubmissionViewHolder) firstHolder, submission, (Activity) mContext, true, true, + null, listView, false, false, null, this); + if (Authentication.isLoggedIn && Authentication.didOnline) { + if (submission.isArchived() || submission.isLocked()) { + firstHolder.itemView.findViewById(R.id.reply).setVisibility(View.GONE); + } else { + firstHolder.itemView.findViewById(R.id.reply) + .setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + doReplySubmission(firstHolder); + } + }); + firstHolder.itemView.findViewById(R.id.discard) + .setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + firstHolder.itemView.findViewById(R.id.innerSend) + .setVisibility(View.GONE); + currentlyEditing = null; + editingPosition = -1; + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + } + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + currentlyEditingId = ""; + backedText = ""; + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + } + }); + } + } else { + firstHolder.itemView.findViewById(R.id.innerSend).setVisibility(View.GONE); + firstHolder.itemView.findViewById(R.id.reply).setVisibility(View.GONE); + } + + firstHolder.itemView.findViewById(R.id.more) + .setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + firstHolder.itemView.findViewById(R.id.menu).callOnClick(); + } + }); + + + } else if (firstHolder instanceof MoreCommentViewHolder) { + final MoreCommentViewHolder holder = (MoreCommentViewHolder) firstHolder; + int nextPos = pos - 1; + + nextPos = getRealPosition(nextPos); + + final MoreChildItem baseNode = (MoreChildItem) currentComments.get(nextPos); + if (baseNode.children.getCount() > 0) { + try { + holder.content.setText(mContext.getString(R.string.comment_load_more_string_new, + baseNode.children.getLocalizedCount())); + } catch (Exception e) { + holder.content.setText(R.string.comment_load_more_number_unknown); + } + } else if (!baseNode.children.getChildrenIds().isEmpty()) { + holder.content.setText(R.string.comment_load_more_number_unknown); + } else { + holder.content.setText(R.string.thread_continue); + } + + int dwidth = (int) ((SettingValues.largeDepth ? 5 : 3) * Resources.getSystem() + .getDisplayMetrics().density); + int width = 0; + for (int i = 1; i < baseNode.comment.getDepth(); i++) { + width += dwidth; + } + + final View progress = holder.loading; + progress.setVisibility(View.GONE); + final int finalNextPos = nextPos; + holder.content.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + if (baseNode.children.getChildrenIds().isEmpty()) { + String toGoTo = "https://reddit.com" + + submission.getPermalink() + + baseNode.comment.getComment().getId() + + "?context=0"; + OpenRedditLink.openUrl(mContext, toGoTo, true); + } else if (progress.getVisibility() == View.GONE) { + progress.setVisibility(View.VISIBLE); + holder.content.setText(R.string.comment_loading_more); + currentLoading = + new AsyncLoadMore(getRealPosition(holder.getBindingAdapterPosition() - 2), + holder.getBindingAdapterPosition(), holder, finalNextPos, + baseNode.comment.getComment().getFullName()); + currentLoading.execute(baseNode); + } + } + }); + + RecyclerView.LayoutParams params = + (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); + params.setMargins(width, 0, 0, 0); + holder.itemView.setLayoutParams(params); + + } + if (firstHolder instanceof SpacerViewHolder) { + //Make a space the size of the toolbar minus 1 so there isn't a gap + firstHolder.itemView.findViewById(R.id.height) + .setLayoutParams( + new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ( + Constants.SINGLE_HEADER_VIEW_OFFSET - DisplayUtil.dpToPxVertical(1) + + mPage.shownHeaders))); + } + } + + AsyncLoadMore currentLoading; + String changedProfile; + + private void doReplySubmission(RecyclerView.ViewHolder submissionViewHolder) { + final View replyArea = submissionViewHolder.itemView.findViewById(R.id.innerSend); + if (replyArea.getVisibility() == View.GONE) { + expandSubmissionReply(replyArea); + EditText replyLine = submissionViewHolder.itemView.findViewById(R.id.replyLine); + DoEditorActions.doActions(replyLine, submissionViewHolder.itemView, fm, + (Activity) mContext, submission.isSelfPost() ? submission.getSelftext() : null, + new String[]{submission.getAuthor()}); + + currentlyEditing = submissionViewHolder.itemView.findViewById(R.id.replyLine); + + final TextView profile = submissionViewHolder.itemView.findViewById(R.id.profile); + changedProfile = Authentication.name; + profile.setText("/u/" + changedProfile); + profile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final HashMap accounts = new HashMap<>(); + + for (String s : Authentication.authentication.getStringSet("accounts", + new HashSet())) { + if (s.contains(":")) { + accounts.put(s.split(":")[0], s.split(":")[1]); + } else { + accounts.put(s, ""); + } + } + final ArrayList keys = new ArrayList<>(accounts.keySet()); + final int i = keys.indexOf(changedProfile); + + new AlertDialog.Builder(mContext) + .setTitle(R.string.replies_switch_accounts) + .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { + changedProfile = keys.get(which); + profile.setText("/u/" + changedProfile); + }) + .setNegativeButton(R.string.btn_cancel, null) + .show(); + } + }); + currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + mPage.fastScroll.setVisibility(View.GONE); + if (mPage.fab != null) mPage.fab.setVisibility(View.GONE); + mPage.overrideFab = true; + } else if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + } + } + }); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + replyLine.setOnFocusChangeListener((v, b) -> { + if (b) { + v.postDelayed(() -> { + if (!v.hasFocus()) + v.requestFocus(); + }, 100); + } + }); + } + replyLine.requestFocus(); + KeyboardUtil.toggleKeyboard(mContext, + InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + + editingPosition = submissionViewHolder.getBindingAdapterPosition(); + + submissionViewHolder.itemView.findViewById(R.id.send) + .setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + dataSet.refreshLayout.setRefreshing(true); + + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + } + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + if (currentlyEditing != null) { + String text = currentlyEditing.getText().toString(); + new ReplyTaskComment(submission, changedProfile).execute(text); + replyArea.setVisibility(View.GONE); + currentlyEditing.setText(""); + currentlyEditing = null; + editingPosition = -1; + //Hide soft keyboard + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + } + } + }); + } else { + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + collapseAndHide(replyArea); + } + } + + public void setViews(String rawHTML, String subredditName, + final SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow) { + if (rawHTML.isEmpty()) { + return; + } + + List blocks = SubmissionParser.getBlocks(rawHTML); + + int startIndex = 0; + // the
case is when the body contains a table or code block first + if (!blocks.get(0).equals("
")) { + firstTextView.setVisibility(View.VISIBLE); + firstTextView.setTextHtml(blocks.get(0), subredditName); + startIndex = 1; + } else { + firstTextView.setText(""); + } + + if (blocks.size() > 1) { + if (startIndex == 0) { + commentOverflow.setViews(blocks, subredditName); + } else { + commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); + } + } else { + commentOverflow.removeAllViews(); + } + + } + + public void setViews(String rawHTML, String subredditName, + final SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow, + View.OnClickListener click, View.OnLongClickListener onLongClickListener) { + if (rawHTML.isEmpty()) { + return; + } + + List blocks = SubmissionParser.getBlocks(rawHTML); + + int startIndex = 0; + // the
case is when the body contains a table or code block first + if (!blocks.get(0).equals("
")) { + firstTextView.setVisibility(View.VISIBLE); + firstTextView.setTextHtml(blocks.get(0) + " ", subredditName); + startIndex = 1; + } else { + firstTextView.setText(""); + } + + if (blocks.size() > 1) { + if (startIndex == 0) { + commentOverflow.setViews(blocks, subredditName, click, onLongClickListener); + } else { + commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName, + click, onLongClickListener); + } + } else { + commentOverflow.removeAllViews(); + } + + } + + private void setViews(String rawHTML, String subredditName, CommentViewHolder holder) { + setViews(rawHTML, subredditName, holder.firstTextView, holder.commentOverflow); + } + + private void setViews(String rawHTML, String subredditName, CommentViewHolder holder, + View.OnClickListener click, View.OnLongClickListener longClickListener) { + setViews(rawHTML, subredditName, holder.firstTextView, holder.commentOverflow, click, + longClickListener); + } + + int editingPosition; + + private void collapseAndHide(final View v) { + int finalHeight = v.getHeight(); + + mAnimator = AnimatorUtil.slideAnimator(finalHeight, 0, v); + + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + //Height=0, but it set visibility to GONE + v.setVisibility(View.GONE); + } + + @Override + public void onAnimationCancel(Animator animation) { + v.setVisibility(View.GONE); + } + }); + mAnimator.start(); + } + + private void collapseAndRemove(final View v) { + int finalHeight = v.getHeight(); + + mAnimator = AnimatorUtil.slideAnimator(finalHeight, 0, v); + + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + //Height=0, but it set visibility to GONE + ((LinearLayout) v).removeAllViews(); + } + + @Override + public void onAnimationCancel(Animator animation) { + ((LinearLayout) v).removeAllViews(); + } + }); + mAnimator.start(); + } + + private void doShowMenu(final View l) { + l.setVisibility(View.VISIBLE); + + final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l.measure(widthSpec, heightSpec); + + + final View l2 = l.findViewById(R.id.menu); + final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l2.measure(widthSpec2, heightSpec2); + ValueAnimator mAnimator = AnimatorUtil.slideAnimator(l.getMeasuredHeight(), l2.getMeasuredHeight(), l); + + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + l2.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationCancel(Animator animation) { + l2.setVisibility(View.VISIBLE); + } + }); + mAnimator.start(); + } + + ValueAnimator mAnimator; + + private void expand(final View l) { + l.setVisibility(View.VISIBLE); + + final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l.measure(widthSpec, heightSpec); + + View l2 = l.findViewById(R.id.replyArea) == null ? l.findViewById(R.id.innerSend) + : l.findViewById(R.id.replyArea); + final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l2.measure(widthSpec2, heightSpec2); + + mAnimator = AnimatorUtil.slideAnimator(0, l.getMeasuredHeight() - l2.getMeasuredHeight(), l); + + mAnimator.start(); + } + + private void expandAndSetParams(final View l) { + l.setVisibility(View.VISIBLE); + + final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l.measure(widthSpec, heightSpec); + + View l2 = l.findViewById(R.id.replyArea) == null ? l.findViewById(R.id.innerSend) + : l.findViewById(R.id.replyArea); + final int widthSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec2 = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l2.measure(widthSpec2, heightSpec2); + + mAnimator = AnimatorUtil.slideAnimator((l.getMeasuredHeight() - l2.getMeasuredHeight()), + l.getMeasuredHeight() - (l.getMeasuredHeight() - l2.getMeasuredHeight()), l); + + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + RelativeLayout.LayoutParams params = + (RelativeLayout.LayoutParams) l.getLayoutParams(); + params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + params.addRule(RelativeLayout.BELOW, R.id.commentOverflow); + l.setLayoutParams(params); + } + + @Override + public void onAnimationCancel(Animator animation) { + RelativeLayout.LayoutParams params = + (RelativeLayout.LayoutParams) l.getLayoutParams(); + params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + params.addRule(RelativeLayout.BELOW, R.id.commentOverflow); + l.setLayoutParams(params); + } + }); + mAnimator.start(); + } + + private void expandSubmissionReply(final View l) { + l.setVisibility(View.VISIBLE); + + final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l.measure(widthSpec, heightSpec); + + mAnimator = AnimatorUtil.slideAnimator(0, l.getMeasuredHeight(), l); + + mAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) l.getLayoutParams(); + params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + l.setLayoutParams(params); + } + + @Override + public void onAnimationCancel(Animator animation) { + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) l.getLayoutParams(); + params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + l.setLayoutParams(params); + } + }); + mAnimator.start(); + } + + CommentNode currentBaseNode; + + public void setCommentStateHighlighted(final CommentViewHolder holder, final Comment n, + final CommentNode baseNode, boolean isReplying, boolean animate) { + if (currentlySelected != null && currentlySelected != holder) { + setCommentStateUnhighlighted(currentlySelected, currentBaseNode, true); + } + + if (mContext instanceof BaseActivity) { + ((BaseActivity) mContext).setShareUrl("https://reddit.com" + + submission.getPermalink() + + n.getFullName() + + "?context=3"); + } + + // If a comment is hidden and (Swap long press == true), then a single click will un-hide the comment + // and expand to show all children comments + if (SettingValues.swap + && holder.firstTextView.getVisibility() == View.GONE + && !isReplying) { + hiddenPersons.remove(n.getFullName()); + unhideAll(baseNode, holder.getBindingAdapterPosition() + 1); + if (toCollapse.contains(n.getFullName()) && SettingValues.collapseComments) { + setViews(n.getDataNode().get("body_html").asText(), submission.getSubredditName(), + holder); + } + CommentAdapterHelper.hideChildrenObject(holder.childrenNumber); + holder.commentOverflow.setVisibility(View.VISIBLE); + toCollapse.remove(n.getFullName()); + } else { + currentlySelected = holder; + currentBaseNode = baseNode; + int color = Palette.getColor(n.getSubredditName()); + currentSelectedItem = n.getFullName(); + currentNode = baseNode; + LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); + resetMenu(holder.menuArea, false); + final View baseView = inflater.inflate( + SettingValues.rightHandedCommentMenu ? + R.layout.comment_menu_right_handed : R.layout.comment_menu, holder.menuArea); + + if (!isReplying) { + baseView.setVisibility(View.GONE); + if (animate) { + expand(baseView); + } else { + baseView.setVisibility(View.VISIBLE); + final int widthSpec = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + baseView.measure(widthSpec, heightSpec); + View l2 = baseView.findViewById(R.id.replyArea) == null ? baseView.findViewById( + R.id.innerSend) : baseView.findViewById(R.id.replyArea); + final int widthSpec2 = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec2 = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l2.measure(widthSpec2, heightSpec2); + ViewGroup.LayoutParams layoutParams = baseView.getLayoutParams(); + layoutParams.height = baseView.getMeasuredHeight() - l2.getMeasuredHeight(); + baseView.setLayoutParams(layoutParams); + } + } + + RecyclerView.LayoutParams params = + (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); + params.setMargins(0, 0, 0, 0); + holder.itemView.setLayoutParams(params); + + View reply = baseView.findViewById(R.id.reply); + View send = baseView.findViewById(R.id.send); + + final View menu = baseView.findViewById(R.id.menu); + final View replyArea = baseView.findViewById(R.id.replyArea); + + final View more = baseView.findViewById(R.id.more); + final ImageView upvote = baseView.findViewById(R.id.upvote); + final ImageView downvote = baseView.findViewById(R.id.downvote); + View discard = baseView.findViewById(R.id.discard); + final EditText replyLine = baseView.findViewById(R.id.replyLine); + final ImageView mod = baseView.findViewById(R.id.mod); + + final Comment comment = baseNode.getComment(); + if (ActionStates.getVoteDirection(comment) == VoteDirection.UPVOTE) { + BlendModeUtil.tintImageViewAsModulate(upvote, holder.textColorUp); + upvote.setContentDescription(mContext.getResources().getString(R.string.btn_upvoted)); + } else if (ActionStates.getVoteDirection(comment) == VoteDirection.DOWNVOTE) { + BlendModeUtil.tintImageViewAsModulate(downvote, holder.textColorDown); + downvote.setContentDescription(mContext.getResources().getString(R.string.btn_downvoted)); + } else { + downvote.clearColorFilter(); + downvote.setContentDescription(mContext.getResources().getString(R.string.btn_downvote)); + upvote.clearColorFilter(); + upvote.setContentDescription(mContext.getResources().getString(R.string.btn_upvote)); + } + + try { + if (UserSubscriptions.modOf.contains(submission.getSubredditName())) { + //todo + mod.setVisibility(View.GONE); + } else { + mod.setVisibility(View.GONE); + } + } catch (Exception e) { + Log.d(LogUtil.getTag(), "Error loading mod " + e.toString()); + } + + if (UserSubscriptions.modOf != null && UserSubscriptions.modOf.contains( + submission.getSubredditName().toLowerCase(Locale.ENGLISH))) { + mod.setVisibility(View.VISIBLE); + final Map reports = comment.getUserReports(); + final Map reports2 = comment.getModeratorReports(); + if (reports.size() + reports2.size() > 0) { + BlendModeUtil.tintImageViewAsSrcAtop( + mod, ContextCompat.getColor(mContext, R.color.md_red_300)); + } else { + BlendModeUtil.tintImageViewAsSrcAtop(mod, Color.WHITE); + } + mod.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + CommentAdapterHelper.showModBottomSheet(CommentAdapter.this, mContext, + baseNode, comment, holder, reports, reports2); + } + }); + } else { + mod.setVisibility(View.GONE); + } + + final ImageView edit = baseView.findViewById(R.id.edit); + if (Authentication.name != null + && Authentication.name.toLowerCase(Locale.ENGLISH) + .equals(comment.getAuthor().toLowerCase(Locale.ENGLISH)) + && Authentication.didOnline) { + edit.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + CommentAdapterHelper.doCommentEdit(CommentAdapter.this, mContext, fm, + baseNode, baseNode.isTopLevel() ? submission.getSelftext() + : baseNode.getParent().getComment().getBody(), holder); + } + }); + } else { + edit.setVisibility(View.GONE); + } + + + final ImageView delete = baseView.findViewById(R.id.delete); + if (Authentication.name != null + && Authentication.name.toLowerCase(Locale.ENGLISH) + .equals(comment.getAuthor().toLowerCase(Locale.ENGLISH)) + && Authentication.didOnline) { + delete.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + CommentAdapterHelper.deleteComment(CommentAdapter.this, mContext, baseNode, + holder); + } + }); + } else { + delete.setVisibility(View.GONE); + } + + if (Authentication.isLoggedIn + && !submission.isArchived() + && !submission.isLocked() + && !(comment.getDataNode().has("locked") && comment.getDataNode().get("locked").asBoolean()) + && !deleted.contains(n.getFullName()) + && !comment.getAuthor().equals("[deleted]") + && Authentication.didOnline) { + if (isReplying) { + baseView.setVisibility(View.VISIBLE); + + final int widthSpec = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + baseView.measure(widthSpec, heightSpec); + + View l2 = baseView.findViewById(R.id.replyArea) == null ? baseView.findViewById( + R.id.innerSend) : baseView.findViewById(R.id.replyArea); + final int widthSpec2 = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + final int heightSpec2 = + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); + l2.measure(widthSpec2, heightSpec2); + RelativeLayout.LayoutParams params2 = + (RelativeLayout.LayoutParams) baseView.getLayoutParams(); + params2.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + params2.addRule(RelativeLayout.BELOW, R.id.commentOverflow); + baseView.setLayoutParams(params2); + replyArea.setVisibility(View.VISIBLE); + menu.setVisibility(View.GONE); + currentlyEditing = replyLine; + currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + mPage.fastScroll.setVisibility(View.GONE); + if (mPage.fab != null) { + mPage.fab.setVisibility(View.GONE); + } + mPage.overrideFab = true; + } else if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + if (mPage.fab != null) { + mPage.fab.setVisibility(View.VISIBLE); + } + mPage.overrideFab = false; + } + } + }); + final TextView profile = baseView.findViewById(R.id.profile); + changedProfile = Authentication.name; + profile.setText("/u/" + changedProfile); + profile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final HashMap accounts = new HashMap<>(); + + for (String s : Authentication.authentication.getStringSet("accounts", + new HashSet())) { + if (s.contains(":")) { + accounts.put(s.split(":")[0], s.split(":")[1]); + } else { + accounts.put(s, ""); + } + } + final ArrayList keys = new ArrayList<>(accounts.keySet()); + final int i = keys.indexOf(changedProfile); + + new AlertDialog.Builder(mContext) + .setTitle(R.string.sorting_choose) + .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { + changedProfile = keys.get(which); + profile.setText("/u/" + changedProfile); + }) + .setNegativeButton(R.string.btn_cancel, null) + .show(); + } + }); + replyLine.requestFocus(); + KeyboardUtil.toggleKeyboard(mContext, + InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + + currentlyEditingId = n.getFullName(); + replyLine.setText(backedText); + replyLine.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + backedText = s.toString(); + } + }); + editingPosition = holder.getBindingAdapterPosition(); + } + reply.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + expandAndSetParams(baseView); + + //If the base theme is Light or Sepia, tint the Editor actions to be white + if (SettingValues.currentTheme == 1 || SettingValues.currentTheme == 5) { + final ImageView saveDraft = (ImageView) replyArea.findViewById(R.id.savedraft); + final ImageView draft = (ImageView) replyArea.findViewById(R.id.draft); + final ImageView imagerep = (ImageView) replyArea.findViewById(R.id.imagerep); + final ImageView link = (ImageView) replyArea.findViewById(R.id.link); + final ImageView bold = (ImageView) replyArea.findViewById(R.id.bold); + final ImageView italics = (ImageView) replyArea.findViewById(R.id.italics); + final ImageView bulletlist = (ImageView) replyArea.findViewById(R.id.bulletlist); + final ImageView numlist = (ImageView) replyArea.findViewById(R.id.numlist); + final ImageView draw = (ImageView) replyArea.findViewById(R.id.draw); + final ImageView quote = (ImageView) replyArea.findViewById(R.id.quote); + final ImageView size = (ImageView) replyArea.findViewById(R.id.size); + final ImageView strike = (ImageView) replyArea.findViewById(R.id.strike); + final ImageView author = (ImageView) replyArea.findViewById(R.id.author); + final ImageView spoiler = (ImageView) replyArea.findViewById(R.id.spoiler); + final List imageViewSet = Arrays.asList( + saveDraft, draft, imagerep, link, bold, italics, bulletlist, + numlist, draw, quote, size, strike, author, spoiler); + BlendModeUtil.tintImageViewsAsSrcAtop(imageViewSet, Color.WHITE); + BlendModeUtil.tintDrawableAsSrcIn(replyLine.getBackground(), Color.WHITE); + } + + replyArea.setVisibility(View.VISIBLE); + menu.setVisibility(View.GONE); + currentlyEditing = replyLine; + DoEditorActions.doActions(currentlyEditing, replyArea, fm, + (Activity) mContext, comment.getBody(), getParents(baseNode)); + currentlyEditing.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + mPage.fastScroll.setVisibility(View.GONE); + if (mPage.fab != null) mPage.fab.setVisibility(View.GONE); + mPage.overrideFab = true; + } else if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + } + } + }); + final TextView profile = baseView.findViewById(R.id.profile); + changedProfile = Authentication.name; + profile.setText("/u/" + changedProfile); + profile.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final HashMap accounts = new HashMap<>(); + + for (String s : Authentication.authentication.getStringSet( + "accounts", new HashSet())) { + if (s.contains(":")) { + accounts.put(s.split(":")[0], s.split(":")[1]); + } else { + accounts.put(s, ""); + } + } + final ArrayList keys = new ArrayList<>(accounts.keySet()); + final int i = keys.indexOf(changedProfile); + + new AlertDialog.Builder(mContext) + .setTitle(R.string.sorting_choose) + .setSingleChoiceItems(keys.toArray(new String[0]), i, (dialog, which) -> { + changedProfile = keys.get(which); + profile.setText("/u/" + changedProfile); + }) + .setNegativeButton(R.string.btn_cancel, null) + .show(); + } + }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + replyLine.setOnFocusChangeListener((view, b) -> { + if (b) { + view.postDelayed(() -> { + if (!view.hasFocus()) + view.requestFocus(); + }, 100); + } + }); + } + replyLine.requestFocus(); // TODO: Not working when called a second time + KeyboardUtil.toggleKeyboard(mContext, + InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + + currentlyEditingId = n.getFullName(); + replyLine.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + backedText = s.toString(); + } + }); + editingPosition = holder.getBindingAdapterPosition(); + } + }); + send.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + currentlyEditingId = ""; + backedText = ""; + + doShowMenu(baseView); + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + } + dataSet.refreshLayout.setRefreshing(true); + if (currentlyEditing != null) { + String text = currentlyEditing.getText().toString(); + new ReplyTaskComment(n, baseNode, holder, changedProfile).execute(text); + currentlyEditing = null; + editingPosition = -1; + } + //Hide soft keyboard + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + } + }); + discard.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + currentlyEditing = null; + editingPosition = -1; + currentlyEditingId = ""; + backedText = ""; + mPage.overrideFab = false; + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + doShowMenu(baseView); + } + }); + } else { + if (reply.getVisibility() == View.VISIBLE) { + reply.setVisibility(View.GONE); + } + if ((submission.isArchived() + || deleted.contains(n.getFullName()) + || comment.getAuthor().equals("[deleted]")) + && Authentication.isLoggedIn + && Authentication.didOnline + && upvote.getVisibility() == View.VISIBLE) { + upvote.setVisibility(View.GONE); + } + if ((submission.isArchived() + || deleted.contains(n.getFullName()) + || comment.getAuthor().equals("[deleted]")) + && Authentication.isLoggedIn + && Authentication.didOnline + && downvote.getVisibility() == View.VISIBLE) { + downvote.setVisibility(View.GONE); + } + } + + more.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + CommentAdapterHelper.showOverflowBottomSheet(CommentAdapter.this, mContext, + holder, baseNode); + } + }); + upvote.setOnClickListener(new OnSingleClickListener() { + + @Override + public void onSingleClick(View v) { + setCommentStateUnhighlighted(holder, comment, baseNode, true); + if (ActionStates.getVoteDirection(comment) == VoteDirection.UPVOTE) { + new Vote(v, mContext).execute(n); + ActionStates.setVoteDirection(comment, VoteDirection.NO_VOTE); + doScoreText(holder, n, CommentAdapter.this); + upvote.clearColorFilter(); + } else { + new Vote(true, v, mContext).execute(n); + ActionStates.setVoteDirection(comment, VoteDirection.UPVOTE); + downvote.clearColorFilter(); // reset colour + doScoreText(holder, n, CommentAdapter.this); + BlendModeUtil.tintImageViewAsModulate(upvote, holder.textColorUp); + } + } + }); + downvote.setOnClickListener(new OnSingleClickListener() { + + @Override + public void onSingleClick(View v) { + setCommentStateUnhighlighted(holder, comment, baseNode, true); + if (ActionStates.getVoteDirection(comment) == VoteDirection.DOWNVOTE) { + new Vote(v, mContext).execute(n); + ActionStates.setVoteDirection(comment, VoteDirection.NO_VOTE); + doScoreText(holder, n, CommentAdapter.this); + downvote.clearColorFilter(); + + } else { + new Vote(false, v, mContext).execute(n); + ActionStates.setVoteDirection(comment, VoteDirection.DOWNVOTE); + upvote.clearColorFilter(); // reset colour + doScoreText(holder, n, CommentAdapter.this); + BlendModeUtil.tintImageViewAsModulate(downvote, holder.textColorDown); + } + } + }); + menu.setBackgroundColor(color); + replyArea.setBackgroundColor(color); + + if (!isReplying) { + menu.setVisibility(View.VISIBLE); + replyArea.setVisibility(View.GONE); + } + + holder.itemView.findViewById(R.id.background) + .setBackgroundColor(Color.argb(50, Color.red(color), Color.green(color), + Color.blue(color))); + } + } + + public void doHighlighted(final CommentViewHolder holder, final Comment n, + final CommentNode baseNode, boolean animate) { + if (mAnimator != null && mAnimator.isRunning()) { + holder.itemView.postDelayed(new Runnable() { + @Override + public void run() { + setCommentStateHighlighted(holder, n, baseNode, false, true); + } + }, mAnimator.getDuration()); + } else { + setCommentStateHighlighted(holder, n, baseNode, false, animate); + } + } + + public EditText currentlyEditing; + + public void resetMenu(LinearLayout v, boolean collapsed) { + v.removeAllViews(); + RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) v.getLayoutParams(); + if (collapsed) { + params.height = 0; + } else { + params.height = RelativeLayout.LayoutParams.WRAP_CONTENT; + } + v.setLayoutParams(params); + } + + public void setCommentStateUnhighlighted(final CommentViewHolder holder, + final CommentNode baseNode, boolean animate) { + if (animate) { + collapseAndRemove(holder.menuArea); + } else { + resetMenu(holder.menuArea, true); + } + + int color; + + Comment c = baseNode.getComment(); + if (lastSeen != 0 + && lastSeen < c.getCreated().getTime() + && !dataSet.single + && SettingValues.commentLastVisit + && !Authentication.name.equals(c.getAuthor())) { + color = Palette.getColor(baseNode.getComment().getSubredditName()); + color = Color.argb(20, Color.red(color), Color.green(color), Color.blue(color)); + } else { + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = mContext.getTheme(); + theme.resolveAttribute(R.attr.card_background, typedValue, true); + color = typedValue.data; + } + int dwidth = (int) (3 * Resources.getSystem().getDisplayMetrics().density); + int width = 0; + + //Padding on the left, starting with the third comment + for (int i = 2; i < baseNode.getDepth(); i++) { + width += dwidth; + } + RecyclerView.LayoutParams params = + (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); + params.setMargins(width, 0, 0, 0); + holder.itemView.setLayoutParams(params); + + holder.itemView.findViewById(R.id.background).setBackgroundColor(color); + } + + public void setCommentStateUnhighlighted(final CommentViewHolder holder, final Comment comment, + final CommentNode baseNode, boolean animate) { + if (currentlyEditing != null + && !currentlyEditing.getText().toString().isEmpty() + && holder.getBindingAdapterPosition() <= editingPosition) { + new AlertDialog.Builder(mContext) + .setTitle(R.string.discard_comment_title) + .setMessage(R.string.comment_discard_msg) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> { + currentlyEditing = null; + editingPosition = -1; + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + } + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + currentlyEditingId = ""; + backedText = ""; + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + if (mContext instanceof BaseActivity) { + ((BaseActivity) mContext).setShareUrl( + "https://reddit.com" + submission.getPermalink()); + } + + setCommentStateUnhighlighted(holder, comment, baseNode, true); + + }) + .setNegativeButton(R.string.btn_no, null) + .show(); + } else { + if (mContext instanceof BaseActivity) { + ((BaseActivity) mContext).setShareUrl( + "https://freddit.com" + submission.getPermalink()); + } + currentlySelected = null; + currentSelectedItem = ""; + if (animate) { + collapseAndRemove(holder.menuArea); + } else { + resetMenu(holder.menuArea, true); + } + int dwidth = (int) (3 * Resources.getSystem().getDisplayMetrics().density); + int width = 0; + + //Padding on the left, starting with the third comment + for (int i = 2; i < baseNode.getDepth(); i++) { + width += dwidth; + } + RecyclerView.LayoutParams params = + (RecyclerView.LayoutParams) holder.itemView.getLayoutParams(); + params.setMargins(width, 0, 0, 0); + holder.itemView.setLayoutParams(params); + + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = mContext.getTheme(); + theme.resolveAttribute(R.attr.card_background, typedValue, true); + int color = typedValue.data; + holder.itemView.findViewById(R.id.background).setBackgroundColor(color); + } + } + + public void doLongClick(final CommentViewHolder holder, final Comment comment, + final CommentNode baseNode) { + if (currentlyEditing != null && !currentlyEditing.getText().toString().isEmpty()) { + new AlertDialog.Builder(mContext) + .setTitle(R.string.discard_comment_title) + .setMessage(R.string.comment_discard_msg) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> { + currentlyEditing = null; + editingPosition = -1; + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + } + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + currentlyEditingId = ""; + backedText = ""; + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + + doLongClick(holder, comment, baseNode); + }) + .setNegativeButton(R.string.btn_no, null) + .show(); + + } else { + if (currentSelectedItem != null && currentSelectedItem.contains( + comment.getFullName())) { + setCommentStateUnhighlighted(holder, comment, baseNode, true); + } else { + doHighlighted(holder, comment, baseNode, true); + } + } + } + + public void doOnClick(CommentViewHolder holder, Comment comment, CommentNode baseNode) { + if (currentSelectedItem != null && currentSelectedItem.contains(comment.getFullName())) { + if (SettingValues.swap) { + //If the comment is highlighted and the user is long pressing the comment, + //hide the comment. + doOnClick(holder, baseNode, comment); + } + setCommentStateUnhighlighted(holder, comment, baseNode, true); + } else { + doOnClick(holder, baseNode, comment); + } + } + + public void doOnClick(final CommentViewHolder holder, final CommentNode baseNode, + final Comment comment) { + if (currentlyEditing != null + && !currentlyEditing.getText().toString().isEmpty() + && holder.getBindingAdapterPosition() <= editingPosition) { + new AlertDialog.Builder(mContext) + .setTitle(R.string.discard_comment_title) + .setMessage(R.string.comment_discard_msg) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> { + currentlyEditing = null; + editingPosition = -1; + if (SettingValues.fastscroll) { + mPage.fastScroll.setVisibility(View.VISIBLE); + } + if (mPage.fab != null) mPage.fab.setVisibility(View.VISIBLE); + mPage.overrideFab = false; + currentlyEditingId = ""; + backedText = ""; + View view = ((Activity) mContext).findViewById(android.R.id.content); + if (view != null) { + KeyboardUtil.hideKeyboard(mContext, view.getWindowToken(), 0); + } + + doOnClick(holder, baseNode, comment); + + }) + .setNegativeButton(R.string.btn_no, null) + .show(); + + } else { + if (isClicking) { + isClicking = false; + resetMenu(holder.menuArea, true); + isHolder.itemView.findViewById(R.id.menu).setVisibility(View.GONE); + } else { + if (hiddenPersons.contains(comment.getFullName())) { + hiddenPersons.remove(comment.getFullName()); + unhideAll(baseNode, holder.getBindingAdapterPosition() + 1); + + if (toCollapse.contains(comment.getFullName()) + && SettingValues.collapseComments) { + setViews(comment.getDataNode().get("body_html").asText(), + submission.getSubredditName(), holder); + } + + CommentAdapterHelper.hideChildrenObject(holder.childrenNumber); + if (!holder.firstTextView.getText().toString().isEmpty()) { + holder.firstTextView.setVisibility(View.VISIBLE); + } else { + holder.firstTextView.setVisibility(View.GONE); + } + holder.commentOverflow.setVisibility(View.VISIBLE); + + + toCollapse.remove(comment.getFullName()); + + } else { + int childNumber = getChildNumber(baseNode); + if (childNumber > 0) { + hideAll(baseNode, holder.getBindingAdapterPosition() + 1); + if (!hiddenPersons.contains(comment.getFullName())) { + hiddenPersons.add(comment.getFullName()); + } + if (childNumber > 0) { + CommentAdapterHelper.showChildrenObject(holder.childrenNumber); + holder.childrenNumber.setText("+" + childNumber); + } + } else { + if (!SettingValues.collapseComments) { + doLongClick(holder, comment, baseNode); + } + } + toCollapse.add(comment.getFullName()); + if ((holder.firstTextView.getVisibility() == View.VISIBLE + || holder.commentOverflow.getVisibility() == View.VISIBLE) + && SettingValues.collapseComments) { + holder.firstTextView.setVisibility(View.GONE); + holder.commentOverflow.setVisibility(View.GONE); + } else if (SettingValues.collapseComments) { + if (!holder.firstTextView.getText().toString().isEmpty()) { + holder.firstTextView.setVisibility(View.VISIBLE); + } else { + holder.firstTextView.setVisibility(View.GONE); + } + holder.commentOverflow.setVisibility(View.VISIBLE); + } + } + clickpos = holder.getBindingAdapterPosition() + 1; + } + } + } + + private int getChildNumber(CommentNode user) { + int i = 0; + for (CommentNode ignored : user.walkTree()) { + i++; + if (ignored.hasMoreComments() && dataSet.online) { + i++; + } + } + + return i - 1; + } + + @Override + public int getItemViewType(int position) { + if (position == 0 || (currentComments != null + && !currentComments.isEmpty() + && position == (currentComments.size() - hidden.size()) + 2) || (currentComments + != null && currentComments.isEmpty() && position == 2)) { + return SPACER; + } else { + position -= 1; + } + if (position == 0) { + return HEADER; + } + + return (currentComments.get(getRealPosition(position - 1)) instanceof CommentItem ? 2 : 3); + } + + @Override + public int getItemCount() { + if (currentComments == null) { + return 2; + } else { + return 3 + (currentComments.size() - hidden.size()); + } + } + + public void unhideAll(CommentNode n, int i) { + try { + int counter = unhideNumber(n, 0); + if (SettingValues.collapseComments) { + listView.setItemAnimator(null); + } else { + try { + listView.setItemAnimator(new AlphaInAnimator()); + } catch (Exception ignored) { + } + } + notifyItemRangeInserted(i, counter); + } catch (Exception ignored) { + + } + } + + public void unhideAll(CommentNode n) { + unhideNumber(n, 0); + if (SettingValues.collapseComments) { + listView.setItemAnimator(null); + } else { + listView.setItemAnimator(new AlphaInAnimator()); + } + notifyDataSetChanged(); + } + + public void hideAll(CommentNode n) { + + hideNumber(n, 0); + if (SettingValues.collapseComments) { + listView.setItemAnimator(null); + } else { + listView.setItemAnimator(new AlphaInAnimator()); + } + notifyDataSetChanged(); + + } + + public void hideAll(CommentNode n, int i) { + + int counter = hideNumber(n, 0); + if (SettingValues.collapseComments) { + listView.setItemAnimator(null); + } else { + listView.setItemAnimator(new AlphaInAnimator()); + } + notifyItemRangeRemoved(i, counter); + + } + + public boolean parentHidden(CommentNode n) { + n = n.getParent(); + while (n != null && n.getDepth() > 0) { + String name = n.getComment().getFullName(); + if (hiddenPersons.contains(name) || hidden.contains(name)) { + return true; + } + n = n.getParent(); + } + return false; + } + + public int unhideNumber(CommentNode n, int i) { + for (CommentNode ignored : n.getChildren()) { + + if (!ignored.getComment().getFullName().equals(n.getComment().getFullName())) { + boolean parentHidden = parentHidden(ignored); + + if (parentHidden) { + continue; + } + + String name = ignored.getComment().getFullName(); + + if (hidden.contains(name) || hiddenPersons.contains(name)) { + hidden.remove(name); + i++; + + if (ignored.hasMoreComments() + && !hiddenPersons.contains(name) + && dataSet.online) { + name = name + "more"; + if (hidden.contains(name)) { + hidden.remove(name); + toCollapse.remove(name); + i++; + } + } + } + i += unhideNumber(ignored, 0); + } + } + if (n.hasMoreComments() && !parentHidden(n) && !hiddenPersons.contains( + n.getComment().getFullName()) && dataSet.online) { + String fullname = n.getComment().getFullName() + "more"; + + if (hidden.contains(fullname)) { + i++; + hidden.remove(fullname); + } + } + return i; + } + + public int hideNumber(CommentNode n, int i) { + for (CommentNode ignored : n.getChildren()) { + if (!ignored.getComment().getFullName().equals(n.getComment().getFullName())) { + String fullname = ignored.getComment().getFullName(); + + if (!hidden.contains(fullname)) { + i++; + hidden.add(fullname); + } + if (ignored.hasMoreComments() && dataSet.online) { + if (currentLoading != null && currentLoading.fullname.equals(fullname)) { + currentLoading.cancel(true); + } + + fullname = fullname + "more"; + + if (!hidden.contains(fullname)) { + i++; + hidden.add(fullname); + } + } + i += hideNumber(ignored, 0); + } + + } + if (n.hasMoreComments() && dataSet.online) { + String fullname = n.getComment().getFullName() + "more"; + if (!hidden.contains(fullname)) { + i++; + hidden.add(fullname); + } + } + return i; + } + + public String[] getParents(CommentNode comment) { + String[] bodies = new String[comment.getDepth() + 1]; + bodies[0] = comment.getComment().getAuthor(); + + CommentNode parent = comment.getParent(); + int index = 1; + + while (parent != null) { + bodies[index] = parent.getComment().getAuthor(); + index++; + parent = parent.getParent(); + } + + bodies[index - 1] = submission.getAuthor(); + + //Reverse the array so Submission > Author > ... > Current OP + for (int i = 0; i < bodies.length / 2; i++) { + String temp = bodies[i]; + bodies[i] = bodies[bodies.length - i - 1]; + bodies[bodies.length - i - 1] = temp; + } + + + return bodies; + } + + public int getRealPosition(int position) { + int hElements = getHiddenCountUpTo(position); + int diff = 0; + for (int i = 0; i < hElements; i++) { + diff++; + if ((currentComments.size() > position + diff) && hidden.contains( + currentComments.get(position + diff).getName())) { + i--; + } + } + return (position + diff); + } + + private int getHiddenCountUpTo(int location) { + int count = 0; + for (int i = 0; (i <= location && i < currentComments.size()); i++) { + if (currentComments.size() > i && hidden.contains(currentComments.get(i).getName())) { + count++; + } + } + return count; + } + + public class AsyncLoadMore extends AsyncTask { + public MoreCommentViewHolder holder; + public int holderPos; + public int position; + public int dataPos; + public String fullname; + + public AsyncLoadMore(int position, int holderPos, MoreCommentViewHolder holder, int dataPos, + String fullname) { + this.holderPos = holderPos; + this.holder = holder; + this.position = position; + this.dataPos = dataPos; + this.fullname = fullname; + } + + @Override + public void onPostExecute(Integer data) { + currentLoading = null; + if (!isCancelled() && data != null) { + shifted += data; + ((Activity) mContext).runOnUiThread(new Runnable() { + @Override + public void run() { + currentComments.remove(position); + notifyItemRemoved(holderPos); + } + }); + int oldSize = currentComments.size(); + currentComments.addAll(position, finalData); + int newSize = currentComments.size(); + + for (int i2 = 0; i2 < currentComments.size(); i2++) { + keys.put(currentComments.get(i2).getName(), i2); + } + data = newSize - oldSize; + listView.setItemAnimator(new SlideRightAlphaAnimator()); + notifyItemRangeInserted(holderPos, data); + currentPos = holderPos; + toShiftTo = + ((LinearLayoutManager) listView.getLayoutManager()).findLastVisibleItemPosition(); + shiftFrom = + ((LinearLayoutManager) listView.getLayoutManager()).findFirstVisibleItemPosition(); + + } else if (data == null && currentComments.get(dataPos) instanceof MoreChildItem) { + final MoreChildItem baseNode = (MoreChildItem) currentComments.get(dataPos); + if (baseNode.children.getCount() > 0) { + holder.content.setText(mContext.getString(R.string.comment_load_more, + baseNode.children.getCount())); + } else if (!baseNode.children.getChildrenIds().isEmpty()) { + holder.content.setText(R.string.comment_load_more_number_unknown); + } else { + holder.content.setText(R.string.thread_continue); + } + holder.loading.setVisibility(View.GONE); + } + } + + ArrayList finalData; + + @Override + protected Integer doInBackground(MoreChildItem... params) { + finalData = new ArrayList<>(); + int i = 0; + if (params.length > 0) { + try { + CommentNode node = params[0].comment; + node.loadMoreComments(Authentication.reddit); + HashMap waiting = new HashMap<>(); + + for (CommentNode n : node.walkTree()) { + if (!keys.containsKey(n.getComment().getFullName())) { + + CommentObject obj = new CommentItem(n); + ArrayList removed = new ArrayList<>(); + Map map = + new TreeMap<>(Collections.reverseOrder()); + map.putAll(waiting); + + for (Integer i2 : map.keySet()) { + if (i2 >= n.getDepth()) { + finalData.add(waiting.get(i2)); + removed.add(i2); + waiting.remove(i2); + i++; + + } + } + + finalData.add(obj); + i++; + + if (n.hasMoreComments()) { + waiting.put(n.getDepth(), + new MoreChildItem(n, n.getMoreChildren())); + } + } + } + if (node.hasMoreComments()) { + finalData.add(new MoreChildItem(node, node.getMoreChildren())); + i++; + } + } catch (Exception e) { + Log.w(LogUtil.getTag(), "Cannot load more comments " + e); + Writer writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + e.printStackTrace(printWriter); + String stacktrace = writer.toString().replace(";", ","); + if (stacktrace.contains("UnknownHostException") || stacktrace.contains( + "SocketTimeoutException") || stacktrace.contains("ConnectException")) { + //is offline + final Handler mHandler = new Handler(Looper.getMainLooper()); + mHandler.post(new Runnable() { + @Override + public void run() { + try { + new AlertDialog.Builder(mContext) + .setTitle(R.string.err_title) + .setMessage(R.string.err_connection_failed_msg) + .setNegativeButton(R.string.btn_ok, null) + .show(); + } catch (Exception ignored) { + + } + } + } + + ); + } else if (stacktrace.contains("403 Forbidden") || stacktrace.contains( + "401 Unauthorized")) { + //Un-authenticated + final Handler mHandler = new Handler(Looper.getMainLooper()); + mHandler.post(new Runnable() { + @Override + public void run() { + try { + new AlertDialog.Builder(mContext) + .setTitle(R.string.err_title) + .setMessage(R.string.err_refused_request_msg) + .setNegativeButton(R.string.btn_no, null) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> + Reddit.authentication.updateToken(mContext)) + .show(); + } catch (Exception ignored) { + + } + } + }); + + } else if (stacktrace.contains("404 Not Found") || stacktrace.contains( + "400 Bad Request")) { + final Handler mHandler = new Handler(Looper.getMainLooper()); + mHandler.post(new Runnable() { + @Override + public void run() { + try { + new AlertDialog.Builder(mContext). + setTitle(R.string.err_title) + .setMessage(R.string.err_could_not_find_content_msg) + .setNegativeButton(R.string.btn_close, null) + .show(); + } catch (Exception ignored) { + + } + } + }); + } + return null; + } + } + return i; + } + } + + public class AsyncForceLoadChild extends AsyncTask { + CommentNode node; + public int holderPos; + public int position; + + + public AsyncForceLoadChild(int position, int holderPos, CommentNode baseNode) { + this.holderPos = holderPos; + this.node = baseNode; + this.position = position; + } + + @Override + public void onPostExecute(Integer data) { + if (data != -1) { + listView.setItemAnimator(new SlideRightAlphaAnimator()); + + notifyItemInserted(holderPos + 1); + + currentPos = holderPos + 1; + toShiftTo = + ((LinearLayoutManager) listView.getLayoutManager()).findLastVisibleItemPosition(); + shiftFrom = + ((LinearLayoutManager) listView.getLayoutManager()).findFirstVisibleItemPosition(); + + dataSet.refreshLayout.setRefreshing(false); + } else { + //Comment could not be found, force a reload + Handler handler2 = new Handler(); + handler2.postDelayed(new Runnable() { + public void run() { + ((Activity) mContext).runOnUiThread(new Runnable() { + @Override + public void run() { + dataSet.refreshLayout.setRefreshing(false); + dataSet.loadMoreReply(CommentAdapter.this); + } + }); + } + }, 2000); + } + } + + @Override + protected Integer doInBackground(String... params) { + + int i = 0; + + if (params.length > 0) { + try { + node.insertComment(Authentication.reddit, "t1_" + params[0]); + for (CommentNode n : node.walkTree()) { + if (n.getComment().getFullName().contains(params[0])) { + currentComments.add(position, new CommentItem(n)); + i++; + } + } + + } catch (Exception e) { + Log.w(LogUtil.getTag(), "Cannot load more comments " + e); + i = -1; + } + + shifted += i; + + if (currentComments != null) { + for (int i2 = 0; i2 < currentComments.size(); i2++) { + keys.put(currentComments.get(i2).getName(), i2); + } + } else { + i = -1; + } + } + return i; + } + } + + public void editComment(CommentNode n, CommentViewHolder holder) { + if (n == null) { + dataSet.loadMoreReply(this); + } else { + int position = getRealPosition(holder.getBindingAdapterPosition() - 1); + final int holderpos = holder.getBindingAdapterPosition(); + currentComments.remove(position - 1); + currentComments.add(position - 1, new CommentItem(n)); + listView.setItemAnimator(new SlideRightAlphaAnimator()); + ((Activity) mContext).runOnUiThread(new Runnable() { + @Override + public void run() { + notifyItemChanged(holderpos); + } + }); + } + } + + + public class ReplyTaskComment extends AsyncTask { + public Contribution sub; + CommentNode node; + CommentViewHolder holder; + boolean isSubmission; + String profileName; + + public ReplyTaskComment(Contribution n, CommentNode node, CommentViewHolder holder, + String profileName) { + sub = n; + this.holder = holder; + this.node = node; + this.profileName = profileName; + } + + public ReplyTaskComment(Contribution n, String profileName) { + sub = n; + isSubmission = true; + this.profileName = profileName; + } + + @Override + public void onPostExecute(final String s) { + if (s == null || s.isEmpty()) { + + if (commentBack != null && !commentBack.isEmpty()) { + Drafts.addDraft(commentBack); + try { + new AlertDialog.Builder(mContext) + .setTitle(R.string.err_comment_post) + .setMessage(((why == null) ? "" + : mContext.getString(R.string.err_comment_post_reason, why)) + + mContext.getString(R.string.err_comment_post_message)) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } catch (Exception ignored) { + + } + } else { + try { + new AlertDialog.Builder(mContext) + .setTitle(R.string.err_comment_post) + .setMessage(((why == null) ? "" + : mContext.getString(R.string.err_comment_post_reason, why)) + + mContext.getString(R.string.err_comment_post_nosave_message)) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } catch (Exception ignored) { + + } + } + } else { + if (isSubmission) { + new AsyncForceLoadChild(0, 0, submission.getComments()).execute(s); + } else { + new AsyncForceLoadChild(getRealPosition(holder.getBindingAdapterPosition() - 1), + holder.getBindingAdapterPosition(), node).execute(s); + } + } + } + + String why; + String commentBack; + + @Override + protected String doInBackground(String... comment) { + if (Authentication.me != null) { + try { + commentBack = comment[0]; + if (profileName.equals(Authentication.name)) { + return new AccountManager(Authentication.reddit).reply(sub, comment[0]); + } else { + LogUtil.v("Switching to " + profileName); + return new AccountManager(getAuthenticatedClient(profileName)).reply(sub, + comment[0]); + } + } catch (Exception e) { + if (e instanceof ApiException) { + why = ((ApiException) e).getExplanation(); + } + return null; + } + } else { + return null; + } + } + } + + private RedditClient getAuthenticatedClient(String profileName) { + String token; + RedditClient reddit = new RedditClient( + UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME)); + final HashMap accounts = new HashMap<>(); + + for (String s : Authentication.authentication.getStringSet("accounts", + new HashSet())) { + if (s.contains(":")) { + accounts.put(s.split(":")[0], s.split(":")[1]); + } else { + accounts.put(s, ""); + } + } + final ArrayList keys = new ArrayList<>(accounts.keySet()); + if (accounts.containsKey(profileName) && !accounts.get(profileName).isEmpty()) { + token = accounts.get(profileName); + } else { + ArrayList tokens = new ArrayList<>( + Authentication.authentication.getStringSet("tokens", new HashSet())); + int index = keys.indexOf(profileName); + if (keys.indexOf(profileName) > tokens.size()) { + index -= 1; + } + token = tokens.get(index); + } + Authentication.doVerify(token, reddit, true, mContext); + return reddit; + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/Authentication.java b/app/src/main/java/me/ccrama/redditslide/Authentication.java index 1c70c1eca..97a14c0a0 100644 --- a/app/src/main/java/me/ccrama/redditslide/Authentication.java +++ b/app/src/main/java/me/ccrama/redditslide/Authentication.java @@ -1,346 +1,346 @@ -package me.ccrama.redditslide; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.util.Log; -import android.widget.Toast; - -import androidx.appcompat.app.AlertDialog; - -import net.dean.jraw.RedditClient; -import net.dean.jraw.http.LoggingMode; -import net.dean.jraw.http.NetworkException; -import net.dean.jraw.http.OkHttpAdapter; -import net.dean.jraw.http.UserAgent; -import net.dean.jraw.http.oauth.Credentials; -import net.dean.jraw.http.oauth.OAuthData; -import net.dean.jraw.http.oauth.OAuthHelper; -import net.dean.jraw.models.LoggedInAccount; - -import java.util.Calendar; -import java.util.HashSet; -import java.util.UUID; - -import me.ccrama.redditslide.util.LogUtil; -import me.ccrama.redditslide.util.NetworkUtil; -import okhttp3.Protocol; - -/** - * Created by ccrama on 3/30/2015. - */ -public class Authentication { - private static final String CLIENT_ID = "KI2Nl9A_ouG9Qw"; - private static final String REDIRECT_URL = "http://www.ccrama.me"; - public static boolean isLoggedIn; - public static RedditClient reddit; - public static LoggedInAccount me; - public static boolean mod; - public static String name; - public static SharedPreferences authentication; - public static String refresh; - - public boolean hasDone; - public static boolean didOnline; - private static OkHttpAdapter httpAdapter; - - public static void resetAdapter() { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - if (httpAdapter != null && httpAdapter.getNativeClient() != null) { - httpAdapter.getNativeClient().connectionPool().evictAll(); - } - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - public Authentication(Context context) { - Reddit.setDefaultErrorHandler(context); - - if (NetworkUtil.isConnected(context)) { - hasDone = true; - httpAdapter = new OkHttpAdapter(Reddit.client, Protocol.HTTP_2); - isLoggedIn = false; - reddit = new RedditClient( - UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME), - httpAdapter); - reddit.setRetryLimit(2); - if (BuildConfig.DEBUG) reddit.setLoggingMode(LoggingMode.ALWAYS); - didOnline = true; - new VerifyCredentials(context).execute(); - } else { - isLoggedIn = Reddit.appRestart.getBoolean("loggedin", false); - name = Reddit.appRestart.getString("name", ""); - if ((name.isEmpty() || !isLoggedIn) && !authentication.getString("lasttoken", "") - .isEmpty()) { - for (String s : Authentication.authentication.getStringSet("accounts", - new HashSet())) { - if (s.contains(authentication.getString("lasttoken", ""))) { - name = (s.split(":")[0]); - break; - } - } - isLoggedIn = true; - } - } - - - } - - - public void updateToken(Context c) { - if (BuildConfig.DEBUG) LogUtil.v("Executing update token"); - if (reddit == null) { - hasDone = true; - isLoggedIn = false; - reddit = new RedditClient( - UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME)); - reddit.setLoggingMode(LoggingMode.ALWAYS); - didOnline = true; - - new VerifyCredentials(c).execute(); - } else { - new UpdateToken(c).execute(); - } - } - - public static boolean authedOnce; - - public static class UpdateToken extends AsyncTask { - - Context context; - - public UpdateToken(Context c) { - this.context = c; - } - - @Override - protected Void doInBackground(Void... params) { - if (authedOnce && NetworkUtil.isConnected(context)) { - didOnline = true; - if (name != null && !name.isEmpty()) { - Log.v(LogUtil.getTag(), "REAUTH"); - if (isLoggedIn) { - try { - - final Credentials credentials = - Credentials.installedApp(CLIENT_ID, REDIRECT_URL); - Log.v(LogUtil.getTag(), "REAUTH LOGGED IN"); - - OAuthHelper oAuthHelper = reddit.getOAuthHelper(); - - oAuthHelper.setRefreshToken(refresh); - OAuthData finalData; - if (authentication.contains("backedCreds") - && authentication.getLong("expires", 0) > Calendar.getInstance() - .getTimeInMillis()) { - finalData = oAuthHelper.refreshToken(credentials, - authentication.getString("backedCreds", - "")); //does a request - } else { - finalData = oAuthHelper.refreshToken(credentials); //does a request - authentication.edit() - .putLong("expires", - Calendar.getInstance().getTimeInMillis() + 3000000) - .commit(); - } - authentication.edit() - .putString("backedCreds", finalData.getDataNode().toString()) - .commit(); - reddit.authenticate(finalData); - refresh = oAuthHelper.getRefreshToken(); - refresh = reddit.getOAuthHelper().getRefreshToken(); - - if (reddit.isAuthenticated()) { - if (me == null) { - me = reddit.me(); - } - Authentication.isLoggedIn = true; - - } - Log.v(LogUtil.getTag(), "AUTHENTICATED"); - } catch (Exception e) { - e.printStackTrace(); - } - - } else { - final Credentials fcreds = - Credentials.userlessApp(CLIENT_ID, UUID.randomUUID()); - OAuthData authData; - if (BuildConfig.DEBUG) LogUtil.v("Not logged in"); - try { - - authData = reddit.getOAuthHelper().easyAuth(fcreds); - authentication.edit() - .putLong("expires", - Calendar.getInstance().getTimeInMillis() + 3000000) - .commit(); - authentication.edit() - .putString("backedCreds", authData.getDataNode().toString()) - .commit(); - Authentication.name = "LOGGEDOUT"; - mod = false; - - reddit.authenticate(authData); - Log.v(LogUtil.getTag(), "REAUTH LOGGED IN"); - - } catch (Exception e) { - try { - ((Activity) context).runOnUiThread(new Runnable() { - @Override - public void run() { - try { - - new AlertDialog.Builder(context) - .setTitle(R.string.err_general) - .setMessage(R.string.err_no_connection) - .setPositiveButton(R.string.btn_yes, (dialog, which) -> - new UpdateToken(context) - .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)) - .setNegativeButton(R.string.btn_no, (dialog, which) -> - Reddit.forceRestart(context, false)) - .show(); - } catch (Exception ignored) { - - } - } - }); - } catch (Exception e2) { - Toast.makeText(context, - "Reddit could not be reached. Try again soon", - Toast.LENGTH_SHORT).show(); - } - - //TODO fail - } - } - - - } - - } - if (BuildConfig.DEBUG) LogUtil.v("Done loading token"); - return null; - - } - - } - - - public static class VerifyCredentials extends AsyncTask { - Context mContext; - String lastToken; - boolean single; - - public VerifyCredentials(Context context) { - mContext = context; - lastToken = authentication.getString("lasttoken", ""); - } - - @Override - protected Void doInBackground(String... subs) { - doVerify(lastToken, reddit,single,mContext); - return null; - } - - } - - public static void doVerify(String lastToken, RedditClient baseReddit,boolean single, Context mContext){ - try { - - if (BuildConfig.DEBUG) LogUtil.v("TOKEN IS " + lastToken); - if (!lastToken.isEmpty()) { - - Credentials credentials = Credentials.installedApp(CLIENT_ID, REDIRECT_URL); - OAuthHelper oAuthHelper = baseReddit.getOAuthHelper(); - oAuthHelper.setRefreshToken(lastToken); - - try { - OAuthData finalData; - if (!single - && authentication.contains("backedCreds") - && authentication.getLong("expires", 0) > Calendar.getInstance() - .getTimeInMillis()) { - finalData = oAuthHelper.refreshToken(credentials, - authentication.getString("backedCreds", "")); - } else { - finalData = oAuthHelper.refreshToken(credentials); //does a request - if (!single) { - authentication.edit() - .putLong("expires", - Calendar.getInstance().getTimeInMillis() + 3000000) - .apply(); - } - } - baseReddit.authenticate(finalData); - - if (!single) { - authentication.edit() - .putString("backedCreds", finalData.getDataNode().toString()) - .apply(); - refresh = oAuthHelper.getRefreshToken(); - if (BuildConfig.DEBUG) { - LogUtil.v("ACCESS TOKEN IS " + finalData.getAccessToken()); - } - - Authentication.isLoggedIn = true; - - UserSubscriptions.doCachedModSubs(); - } - - } catch (Exception e) { - e.printStackTrace(); - if (e instanceof NetworkException) { - Toast.makeText(mContext, "Error " + ((NetworkException) e).getResponse() - .getStatusMessage() + ": " + (e).getMessage(), - Toast.LENGTH_LONG).show(); - } - - } - didOnline = true; - - } else if (!single) { - if (BuildConfig.DEBUG) LogUtil.v("NOT LOGGED IN"); - - final Credentials fcreds = - Credentials.userlessApp(CLIENT_ID, UUID.randomUUID()); - OAuthData authData; - try { - - authData = reddit.getOAuthHelper().easyAuth(fcreds); - authentication.edit() - .putLong("expires", - Calendar.getInstance().getTimeInMillis() + 3000000) - .apply(); - authentication.edit() - .putString("backedCreds", authData.getDataNode().toString()) - .apply(); - reddit.authenticate(authData); - - Authentication.name = "LOGGEDOUT"; - Reddit.notFirst = true; - didOnline = true; - - } catch (Exception e) { - e.printStackTrace(); - if (e instanceof NetworkException) { - Toast.makeText(mContext, "Error " + ((NetworkException) e).getResponse() - .getStatusMessage() + ": " + (e).getMessage(), - Toast.LENGTH_LONG).show(); - } - } - - - } - if (!single) authedOnce = true; - - } catch (Exception e) { - //TODO fail - - - } - } -} +package me.ccrama.redditslide; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.util.Log; +import android.widget.Toast; + +import androidx.appcompat.app.AlertDialog; + +import net.dean.jraw.RedditClient; +import net.dean.jraw.http.LoggingMode; +import net.dean.jraw.http.NetworkException; +import net.dean.jraw.http.OkHttpAdapter; +import net.dean.jraw.http.UserAgent; +import net.dean.jraw.http.oauth.Credentials; +import net.dean.jraw.http.oauth.OAuthData; +import net.dean.jraw.http.oauth.OAuthHelper; +import net.dean.jraw.models.LoggedInAccount; + +import java.util.Calendar; +import java.util.HashSet; +import java.util.UUID; + +import me.ccrama.redditslide.util.LogUtil; +import me.ccrama.redditslide.util.NetworkUtil; +import okhttp3.Protocol; + +/** + * Created by ccrama on 3/30/2015. + */ +public class Authentication { + private static final String CLIENT_ID = "KI2Nl9A_ouG9Qw"; + private static final String REDIRECT_URL = "http://www.ccrama.me"; + public static boolean isLoggedIn; + public static RedditClient reddit; + public static LoggedInAccount me; + public static boolean mod; + public static String name; + public static SharedPreferences authentication; + public static String refresh; + + public boolean hasDone; + public static boolean didOnline; + private static OkHttpAdapter httpAdapter; + + public static void resetAdapter() { + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + if (httpAdapter != null && httpAdapter.getNativeClient() != null) { + httpAdapter.getNativeClient().connectionPool().evictAll(); + } + return null; + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + public Authentication(Context context) { + Reddit.setDefaultErrorHandler(context); + + if (NetworkUtil.isConnected(context)) { + hasDone = true; + httpAdapter = new OkHttpAdapter(Reddit.client, Protocol.HTTP_2); + isLoggedIn = false; + reddit = new RedditClient( + UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME), + httpAdapter); + reddit.setRetryLimit(2); + if (BuildConfig.DEBUG) reddit.setLoggingMode(LoggingMode.ALWAYS); + didOnline = true; + new VerifyCredentials(context).execute(); + } else { + isLoggedIn = Reddit.appRestart.getBoolean("loggedin", false); + name = Reddit.appRestart.getString("name", ""); + if ((name.isEmpty() || !isLoggedIn) && !authentication.getString("lasttoken", "") + .isEmpty()) { + for (String s : Authentication.authentication.getStringSet("accounts", + new HashSet())) { + if (s.contains(authentication.getString("lasttoken", ""))) { + name = (s.split(":")[0]); + break; + } + } + isLoggedIn = true; + } + } + + + } + + + public void updateToken(Context c) { + if (BuildConfig.DEBUG) LogUtil.v("Executing update token"); + if (reddit == null) { + hasDone = true; + isLoggedIn = false; + reddit = new RedditClient( + UserAgent.of("android:me.ccrama.RedditSlide:v" + BuildConfig.VERSION_NAME)); + reddit.setLoggingMode(LoggingMode.ALWAYS); + didOnline = true; + + new VerifyCredentials(c).execute(); + } else { + new UpdateToken(c).execute(); + } + } + + public static boolean authedOnce; + + public static class UpdateToken extends AsyncTask { + + Context context; + + public UpdateToken(Context c) { + this.context = c; + } + + @Override + protected Void doInBackground(Void... params) { + if (authedOnce && NetworkUtil.isConnected(context)) { + didOnline = true; + if (name != null && !name.isEmpty()) { + Log.v(LogUtil.getTag(), "REAUTH"); + if (isLoggedIn) { + try { + + final Credentials credentials = + Credentials.installedApp(CLIENT_ID, REDIRECT_URL); + Log.v(LogUtil.getTag(), "REAUTH LOGGED IN"); + + OAuthHelper oAuthHelper = reddit.getOAuthHelper(); + + oAuthHelper.setRefreshToken(refresh); + OAuthData finalData; + if (authentication.contains("backedCreds") + && authentication.getLong("expires", 0) > Calendar.getInstance() + .getTimeInMillis()) { + finalData = oAuthHelper.refreshToken(credentials, + authentication.getString("backedCreds", + "")); //does a request + } else { + finalData = oAuthHelper.refreshToken(credentials); //does a request + authentication.edit() + .putLong("expires", + Calendar.getInstance().getTimeInMillis() + 3000000) + .commit(); + } + authentication.edit() + .putString("backedCreds", finalData.getDataNode().toString()) + .commit(); + reddit.authenticate(finalData); + refresh = oAuthHelper.getRefreshToken(); + refresh = reddit.getOAuthHelper().getRefreshToken(); + + if (reddit.isAuthenticated()) { + if (me == null) { + me = reddit.me(); + } + Authentication.isLoggedIn = true; + + } + Log.v(LogUtil.getTag(), "AUTHENTICATED"); + } catch (Exception e) { + e.printStackTrace(); + } + + } else { + final Credentials fcreds = + Credentials.userlessApp(CLIENT_ID, UUID.randomUUID()); + OAuthData authData; + if (BuildConfig.DEBUG) LogUtil.v("Not logged in"); + try { + + authData = reddit.getOAuthHelper().easyAuth(fcreds); + authentication.edit() + .putLong("expires", + Calendar.getInstance().getTimeInMillis() + 3000000) + .commit(); + authentication.edit() + .putString("backedCreds", authData.getDataNode().toString()) + .commit(); + Authentication.name = "LOGGEDOUT"; + mod = false; + + reddit.authenticate(authData); + Log.v(LogUtil.getTag(), "REAUTH LOGGED IN"); + + } catch (Exception e) { + try { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + try { + + new AlertDialog.Builder(context) + .setTitle(R.string.err_general) + .setMessage(R.string.err_no_connection) + .setPositiveButton(R.string.btn_yes, (dialog, which) -> + new UpdateToken(context) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)) + .setNegativeButton(R.string.btn_no, (dialog, which) -> + Reddit.forceRestart(context, false)) + .show(); + } catch (Exception ignored) { + + } + } + }); + } catch (Exception e2) { + Toast.makeText(context, + "Reddit could not be reached. Try again soon", + Toast.LENGTH_SHORT).show(); + } + + //TODO fail + } + } + + + } + + } + if (BuildConfig.DEBUG) LogUtil.v("Done loading token"); + return null; + + } + + } + + + public static class VerifyCredentials extends AsyncTask { + Context mContext; + String lastToken; + boolean single; + + public VerifyCredentials(Context context) { + mContext = context; + lastToken = authentication.getString("lasttoken", ""); + } + + @Override + protected Void doInBackground(String... subs) { + doVerify(lastToken, reddit,single,mContext); + return null; + } + + } + + public static void doVerify(String lastToken, RedditClient baseReddit,boolean single, Context mContext){ + try { + + if (BuildConfig.DEBUG) LogUtil.v("TOKEN IS " + lastToken); + if (!lastToken.isEmpty()) { + + Credentials credentials = Credentials.installedApp(CLIENT_ID, REDIRECT_URL); + OAuthHelper oAuthHelper = baseReddit.getOAuthHelper(); + oAuthHelper.setRefreshToken(lastToken); + + try { + OAuthData finalData; + if (!single + && authentication.contains("backedCreds") + && authentication.getLong("expires", 0) > Calendar.getInstance() + .getTimeInMillis()) { + finalData = oAuthHelper.refreshToken(credentials, + authentication.getString("backedCreds", "")); + } else { + finalData = oAuthHelper.refreshToken(credentials); //does a request + if (!single) { + authentication.edit() + .putLong("expires", + Calendar.getInstance().getTimeInMillis() + 3000000) + .apply(); + } + } + baseReddit.authenticate(finalData); + + if (!single) { + authentication.edit() + .putString("backedCreds", finalData.getDataNode().toString()) + .apply(); + refresh = oAuthHelper.getRefreshToken(); + if (BuildConfig.DEBUG) { + LogUtil.v("ACCESS TOKEN IS " + finalData.getAccessToken()); + } + + Authentication.isLoggedIn = true; + + UserSubscriptions.doCachedModSubs(); + } + + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof NetworkException) { + Toast.makeText(mContext, "Error " + ((NetworkException) e).getResponse() + .getStatusMessage() + ": " + (e).getMessage(), + Toast.LENGTH_LONG).show(); + } + + } + didOnline = true; + + } else if (!single) { + if (BuildConfig.DEBUG) LogUtil.v("NOT LOGGED IN"); + + final Credentials fcreds = + Credentials.userlessApp(CLIENT_ID, UUID.randomUUID()); + OAuthData authData; + try { + + authData = reddit.getOAuthHelper().easyAuth(fcreds); + authentication.edit() + .putLong("expires", + Calendar.getInstance().getTimeInMillis() + 3000000) + .apply(); + authentication.edit() + .putString("backedCreds", authData.getDataNode().toString()) + .apply(); + reddit.authenticate(authData); + + Authentication.name = "LOGGEDOUT"; + Reddit.notFirst = true; + didOnline = true; + + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof NetworkException) { + Toast.makeText(mContext, "Error " + ((NetworkException) e).getResponse() + .getStatusMessage() + ": " + (e).getMessage(), + Toast.LENGTH_LONG).show(); + } + } + + + } + if (!single) authedOnce = true; + + } catch (Exception e) { + //TODO fail + + + } + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/UserSubscriptions.java b/app/src/main/java/me/ccrama/redditslide/UserSubscriptions.java index 0c6de07d2..e6e5a45c4 100644 --- a/app/src/main/java/me/ccrama/redditslide/UserSubscriptions.java +++ b/app/src/main/java/me/ccrama/redditslide/UserSubscriptions.java @@ -1,796 +1,796 @@ -package me.ccrama.redditslide; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.widget.Toast; - -import net.dean.jraw.ApiException; -import net.dean.jraw.http.NetworkException; -import net.dean.jraw.managers.AccountManager; -import net.dean.jraw.managers.MultiRedditManager; -import net.dean.jraw.models.MultiReddit; -import net.dean.jraw.models.MultiSubreddit; -import net.dean.jraw.models.Subreddit; -import net.dean.jraw.models.UserRecord; -import net.dean.jraw.paginators.ImportantUserPaginator; -import net.dean.jraw.paginators.UserSubredditsPaginator; - -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 me.ccrama.redditslide.Activities.Login; -import me.ccrama.redditslide.Activities.MainActivity; -import me.ccrama.redditslide.Activities.MultiredditOverview; -import me.ccrama.redditslide.Activities.NewsActivity; -import me.ccrama.redditslide.Toolbox.Toolbox; -import me.ccrama.redditslide.ui.settings.dragSort.ReorderSubreddits; -import me.ccrama.redditslide.util.NetworkUtil; -import me.ccrama.redditslide.util.StringUtil; - -/** - * Created by carlo_000 on 1/16/2016. - */ -public class UserSubscriptions { - public static final String SUB_NAME_TO_PROPERTIES = "multiNameToSubs"; - public static final List defaultSubs = - Arrays.asList("frontpage", "all", "announcements", "Art", "AskReddit", "askscience", - "aww", "blog", "books", "creepy", "dataisbeautiful", "DIY", "Documentaries", - "EarthPorn", "explainlikeimfive", "Fitness", "food", "funny", "Futurology", - "gadgets", "gaming", "GetMotivated", "gifs", "history", "IAmA", - "InternetIsBeautiful", "Jokes", "LifeProTips", "listentothis", - "mildlyinteresting", "movies", "Music", "news", "nosleep", "nottheonion", - "OldSchoolCool", "personalfinance", "philosophy", "photoshopbattles", "pics", - "science", "Showerthoughts", "space", "sports", "television", "tifu", - "todayilearned", "TwoXChromosomes", "UpliftingNews", "videos", "worldnews", - "WritingPrompts"); - public static final List specialSubreddits = - Arrays.asList("frontpage", "all", "random", "randnsfw", "myrandom", "friends", "mod", - "popular"); - public static SharedPreferences subscriptions; - public static SharedPreferences multiNameToSubs; - public static SharedPreferences newsNameToSubs; - public static SharedPreferences news; - public static SharedPreferences pinned; - - public static void setSubNameToProperties(String name, String descrption) { - multiNameToSubs.edit().putString(name, descrption).apply(); - } - - public static Map getMultiNameToSubs(boolean all) { - return getNameToSubs(multiNameToSubs, all); - } - - public static Map getNewsNameToSubs(boolean all) { - return getNameToSubs(newsNameToSubs, all); - } - - private static Map getNameToSubs(SharedPreferences sP, boolean all) { - Map multiNameToSubsMapBase = new HashMap<>(); - - Map multiNameToSubsObject = sP.getAll(); - - for (Map.Entry entry : multiNameToSubsObject.entrySet()) { - multiNameToSubsMapBase.put(entry.getKey(), entry.getValue().toString()); - } - if (all) multiNameToSubsMapBase.putAll(getSubsNameToMulti()); - - Map multiNameToSubsMap = new HashMap<>(); - - for (Map.Entry entries : multiNameToSubsMapBase.entrySet()) { - multiNameToSubsMap.put(entries.getKey().toLowerCase(Locale.ENGLISH), entries.getValue()); - } - - return multiNameToSubsMap; - } - - - private static Map getSubsNameToMulti() { - Map multiNameToSubsMap = new HashMap<>(); - - Map multiNameToSubsObject = multiNameToSubs.getAll(); - - for (Map.Entry entry : multiNameToSubsObject.entrySet()) { - multiNameToSubsMap.put(entry.getValue().toString(), entry.getKey()); - } - - return multiNameToSubsMap; - } - - public static void doMainActivitySubs(MainActivity c) { - if (NetworkUtil.isConnected(c)) { - String s = subscriptions.getString(Authentication.name, ""); - if (s.isEmpty()) { - //get online subs - c.updateSubs(syncSubscriptionsOverwrite(c)); - } else { - CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); - } - c.updateSubs(subredditsForHome); - } - c.updateMultiNameToSubs(getMultiNameToSubs(false)); - - } else { - String s = subscriptions.getString(Authentication.name, ""); - List subredditsForHome = new CaseInsensitiveArrayList(); - if (!s.isEmpty()) { - for (String s2 : s.split(",")) { - subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); - } - } - CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); - List offline = OfflineSubreddit.getAllFormatted(); - for (String subs : subredditsForHome) { - if (offline.contains(subs)) { - finals.add(subs); - } - } - for (String subs : offline) { - if (!finals.contains(subs)) { - finals.add(subs); - } - } - c.updateSubs(finals); - c.updateMultiNameToSubs(getMultiNameToSubs(false)); - } - } - - public static void doNewsSubs(NewsActivity c) { - if (NetworkUtil.isConnected(c)) { - String s = news.getString("subs", "news,android"); - if (s.isEmpty()) { - //get online subs - c.updateSubs(syncSubscriptionsOverwrite(c)); - } else { - CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); - } - c.updateSubs(subredditsForHome); - } - c.updateMultiNameToSubs(getNewsNameToSubs(false)); - - } else { - String s = news.getString("subs", "news,android"); - List subredditsForHome = new CaseInsensitiveArrayList(); - if (!s.isEmpty()) { - for (String s2 : s.split(",")) { - subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); - } - } - CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); - List offline = OfflineSubreddit.getAllFormatted(); - for (String subs : subredditsForHome) { - if (offline.contains(subs)) { - finals.add(subs); - } - } - for (String subs : offline) { - if (!finals.contains(subs)) { - finals.add(subs); - } - } - c.updateSubs(finals); - c.updateMultiNameToSubs(getMultiNameToSubs(false)); - } - } - - public static void doCachedModSubs() { - if (modOf == null || modOf.isEmpty()) { - String s = subscriptions.getString(Authentication.name + "mod", ""); - if (!s.isEmpty()) { - modOf = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - modOf.add(s2.toLowerCase(Locale.ENGLISH)); - } - } - } - } - - public static void cacheModOf() { - subscriptions.edit() - .putString(Authentication.name + "mod", StringUtil.arrayToString(modOf)) - .apply(); - } - - public static class SyncMultireddits extends AsyncTask { - - Context c; - - public SyncMultireddits(Context c) { - this.c = c; - } - - @Override - public void onPostExecute(Boolean b) { - Intent i = new Intent(c, MultiredditOverview.class); - c.startActivity(i); - ((Activity) c).finish(); - } - - @Override - public Boolean doInBackground(Void... params) { - syncMultiReddits(c); - return null; - } - } - - public static CaseInsensitiveArrayList getSubscriptions(Context c) { - String s = subscriptions.getString(Authentication.name, ""); - if (s.isEmpty()) { - //get online subs - return syncSubscriptionsOverwrite(c); - } else { - CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - if (!subredditsForHome.contains(s2)) subredditsForHome.add(s2); - } - return subredditsForHome; - } - } - - public static CaseInsensitiveArrayList pins; - - public static CaseInsensitiveArrayList getPinned() { - String s = pinned.getString(Authentication.name, ""); - if (s.isEmpty()) { - //get online subs - return new CaseInsensitiveArrayList(); - } else if (pins == null) { - pins = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - if (!pins.contains(s2)) pins.add(s2); - } - return pins; - } else { - return pins; - } - } - - public static CaseInsensitiveArrayList getSubscriptionsForShortcut(Context c) { - String s = subscriptions.getString(Authentication.name, ""); - if (s.isEmpty()) { - //get online subs - return syncSubscriptionsOverwrite(c); - } else { - CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); - for (String s2 : s.split(",")) { - if (!s2.contains("/m/")) subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); - } - return subredditsForHome; - } - } - - public static boolean hasSubs() { - String s = subscriptions.getString(Authentication.name, ""); - return s.isEmpty(); - } - - public static CaseInsensitiveArrayList modOf; - public static ArrayList multireddits; - public static HashMap> public_multireddits = - new HashMap>(); - - public static void doOnlineSyncing() { - if (Authentication.mod) { - doModOf(); - if (modOf != null) { - for (String sub : modOf) { - Toolbox.ensureConfigCachedLoaded(sub); - Toolbox.ensureUsernotesCachedLoaded(sub); - } - } - } - doFriendsOf(); - loadMultireddits(); - } - - public static CaseInsensitiveArrayList toreturn; - public static CaseInsensitiveArrayList friends = new CaseInsensitiveArrayList(); - - public static CaseInsensitiveArrayList syncSubscriptionsOverwrite(final Context c) { - toreturn = new CaseInsensitiveArrayList(); - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - toreturn = syncSubreddits(c); - toreturn = sort(toreturn); - setSubscriptions(toreturn); - return null; - } - }.execute(); - - if (toreturn.isEmpty()) { - //failed, load defaults - toreturn.addAll(defaultSubs); - } - - return toreturn; - } - - public static CaseInsensitiveArrayList syncSubreddits(Context c) { - CaseInsensitiveArrayList toReturn = new CaseInsensitiveArrayList(); - if (Authentication.isLoggedIn && NetworkUtil.isConnected(c)) { - UserSubredditsPaginator pag = - new UserSubredditsPaginator(Authentication.reddit, "subscriber"); - pag.setLimit(100); - try { - while (pag.hasNext()) { - for (Subreddit s : pag.next()) { - toReturn.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); - } - } - if (toReturn.isEmpty() && subscriptions.getString(Authentication.name, "") - .isEmpty()) { - toreturn.addAll(defaultSubs); - } - } catch (Exception e) { - //failed; - e.printStackTrace(); - } - addSubsToHistory(toReturn); - } else { - toReturn.addAll(defaultSubs); - } - return toReturn; - } - - public static void syncMultiReddits(Context c) { - try { - multireddits = new ArrayList<>(new MultiRedditManager(Authentication.reddit).mine()); - for (MultiReddit multiReddit : multireddits) { - if (MainActivity.multiNameToSubsMap.containsKey( - ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName())) { - StringBuilder concatenatedSubs = new StringBuilder(); - for (MultiSubreddit subreddit : multiReddit.getSubreddits()) { - concatenatedSubs.append(subreddit.getDisplayName()); - concatenatedSubs.append("+"); - } - MainActivity.multiNameToSubsMap.put( - ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName(), - concatenatedSubs.toString()); - UserSubscriptions.setSubNameToProperties( - ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName(), - concatenatedSubs.toString()); - } - } - } catch (ApiException | NetworkException e) { - e.printStackTrace(); - } - } - - public static void setSubscriptions(CaseInsensitiveArrayList subs) { - subscriptions.edit().putString(Authentication.name, StringUtil.arrayToString(subs)).apply(); - } - - public static void setPinned(CaseInsensitiveArrayList subs) { - pinned.edit().putString(Authentication.name, StringUtil.arrayToString(subs)).apply(); - pins = null; - } - - public static void switchAccounts() { - SharedPreferences.Editor editor = Reddit.appRestart.edit(); - editor.putBoolean("back", true); - editor.putString("subs", ""); - Authentication.authentication.edit().remove("backedCreds").remove("expires").commit(); - editor.putBoolean("loggedin", Authentication.isLoggedIn); - editor.putString("name", Authentication.name); - editor.commit(); - } - - /** - * @return list of multireddits if they are available, null if could not fetch multireddits - */ - public static void getMultireddits(final MultiCallback callback) { - new AsyncTask>() { - - @Override - protected List doInBackground(Void... params) { - loadMultireddits(); - return multireddits; - } - - @Override - protected void onPostExecute(List multiReddits) { - callback.onComplete(multiReddits); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - public interface MultiCallback { - void onComplete(List multis); - } - - public static void loadMultireddits() { - if (Authentication.isLoggedIn && Authentication.didOnline && (multireddits == null - || multireddits.isEmpty())) { - try { - multireddits = - new ArrayList<>(new MultiRedditManager(Authentication.reddit).mine()); - } catch (Exception e) { - multireddits = null; - e.printStackTrace(); - } - } - } - - /** - * @return list of multireddits if they are available, null if could not fetch multireddits - */ - public static void getPublicMultireddits(MultiCallback callback, final String profile) { - if (profile.isEmpty()) { - getMultireddits(callback); - } - - if (public_multireddits.get(profile) == null) { - // It appears your own multis are pre-loaded at some point - // but some other user's multis obviously can't be so - // don't return until we've loaded them. - loadPublicMultireddits(callback, profile); - } else { - callback.onComplete(public_multireddits.get(profile)); - } - } - - private static void loadPublicMultireddits(final MultiCallback callback, final String profile) { - new AsyncTask>() { - - @Override - protected List doInBackground(Void... params) { - try { - public_multireddits.put(profile, new ArrayList( - new MultiRedditManager(Authentication.reddit).getPublicMultis(profile))); - } catch (Exception e) { - public_multireddits.put(profile, null); - e.printStackTrace(); - } - return public_multireddits.get(profile); - } - - @Override - protected void onPostExecute(List multiReddits) { - callback.onComplete(multiReddits); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - private static CaseInsensitiveArrayList doModOf() { - CaseInsensitiveArrayList finished = new CaseInsensitiveArrayList(); - - UserSubredditsPaginator pag = - new UserSubredditsPaginator(Authentication.reddit, "moderator"); - pag.setLimit(100); - try { - while (pag.hasNext()) { - for (Subreddit s : pag.next()) { - finished.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); - } - } - modOf = (finished); - cacheModOf(); - } catch (Exception e) { - //failed; - e.printStackTrace(); - } - - return finished; - } - - public static void doFriendsOfMain(MainActivity main) { - main.doFriends(doFriendsOf()); - } - - private static List doFriendsOf() { - if (friends == null || friends.isEmpty()) { - friends = new CaseInsensitiveArrayList(); - CaseInsensitiveArrayList finished = new CaseInsensitiveArrayList(); - - ImportantUserPaginator pag = - new ImportantUserPaginator(Authentication.reddit, "friends"); - pag.setLimit(100); - try { - while (pag.hasNext()) { - for (UserRecord s : pag.next()) { - finished.add(s.getFullName()); - } - } - friends = (finished); - return friends; - - } catch (Exception e) { - //failed; - e.printStackTrace(); - } - } - return friends; - } - - public static MultiReddit getMultiredditByDisplayName(String displayName) { - if (multireddits != null) { - for (MultiReddit multiReddit : multireddits) { - if (multiReddit.getDisplayName().equals(displayName)) { - return multiReddit; - } - } - } - return null; - } - - public static MultiReddit getPublicMultiredditByDisplayName(String profile, - String displayName) { - if (profile.isEmpty()) { - return getMultiredditByDisplayName(displayName); - } - - if (public_multireddits.get(profile) != null) { - for (MultiReddit multiReddit : public_multireddits.get(profile)) { - if (multiReddit.getDisplayName().equals(displayName)) { - return multiReddit; - } - } - } - return null; - } - - //Gets user subscriptions + top 500 subs + subs in history - public static CaseInsensitiveArrayList getAllSubreddits(Context c) { - CaseInsensitiveArrayList finalReturn = new CaseInsensitiveArrayList(); - CaseInsensitiveArrayList history = getHistory(); - CaseInsensitiveArrayList defaults = getDefaults(c); - finalReturn.addAll(getSubscriptions(c)); - for (String s : finalReturn) { - history.remove(s); - defaults.remove(s); - } - for (String s : history) { - defaults.remove(s); - } - for (String s : history) { - if (!finalReturn.contains(s)) { - finalReturn.add(s); - } - } - for (String s : defaults) { - if (!finalReturn.contains(s)) { - finalReturn.add(s); - } - } - return finalReturn; - } - - //Gets user subscriptions + top 500 subs + subs in history - public static CaseInsensitiveArrayList getAllUserSubreddits(Context c) { - CaseInsensitiveArrayList finalReturn = new CaseInsensitiveArrayList(); - finalReturn.addAll(getSubscriptions(c)); - finalReturn.removeAll(getHistory()); - finalReturn.addAll(getHistory()); - return finalReturn; - } - - public static CaseInsensitiveArrayList getHistory() { - String[] hist = subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH).split(","); - CaseInsensitiveArrayList history = new CaseInsensitiveArrayList(); - Collections.addAll(history, hist); - return history; - } - - public static CaseInsensitiveArrayList getDefaults(Context c) { - CaseInsensitiveArrayList history = new CaseInsensitiveArrayList(); - Collections.addAll(history, c.getString(R.string.top_500_csv).split(",")); - return history; - } - - public static void addSubreddit(String s, Context c) { - CaseInsensitiveArrayList subs = getSubscriptions(c); - subs.add(s); - if (SettingValues.alphabetizeOnSubscribe) { - setSubscriptions(sortNoExtras(subs)); - } else { - setSubscriptions(subs); - } - } - - public static void removeSubreddit(String s, Context c) { - CaseInsensitiveArrayList subs = getSubscriptions(c); - subs.remove(s); - setSubscriptions(subs); - } - - public static void addPinned(String s, Context c) { - CaseInsensitiveArrayList subs = getPinned(); - subs.add(s); - setPinned(subs); - } - - public static void removePinned(String s, Context c) { - CaseInsensitiveArrayList subs = getPinned(); - subs.remove(s); - setPinned(subs); - } - - //Sets sub as "searched for", will apply to all accounts - public static void addSubToHistory(String s) { - String history = subscriptions.getString("subhistory", ""); - if (!history.contains(s.toLowerCase(Locale.ENGLISH))) { - history += "," + s.toLowerCase(Locale.ENGLISH); - subscriptions.edit().putString("subhistory", history).apply(); - } - } - - //Sets a list of subreddits as "searched for", will apply to all accounts - public static void addSubsToHistory(ArrayList s2) { - StringBuilder history = new StringBuilder(subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH)); - for (Subreddit s : s2) { - if (!history.toString().contains(s.getDisplayName().toLowerCase(Locale.ENGLISH))) { - history.append(",").append(s.getDisplayName().toLowerCase(Locale.ENGLISH)); - } - } - subscriptions.edit().putString("subhistory", history.toString()).apply(); - } - - public static void addSubsToHistory(CaseInsensitiveArrayList s2) { - StringBuilder history = new StringBuilder(subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH)); - for (String s : s2) { - if (!history.toString().contains(s.toLowerCase(Locale.ENGLISH))) { - history.append(",").append(s.toLowerCase(Locale.ENGLISH)); - } - } - subscriptions.edit().putString("subhistory", history.toString()).apply(); - } - - public static ArrayList syncSubredditsGetObject() { - ArrayList toReturn = new ArrayList<>(); - if (Authentication.isLoggedIn) { - UserSubredditsPaginator pag = - new UserSubredditsPaginator(Authentication.reddit, "subscriber"); - pag.setLimit(100); - - - try { - while (pag.hasNext()) { - toReturn.addAll(pag.next()); - } - - - } catch (Exception e) { - //failed; - e.printStackTrace(); - } - - addSubsToHistory(toReturn); - return toReturn; - } - return toReturn; - } - - public static void syncSubredditsGetObjectAsync(final Login mainActivity) { - final ArrayList toReturn = new ArrayList<>(); - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - if (Authentication.isLoggedIn) { - UserSubredditsPaginator pag = - new UserSubredditsPaginator(Authentication.reddit, "subscriber"); - pag.setLimit(100); - - - try { - while (pag.hasNext()) { - toReturn.addAll(pag.next()); - } - - - } catch (Exception e) { - //failed; - e.printStackTrace(); - } - } - return null; - - } - - @Override - protected void onPostExecute(Void aVoid) { - mainActivity.doLastStuff(toReturn); - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - /** - * Sorts the subreddit ArrayList, keeping special subreddits at the top of the list (e.g. - * frontpage, all, the random subreddits). Always adds frontpage and all - * - * @param unsorted the ArrayList to sort - * @return the sorted ArrayList - * @see #sortNoExtras(CaseInsensitiveArrayList) - */ - public static CaseInsensitiveArrayList sort(CaseInsensitiveArrayList unsorted) { - CaseInsensitiveArrayList subs = new CaseInsensitiveArrayList(unsorted); - - if (!subs.contains("frontpage")) { - subs.add("frontpage"); - } - - if (!subs.contains("all")) { - subs.add("all"); - } - - return sortNoExtras(subs); - } - - /** - * Sorts the subreddit ArrayList, keeping special subreddits at the top of the list (e.g. - * frontpage, all, the random subreddits) - * - * @param unsorted the ArrayList to sort - * @return the sorted ArrayList - * @see #sort(CaseInsensitiveArrayList) - */ - public static CaseInsensitiveArrayList sortNoExtras(CaseInsensitiveArrayList unsorted) { - List subs = new CaseInsensitiveArrayList(unsorted); - CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); - - for (String subreddit : getPinned()) { - if (subs.contains(subreddit)) { - subs.remove(subreddit); - finals.add(subreddit); - } - } - - for (String subreddit : specialSubreddits) { - if (subs.contains(subreddit)) { - subs.remove(subreddit); - finals.add(subreddit); - } - } - - - java.util.Collections.sort(subs, String.CASE_INSENSITIVE_ORDER); - finals.addAll(subs); - return finals; - } - - public static class SubscribeTask extends AsyncTask { - Context context; - public SubscribeTask(Context context){ - this.context = context; - } - - @Override - protected Void doInBackground(String... subreddits) { - final AccountManager m = new AccountManager(Authentication.reddit); - for (String subreddit : subreddits) { - try { - m.subscribe(Authentication.reddit.getSubreddit(subreddit)); - } catch(Exception e){ - Toast.makeText(context, "Couldn't subscribe, subreddit is private, quarantined, or invite only", Toast.LENGTH_SHORT).show(); - } - } - return null; - } - } - - public static class UnsubscribeTask extends AsyncTask { - @Override - protected Void doInBackground(String... subreddits) { - final AccountManager m = new AccountManager(Authentication.reddit); - try { - for (String subreddit : subreddits) { - m.unsubscribe(Authentication.reddit.getSubreddit(subreddit)); - } - } catch(Exception e){ - - } - return null; - } - } -} +package me.ccrama.redditslide; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.widget.Toast; + +import net.dean.jraw.ApiException; +import net.dean.jraw.http.NetworkException; +import net.dean.jraw.managers.AccountManager; +import net.dean.jraw.managers.MultiRedditManager; +import net.dean.jraw.models.MultiReddit; +import net.dean.jraw.models.MultiSubreddit; +import net.dean.jraw.models.Subreddit; +import net.dean.jraw.models.UserRecord; +import net.dean.jraw.paginators.ImportantUserPaginator; +import net.dean.jraw.paginators.UserSubredditsPaginator; + +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 me.ccrama.redditslide.Activities.Login; +import me.ccrama.redditslide.Activities.MainActivity; +import me.ccrama.redditslide.Activities.MultiredditOverview; +import me.ccrama.redditslide.Activities.NewsActivity; +import me.ccrama.redditslide.Toolbox.Toolbox; +import me.ccrama.redditslide.ui.settings.dragSort.ReorderSubreddits; +import me.ccrama.redditslide.util.NetworkUtil; +import me.ccrama.redditslide.util.StringUtil; + +/** + * Created by carlo_000 on 1/16/2016. + */ +public class UserSubscriptions { + public static final String SUB_NAME_TO_PROPERTIES = "multiNameToSubs"; + public static final List defaultSubs = + Arrays.asList("frontpage", "all", "announcements", "Art", "AskReddit", "askscience", + "aww", "blog", "books", "creepy", "dataisbeautiful", "DIY", "Documentaries", + "EarthPorn", "explainlikeimfive", "Fitness", "food", "funny", "Futurology", + "gadgets", "gaming", "GetMotivated", "gifs", "history", "IAmA", + "InternetIsBeautiful", "Jokes", "LifeProTips", "listentothis", + "mildlyinteresting", "movies", "Music", "news", "nosleep", "nottheonion", + "OldSchoolCool", "personalfinance", "philosophy", "photoshopbattles", "pics", + "science", "Showerthoughts", "space", "sports", "television", "tifu", + "todayilearned", "TwoXChromosomes", "UpliftingNews", "videos", "worldnews", + "WritingPrompts"); + public static final List specialSubreddits = + Arrays.asList("frontpage", "all", "random", "randnsfw", "myrandom", "friends", "mod", + "popular"); + public static SharedPreferences subscriptions; + public static SharedPreferences multiNameToSubs; + public static SharedPreferences newsNameToSubs; + public static SharedPreferences news; + public static SharedPreferences pinned; + + public static void setSubNameToProperties(String name, String descrption) { + multiNameToSubs.edit().putString(name, descrption).apply(); + } + + public static Map getMultiNameToSubs(boolean all) { + return getNameToSubs(multiNameToSubs, all); + } + + public static Map getNewsNameToSubs(boolean all) { + return getNameToSubs(newsNameToSubs, all); + } + + private static Map getNameToSubs(SharedPreferences sP, boolean all) { + Map multiNameToSubsMapBase = new HashMap<>(); + + Map multiNameToSubsObject = sP.getAll(); + + for (Map.Entry entry : multiNameToSubsObject.entrySet()) { + multiNameToSubsMapBase.put(entry.getKey(), entry.getValue().toString()); + } + if (all) multiNameToSubsMapBase.putAll(getSubsNameToMulti()); + + Map multiNameToSubsMap = new HashMap<>(); + + for (Map.Entry entries : multiNameToSubsMapBase.entrySet()) { + multiNameToSubsMap.put(entries.getKey().toLowerCase(Locale.ENGLISH), entries.getValue()); + } + + return multiNameToSubsMap; + } + + + private static Map getSubsNameToMulti() { + Map multiNameToSubsMap = new HashMap<>(); + + Map multiNameToSubsObject = multiNameToSubs.getAll(); + + for (Map.Entry entry : multiNameToSubsObject.entrySet()) { + multiNameToSubsMap.put(entry.getValue().toString(), entry.getKey()); + } + + return multiNameToSubsMap; + } + + public static void doMainActivitySubs(MainActivity c) { + if (NetworkUtil.isConnected(c)) { + String s = subscriptions.getString(Authentication.name, ""); + if (s.isEmpty()) { + //get online subs + c.updateSubs(syncSubscriptionsOverwrite(c)); + } else { + CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); + } + c.updateSubs(subredditsForHome); + } + c.updateMultiNameToSubs(getMultiNameToSubs(false)); + + } else { + String s = subscriptions.getString(Authentication.name, ""); + List subredditsForHome = new CaseInsensitiveArrayList(); + if (!s.isEmpty()) { + for (String s2 : s.split(",")) { + subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); + } + } + CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); + List offline = OfflineSubreddit.getAllFormatted(); + for (String subs : subredditsForHome) { + if (offline.contains(subs)) { + finals.add(subs); + } + } + for (String subs : offline) { + if (!finals.contains(subs)) { + finals.add(subs); + } + } + c.updateSubs(finals); + c.updateMultiNameToSubs(getMultiNameToSubs(false)); + } + } + + public static void doNewsSubs(NewsActivity c) { + if (NetworkUtil.isConnected(c)) { + String s = news.getString("subs", "news,android"); + if (s.isEmpty()) { + //get online subs + c.updateSubs(syncSubscriptionsOverwrite(c)); + } else { + CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); + } + c.updateSubs(subredditsForHome); + } + c.updateMultiNameToSubs(getNewsNameToSubs(false)); + + } else { + String s = news.getString("subs", "news,android"); + List subredditsForHome = new CaseInsensitiveArrayList(); + if (!s.isEmpty()) { + for (String s2 : s.split(",")) { + subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); + } + } + CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); + List offline = OfflineSubreddit.getAllFormatted(); + for (String subs : subredditsForHome) { + if (offline.contains(subs)) { + finals.add(subs); + } + } + for (String subs : offline) { + if (!finals.contains(subs)) { + finals.add(subs); + } + } + c.updateSubs(finals); + c.updateMultiNameToSubs(getMultiNameToSubs(false)); + } + } + + public static void doCachedModSubs() { + if (modOf == null || modOf.isEmpty()) { + String s = subscriptions.getString(Authentication.name + "mod", ""); + if (!s.isEmpty()) { + modOf = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + modOf.add(s2.toLowerCase(Locale.ENGLISH)); + } + } + } + } + + public static void cacheModOf() { + subscriptions.edit() + .putString(Authentication.name + "mod", StringUtil.arrayToString(modOf)) + .apply(); + } + + public static class SyncMultireddits extends AsyncTask { + + Context c; + + public SyncMultireddits(Context c) { + this.c = c; + } + + @Override + public void onPostExecute(Boolean b) { + Intent i = new Intent(c, MultiredditOverview.class); + c.startActivity(i); + ((Activity) c).finish(); + } + + @Override + public Boolean doInBackground(Void... params) { + syncMultiReddits(c); + return null; + } + } + + public static CaseInsensitiveArrayList getSubscriptions(Context c) { + String s = subscriptions.getString(Authentication.name, ""); + if (s.isEmpty()) { + //get online subs + return syncSubscriptionsOverwrite(c); + } else { + CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + if (!subredditsForHome.contains(s2)) subredditsForHome.add(s2); + } + return subredditsForHome; + } + } + + public static CaseInsensitiveArrayList pins; + + public static CaseInsensitiveArrayList getPinned() { + String s = pinned.getString(Authentication.name, ""); + if (s.isEmpty()) { + //get online subs + return new CaseInsensitiveArrayList(); + } else if (pins == null) { + pins = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + if (!pins.contains(s2)) pins.add(s2); + } + return pins; + } else { + return pins; + } + } + + public static CaseInsensitiveArrayList getSubscriptionsForShortcut(Context c) { + String s = subscriptions.getString(Authentication.name, ""); + if (s.isEmpty()) { + //get online subs + return syncSubscriptionsOverwrite(c); + } else { + CaseInsensitiveArrayList subredditsForHome = new CaseInsensitiveArrayList(); + for (String s2 : s.split(",")) { + if (!s2.contains("/m/")) subredditsForHome.add(s2.toLowerCase(Locale.ENGLISH)); + } + return subredditsForHome; + } + } + + public static boolean hasSubs() { + String s = subscriptions.getString(Authentication.name, ""); + return s.isEmpty(); + } + + public static CaseInsensitiveArrayList modOf; + public static ArrayList multireddits; + public static HashMap> public_multireddits = + new HashMap>(); + + public static void doOnlineSyncing() { + if (Authentication.mod) { + doModOf(); + if (modOf != null) { + for (String sub : modOf) { + Toolbox.ensureConfigCachedLoaded(sub); + Toolbox.ensureUsernotesCachedLoaded(sub); + } + } + } + doFriendsOf(); + loadMultireddits(); + } + + public static CaseInsensitiveArrayList toreturn; + public static CaseInsensitiveArrayList friends = new CaseInsensitiveArrayList(); + + public static CaseInsensitiveArrayList syncSubscriptionsOverwrite(final Context c) { + toreturn = new CaseInsensitiveArrayList(); + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + toreturn = syncSubreddits(c); + toreturn = sort(toreturn); + setSubscriptions(toreturn); + return null; + } + }.execute(); + + if (toreturn.isEmpty()) { + //failed, load defaults + toreturn.addAll(defaultSubs); + } + + return toreturn; + } + + public static CaseInsensitiveArrayList syncSubreddits(Context c) { + CaseInsensitiveArrayList toReturn = new CaseInsensitiveArrayList(); + if (Authentication.isLoggedIn && NetworkUtil.isConnected(c)) { + UserSubredditsPaginator pag = + new UserSubredditsPaginator(Authentication.reddit, "subscriber"); + pag.setLimit(100); + try { + while (pag.hasNext()) { + for (Subreddit s : pag.next()) { + toReturn.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); + } + } + if (toReturn.isEmpty() && subscriptions.getString(Authentication.name, "") + .isEmpty()) { + toreturn.addAll(defaultSubs); + } + } catch (Exception e) { + //failed; + e.printStackTrace(); + } + addSubsToHistory(toReturn); + } else { + toReturn.addAll(defaultSubs); + } + return toReturn; + } + + public static void syncMultiReddits(Context c) { + try { + multireddits = new ArrayList<>(new MultiRedditManager(Authentication.reddit).mine()); + for (MultiReddit multiReddit : multireddits) { + if (MainActivity.multiNameToSubsMap.containsKey( + ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName())) { + StringBuilder concatenatedSubs = new StringBuilder(); + for (MultiSubreddit subreddit : multiReddit.getSubreddits()) { + concatenatedSubs.append(subreddit.getDisplayName()); + concatenatedSubs.append("+"); + } + MainActivity.multiNameToSubsMap.put( + ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName(), + concatenatedSubs.toString()); + UserSubscriptions.setSubNameToProperties( + ReorderSubreddits.MULTI_REDDIT + multiReddit.getDisplayName(), + concatenatedSubs.toString()); + } + } + } catch (ApiException | NetworkException e) { + e.printStackTrace(); + } + } + + public static void setSubscriptions(CaseInsensitiveArrayList subs) { + subscriptions.edit().putString(Authentication.name, StringUtil.arrayToString(subs)).apply(); + } + + public static void setPinned(CaseInsensitiveArrayList subs) { + pinned.edit().putString(Authentication.name, StringUtil.arrayToString(subs)).apply(); + pins = null; + } + + public static void switchAccounts() { + SharedPreferences.Editor editor = Reddit.appRestart.edit(); + editor.putBoolean("back", true); + editor.putString("subs", ""); + Authentication.authentication.edit().remove("backedCreds").remove("expires").commit(); + editor.putBoolean("loggedin", Authentication.isLoggedIn); + editor.putString("name", Authentication.name); + editor.commit(); + } + + /** + * @return list of multireddits if they are available, null if could not fetch multireddits + */ + public static void getMultireddits(final MultiCallback callback) { + new AsyncTask>() { + + @Override + protected List doInBackground(Void... params) { + loadMultireddits(); + return multireddits; + } + + @Override + protected void onPostExecute(List multiReddits) { + callback.onComplete(multiReddits); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + public interface MultiCallback { + void onComplete(List multis); + } + + public static void loadMultireddits() { + if (Authentication.isLoggedIn && Authentication.didOnline && (multireddits == null + || multireddits.isEmpty())) { + try { + multireddits = + new ArrayList<>(new MultiRedditManager(Authentication.reddit).mine()); + } catch (Exception e) { + multireddits = null; + e.printStackTrace(); + } + } + } + + /** + * @return list of multireddits if they are available, null if could not fetch multireddits + */ + public static void getPublicMultireddits(MultiCallback callback, final String profile) { + if (profile.isEmpty()) { + getMultireddits(callback); + } + + if (public_multireddits.get(profile) == null) { + // It appears your own multis are pre-loaded at some point + // but some other user's multis obviously can't be so + // don't return until we've loaded them. + loadPublicMultireddits(callback, profile); + } else { + callback.onComplete(public_multireddits.get(profile)); + } + } + + private static void loadPublicMultireddits(final MultiCallback callback, final String profile) { + new AsyncTask>() { + + @Override + protected List doInBackground(Void... params) { + try { + public_multireddits.put(profile, new ArrayList( + new MultiRedditManager(Authentication.reddit).getPublicMultis(profile))); + } catch (Exception e) { + public_multireddits.put(profile, null); + e.printStackTrace(); + } + return public_multireddits.get(profile); + } + + @Override + protected void onPostExecute(List multiReddits) { + callback.onComplete(multiReddits); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + private static CaseInsensitiveArrayList doModOf() { + CaseInsensitiveArrayList finished = new CaseInsensitiveArrayList(); + + UserSubredditsPaginator pag = + new UserSubredditsPaginator(Authentication.reddit, "moderator"); + pag.setLimit(100); + try { + while (pag.hasNext()) { + for (Subreddit s : pag.next()) { + finished.add(s.getDisplayName().toLowerCase(Locale.ENGLISH)); + } + } + modOf = (finished); + cacheModOf(); + } catch (Exception e) { + //failed; + e.printStackTrace(); + } + + return finished; + } + + public static void doFriendsOfMain(MainActivity main) { + main.doFriends(doFriendsOf()); + } + + private static List doFriendsOf() { + if (friends == null || friends.isEmpty()) { + friends = new CaseInsensitiveArrayList(); + CaseInsensitiveArrayList finished = new CaseInsensitiveArrayList(); + + ImportantUserPaginator pag = + new ImportantUserPaginator(Authentication.reddit, "friends"); + pag.setLimit(100); + try { + while (pag.hasNext()) { + for (UserRecord s : pag.next()) { + finished.add(s.getFullName()); + } + } + friends = (finished); + return friends; + + } catch (Exception e) { + //failed; + e.printStackTrace(); + } + } + return friends; + } + + public static MultiReddit getMultiredditByDisplayName(String displayName) { + if (multireddits != null) { + for (MultiReddit multiReddit : multireddits) { + if (multiReddit.getDisplayName().equals(displayName)) { + return multiReddit; + } + } + } + return null; + } + + public static MultiReddit getPublicMultiredditByDisplayName(String profile, + String displayName) { + if (profile.isEmpty()) { + return getMultiredditByDisplayName(displayName); + } + + if (public_multireddits.get(profile) != null) { + for (MultiReddit multiReddit : public_multireddits.get(profile)) { + if (multiReddit.getDisplayName().equals(displayName)) { + return multiReddit; + } + } + } + return null; + } + + //Gets user subscriptions + top 500 subs + subs in history + public static CaseInsensitiveArrayList getAllSubreddits(Context c) { + CaseInsensitiveArrayList finalReturn = new CaseInsensitiveArrayList(); + CaseInsensitiveArrayList history = getHistory(); + CaseInsensitiveArrayList defaults = getDefaults(c); + finalReturn.addAll(getSubscriptions(c)); + for (String s : finalReturn) { + history.remove(s); + defaults.remove(s); + } + for (String s : history) { + defaults.remove(s); + } + for (String s : history) { + if (!finalReturn.contains(s)) { + finalReturn.add(s); + } + } + for (String s : defaults) { + if (!finalReturn.contains(s)) { + finalReturn.add(s); + } + } + return finalReturn; + } + + //Gets user subscriptions + top 500 subs + subs in history + public static CaseInsensitiveArrayList getAllUserSubreddits(Context c) { + CaseInsensitiveArrayList finalReturn = new CaseInsensitiveArrayList(); + finalReturn.addAll(getSubscriptions(c)); + finalReturn.removeAll(getHistory()); + finalReturn.addAll(getHistory()); + return finalReturn; + } + + public static CaseInsensitiveArrayList getHistory() { + String[] hist = subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH).split(","); + CaseInsensitiveArrayList history = new CaseInsensitiveArrayList(); + Collections.addAll(history, hist); + return history; + } + + public static CaseInsensitiveArrayList getDefaults(Context c) { + CaseInsensitiveArrayList history = new CaseInsensitiveArrayList(); + Collections.addAll(history, c.getString(R.string.top_500_csv).split(",")); + return history; + } + + public static void addSubreddit(String s, Context c) { + CaseInsensitiveArrayList subs = getSubscriptions(c); + subs.add(s); + if (SettingValues.alphabetizeOnSubscribe) { + setSubscriptions(sortNoExtras(subs)); + } else { + setSubscriptions(subs); + } + } + + public static void removeSubreddit(String s, Context c) { + CaseInsensitiveArrayList subs = getSubscriptions(c); + subs.remove(s); + setSubscriptions(subs); + } + + public static void addPinned(String s, Context c) { + CaseInsensitiveArrayList subs = getPinned(); + subs.add(s); + setPinned(subs); + } + + public static void removePinned(String s, Context c) { + CaseInsensitiveArrayList subs = getPinned(); + subs.remove(s); + setPinned(subs); + } + + //Sets sub as "searched for", will apply to all accounts + public static void addSubToHistory(String s) { + String history = subscriptions.getString("subhistory", ""); + if (!history.contains(s.toLowerCase(Locale.ENGLISH))) { + history += "," + s.toLowerCase(Locale.ENGLISH); + subscriptions.edit().putString("subhistory", history).apply(); + } + } + + //Sets a list of subreddits as "searched for", will apply to all accounts + public static void addSubsToHistory(ArrayList s2) { + StringBuilder history = new StringBuilder(subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH)); + for (Subreddit s : s2) { + if (!history.toString().contains(s.getDisplayName().toLowerCase(Locale.ENGLISH))) { + history.append(",").append(s.getDisplayName().toLowerCase(Locale.ENGLISH)); + } + } + subscriptions.edit().putString("subhistory", history.toString()).apply(); + } + + public static void addSubsToHistory(CaseInsensitiveArrayList s2) { + StringBuilder history = new StringBuilder(subscriptions.getString("subhistory", "").toLowerCase(Locale.ENGLISH)); + for (String s : s2) { + if (!history.toString().contains(s.toLowerCase(Locale.ENGLISH))) { + history.append(",").append(s.toLowerCase(Locale.ENGLISH)); + } + } + subscriptions.edit().putString("subhistory", history.toString()).apply(); + } + + public static ArrayList syncSubredditsGetObject() { + ArrayList toReturn = new ArrayList<>(); + if (Authentication.isLoggedIn) { + UserSubredditsPaginator pag = + new UserSubredditsPaginator(Authentication.reddit, "subscriber"); + pag.setLimit(100); + + + try { + while (pag.hasNext()) { + toReturn.addAll(pag.next()); + } + + + } catch (Exception e) { + //failed; + e.printStackTrace(); + } + + addSubsToHistory(toReturn); + return toReturn; + } + return toReturn; + } + + public static void syncSubredditsGetObjectAsync(final Login mainActivity) { + final ArrayList toReturn = new ArrayList<>(); + new AsyncTask() { + @Override + protected Void doInBackground(Void... params) { + if (Authentication.isLoggedIn) { + UserSubredditsPaginator pag = + new UserSubredditsPaginator(Authentication.reddit, "subscriber"); + pag.setLimit(100); + + + try { + while (pag.hasNext()) { + toReturn.addAll(pag.next()); + } + + + } catch (Exception e) { + //failed; + e.printStackTrace(); + } + } + return null; + + } + + @Override + protected void onPostExecute(Void aVoid) { + mainActivity.doLastStuff(toReturn); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + /** + * Sorts the subreddit ArrayList, keeping special subreddits at the top of the list (e.g. + * frontpage, all, the random subreddits). Always adds frontpage and all + * + * @param unsorted the ArrayList to sort + * @return the sorted ArrayList + * @see #sortNoExtras(CaseInsensitiveArrayList) + */ + public static CaseInsensitiveArrayList sort(CaseInsensitiveArrayList unsorted) { + CaseInsensitiveArrayList subs = new CaseInsensitiveArrayList(unsorted); + + if (!subs.contains("frontpage")) { + subs.add("frontpage"); + } + + if (!subs.contains("all")) { + subs.add("all"); + } + + return sortNoExtras(subs); + } + + /** + * Sorts the subreddit ArrayList, keeping special subreddits at the top of the list (e.g. + * frontpage, all, the random subreddits) + * + * @param unsorted the ArrayList to sort + * @return the sorted ArrayList + * @see #sort(CaseInsensitiveArrayList) + */ + public static CaseInsensitiveArrayList sortNoExtras(CaseInsensitiveArrayList unsorted) { + List subs = new CaseInsensitiveArrayList(unsorted); + CaseInsensitiveArrayList finals = new CaseInsensitiveArrayList(); + + for (String subreddit : getPinned()) { + if (subs.contains(subreddit)) { + subs.remove(subreddit); + finals.add(subreddit); + } + } + + for (String subreddit : specialSubreddits) { + if (subs.contains(subreddit)) { + subs.remove(subreddit); + finals.add(subreddit); + } + } + + + java.util.Collections.sort(subs, String.CASE_INSENSITIVE_ORDER); + finals.addAll(subs); + return finals; + } + + public static class SubscribeTask extends AsyncTask { + Context context; + public SubscribeTask(Context context){ + this.context = context; + } + + @Override + protected Void doInBackground(String... subreddits) { + final AccountManager m = new AccountManager(Authentication.reddit); + for (String subreddit : subreddits) { + try { + m.subscribe(Authentication.reddit.getSubreddit(subreddit)); + } catch(Exception e){ + Toast.makeText(context, "Couldn't subscribe, subreddit is private, quarantined, or invite only", Toast.LENGTH_SHORT).show(); + } + } + return null; + } + } + + public static class UnsubscribeTask extends AsyncTask { + @Override + protected Void doInBackground(String... subreddits) { + final AccountManager m = new AccountManager(Authentication.reddit); + try { + for (String subreddit : subreddits) { + m.unsubscribe(Authentication.reddit.getSubreddit(subreddit)); + } + } catch(Exception e){ + + } + return null; + } + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/Views/DoEditorActions.java b/app/src/main/java/me/ccrama/redditslide/Views/DoEditorActions.java index f7c64ffa2..78bb2646a 100644 --- a/app/src/main/java/me/ccrama/redditslide/Views/DoEditorActions.java +++ b/app/src/main/java/me/ccrama/redditslide/Views/DoEditorActions.java @@ -1,786 +1,786 @@ -package me.ccrama.redditslide.Views; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.net.Uri; -import android.text.Editable; -import android.util.Base64; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; -import com.google.android.material.snackbar.Snackbar; - -import org.apache.commons.text.StringEscapeUtils; -import org.commonmark.Extension; -import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; -import org.commonmark.ext.gfm.tables.TablesExtension; -import org.commonmark.html.HtmlRenderer; -import org.commonmark.node.Node; -import org.commonmark.parser.Parser; -import org.json.JSONObject; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import gun0912.tedbottompicker.TedBottomPicker; -import me.ccrama.redditslide.Activities.Draw; -import me.ccrama.redditslide.Drafts; -import me.ccrama.redditslide.ImgurAlbum.UploadImgur; -import me.ccrama.redditslide.ImgurAlbum.UploadImgurAlbum; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.SpoilerRobotoTextView; -import me.ccrama.redditslide.Visuals.ColorPreferences; -import me.ccrama.redditslide.util.DisplayUtil; -import me.ccrama.redditslide.util.KeyboardUtil; -import me.ccrama.redditslide.util.ProUtil; -import me.ccrama.redditslide.util.SubmissionParser; - -/** - * Created by carlo_000 on 10/18/2015. - */ -public class DoEditorActions { - - public static void doActions(final EditText editText, final View baseView, - final FragmentManager fm, final Activity a, final String oldComment, - @Nullable final String[] authors) { - baseView.findViewById(R.id.bold).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (editText.hasSelection()) { - wrapString("**", - editText); //If the user has text selected, wrap that text in the symbols - } else { - //If the user doesn't have text selected, put the symbols around the cursor's position - int pos = editText.getSelectionStart(); - editText.getText().insert(pos, "**"); - editText.getText().insert(pos + 1, "**"); - editText.setSelection(pos + 2); //put the cursor between the symbols - } - } - }); - - if (baseView.findViewById(R.id.author) != null) { - if (authors != null && authors.length > 0) { - baseView.findViewById(R.id.author).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (authors.length == 1) { - String author = "/u/" + authors[0]; - insertBefore(author, editText); - } else { - new AlertDialog.Builder(a) - .setTitle(R.string.authors_above) - .setItems(authors, (dialog, which) -> { - String author = "/u/" + authors[which]; - insertBefore(author, editText); - }) - .setNeutralButton(R.string.btn_cancel, null) - .show(); - } - } - }); - } else { - baseView.findViewById(R.id.author).setVisibility(View.GONE); - } - } - - baseView.findViewById(R.id.italics).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (editText.hasSelection()) { - wrapString("*", - editText); //If the user has text selected, wrap that text in the symbols - } else { - //If the user doesn't have text selected, put the symbols around the cursor's position - int pos = editText.getSelectionStart(); - editText.getText().insert(pos, "*"); - editText.getText().insert(pos + 1, "*"); - editText.setSelection(pos + 1); //put the cursor between the symbols - } - } - }); - - baseView.findViewById(R.id.strike).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (editText.hasSelection()) { - wrapString("~~", - editText); //If the user has text selected, wrap that text in the symbols - } else { - //If the user doesn't have text selected, put the symbols around the cursor's position - int pos = editText.getSelectionStart(); - editText.getText().insert(pos, "~~"); - editText.getText().insert(pos + 2, "~~"); - editText.setSelection(pos + 2); //put the cursor between the symbols - } - } - }); - - baseView.findViewById(R.id.spoiler).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (editText.hasSelection()) { - wrapString(">!", "!<", editText); //If the user has text selected, wrap that text in the symbols - } else { - //If the user doesn't have text selected, put the symbols around the cursor's position - int pos = editText.getSelectionStart(); - editText.getText().insert(pos, ">!"); - editText.getText().insert(pos + 2, "!<"); - editText.setSelection(pos + 2); //put the cursor between the symbols - } - } - }); - - baseView.findViewById(R.id.savedraft).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Drafts.addDraft(editText.getText().toString()); - Snackbar s = Snackbar.make(baseView.findViewById(R.id.savedraft), "Draft saved", - Snackbar.LENGTH_SHORT); - View view = s.getView(); - TextView tv = view.findViewById(com.google.android.material.R.id.snackbar_text); - tv.setTextColor(Color.WHITE); - s.setAction(R.string.btn_discard, new View.OnClickListener() { - @Override - public void onClick(View view) { - Drafts.deleteDraft(Drafts.getDrafts().size() - 1); - } - }); - s.show(); - } - }); - baseView.findViewById(R.id.draft).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final ArrayList drafts = Drafts.getDrafts(); - Collections.reverse(drafts); - final String[] draftText = new String[drafts.size()]; - for (int i = 0; i < drafts.size(); i++) { - draftText[i] = drafts.get(i); - } - if (drafts.isEmpty()) { - new AlertDialog.Builder(a) - .setTitle(R.string.dialog_no_drafts) - .setMessage(R.string.dialog_no_drafts_msg) - .setPositiveButton(R.string.btn_ok, null) - .show(); - } else { - new AlertDialog.Builder(a) - .setTitle(R.string.choose_draft) - .setItems(draftText, (dialog, which) -> - editText.setText(editText.getText().toString() + draftText[which])) - .setNeutralButton(R.string.btn_cancel, null) - .setPositiveButton(R.string.manage_drafts, (dialog, which) -> { - final boolean[] selected = new boolean[drafts.size()]; - new AlertDialog.Builder(a) - .setTitle(R.string.choose_draft) - .setNeutralButton(R.string.btn_cancel, null) - .setNegativeButton(R.string.btn_delete, (dialog1, which1) -> - new AlertDialog.Builder(a) - .setTitle(R.string.really_delete_drafts) - .setCancelable(false) - .setPositiveButton(R.string.btn_yes, (dialog11, which11) -> { - ArrayList draf = new ArrayList<>(); - for (int i = 0; i < draftText.length; i++) { - if (!selected[i]) { - draf.add(draftText[i]); - } - } - Drafts.save(draf); - }) - .setNegativeButton(R.string.btn_no, null) - .show()) - .setMultiChoiceItems(draftText, selected, (dialog12, which12, isChecked) -> - selected[which12] = isChecked) - .show(); - }) - .show(); - } - } - }); - baseView.findViewById(R.id.imagerep).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - e = editText.getText(); - - sStart = editText.getSelectionStart(); - sEnd = editText.getSelectionEnd(); - - TedBottomPicker tedBottomPicker = new TedBottomPicker.Builder(editText.getContext()) - .setOnImageSelectedListener(new TedBottomPicker.OnImageSelectedListener() { - @Override - public void onImageSelected(List uri) { - handleImageIntent(uri, editText, a); - } - }) - .setLayoutResource(R.layout.image_sheet_dialog) - .setTitle("Choose a photo") - .create(); - - tedBottomPicker.show(fm); - KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); - } - }); - - baseView.findViewById(R.id.draw).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (SettingValues.isPro) { - doDraw(a, editText, fm); - } else { - final AlertDialog.Builder b = - ProUtil.proUpgradeMsg(a, R.string.general_cropdraw_ispro) - .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> - dialog.dismiss()); - if (SettingValues.previews > 0) { - b.setNeutralButton( - a.getString(R.string.pro_previews, SettingValues.previews), - (dialog, which) -> { - SettingValues.prefs.edit() - .putInt(SettingValues.PREVIEWS_LEFT, - SettingValues.previews - 1) - .apply(); - SettingValues.previews = SettingValues.prefs.getInt( - SettingValues.PREVIEWS_LEFT, 10); - doDraw(a, editText, fm); - }); - } - b.show(); - } - } - }); - /*todo baseView.findViewById(R.id.superscript).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - insertBefore("^", editText); - } - });*/ - baseView.findViewById(R.id.size).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - insertBefore("#", editText); - } - }); - - baseView.findViewById(R.id.quote).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - if (oldComment != null) { - final TextView showText = new TextView(a); - showText.setText(StringEscapeUtils.unescapeHtml4(oldComment)); // text we get is escaped, we don't want that - showText.setTextIsSelectable(true); - int sixteen = DisplayUtil.dpToPxVertical(24); - showText.setPadding(sixteen, 0, sixteen, 0); - MaterialDialog.Builder builder = new MaterialDialog.Builder(a); - builder.customView(showText, false) - .title(R.string.editor_actions_quote_comment) - .cancelable(true) - .positiveText(a.getString(R.string.btn_select)) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { - String selected = showText.getText() - .toString() - .substring(showText.getSelectionStart(), showText.getSelectionEnd()); - if (selected.isEmpty()) { - selected = StringEscapeUtils.unescapeHtml4(oldComment); - } - insertBefore("> " + selected.replaceAll("\n", "\n> ") + "\n\n", editText); - } - }) - .negativeText(a.getString(R.string.btn_cancel)) - .show(); - KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); - } else { - insertBefore("> ", editText); - } - } - }); - - baseView.findViewById(R.id.bulletlist).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int start = editText.getSelectionStart(); - int end = editText.getSelectionEnd(); - String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); - if (!selected.isEmpty()) { - selected = selected.replaceFirst("^[^\n]", "* $0").replaceAll("\n", "\n* "); - editText.getText().replace(Math.min(start, end), Math.max(start, end), selected); - } else { - insertBefore("* ", editText); - } - } - }); - - baseView.findViewById(R.id.numlist).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - int start = editText.getSelectionStart(); - int end = editText.getSelectionEnd(); - String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); - if (!selected.isEmpty()) { - selected = selected.replaceFirst("^[^\n]", "1. $0").replaceAll("\n", "\n1. "); - editText.getText().replace(Math.min(start, end), Math.max(start, end), selected); - } else { - insertBefore("1. ", editText); - } - } - }); - - baseView.findViewById(R.id.preview).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - List extensions = - Arrays.asList(TablesExtension.create(), StrikethroughExtension.create()); - Parser parser = Parser.builder().extensions(extensions).build(); - HtmlRenderer renderer = HtmlRenderer.builder().extensions(extensions).build(); - Node document = parser.parse(editText.getText().toString()); - String html = renderer.render(document); - LayoutInflater inflater = a.getLayoutInflater(); - final View dialoglayout = inflater.inflate(R.layout.parent_comment_dialog, null); - setViews(html, "NO sub", - dialoglayout.findViewById(R.id.firstTextView), - dialoglayout.findViewById(R.id.commentOverflow)); - - new AlertDialog.Builder(a) - .setView(dialoglayout) - .show(); - } - }); - - baseView.findViewById(R.id.link).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final LayoutInflater inflater = LayoutInflater.from(a); - final LinearLayout layout = - (LinearLayout) inflater.inflate(R.layout.insert_link, null); - - int[] attrs = {R.attr.fontColor}; - - TypedArray ta = baseView.getContext() - .obtainStyledAttributes( - new ColorPreferences(baseView.getContext()).getFontStyle() - .getBaseId(), attrs); - ta.recycle(); - - String selectedText = ""; - //if the user highlighted text before inputting a URL, use that text for the descriptionBox - if (editText.hasSelection()) { - final int startSelection = editText.getSelectionStart(); - final int endSelection = editText.getSelectionEnd(); - - selectedText = - editText.getText().toString().substring(startSelection, endSelection); - } - - final boolean selectedTextNotEmpty = !selectedText.isEmpty(); - - final MaterialDialog dialog = - new MaterialDialog.Builder(editText.getContext()).title( - R.string.editor_title_link) - .customView(layout, false) - .positiveColorAttr(R.attr.tintColor) - .positiveText(R.string.editor_action_link) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(@NonNull MaterialDialog dialog, - @NonNull DialogAction which) { - final EditText urlBox = - (EditText) dialog.findViewById(R.id.url_box); - final EditText textBox = - (EditText) dialog.findViewById(R.id.text_box); - dialog.dismiss(); - - final String s = "[" + textBox.getText().toString() - + "](" - + urlBox.getText().toString() - + ")"; - - int start = Math.max(editText.getSelectionStart(), 0); - int end = Math.max(editText.getSelectionEnd(), 0); - - editText.getText().insert(Math.max(start, end), s); - - //delete the selected text to avoid duplication - if (selectedTextNotEmpty) { - editText.getText().delete(start, end); - } - } - }) - .build(); - - //Tint the hint text if the base theme is Sepia - if (SettingValues.currentTheme == 5) { - ((EditText) dialog.findViewById(R.id.url_box)).setHintTextColor( - ContextCompat.getColor(dialog.getContext(), R.color.md_grey_600)); - ((EditText) dialog.findViewById(R.id.text_box)).setHintTextColor( - ContextCompat.getColor(dialog.getContext(), R.color.md_grey_600)); - } - - //use the selected text as the text for the link - if (!selectedText.isEmpty()) { - ((EditText) dialog.findViewById(R.id.text_box)).setText(selectedText); - } - - dialog.show(); - } - }); - - try { - ((ImageInsertEditText) editText).setImageSelectedCallback( - new ImageInsertEditText.ImageSelectedCallback() { - @Override - public void onImageSelected(final Uri content, String mimeType) { - e = editText.getText(); - - sStart = editText.getSelectionStart(); - sEnd = editText.getSelectionEnd(); - handleImageIntent(new ArrayList() {{ - add(content); - }}, editText, a); - } - }); - } catch (Exception e) { - //if thrown, there is likely an issue implementing this on the user's version of Android. There shouldn't be an issue, but just in case - } - } - - public static Editable e; - public static int sStart, sEnd; - - public static void doDraw(final Activity a, final EditText editText, final FragmentManager fm) { - final Intent intent = new Intent(a, Draw.class); - KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); - e = editText.getText(); - TedBottomPicker tedBottomPicker = - new TedBottomPicker.Builder(editText.getContext()).setOnImageSelectedListener( - new TedBottomPicker.OnImageSelectedListener() { - @Override - public void onImageSelected(List uri) { - Draw.uri = uri.get(0); - Fragment auxiliary = new AuxiliaryFragment(); - - sStart = editText.getSelectionStart(); - sEnd = editText.getSelectionEnd(); - - fm.beginTransaction().add(auxiliary, "IMAGE_UPLOAD").commit(); - fm.executePendingTransactions(); - - auxiliary.startActivityForResult(intent, 3333); - } - }) - .setLayoutResource(R.layout.image_sheet_dialog) - .setTitle("Choose a photo") - .create(); - - tedBottomPicker.show(fm); - } - - public static class AuxiliaryFragment extends Fragment { - @Override - public void onActivityResult(int requestCode, int resultCode, final Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if(data != null && data.getData() != null) { - handleImageIntent(new ArrayList() {{ - add(data.getData()); - }}, e, getContext()); - - getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); - } - - } - } - - public static String getImageLink(Bitmap b) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - b.compress(Bitmap.CompressFormat.JPEG, 100, - baos); // Not sure whether this should be jpeg or png, try both and see which works best - return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); - } - - public static void insertBefore(String wrapText, EditText editText) { - int start = Math.max(editText.getSelectionStart(), 0); - int end = Math.max(editText.getSelectionEnd(), 0); - editText.getText().insert(Math.min(start, end), wrapText); - } - - /* not using this method anywhere ¯\_(ツ)_/¯ */ -// public static void wrapNewline(String wrapText, EditText editText) { -// int start = Math.max(editText.getSelectionStart(), 0); -// int end = Math.max(editText.getSelectionEnd(), 0); -// String s = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); -// s = s.replace("\n", "\n" + wrapText); -// editText.getText().replace(Math.min(start, end), Math.max(start, end), s); -// } - - /** - * Wrap selected text in one or multiple characters, handling newlines and spaces properly for markdown - * @param wrapText Character(s) to wrap the selected text in - * @param editText EditText - */ - public static void wrapString(String wrapText, EditText editText) { - wrapString(wrapText, wrapText, editText); - } - - /** - * Wrap selected text in one or multiple characters, handling newlines, spaces, >s properly for markdown, - * with different start and end text. - * @param startWrap Character(s) to start wrapping with - * @param endWrap Character(s) to close wrapping with - * @param editText EditText - */ - public static void wrapString(String startWrap, String endWrap, EditText editText) { - int start = Math.max(editText.getSelectionStart(), 0); - int end = Math.max(editText.getSelectionEnd(), 0); - String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); - // insert the wrapping character inside any selected spaces and >s because they stop markdown formatting - // we use replaceFirst because anchors (\A, \Z) aren't consumed - selected = selected.replaceFirst("\\A[\\n> ]*", "$0" + startWrap) - .replaceFirst("[\\n> ]*\\Z", endWrap + "$0"); - // 2+ newlines stop formatting, so we do the formatting on each instance of text surrounded by 2+ newlines - /* in case anyone needs to understand this in the future: - * ([^\n> ]) captures any character that isn't a newline, >, or space - * (\n[> ]*){2,} captures any number of two or more newlines with any combination of spaces or >s since markdown ignores those by themselves - * (?=[^\n> ]) performs a lookahead and ensures there's a character that isn't a newline, >, or space - */ - selected = selected.replaceAll("([^\\n> ])(\\n[> ]*){2,}(?=[^\\n> ])", "$1" + endWrap + "$2" + startWrap); - editText.getText().replace(start, end, selected); - } - - private static void setViews(String rawHTML, String subredditName, - SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow) { - if (rawHTML.isEmpty()) { - return; - } - - List blocks = SubmissionParser.getBlocks(rawHTML); - - int startIndex = 0; - // the
case is when the body contains a table or code block first - if (!blocks.get(0).equals("
")) { - firstTextView.setVisibility(View.VISIBLE); - firstTextView.setTextHtml(blocks.get(0), subredditName); - firstTextView.setLinkTextColor( - new ColorPreferences(firstTextView.getContext()).getColor(subredditName)); - startIndex = 1; - } else { - firstTextView.setText(""); - firstTextView.setVisibility(View.GONE); - } - - if (blocks.size() > 1) { - if (startIndex == 0) { - commentOverflow.setViews(blocks, subredditName); - } else { - commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); - } - } else { - commentOverflow.removeAllViews(); - } - } - - private static class UploadImgurDEA extends UploadImgur { - - public UploadImgurDEA(Context c) { - this.c = c; - dialog = new MaterialDialog.Builder(c).title( - c.getString(R.string.editor_uploading_image)) - .progress(false, 100) - .cancelable(false) - .show(); - } - - @Override - protected void onPostExecute(final JSONObject result) { - dialog.dismiss(); - try { - int[] attrs = {R.attr.fontColor}; - TypedArray ta = - c.obtainStyledAttributes(new ColorPreferences(c).getFontStyle().getBaseId(), - attrs); - final String url = result.getJSONObject("data").getString("link"); - LinearLayout layout = new LinearLayout(c); - layout.setOrientation(LinearLayout.VERTICAL); - - final TextView titleBox = new TextView(c); - titleBox.setText(url); - layout.addView(titleBox); - titleBox.setEnabled(false); - titleBox.setTextColor(ta.getColor(0, Color.WHITE)); - - final EditText descriptionBox = new EditText(c); - descriptionBox.setHint(R.string.editor_title); - descriptionBox.setEnabled(true); - descriptionBox.setTextColor(ta.getColor(0, Color.WHITE)); - KeyboardUtil.toggleKeyboard(c, - InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); - - if (DoEditorActions.e != null) { - descriptionBox.setText(DoEditorActions.e.toString().substring(sStart, sEnd)); - } - - ta.recycle(); - int sixteen = DisplayUtil.dpToPxVertical(16); - layout.setPadding(sixteen, sixteen, sixteen, sixteen); - layout.addView(descriptionBox); - new MaterialDialog.Builder(c).title(R.string.editor_title_link) - .customView(layout, false) - .positiveText(R.string.editor_action_link) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { - dialog.dismiss(); - String s = "[" - + descriptionBox.getText().toString() - + "](" - + url - + ")"; - if (descriptionBox.getText().toString().trim().isEmpty()) { - s = url + " "; - } - int start = Math.max(sStart, 0); - int end = Math.max(sEnd, 0); - if (DoEditorActions.e != null) { - DoEditorActions.e.insert(Math.max(start, end), s); - DoEditorActions.e.delete(start, end); - DoEditorActions.e = null; - } - sStart = 0; - sEnd = 0; - } - }) - .canceledOnTouchOutside(false) - .show(); - - } catch (Exception e) { - new AlertDialog.Builder(c) - .setTitle(R.string.err_title) - .setMessage(R.string.editor_err_msg) - .setPositiveButton(R.string.btn_ok, null) - .show(); - e.printStackTrace(); - } - } - } - - private static class UploadImgurAlbumDEA extends UploadImgurAlbum { - - public UploadImgurAlbumDEA(Context c) { - this.c = c; - dialog = new MaterialDialog.Builder(c).title( - c.getString(R.string.editor_uploading_image)) - .progress(false, 100) - .cancelable(false) - .show(); - } - - @Override - protected void onPostExecute(final String result) { - dialog.dismiss(); - try { - int[] attrs = {R.attr.fontColor}; - TypedArray ta = - c.obtainStyledAttributes(new ColorPreferences(c).getFontStyle().getBaseId(), - attrs); - LinearLayout layout = new LinearLayout(c); - layout.setOrientation(LinearLayout.VERTICAL); - - final TextView titleBox = new TextView(c); - titleBox.setText(finalUrl); - layout.addView(titleBox); - titleBox.setEnabled(false); - titleBox.setTextColor(ta.getColor(0, Color.WHITE)); - - final EditText descriptionBox = new EditText(c); - descriptionBox.setHint(R.string.editor_title); - descriptionBox.setEnabled(true); - descriptionBox.setTextColor(ta.getColor(0, Color.WHITE)); - - if (DoEditorActions.e != null) { - descriptionBox.setText(DoEditorActions.e.toString().substring(sStart, sEnd)); - } - - ta.recycle(); - int sixteen = DisplayUtil.dpToPxVertical(16); - layout.setPadding(sixteen, sixteen, sixteen, sixteen); - layout.addView(descriptionBox); - new MaterialDialog.Builder(c).title(R.string.editor_title_link) - .customView(layout, false) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(MaterialDialog dialog, DialogAction which) { - dialog.dismiss(); - String s = "[" - + descriptionBox.getText().toString() - + "](" - + finalUrl - + ")"; - int start = Math.max(sStart, 0); - int end = Math.max(sEnd, 0); - DoEditorActions.e.insert(Math.max(start, end), s); - DoEditorActions.e.delete(start, end); - DoEditorActions.e = null; - sStart = 0; - sEnd = 0; - } - }) - .positiveText(R.string.editor_action_link) - .canceledOnTouchOutside(false) - .show(); - - } catch (Exception e) { - new AlertDialog.Builder(c) - .setTitle(R.string.err_title) - .setMessage(R.string.editor_err_msg) - .setPositiveButton(R.string.btn_ok, null) - .show(); - e.printStackTrace(); - } - } - } - - public static void handleImageIntent(List uris, EditText ed, Context c) { - handleImageIntent(uris, ed.getText(), c); - } - - public static void handleImageIntent(List uris, Editable ed, Context c) { - if (uris.size() == 1) { - // Get the Image from data (single image) - try { - new UploadImgurDEA(c).execute(uris.get(0)); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - //Multiple images - try { - new UploadImgurAlbumDEA(c).execute(uris.toArray(new Uri[0])); - } catch (Exception e) { - e.printStackTrace(); - - } - } - } -} +package me.ccrama.redditslide.Views; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.net.Uri; +import android.text.Editable; +import android.util.Base64; +import android.view.LayoutInflater; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.google.android.material.snackbar.Snackbar; + +import org.apache.commons.text.StringEscapeUtils; +import org.commonmark.Extension; +import org.commonmark.ext.gfm.strikethrough.StrikethroughExtension; +import org.commonmark.ext.gfm.tables.TablesExtension; +import org.commonmark.html.HtmlRenderer; +import org.commonmark.node.Node; +import org.commonmark.parser.Parser; +import org.json.JSONObject; + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import gun0912.tedbottompicker.TedBottomPicker; +import me.ccrama.redditslide.Activities.Draw; +import me.ccrama.redditslide.Drafts; +import me.ccrama.redditslide.ImgurAlbum.UploadImgur; +import me.ccrama.redditslide.ImgurAlbum.UploadImgurAlbum; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.SpoilerRobotoTextView; +import me.ccrama.redditslide.Visuals.ColorPreferences; +import me.ccrama.redditslide.util.DisplayUtil; +import me.ccrama.redditslide.util.KeyboardUtil; +import me.ccrama.redditslide.util.ProUtil; +import me.ccrama.redditslide.util.SubmissionParser; + +/** + * Created by carlo_000 on 10/18/2015. + */ +public class DoEditorActions { + + public static void doActions(final EditText editText, final View baseView, + final FragmentManager fm, final Activity a, final String oldComment, + @Nullable final String[] authors) { + baseView.findViewById(R.id.bold).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (editText.hasSelection()) { + wrapString("**", + editText); //If the user has text selected, wrap that text in the symbols + } else { + //If the user doesn't have text selected, put the symbols around the cursor's position + int pos = editText.getSelectionStart(); + editText.getText().insert(pos, "**"); + editText.getText().insert(pos + 1, "**"); + editText.setSelection(pos + 2); //put the cursor between the symbols + } + } + }); + + if (baseView.findViewById(R.id.author) != null) { + if (authors != null && authors.length > 0) { + baseView.findViewById(R.id.author).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (authors.length == 1) { + String author = "/u/" + authors[0]; + insertBefore(author, editText); + } else { + new AlertDialog.Builder(a) + .setTitle(R.string.authors_above) + .setItems(authors, (dialog, which) -> { + String author = "/u/" + authors[which]; + insertBefore(author, editText); + }) + .setNeutralButton(R.string.btn_cancel, null) + .show(); + } + } + }); + } else { + baseView.findViewById(R.id.author).setVisibility(View.GONE); + } + } + + baseView.findViewById(R.id.italics).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (editText.hasSelection()) { + wrapString("*", + editText); //If the user has text selected, wrap that text in the symbols + } else { + //If the user doesn't have text selected, put the symbols around the cursor's position + int pos = editText.getSelectionStart(); + editText.getText().insert(pos, "*"); + editText.getText().insert(pos + 1, "*"); + editText.setSelection(pos + 1); //put the cursor between the symbols + } + } + }); + + baseView.findViewById(R.id.strike).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (editText.hasSelection()) { + wrapString("~~", + editText); //If the user has text selected, wrap that text in the symbols + } else { + //If the user doesn't have text selected, put the symbols around the cursor's position + int pos = editText.getSelectionStart(); + editText.getText().insert(pos, "~~"); + editText.getText().insert(pos + 2, "~~"); + editText.setSelection(pos + 2); //put the cursor between the symbols + } + } + }); + + baseView.findViewById(R.id.spoiler).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (editText.hasSelection()) { + wrapString(">!", "!<", editText); //If the user has text selected, wrap that text in the symbols + } else { + //If the user doesn't have text selected, put the symbols around the cursor's position + int pos = editText.getSelectionStart(); + editText.getText().insert(pos, ">!"); + editText.getText().insert(pos + 2, "!<"); + editText.setSelection(pos + 2); //put the cursor between the symbols + } + } + }); + + baseView.findViewById(R.id.savedraft).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Drafts.addDraft(editText.getText().toString()); + Snackbar s = Snackbar.make(baseView.findViewById(R.id.savedraft), "Draft saved", + Snackbar.LENGTH_SHORT); + View view = s.getView(); + TextView tv = view.findViewById(com.google.android.material.R.id.snackbar_text); + tv.setTextColor(Color.WHITE); + s.setAction(R.string.btn_discard, new View.OnClickListener() { + @Override + public void onClick(View view) { + Drafts.deleteDraft(Drafts.getDrafts().size() - 1); + } + }); + s.show(); + } + }); + baseView.findViewById(R.id.draft).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final ArrayList drafts = Drafts.getDrafts(); + Collections.reverse(drafts); + final String[] draftText = new String[drafts.size()]; + for (int i = 0; i < drafts.size(); i++) { + draftText[i] = drafts.get(i); + } + if (drafts.isEmpty()) { + new AlertDialog.Builder(a) + .setTitle(R.string.dialog_no_drafts) + .setMessage(R.string.dialog_no_drafts_msg) + .setPositiveButton(R.string.btn_ok, null) + .show(); + } else { + new AlertDialog.Builder(a) + .setTitle(R.string.choose_draft) + .setItems(draftText, (dialog, which) -> + editText.setText(editText.getText().toString() + draftText[which])) + .setNeutralButton(R.string.btn_cancel, null) + .setPositiveButton(R.string.manage_drafts, (dialog, which) -> { + final boolean[] selected = new boolean[drafts.size()]; + new AlertDialog.Builder(a) + .setTitle(R.string.choose_draft) + .setNeutralButton(R.string.btn_cancel, null) + .setNegativeButton(R.string.btn_delete, (dialog1, which1) -> + new AlertDialog.Builder(a) + .setTitle(R.string.really_delete_drafts) + .setCancelable(false) + .setPositiveButton(R.string.btn_yes, (dialog11, which11) -> { + ArrayList draf = new ArrayList<>(); + for (int i = 0; i < draftText.length; i++) { + if (!selected[i]) { + draf.add(draftText[i]); + } + } + Drafts.save(draf); + }) + .setNegativeButton(R.string.btn_no, null) + .show()) + .setMultiChoiceItems(draftText, selected, (dialog12, which12, isChecked) -> + selected[which12] = isChecked) + .show(); + }) + .show(); + } + } + }); + baseView.findViewById(R.id.imagerep).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + e = editText.getText(); + + sStart = editText.getSelectionStart(); + sEnd = editText.getSelectionEnd(); + + TedBottomPicker tedBottomPicker = new TedBottomPicker.Builder(editText.getContext()) + .setOnImageSelectedListener(new TedBottomPicker.OnImageSelectedListener() { + @Override + public void onImageSelected(List uri) { + handleImageIntent(uri, editText, a); + } + }) + .setLayoutResource(R.layout.image_sheet_dialog) + .setTitle("Choose a photo") + .create(); + + tedBottomPicker.show(fm); + KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); + } + }); + + baseView.findViewById(R.id.draw).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (SettingValues.isPro) { + doDraw(a, editText, fm); + } else { + final AlertDialog.Builder b = + ProUtil.proUpgradeMsg(a, R.string.general_cropdraw_ispro) + .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> + dialog.dismiss()); + if (SettingValues.previews > 0) { + b.setNeutralButton( + a.getString(R.string.pro_previews, SettingValues.previews), + (dialog, which) -> { + SettingValues.prefs.edit() + .putInt(SettingValues.PREVIEWS_LEFT, + SettingValues.previews - 1) + .apply(); + SettingValues.previews = SettingValues.prefs.getInt( + SettingValues.PREVIEWS_LEFT, 10); + doDraw(a, editText, fm); + }); + } + b.show(); + } + } + }); + /*todo baseView.findViewById(R.id.superscript).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + insertBefore("^", editText); + } + });*/ + baseView.findViewById(R.id.size).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + insertBefore("#", editText); + } + }); + + baseView.findViewById(R.id.quote).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (oldComment != null) { + final TextView showText = new TextView(a); + showText.setText(StringEscapeUtils.unescapeHtml4(oldComment)); // text we get is escaped, we don't want that + showText.setTextIsSelectable(true); + int sixteen = DisplayUtil.dpToPxVertical(24); + showText.setPadding(sixteen, 0, sixteen, 0); + MaterialDialog.Builder builder = new MaterialDialog.Builder(a); + builder.customView(showText, false) + .title(R.string.editor_actions_quote_comment) + .cancelable(true) + .positiveText(a.getString(R.string.btn_select)) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + String selected = showText.getText() + .toString() + .substring(showText.getSelectionStart(), showText.getSelectionEnd()); + if (selected.isEmpty()) { + selected = StringEscapeUtils.unescapeHtml4(oldComment); + } + insertBefore("> " + selected.replaceAll("\n", "\n> ") + "\n\n", editText); + } + }) + .negativeText(a.getString(R.string.btn_cancel)) + .show(); + KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); + } else { + insertBefore("> ", editText); + } + } + }); + + baseView.findViewById(R.id.bulletlist).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int start = editText.getSelectionStart(); + int end = editText.getSelectionEnd(); + String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); + if (!selected.isEmpty()) { + selected = selected.replaceFirst("^[^\n]", "* $0").replaceAll("\n", "\n* "); + editText.getText().replace(Math.min(start, end), Math.max(start, end), selected); + } else { + insertBefore("* ", editText); + } + } + }); + + baseView.findViewById(R.id.numlist).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int start = editText.getSelectionStart(); + int end = editText.getSelectionEnd(); + String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); + if (!selected.isEmpty()) { + selected = selected.replaceFirst("^[^\n]", "1. $0").replaceAll("\n", "\n1. "); + editText.getText().replace(Math.min(start, end), Math.max(start, end), selected); + } else { + insertBefore("1. ", editText); + } + } + }); + + baseView.findViewById(R.id.preview).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + List extensions = + Arrays.asList(TablesExtension.create(), StrikethroughExtension.create()); + Parser parser = Parser.builder().extensions(extensions).build(); + HtmlRenderer renderer = HtmlRenderer.builder().extensions(extensions).build(); + Node document = parser.parse(editText.getText().toString()); + String html = renderer.render(document); + LayoutInflater inflater = a.getLayoutInflater(); + final View dialoglayout = inflater.inflate(R.layout.parent_comment_dialog, null); + setViews(html, "NO sub", + dialoglayout.findViewById(R.id.firstTextView), + dialoglayout.findViewById(R.id.commentOverflow)); + + new AlertDialog.Builder(a) + .setView(dialoglayout) + .show(); + } + }); + + baseView.findViewById(R.id.link).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final LayoutInflater inflater = LayoutInflater.from(a); + final LinearLayout layout = + (LinearLayout) inflater.inflate(R.layout.insert_link, null); + + int[] attrs = {R.attr.fontColor}; + + TypedArray ta = baseView.getContext() + .obtainStyledAttributes( + new ColorPreferences(baseView.getContext()).getFontStyle() + .getBaseId(), attrs); + ta.recycle(); + + String selectedText = ""; + //if the user highlighted text before inputting a URL, use that text for the descriptionBox + if (editText.hasSelection()) { + final int startSelection = editText.getSelectionStart(); + final int endSelection = editText.getSelectionEnd(); + + selectedText = + editText.getText().toString().substring(startSelection, endSelection); + } + + final boolean selectedTextNotEmpty = !selectedText.isEmpty(); + + final MaterialDialog dialog = + new MaterialDialog.Builder(editText.getContext()).title( + R.string.editor_title_link) + .customView(layout, false) + .positiveColorAttr(R.attr.tintColor) + .positiveText(R.string.editor_action_link) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, + @NonNull DialogAction which) { + final EditText urlBox = + (EditText) dialog.findViewById(R.id.url_box); + final EditText textBox = + (EditText) dialog.findViewById(R.id.text_box); + dialog.dismiss(); + + final String s = "[" + textBox.getText().toString() + + "](" + + urlBox.getText().toString() + + ")"; + + int start = Math.max(editText.getSelectionStart(), 0); + int end = Math.max(editText.getSelectionEnd(), 0); + + editText.getText().insert(Math.max(start, end), s); + + //delete the selected text to avoid duplication + if (selectedTextNotEmpty) { + editText.getText().delete(start, end); + } + } + }) + .build(); + + //Tint the hint text if the base theme is Sepia + if (SettingValues.currentTheme == 5) { + ((EditText) dialog.findViewById(R.id.url_box)).setHintTextColor( + ContextCompat.getColor(dialog.getContext(), R.color.md_grey_600)); + ((EditText) dialog.findViewById(R.id.text_box)).setHintTextColor( + ContextCompat.getColor(dialog.getContext(), R.color.md_grey_600)); + } + + //use the selected text as the text for the link + if (!selectedText.isEmpty()) { + ((EditText) dialog.findViewById(R.id.text_box)).setText(selectedText); + } + + dialog.show(); + } + }); + + try { + ((ImageInsertEditText) editText).setImageSelectedCallback( + new ImageInsertEditText.ImageSelectedCallback() { + @Override + public void onImageSelected(final Uri content, String mimeType) { + e = editText.getText(); + + sStart = editText.getSelectionStart(); + sEnd = editText.getSelectionEnd(); + handleImageIntent(new ArrayList() {{ + add(content); + }}, editText, a); + } + }); + } catch (Exception e) { + //if thrown, there is likely an issue implementing this on the user's version of Android. There shouldn't be an issue, but just in case + } + } + + public static Editable e; + public static int sStart, sEnd; + + public static void doDraw(final Activity a, final EditText editText, final FragmentManager fm) { + final Intent intent = new Intent(a, Draw.class); + KeyboardUtil.hideKeyboard(editText.getContext(), editText.getWindowToken(), 0); + e = editText.getText(); + TedBottomPicker tedBottomPicker = + new TedBottomPicker.Builder(editText.getContext()).setOnImageSelectedListener( + new TedBottomPicker.OnImageSelectedListener() { + @Override + public void onImageSelected(List uri) { + Draw.uri = uri.get(0); + Fragment auxiliary = new AuxiliaryFragment(); + + sStart = editText.getSelectionStart(); + sEnd = editText.getSelectionEnd(); + + fm.beginTransaction().add(auxiliary, "IMAGE_UPLOAD").commit(); + fm.executePendingTransactions(); + + auxiliary.startActivityForResult(intent, 3333); + } + }) + .setLayoutResource(R.layout.image_sheet_dialog) + .setTitle("Choose a photo") + .create(); + + tedBottomPicker.show(fm); + } + + public static class AuxiliaryFragment extends Fragment { + @Override + public void onActivityResult(int requestCode, int resultCode, final Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(data != null && data.getData() != null) { + handleImageIntent(new ArrayList() {{ + add(data.getData()); + }}, e, getContext()); + + getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit(); + } + + } + } + + public static String getImageLink(Bitmap b) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + b.compress(Bitmap.CompressFormat.JPEG, 100, + baos); // Not sure whether this should be jpeg or png, try both and see which works best + return Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); + } + + public static void insertBefore(String wrapText, EditText editText) { + int start = Math.max(editText.getSelectionStart(), 0); + int end = Math.max(editText.getSelectionEnd(), 0); + editText.getText().insert(Math.min(start, end), wrapText); + } + + /* not using this method anywhere ¯\_(ツ)_/¯ */ +// public static void wrapNewline(String wrapText, EditText editText) { +// int start = Math.max(editText.getSelectionStart(), 0); +// int end = Math.max(editText.getSelectionEnd(), 0); +// String s = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); +// s = s.replace("\n", "\n" + wrapText); +// editText.getText().replace(Math.min(start, end), Math.max(start, end), s); +// } + + /** + * Wrap selected text in one or multiple characters, handling newlines and spaces properly for markdown + * @param wrapText Character(s) to wrap the selected text in + * @param editText EditText + */ + public static void wrapString(String wrapText, EditText editText) { + wrapString(wrapText, wrapText, editText); + } + + /** + * Wrap selected text in one or multiple characters, handling newlines, spaces, >s properly for markdown, + * with different start and end text. + * @param startWrap Character(s) to start wrapping with + * @param endWrap Character(s) to close wrapping with + * @param editText EditText + */ + public static void wrapString(String startWrap, String endWrap, EditText editText) { + int start = Math.max(editText.getSelectionStart(), 0); + int end = Math.max(editText.getSelectionEnd(), 0); + String selected = editText.getText().toString().substring(Math.min(start, end), Math.max(start, end)); + // insert the wrapping character inside any selected spaces and >s because they stop markdown formatting + // we use replaceFirst because anchors (\A, \Z) aren't consumed + selected = selected.replaceFirst("\\A[\\n> ]*", "$0" + startWrap) + .replaceFirst("[\\n> ]*\\Z", endWrap + "$0"); + // 2+ newlines stop formatting, so we do the formatting on each instance of text surrounded by 2+ newlines + /* in case anyone needs to understand this in the future: + * ([^\n> ]) captures any character that isn't a newline, >, or space + * (\n[> ]*){2,} captures any number of two or more newlines with any combination of spaces or >s since markdown ignores those by themselves + * (?=[^\n> ]) performs a lookahead and ensures there's a character that isn't a newline, >, or space + */ + selected = selected.replaceAll("([^\\n> ])(\\n[> ]*){2,}(?=[^\\n> ])", "$1" + endWrap + "$2" + startWrap); + editText.getText().replace(start, end, selected); + } + + private static void setViews(String rawHTML, String subredditName, + SpoilerRobotoTextView firstTextView, CommentOverflow commentOverflow) { + if (rawHTML.isEmpty()) { + return; + } + + List blocks = SubmissionParser.getBlocks(rawHTML); + + int startIndex = 0; + // the
case is when the body contains a table or code block first + if (!blocks.get(0).equals("
")) { + firstTextView.setVisibility(View.VISIBLE); + firstTextView.setTextHtml(blocks.get(0), subredditName); + firstTextView.setLinkTextColor( + new ColorPreferences(firstTextView.getContext()).getColor(subredditName)); + startIndex = 1; + } else { + firstTextView.setText(""); + firstTextView.setVisibility(View.GONE); + } + + if (blocks.size() > 1) { + if (startIndex == 0) { + commentOverflow.setViews(blocks, subredditName); + } else { + commentOverflow.setViews(blocks.subList(startIndex, blocks.size()), subredditName); + } + } else { + commentOverflow.removeAllViews(); + } + } + + private static class UploadImgurDEA extends UploadImgur { + + public UploadImgurDEA(Context c) { + this.c = c; + dialog = new MaterialDialog.Builder(c).title( + c.getString(R.string.editor_uploading_image)) + .progress(false, 100) + .cancelable(false) + .show(); + } + + @Override + protected void onPostExecute(final JSONObject result) { + dialog.dismiss(); + try { + int[] attrs = {R.attr.fontColor}; + TypedArray ta = + c.obtainStyledAttributes(new ColorPreferences(c).getFontStyle().getBaseId(), + attrs); + final String url = result.getJSONObject("data").getString("link"); + LinearLayout layout = new LinearLayout(c); + layout.setOrientation(LinearLayout.VERTICAL); + + final TextView titleBox = new TextView(c); + titleBox.setText(url); + layout.addView(titleBox); + titleBox.setEnabled(false); + titleBox.setTextColor(ta.getColor(0, Color.WHITE)); + + final EditText descriptionBox = new EditText(c); + descriptionBox.setHint(R.string.editor_title); + descriptionBox.setEnabled(true); + descriptionBox.setTextColor(ta.getColor(0, Color.WHITE)); + KeyboardUtil.toggleKeyboard(c, + InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); + + if (DoEditorActions.e != null) { + descriptionBox.setText(DoEditorActions.e.toString().substring(sStart, sEnd)); + } + + ta.recycle(); + int sixteen = DisplayUtil.dpToPxVertical(16); + layout.setPadding(sixteen, sixteen, sixteen, sixteen); + layout.addView(descriptionBox); + new MaterialDialog.Builder(c).title(R.string.editor_title_link) + .customView(layout, false) + .positiveText(R.string.editor_action_link) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { + dialog.dismiss(); + String s = "[" + + descriptionBox.getText().toString() + + "](" + + url + + ")"; + if (descriptionBox.getText().toString().trim().isEmpty()) { + s = url + " "; + } + int start = Math.max(sStart, 0); + int end = Math.max(sEnd, 0); + if (DoEditorActions.e != null) { + DoEditorActions.e.insert(Math.max(start, end), s); + DoEditorActions.e.delete(start, end); + DoEditorActions.e = null; + } + sStart = 0; + sEnd = 0; + } + }) + .canceledOnTouchOutside(false) + .show(); + + } catch (Exception e) { + new AlertDialog.Builder(c) + .setTitle(R.string.err_title) + .setMessage(R.string.editor_err_msg) + .setPositiveButton(R.string.btn_ok, null) + .show(); + e.printStackTrace(); + } + } + } + + private static class UploadImgurAlbumDEA extends UploadImgurAlbum { + + public UploadImgurAlbumDEA(Context c) { + this.c = c; + dialog = new MaterialDialog.Builder(c).title( + c.getString(R.string.editor_uploading_image)) + .progress(false, 100) + .cancelable(false) + .show(); + } + + @Override + protected void onPostExecute(final String result) { + dialog.dismiss(); + try { + int[] attrs = {R.attr.fontColor}; + TypedArray ta = + c.obtainStyledAttributes(new ColorPreferences(c).getFontStyle().getBaseId(), + attrs); + LinearLayout layout = new LinearLayout(c); + layout.setOrientation(LinearLayout.VERTICAL); + + final TextView titleBox = new TextView(c); + titleBox.setText(finalUrl); + layout.addView(titleBox); + titleBox.setEnabled(false); + titleBox.setTextColor(ta.getColor(0, Color.WHITE)); + + final EditText descriptionBox = new EditText(c); + descriptionBox.setHint(R.string.editor_title); + descriptionBox.setEnabled(true); + descriptionBox.setTextColor(ta.getColor(0, Color.WHITE)); + + if (DoEditorActions.e != null) { + descriptionBox.setText(DoEditorActions.e.toString().substring(sStart, sEnd)); + } + + ta.recycle(); + int sixteen = DisplayUtil.dpToPxVertical(16); + layout.setPadding(sixteen, sixteen, sixteen, sixteen); + layout.addView(descriptionBox); + new MaterialDialog.Builder(c).title(R.string.editor_title_link) + .customView(layout, false) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(MaterialDialog dialog, DialogAction which) { + dialog.dismiss(); + String s = "[" + + descriptionBox.getText().toString() + + "](" + + finalUrl + + ")"; + int start = Math.max(sStart, 0); + int end = Math.max(sEnd, 0); + DoEditorActions.e.insert(Math.max(start, end), s); + DoEditorActions.e.delete(start, end); + DoEditorActions.e = null; + sStart = 0; + sEnd = 0; + } + }) + .positiveText(R.string.editor_action_link) + .canceledOnTouchOutside(false) + .show(); + + } catch (Exception e) { + new AlertDialog.Builder(c) + .setTitle(R.string.err_title) + .setMessage(R.string.editor_err_msg) + .setPositiveButton(R.string.btn_ok, null) + .show(); + e.printStackTrace(); + } + } + } + + public static void handleImageIntent(List uris, EditText ed, Context c) { + handleImageIntent(uris, ed.getText(), c); + } + + public static void handleImageIntent(List uris, Editable ed, Context c) { + if (uris.size() == 1) { + // Get the Image from data (single image) + try { + new UploadImgurDEA(c).execute(uris.get(0)); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + //Multiple images + try { + new UploadImgurAlbumDEA(c).execute(uris.toArray(new Uri[0])); + } catch (Exception e) { + e.printStackTrace(); + + } + } + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/ManageOfflineContentFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/ManageOfflineContentFragment.java index 9a1c47172..10c264397 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/ManageOfflineContentFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/ManageOfflineContentFragment.java @@ -1,277 +1,277 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Activity; -import android.content.res.Resources; -import android.os.Build; -import android.util.TypedValue; -import android.view.View; -import android.widget.CompoundButton; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.SwitchCompat; - -import com.google.common.collect.ImmutableList; -import com.rey.material.app.TimePickerDialog; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import me.ccrama.redditslide.Autocache.AutoCacheScheduler; -import me.ccrama.redditslide.CommentCacheAsync; -import me.ccrama.redditslide.OfflineSubreddit; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.Reddit; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Visuals.ColorPreferences; -import me.ccrama.redditslide.util.NetworkUtil; -import me.ccrama.redditslide.util.StringUtil; -import me.ccrama.redditslide.util.TimeUtils; - -public class ManageOfflineContentFragment { - - private Activity context; - - public ManageOfflineContentFragment(Activity context) { - this.context = context; - } - - public void Bind() { - if (!NetworkUtil.isConnected(context)) SettingsThemeFragment.changed = true; - context.findViewById(R.id.manage_history_clear_all).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - boolean wifi = Reddit.cachedData.getBoolean("wifiOnly", false); - String sync = Reddit.cachedData.getString("toCache", ""); - int hour = (Reddit.cachedData.getInt("hour", 0)); - int minute = (Reddit.cachedData.getInt("minute", 0)); - Reddit.cachedData.edit().clear().apply(); - Reddit.cachedData.edit().putBoolean("wifiOnly", wifi).putString( - "toCache", sync).putInt("hour", hour).putInt("minute", minute).apply(); - context.finish(); - } - }); - if (NetworkUtil.isConnectedNoOverride(context)) { - context.findViewById(R.id.manage_history_sync_now).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new CommentCacheAsync(context, Reddit.cachedData.getString( - "toCache", "").split(",")).execute(); - } - }); - } else { - context.findViewById(R.id.manage_history_sync_now).setVisibility(View.GONE); - } - { - SwitchCompat single = context.findViewById(R.id.manage_history_wifi); - - single.setChecked(Reddit.cachedData.getBoolean("wifiOnly", false)); - single.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - Reddit.cachedData.edit().putBoolean("wifiOnly", isChecked).apply(); - } - }); - } - updateBackup(); - updateFilters(); - final List commentDepths = ImmutableList.of("2", "4", "6", "8", "10"); - final String[] commentDepthArray = new String[commentDepths.size()]; - - context.findViewById(R.id.manage_history_comments_depth).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final String commentDepth = SettingValues.prefs.getString(SettingValues.COMMENT_DEPTH, "2"); - new AlertDialog.Builder(context) - .setTitle(R.string.comments_depth) - .setSingleChoiceItems( - commentDepths.toArray(commentDepthArray), - commentDepths.indexOf(commentDepth), (dialog, which) -> - SettingValues.prefs.edit() - .putString(SettingValues.COMMENT_DEPTH, commentDepths.get(which)) - .apply()) - .show(); - - } - }); - - final List commentCounts = ImmutableList.of("20", "40", "60", "80", "100"); - final String[] commentCountArray = new String[commentCounts.size()]; - - context.findViewById(R.id.manage_history_comments_count).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final String commentCount = SettingValues.prefs.getString(SettingValues.COMMENT_COUNT, "2"); - new AlertDialog.Builder(context) - .setTitle(R.string.comments_count) - .setSingleChoiceItems( - commentCounts.toArray(commentCountArray), - commentCounts.indexOf(commentCount), (dialog, which) -> - SettingValues.prefs.edit() - .putString(SettingValues.COMMENT_COUNT, commentCounts.get(which)) - .apply()) - .show(); - - } - }); - - context.findViewById(R.id.manage_history_autocache).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - List sorted = UserSubscriptions.sort( - UserSubscriptions.getSubscriptions(context)); - final String[] all = new String[sorted.size()]; - boolean[] checked = new boolean[all.length]; - - int i = 0; - List s2 = new ArrayList<>(); - Collections.addAll(s2, Reddit.cachedData.getString("toCache", "").split(",")); - - for (String s : sorted) { - all[i] = s; - if (s2.contains(s)) { - checked[i] = true; - } - i++; - } - - final ArrayList toCheck = new ArrayList<>(s2); - new AlertDialog.Builder(context) - .setMultiChoiceItems(all, checked, (dialog, which, isChecked) -> { - if (!isChecked) { - toCheck.remove(all[which]); - } else { - toCheck.add(all[which]); - } - }) - .setTitle(R.string.multireddit_selector) - .setPositiveButton(context.getString(R.string.btn_add).toUpperCase(), (dialog, which) -> { - Reddit.cachedData.edit().putString("toCache", StringUtil.arrayToString(toCheck)).apply(); - updateBackup(); - }) - .show(); - } - - - }); - updateTime(); - context.findViewById(R.id.manage_history_autocache_time_touch).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - - final TimePickerDialog d = new TimePickerDialog(context); - d.hour(Reddit.cachedData.getInt("hour", 0)); - d.minute(Reddit.cachedData.getInt("minute", 0)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - d.applyStyle(new ColorPreferences(context).getFontStyle().getBaseId()); - d.positiveAction("SET"); - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = context.getTheme(); - theme.resolveAttribute(R.attr.activity_background, typedValue, true); - int color = typedValue.data; - d.backgroundColor(color); - d.actionTextColor(context.getResources().getColor( - new ColorPreferences(context).getFontStyle().getColor())); - d.positiveActionClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Reddit.cachedData.edit() - .putInt("hour", d.getHour()) - .putInt("minute", d.getMinute()) - .commit(); - Reddit.autoCache = new AutoCacheScheduler(context); - Reddit.autoCache.start(); - updateTime(); - d.dismiss(); - } - }); - theme.resolveAttribute(R.attr.fontColor, typedValue, true); - int color2 = typedValue.data; - - d.setTitle(context.getString(R.string.choose_sync_time)); - d.titleColor(color2); - d.show(); - } - }); - - } - - public void updateTime() { - TextView text = context.findViewById(R.id.manage_history_autocache_time); - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.HOUR_OF_DAY, Reddit.cachedData.getInt("hour", 0)); - cal.set(Calendar.MINUTE, Reddit.cachedData.getInt("minute", 0)); - if (text != null) { - text.setText(context.getString( - R.string.settings_backup_occurs, new SimpleDateFormat("hh:mm a").format(cal.getTime()))); - } - } - - public void updateBackup() { - subsToBack = new ArrayList<>(); - Collections.addAll(subsToBack, Reddit.cachedData.getString("toCache", "").split(",")); - TextView text = context.findViewById(R.id.manage_history_autocache_text); - if (!Reddit.cachedData.getString("toCache", "").contains(",") || subsToBack.isEmpty()) { - text.setText(R.string.settings_backup_none); - } else { - StringBuilder toSayBuilder = new StringBuilder(); - for (String s : subsToBack) { - if (!s.isEmpty()) - toSayBuilder.append(s).append(", "); - } - String toSay = toSayBuilder.toString(); - toSay = toSay.substring(0, toSay.length() - 2); - toSay += context.getString(R.string.settings_backup_will_backup); - text.setText(toSay); - } - } - - public ArrayList domains = new ArrayList<>(); - List subsToBack; - - public void updateFilters() { - if (context.findViewById(R.id.manage_history_domainlist) != null) { - Map multiNameToSubsMap = UserSubscriptions.getMultiNameToSubs(true); - - domains = new ArrayList<>(); - ((LinearLayout) context.findViewById(R.id.manage_history_domainlist)).removeAllViews(); - for (final String s : OfflineSubreddit.getAll()) { - if (!s.isEmpty()) { - - String[] split = s.split(","); - String sub = split[0]; - if (multiNameToSubsMap.containsKey(sub)) { - sub = multiNameToSubsMap.get(sub); - } - final String name = (sub.contains("/m/") ? sub : "/r/" + sub) + " → " + (Long.parseLong(split[1]) == 0 ? context.getString(R.string.settings_backup_submission_only) : TimeUtils.getTimeAgo(Long.parseLong(split[1]), context) + context.getString(R.string.settings_backup_comments)); - domains.add(name); - - final View t = context.getLayoutInflater().inflate( - R.layout.account_textview, - context.findViewById(R.id.manage_history_domainlist), - false); - - ((TextView) t.findViewById(R.id.name)).setText(name); - t.findViewById(R.id.remove).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - domains.remove(name); - Reddit.cachedData.edit().remove(s).apply(); - updateFilters(); - } - }); - ((LinearLayout) context.findViewById(R.id.manage_history_domainlist)).addView(t); - - } - } - } - } - -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Activity; +import android.content.res.Resources; +import android.os.Build; +import android.util.TypedValue; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; + +import com.google.common.collect.ImmutableList; +import com.rey.material.app.TimePickerDialog; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import me.ccrama.redditslide.Autocache.AutoCacheScheduler; +import me.ccrama.redditslide.CommentCacheAsync; +import me.ccrama.redditslide.OfflineSubreddit; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.Reddit; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Visuals.ColorPreferences; +import me.ccrama.redditslide.util.NetworkUtil; +import me.ccrama.redditslide.util.StringUtil; +import me.ccrama.redditslide.util.TimeUtils; + +public class ManageOfflineContentFragment { + + private Activity context; + + public ManageOfflineContentFragment(Activity context) { + this.context = context; + } + + public void Bind() { + if (!NetworkUtil.isConnected(context)) SettingsThemeFragment.changed = true; + context.findViewById(R.id.manage_history_clear_all).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + boolean wifi = Reddit.cachedData.getBoolean("wifiOnly", false); + String sync = Reddit.cachedData.getString("toCache", ""); + int hour = (Reddit.cachedData.getInt("hour", 0)); + int minute = (Reddit.cachedData.getInt("minute", 0)); + Reddit.cachedData.edit().clear().apply(); + Reddit.cachedData.edit().putBoolean("wifiOnly", wifi).putString( + "toCache", sync).putInt("hour", hour).putInt("minute", minute).apply(); + context.finish(); + } + }); + if (NetworkUtil.isConnectedNoOverride(context)) { + context.findViewById(R.id.manage_history_sync_now).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new CommentCacheAsync(context, Reddit.cachedData.getString( + "toCache", "").split(",")).execute(); + } + }); + } else { + context.findViewById(R.id.manage_history_sync_now).setVisibility(View.GONE); + } + { + SwitchCompat single = context.findViewById(R.id.manage_history_wifi); + + single.setChecked(Reddit.cachedData.getBoolean("wifiOnly", false)); + single.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + Reddit.cachedData.edit().putBoolean("wifiOnly", isChecked).apply(); + } + }); + } + updateBackup(); + updateFilters(); + final List commentDepths = ImmutableList.of("2", "4", "6", "8", "10"); + final String[] commentDepthArray = new String[commentDepths.size()]; + + context.findViewById(R.id.manage_history_comments_depth).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final String commentDepth = SettingValues.prefs.getString(SettingValues.COMMENT_DEPTH, "2"); + new AlertDialog.Builder(context) + .setTitle(R.string.comments_depth) + .setSingleChoiceItems( + commentDepths.toArray(commentDepthArray), + commentDepths.indexOf(commentDepth), (dialog, which) -> + SettingValues.prefs.edit() + .putString(SettingValues.COMMENT_DEPTH, commentDepths.get(which)) + .apply()) + .show(); + + } + }); + + final List commentCounts = ImmutableList.of("20", "40", "60", "80", "100"); + final String[] commentCountArray = new String[commentCounts.size()]; + + context.findViewById(R.id.manage_history_comments_count).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final String commentCount = SettingValues.prefs.getString(SettingValues.COMMENT_COUNT, "2"); + new AlertDialog.Builder(context) + .setTitle(R.string.comments_count) + .setSingleChoiceItems( + commentCounts.toArray(commentCountArray), + commentCounts.indexOf(commentCount), (dialog, which) -> + SettingValues.prefs.edit() + .putString(SettingValues.COMMENT_COUNT, commentCounts.get(which)) + .apply()) + .show(); + + } + }); + + context.findViewById(R.id.manage_history_autocache).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + List sorted = UserSubscriptions.sort( + UserSubscriptions.getSubscriptions(context)); + final String[] all = new String[sorted.size()]; + boolean[] checked = new boolean[all.length]; + + int i = 0; + List s2 = new ArrayList<>(); + Collections.addAll(s2, Reddit.cachedData.getString("toCache", "").split(",")); + + for (String s : sorted) { + all[i] = s; + if (s2.contains(s)) { + checked[i] = true; + } + i++; + } + + final ArrayList toCheck = new ArrayList<>(s2); + new AlertDialog.Builder(context) + .setMultiChoiceItems(all, checked, (dialog, which, isChecked) -> { + if (!isChecked) { + toCheck.remove(all[which]); + } else { + toCheck.add(all[which]); + } + }) + .setTitle(R.string.multireddit_selector) + .setPositiveButton(context.getString(R.string.btn_add).toUpperCase(), (dialog, which) -> { + Reddit.cachedData.edit().putString("toCache", StringUtil.arrayToString(toCheck)).apply(); + updateBackup(); + }) + .show(); + } + + + }); + updateTime(); + context.findViewById(R.id.manage_history_autocache_time_touch).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + final TimePickerDialog d = new TimePickerDialog(context); + d.hour(Reddit.cachedData.getInt("hour", 0)); + d.minute(Reddit.cachedData.getInt("minute", 0)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) + d.applyStyle(new ColorPreferences(context).getFontStyle().getBaseId()); + d.positiveAction("SET"); + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = context.getTheme(); + theme.resolveAttribute(R.attr.activity_background, typedValue, true); + int color = typedValue.data; + d.backgroundColor(color); + d.actionTextColor(context.getResources().getColor( + new ColorPreferences(context).getFontStyle().getColor())); + d.positiveActionClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Reddit.cachedData.edit() + .putInt("hour", d.getHour()) + .putInt("minute", d.getMinute()) + .commit(); + Reddit.autoCache = new AutoCacheScheduler(context); + Reddit.autoCache.start(); + updateTime(); + d.dismiss(); + } + }); + theme.resolveAttribute(R.attr.fontColor, typedValue, true); + int color2 = typedValue.data; + + d.setTitle(context.getString(R.string.choose_sync_time)); + d.titleColor(color2); + d.show(); + } + }); + + } + + public void updateTime() { + TextView text = context.findViewById(R.id.manage_history_autocache_time); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.HOUR_OF_DAY, Reddit.cachedData.getInt("hour", 0)); + cal.set(Calendar.MINUTE, Reddit.cachedData.getInt("minute", 0)); + if (text != null) { + text.setText(context.getString( + R.string.settings_backup_occurs, new SimpleDateFormat("hh:mm a").format(cal.getTime()))); + } + } + + public void updateBackup() { + subsToBack = new ArrayList<>(); + Collections.addAll(subsToBack, Reddit.cachedData.getString("toCache", "").split(",")); + TextView text = context.findViewById(R.id.manage_history_autocache_text); + if (!Reddit.cachedData.getString("toCache", "").contains(",") || subsToBack.isEmpty()) { + text.setText(R.string.settings_backup_none); + } else { + StringBuilder toSayBuilder = new StringBuilder(); + for (String s : subsToBack) { + if (!s.isEmpty()) + toSayBuilder.append(s).append(", "); + } + String toSay = toSayBuilder.toString(); + toSay = toSay.substring(0, toSay.length() - 2); + toSay += context.getString(R.string.settings_backup_will_backup); + text.setText(toSay); + } + } + + public ArrayList domains = new ArrayList<>(); + List subsToBack; + + public void updateFilters() { + if (context.findViewById(R.id.manage_history_domainlist) != null) { + Map multiNameToSubsMap = UserSubscriptions.getMultiNameToSubs(true); + + domains = new ArrayList<>(); + ((LinearLayout) context.findViewById(R.id.manage_history_domainlist)).removeAllViews(); + for (final String s : OfflineSubreddit.getAll()) { + if (!s.isEmpty()) { + + String[] split = s.split(","); + String sub = split[0]; + if (multiNameToSubsMap.containsKey(sub)) { + sub = multiNameToSubsMap.get(sub); + } + final String name = (sub.contains("/m/") ? sub : "/r/" + sub) + " → " + (Long.parseLong(split[1]) == 0 ? context.getString(R.string.settings_backup_submission_only) : TimeUtils.getTimeAgo(Long.parseLong(split[1]), context) + context.getString(R.string.settings_backup_comments)); + domains.add(name); + + final View t = context.getLayoutInflater().inflate( + R.layout.account_textview, + context.findViewById(R.id.manage_history_domainlist), + false); + + ((TextView) t.findViewById(R.id.name)).setText(name); + t.findViewById(R.id.remove).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + domains.remove(name); + Reddit.cachedData.edit().remove(s).apply(); + updateFilters(); + } + }); + ((LinearLayout) context.findViewById(R.id.manage_history_domainlist)).addView(t); + + } + } + } + } + +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsCommentsFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsCommentsFragment.java index 4c268f95c..4572384a6 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsCommentsFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsCommentsFragment.java @@ -1,185 +1,185 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Activity; -import android.widget.TextView; - -import androidx.appcompat.widget.SwitchCompat; - -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SettingValues; - -public class SettingsCommentsFragment { - - private final Activity context; - - public SettingsCommentsFragment(Activity context) { - this.context = context; - } - - public void Bind() { - final SwitchCompat commentsCropImageSwitch = context.findViewById(R.id.settings_comments_cropImage); - final SwitchCompat commentsColorDepthSwitch = context.findViewById(R.id.settings_comments_colorDepth); - final SwitchCompat commentsHighlightOpColorSwitch = context.findViewById(R.id.settings_comments_highlightOpColor); - final SwitchCompat commentsWideDepthSwitch = context.findViewById(R.id.settings_comments_wideDepth); - final SwitchCompat commentsShowCreateFabSwitch = context.findViewById(R.id.settings_comments_showCreateFab); - final SwitchCompat commentsRightHandedCommentsSwitch = context.findViewById(R.id.settings_comments_rightHandedComments); - final SwitchCompat commentsUpvotePercentSwitch = context.findViewById(R.id.settings_comments_upvotePercent); - final SwitchCompat commentsColoredTimeBubbleSwitch = context.findViewById(R.id.settings_comments_coloredTimeBubble); - final SwitchCompat commentsHideAwardsSwitch = context.findViewById(R.id.settings_comments_hideAwards); - - final SwitchCompat commentsParentCommentNavSwitch = context.findViewById(R.id.settings_comments_parentCommentNav); - final TextView commentsAutohideNavbarView = context.findViewById(R.id.settings_comments_autohideCommentNavbarView); - final SwitchCompat commentsAutohideNavbarSwitch = context.findViewById(R.id.settings_comments_autohideCommentNavbar); - final TextView commentsShowCollapseExpandView = context.findViewById(R.id.settings_comments_showCollapseExpandView); - final SwitchCompat commentsShowCollapseExpandSwitch = context.findViewById(R.id.settings_comments_showCollapseExpand); - final SwitchCompat commentsVolumeNavCommentsSwitch = context.findViewById(R.id.settings_comments_volumeNavComments); - final SwitchCompat commentsNavbarVoteGesturesSwitch = context.findViewById(R.id.settings_comments_navbarVoteGestures); - - final SwitchCompat commentsSwapLongpressTapSwitch = context.findViewById(R.id.settings_comments_swapLongpressTap); - final SwitchCompat commentsFullCollapseSwitch = context.findViewById(R.id.settings_comments_fullCollapse); - final SwitchCompat commentsCollapseChildCommentsSwitch = context.findViewById(R.id.settings_comments_collapseChildComments); - final SwitchCompat commentsCollapseDeletedCommentsSwitch = context.findViewById(R.id.settings_comments_collapseDeletedComments); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Display */ - commentsCropImageSwitch.setChecked(SettingValues.cropImage); - commentsCropImageSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.cropImage = isChecked; - editSharedBooleanPreference(SettingValues.PREF_CROP_IMAGE, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsColorDepthSwitch.setChecked(SettingValues.colorCommentDepth); - commentsColorDepthSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.colorCommentDepth = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLOR_COMMENT_DEPTH, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsHighlightOpColorSwitch.setChecked(SettingValues.highlightCommentOP); - commentsHighlightOpColorSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.highlightCommentOP = isChecked; - editSharedBooleanPreference(SettingValues.PREF_HIGHLIGHT_COMMENT_OP, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsWideDepthSwitch.setChecked(SettingValues.largeDepth); - commentsWideDepthSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.largeDepth = isChecked; - editSharedBooleanPreference(SettingValues.PREF_LARGE_DEPTH, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsShowCreateFabSwitch.setChecked(SettingValues.fabComments); - commentsShowCreateFabSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.fabComments = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COMMENT_FAB, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsRightHandedCommentsSwitch.setChecked(SettingValues.rightHandedCommentMenu); - commentsRightHandedCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.rightHandedCommentMenu = isChecked; - editSharedBooleanPreference(SettingValues.PREF_RIGHT_HANDED_COMMENT_MENU, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsUpvotePercentSwitch.setChecked(SettingValues.upvotePercentage); - commentsUpvotePercentSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.upvotePercentage = isChecked; - editSharedBooleanPreference(SettingValues.PREF_UPVOTE_PERCENTAGE, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsColoredTimeBubbleSwitch.setChecked(SettingValues.highlightTime); - commentsColoredTimeBubbleSwitch.setEnabled(SettingValues.commentLastVisit); - commentsColoredTimeBubbleSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.highlightTime = isChecked; - editSharedBooleanPreference(SettingValues.PREF_HIGHLIGHT_TIME, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsHideAwardsSwitch.setChecked(SettingValues.hideCommentAwards); - commentsHideAwardsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.hideCommentAwards = isChecked; - editSharedBooleanPreference(SettingValues.PREF_HIDE_COMMENT_AWARDS, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Navigation */ - commentsParentCommentNavSwitch.setChecked(SettingValues.fastscroll); - commentsParentCommentNavSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.fastscroll = isChecked; - editSharedBooleanPreference(SettingValues.PREF_FASTSCROLL, isChecked); - - //Disable autohidenav and showcollapseexpand if commentNav isn't checked - if (!isChecked) { - commentsAutohideNavbarSwitch.setEnabled(false); - commentsAutohideNavbarSwitch.setChecked(SettingValues.commentAutoHide); - commentsAutohideNavbarView.setAlpha(0.25f); - commentsShowCollapseExpandSwitch.setEnabled(false); - commentsShowCollapseExpandSwitch.setChecked(SettingValues.commentAutoHide); - commentsShowCollapseExpandView.setAlpha(0.25f); - } else { - commentsAutohideNavbarSwitch.setEnabled(true); - commentsAutohideNavbarView.setAlpha(1f); - commentsShowCollapseExpandSwitch.setEnabled(true); - commentsShowCollapseExpandView.setAlpha(1f); - } - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsAutohideNavbarSwitch.setChecked(SettingValues.commentAutoHide); - if (!commentsParentCommentNavSwitch.isChecked()) { - commentsAutohideNavbarSwitch.setEnabled(false); - commentsAutohideNavbarView.setAlpha(0.25f); - } - commentsAutohideNavbarSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.commentAutoHide = isChecked; - editSharedBooleanPreference(SettingValues.PREF_AUTOHIDE_COMMENTS, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsShowCollapseExpandSwitch.setChecked(SettingValues.showCollapseExpand); - if (!commentsParentCommentNavSwitch.isChecked()) { - commentsShowCollapseExpandSwitch.setEnabled(false); - commentsShowCollapseExpandView.setAlpha(0.25f); - } - commentsShowCollapseExpandSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.showCollapseExpand = isChecked; - editSharedBooleanPreference(SettingValues.PREF_SHOW_COLLAPSE_EXPAND, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsVolumeNavCommentsSwitch.setChecked(SettingValues.commentVolumeNav); - commentsVolumeNavCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.commentVolumeNav = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COMMENT_NAV, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsNavbarVoteGesturesSwitch.setChecked(SettingValues.voteGestures); - commentsNavbarVoteGesturesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.voteGestures = isChecked; - editSharedBooleanPreference(SettingValues.PREF_VOTE_GESTURES, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Collapse actions */ - commentsSwapLongpressTapSwitch.setChecked(SettingValues.swap); - commentsSwapLongpressTapSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.swap = isChecked; - editSharedBooleanPreference(SettingValues.PREF_SWAP, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsFullCollapseSwitch.setChecked(SettingValues.collapseComments); - commentsFullCollapseSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.collapseComments = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_COMMENTS, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsCollapseChildCommentsSwitch.setChecked(SettingValues.collapseCommentsDefault); - commentsCollapseChildCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.collapseCommentsDefault = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_COMMENTS_DEFAULT, isChecked); - }); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - commentsCollapseDeletedCommentsSwitch.setChecked(SettingValues.collapseDeletedComments); - commentsCollapseDeletedCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.collapseDeletedComments = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_DELETED_COMMENTS, isChecked); - }); - } - - private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { - SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); - } -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Activity; +import android.widget.TextView; + +import androidx.appcompat.widget.SwitchCompat; + +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SettingValues; + +public class SettingsCommentsFragment { + + private final Activity context; + + public SettingsCommentsFragment(Activity context) { + this.context = context; + } + + public void Bind() { + final SwitchCompat commentsCropImageSwitch = context.findViewById(R.id.settings_comments_cropImage); + final SwitchCompat commentsColorDepthSwitch = context.findViewById(R.id.settings_comments_colorDepth); + final SwitchCompat commentsHighlightOpColorSwitch = context.findViewById(R.id.settings_comments_highlightOpColor); + final SwitchCompat commentsWideDepthSwitch = context.findViewById(R.id.settings_comments_wideDepth); + final SwitchCompat commentsShowCreateFabSwitch = context.findViewById(R.id.settings_comments_showCreateFab); + final SwitchCompat commentsRightHandedCommentsSwitch = context.findViewById(R.id.settings_comments_rightHandedComments); + final SwitchCompat commentsUpvotePercentSwitch = context.findViewById(R.id.settings_comments_upvotePercent); + final SwitchCompat commentsColoredTimeBubbleSwitch = context.findViewById(R.id.settings_comments_coloredTimeBubble); + final SwitchCompat commentsHideAwardsSwitch = context.findViewById(R.id.settings_comments_hideAwards); + + final SwitchCompat commentsParentCommentNavSwitch = context.findViewById(R.id.settings_comments_parentCommentNav); + final TextView commentsAutohideNavbarView = context.findViewById(R.id.settings_comments_autohideCommentNavbarView); + final SwitchCompat commentsAutohideNavbarSwitch = context.findViewById(R.id.settings_comments_autohideCommentNavbar); + final TextView commentsShowCollapseExpandView = context.findViewById(R.id.settings_comments_showCollapseExpandView); + final SwitchCompat commentsShowCollapseExpandSwitch = context.findViewById(R.id.settings_comments_showCollapseExpand); + final SwitchCompat commentsVolumeNavCommentsSwitch = context.findViewById(R.id.settings_comments_volumeNavComments); + final SwitchCompat commentsNavbarVoteGesturesSwitch = context.findViewById(R.id.settings_comments_navbarVoteGestures); + + final SwitchCompat commentsSwapLongpressTapSwitch = context.findViewById(R.id.settings_comments_swapLongpressTap); + final SwitchCompat commentsFullCollapseSwitch = context.findViewById(R.id.settings_comments_fullCollapse); + final SwitchCompat commentsCollapseChildCommentsSwitch = context.findViewById(R.id.settings_comments_collapseChildComments); + final SwitchCompat commentsCollapseDeletedCommentsSwitch = context.findViewById(R.id.settings_comments_collapseDeletedComments); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Display */ + commentsCropImageSwitch.setChecked(SettingValues.cropImage); + commentsCropImageSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.cropImage = isChecked; + editSharedBooleanPreference(SettingValues.PREF_CROP_IMAGE, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsColorDepthSwitch.setChecked(SettingValues.colorCommentDepth); + commentsColorDepthSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.colorCommentDepth = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLOR_COMMENT_DEPTH, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsHighlightOpColorSwitch.setChecked(SettingValues.highlightCommentOP); + commentsHighlightOpColorSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.highlightCommentOP = isChecked; + editSharedBooleanPreference(SettingValues.PREF_HIGHLIGHT_COMMENT_OP, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsWideDepthSwitch.setChecked(SettingValues.largeDepth); + commentsWideDepthSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.largeDepth = isChecked; + editSharedBooleanPreference(SettingValues.PREF_LARGE_DEPTH, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsShowCreateFabSwitch.setChecked(SettingValues.fabComments); + commentsShowCreateFabSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.fabComments = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COMMENT_FAB, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsRightHandedCommentsSwitch.setChecked(SettingValues.rightHandedCommentMenu); + commentsRightHandedCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.rightHandedCommentMenu = isChecked; + editSharedBooleanPreference(SettingValues.PREF_RIGHT_HANDED_COMMENT_MENU, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsUpvotePercentSwitch.setChecked(SettingValues.upvotePercentage); + commentsUpvotePercentSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.upvotePercentage = isChecked; + editSharedBooleanPreference(SettingValues.PREF_UPVOTE_PERCENTAGE, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsColoredTimeBubbleSwitch.setChecked(SettingValues.highlightTime); + commentsColoredTimeBubbleSwitch.setEnabled(SettingValues.commentLastVisit); + commentsColoredTimeBubbleSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.highlightTime = isChecked; + editSharedBooleanPreference(SettingValues.PREF_HIGHLIGHT_TIME, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsHideAwardsSwitch.setChecked(SettingValues.hideCommentAwards); + commentsHideAwardsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.hideCommentAwards = isChecked; + editSharedBooleanPreference(SettingValues.PREF_HIDE_COMMENT_AWARDS, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Navigation */ + commentsParentCommentNavSwitch.setChecked(SettingValues.fastscroll); + commentsParentCommentNavSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.fastscroll = isChecked; + editSharedBooleanPreference(SettingValues.PREF_FASTSCROLL, isChecked); + + //Disable autohidenav and showcollapseexpand if commentNav isn't checked + if (!isChecked) { + commentsAutohideNavbarSwitch.setEnabled(false); + commentsAutohideNavbarSwitch.setChecked(SettingValues.commentAutoHide); + commentsAutohideNavbarView.setAlpha(0.25f); + commentsShowCollapseExpandSwitch.setEnabled(false); + commentsShowCollapseExpandSwitch.setChecked(SettingValues.commentAutoHide); + commentsShowCollapseExpandView.setAlpha(0.25f); + } else { + commentsAutohideNavbarSwitch.setEnabled(true); + commentsAutohideNavbarView.setAlpha(1f); + commentsShowCollapseExpandSwitch.setEnabled(true); + commentsShowCollapseExpandView.setAlpha(1f); + } + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsAutohideNavbarSwitch.setChecked(SettingValues.commentAutoHide); + if (!commentsParentCommentNavSwitch.isChecked()) { + commentsAutohideNavbarSwitch.setEnabled(false); + commentsAutohideNavbarView.setAlpha(0.25f); + } + commentsAutohideNavbarSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.commentAutoHide = isChecked; + editSharedBooleanPreference(SettingValues.PREF_AUTOHIDE_COMMENTS, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsShowCollapseExpandSwitch.setChecked(SettingValues.showCollapseExpand); + if (!commentsParentCommentNavSwitch.isChecked()) { + commentsShowCollapseExpandSwitch.setEnabled(false); + commentsShowCollapseExpandView.setAlpha(0.25f); + } + commentsShowCollapseExpandSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.showCollapseExpand = isChecked; + editSharedBooleanPreference(SettingValues.PREF_SHOW_COLLAPSE_EXPAND, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsVolumeNavCommentsSwitch.setChecked(SettingValues.commentVolumeNav); + commentsVolumeNavCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.commentVolumeNav = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COMMENT_NAV, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsNavbarVoteGesturesSwitch.setChecked(SettingValues.voteGestures); + commentsNavbarVoteGesturesSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.voteGestures = isChecked; + editSharedBooleanPreference(SettingValues.PREF_VOTE_GESTURES, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Collapse actions */ + commentsSwapLongpressTapSwitch.setChecked(SettingValues.swap); + commentsSwapLongpressTapSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.swap = isChecked; + editSharedBooleanPreference(SettingValues.PREF_SWAP, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsFullCollapseSwitch.setChecked(SettingValues.collapseComments); + commentsFullCollapseSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.collapseComments = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_COMMENTS, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsCollapseChildCommentsSwitch.setChecked(SettingValues.collapseCommentsDefault); + commentsCollapseChildCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.collapseCommentsDefault = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_COMMENTS_DEFAULT, isChecked); + }); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + commentsCollapseDeletedCommentsSwitch.setChecked(SettingValues.collapseDeletedComments); + commentsCollapseDeletedCommentsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.collapseDeletedComments = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLLAPSE_DELETED_COMMENTS, isChecked); + }); + } + + private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { + SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsFontFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsFontFragment.java index 03593d38c..a0ca8d11e 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsFontFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsFontFragment.java @@ -1,227 +1,227 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Activity; -import android.view.Menu; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.appcompat.widget.PopupMenu; -import androidx.appcompat.widget.SwitchCompat; - -import com.devspark.robototextview.widget.RobotoRadioButton; - -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.Visuals.FontPreferences; -import me.ccrama.redditslide.Visuals.FontPreferences.FontTypeComment; -import me.ccrama.redditslide.Visuals.FontPreferences.FontTypeTitle; - -public class SettingsFontFragment { - - private final Activity context; - - public SettingsFontFragment(Activity context) { - this.context = context; - } - - private static String getFontName(int resource) { - switch (resource) { - case R.string.font_size_huge: - return "Huge"; - case R.string.font_size_larger: - return "Larger"; - case R.string.font_size_large: - return "Large"; - case R.string.font_size_small: - return "Small"; - case R.string.font_size_smaller: - return "Smaller"; - case R.string.font_size_tiny: - return "Tiny"; - case R.string.font_size_medium: - default: - return "Medium"; - } - } - - public void Bind() { - final SwitchCompat fontEnlargeLinksSwitch = context.findViewById(R.id.settings_font_enlarge_links); - final SwitchCompat fontLinkTypeSwitch = context.findViewById(R.id.settings_font_linktype); - - final LinearLayout fontCommentFontSizeLayout = context.findViewById(R.id.settings_font_commentfontsize); - final TextView fontCommentFontView = context.findViewById(R.id.settings_font_commentFont); - - final RobotoRadioButton fontCommentStyleRegularButton = context.findViewById(R.id.settings_font_creg); - final RobotoRadioButton fontCommentStyleSlabButton = context.findViewById(R.id.settings_font_cslab); - final RobotoRadioButton fontCommentStyleCondensedButton = context.findViewById(R.id.settings_font_ccond); - final RobotoRadioButton fontCommentStyleLightButton = context.findViewById(R.id.settings_font_clight); - final RobotoRadioButton fontCommentStyleSystemButton = context.findViewById(R.id.settings_font_cnone); - - final LinearLayout fontPostFontSizeLayout = context.findViewById(R.id.settings_font_postfontsize); - final TextView fontPostFontView = context.findViewById(R.id.settings_font_postFont); - - final RobotoRadioButton fontPostStyleRegularButton = context.findViewById(R.id.settings_font_sreg); - final RobotoRadioButton fontPostStyleBoldButton = context.findViewById(R.id.settings_font_sbold); - final RobotoRadioButton fontPostStyleMediumButton = context.findViewById(R.id.settings_font_smed); - final RobotoRadioButton fontPostStyleLightButton = context.findViewById(R.id.settings_font_slight); - final RobotoRadioButton fontPostStyleSlabButton = context.findViewById(R.id.settings_font_sslab); - final RobotoRadioButton fontPostStyleSlabLightButton = context.findViewById(R.id.settings_font_sslabl); - final RobotoRadioButton fontPostStyleCondensedButton = context.findViewById(R.id.settings_font_scond); - final RobotoRadioButton fontPostStyleCondensedLightButton = context.findViewById(R.id.settings_font_scondl); - final RobotoRadioButton fontPostStyleCondensedBoldButton = context.findViewById(R.id.settings_font_scondb); - final RobotoRadioButton fontPostStyleSystemButton = context.findViewById(R.id.settings_font_snone); - - final FontPreferences newFontPrefs = new FontPreferences(context); -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Links */ - fontEnlargeLinksSwitch.setChecked(SettingValues.largeLinks); - fontEnlargeLinksSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.largeLinks = isChecked; - editSharedBooleanPreference(SettingValues.PREF_LARGE_LINKS, isChecked); - }); - - fontLinkTypeSwitch.setChecked(SettingValues.typeInText); - fontLinkTypeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.typeInText = isChecked; - editSharedBooleanPreference(SettingValues.PREF_TYPE_IN_TEXT, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Font styles */ - fontCommentFontSizeLayout.setOnClickListener(v -> { - PopupMenu popup = new PopupMenu(context, v); - Menu getPopupMenu = popup.getMenu(); - getPopupMenu.add(0, R.string.font_size_huge, 0, R.string.font_size_huge); - getPopupMenu.add(0, R.string.font_size_larger, 0, R.string.font_size_larger); - getPopupMenu.add(0, R.string.font_size_large, 0, R.string.font_size_large); - getPopupMenu.add(0, R.string.font_size_medium, 0, R.string.font_size_medium); - getPopupMenu.add(0, R.string.font_size_small, 0, R.string.font_size_small); - getPopupMenu.add(0, R.string.font_size_smaller, 0, R.string.font_size_smaller); - - //registering popup with OnMenuItemClickListener - popup.setOnMenuItemClickListener(item -> { - newFontPrefs.setCommentFontStyle( - FontPreferences.FontStyleComment.valueOf(getFontName(item.getItemId()))); - fontCommentFontView.setText(newFontPrefs.getCommentFontStyle().getTitle()); - SettingsThemeFragment.changed = true; - return true; - }); - popup.show(); - }); - fontCommentFontView.setText(newFontPrefs.getCommentFontStyle().getTitle()); - - switch (newFontPrefs.getFontTypeComment()) { - case Regular: - fontCommentStyleRegularButton.setChecked(true); - break; - case Slab: - fontCommentStyleSlabButton.setChecked(true); - break; - case Condensed: - fontCommentStyleCondensedButton.setChecked(true); - break; - case Light: - fontCommentStyleLightButton.setChecked(true); - break; - case System: - fontCommentStyleSystemButton.setChecked(true); - break; - } - setCommentFontTypeListener(newFontPrefs, fontCommentStyleRegularButton, FontTypeComment.Regular); - setCommentFontTypeListener(newFontPrefs, fontCommentStyleSlabButton, FontTypeComment.Slab); - setCommentFontTypeListener(newFontPrefs, fontCommentStyleCondensedButton, FontTypeComment.Condensed); - setCommentFontTypeListener(newFontPrefs, fontCommentStyleLightButton, FontTypeComment.Light); - setCommentFontTypeListener(newFontPrefs, fontCommentStyleSystemButton, FontTypeComment.System); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - fontPostFontSizeLayout.setOnClickListener(v -> { - PopupMenu popup = new PopupMenu(context, v); - Menu getPopupMenu = popup.getMenu(); - getPopupMenu.add(0, R.string.font_size_huge, 0, R.string.font_size_huge); - getPopupMenu.add(0, R.string.font_size_larger, 0, R.string.font_size_larger); - getPopupMenu.add(0, R.string.font_size_large, 0, R.string.font_size_large); - getPopupMenu.add(0, R.string.font_size_medium, 0, R.string.font_size_medium); - getPopupMenu.add(0, R.string.font_size_small, 0, R.string.font_size_small); - getPopupMenu.add(0, R.string.font_size_smaller, 0, R.string.font_size_smaller); - getPopupMenu.add(0, R.string.font_size_tiny, 0, R.string.font_size_tiny); - - //registering popup with OnMenuItemClickListener - popup.setOnMenuItemClickListener(item -> { - newFontPrefs.setPostFontStyle( - FontPreferences.FontStyle.valueOf(getFontName(item.getItemId()))); - fontPostFontView.setText(newFontPrefs.getPostFontStyle().getTitle()); - SettingsThemeFragment.changed = true; - return true; - }); - popup.show(); - }); - fontPostFontView.setText(newFontPrefs.getPostFontStyle().getTitle()); - - switch (newFontPrefs.getFontTypeTitle()) { - case Regular: - fontPostStyleRegularButton.setChecked(true); - break; - case Bold: - fontPostStyleBoldButton.setChecked(true); - break; - case Medium: - fontPostStyleMediumButton.setChecked(true); - break; - case Light: - fontPostStyleLightButton.setChecked(true); - break; - case SlabRegular: - fontPostStyleSlabButton.setChecked(true); - break; - case SlabLight: - fontPostStyleSlabLightButton.setChecked(true); - break; - case CondensedRegular: - fontPostStyleCondensedButton.setChecked(true); - break; - case CondensedLight: - fontPostStyleCondensedLightButton.setChecked(true); - break; - case CondensedBold: - fontPostStyleCondensedBoldButton.setChecked(true); - break; - case System: - fontPostStyleSystemButton.setChecked(true); - break; - } - setTitleFontTypeListener(newFontPrefs, fontPostStyleRegularButton, FontTypeTitle.Regular); - setTitleFontTypeListener(newFontPrefs, fontPostStyleBoldButton, FontTypeTitle.Bold); - setTitleFontTypeListener(newFontPrefs, fontPostStyleMediumButton, FontTypeTitle.Medium); - setTitleFontTypeListener(newFontPrefs, fontPostStyleLightButton, FontTypeTitle.Light); - setTitleFontTypeListener(newFontPrefs, fontPostStyleSlabButton, FontTypeTitle.SlabRegular); - setTitleFontTypeListener(newFontPrefs, fontPostStyleSlabLightButton, FontTypeTitle.SlabLight); - setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedButton, FontTypeTitle.CondensedRegular); - setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedLightButton, FontTypeTitle.CondensedLight); - setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedBoldButton, FontTypeTitle.CondensedBold); - setTitleFontTypeListener(newFontPrefs, fontPostStyleSystemButton, FontTypeTitle.System); - } - - private void setCommentFontTypeListener(final FontPreferences newFontPrefs, - final RobotoRadioButton button, final FontTypeComment fontTypeComment) { - button.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) { - SettingsThemeFragment.changed = true; - newFontPrefs.setCommentFont(fontTypeComment); - } - }); - } - - private void setTitleFontTypeListener(final FontPreferences newFontPrefs, - final RobotoRadioButton button, final FontTypeTitle fontTypeTitle) { - button.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) { - SettingsThemeFragment.changed = true; - newFontPrefs.setTitleFont(fontTypeTitle); - } - }); - } - - private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { - SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); - } -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Activity; +import android.view.Menu; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.appcompat.widget.PopupMenu; +import androidx.appcompat.widget.SwitchCompat; + +import com.devspark.robototextview.widget.RobotoRadioButton; + +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.Visuals.FontPreferences; +import me.ccrama.redditslide.Visuals.FontPreferences.FontTypeComment; +import me.ccrama.redditslide.Visuals.FontPreferences.FontTypeTitle; + +public class SettingsFontFragment { + + private final Activity context; + + public SettingsFontFragment(Activity context) { + this.context = context; + } + + private static String getFontName(int resource) { + switch (resource) { + case R.string.font_size_huge: + return "Huge"; + case R.string.font_size_larger: + return "Larger"; + case R.string.font_size_large: + return "Large"; + case R.string.font_size_small: + return "Small"; + case R.string.font_size_smaller: + return "Smaller"; + case R.string.font_size_tiny: + return "Tiny"; + case R.string.font_size_medium: + default: + return "Medium"; + } + } + + public void Bind() { + final SwitchCompat fontEnlargeLinksSwitch = context.findViewById(R.id.settings_font_enlarge_links); + final SwitchCompat fontLinkTypeSwitch = context.findViewById(R.id.settings_font_linktype); + + final LinearLayout fontCommentFontSizeLayout = context.findViewById(R.id.settings_font_commentfontsize); + final TextView fontCommentFontView = context.findViewById(R.id.settings_font_commentFont); + + final RobotoRadioButton fontCommentStyleRegularButton = context.findViewById(R.id.settings_font_creg); + final RobotoRadioButton fontCommentStyleSlabButton = context.findViewById(R.id.settings_font_cslab); + final RobotoRadioButton fontCommentStyleCondensedButton = context.findViewById(R.id.settings_font_ccond); + final RobotoRadioButton fontCommentStyleLightButton = context.findViewById(R.id.settings_font_clight); + final RobotoRadioButton fontCommentStyleSystemButton = context.findViewById(R.id.settings_font_cnone); + + final LinearLayout fontPostFontSizeLayout = context.findViewById(R.id.settings_font_postfontsize); + final TextView fontPostFontView = context.findViewById(R.id.settings_font_postFont); + + final RobotoRadioButton fontPostStyleRegularButton = context.findViewById(R.id.settings_font_sreg); + final RobotoRadioButton fontPostStyleBoldButton = context.findViewById(R.id.settings_font_sbold); + final RobotoRadioButton fontPostStyleMediumButton = context.findViewById(R.id.settings_font_smed); + final RobotoRadioButton fontPostStyleLightButton = context.findViewById(R.id.settings_font_slight); + final RobotoRadioButton fontPostStyleSlabButton = context.findViewById(R.id.settings_font_sslab); + final RobotoRadioButton fontPostStyleSlabLightButton = context.findViewById(R.id.settings_font_sslabl); + final RobotoRadioButton fontPostStyleCondensedButton = context.findViewById(R.id.settings_font_scond); + final RobotoRadioButton fontPostStyleCondensedLightButton = context.findViewById(R.id.settings_font_scondl); + final RobotoRadioButton fontPostStyleCondensedBoldButton = context.findViewById(R.id.settings_font_scondb); + final RobotoRadioButton fontPostStyleSystemButton = context.findViewById(R.id.settings_font_snone); + + final FontPreferences newFontPrefs = new FontPreferences(context); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Links */ + fontEnlargeLinksSwitch.setChecked(SettingValues.largeLinks); + fontEnlargeLinksSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.largeLinks = isChecked; + editSharedBooleanPreference(SettingValues.PREF_LARGE_LINKS, isChecked); + }); + + fontLinkTypeSwitch.setChecked(SettingValues.typeInText); + fontLinkTypeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.typeInText = isChecked; + editSharedBooleanPreference(SettingValues.PREF_TYPE_IN_TEXT, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Font styles */ + fontCommentFontSizeLayout.setOnClickListener(v -> { + PopupMenu popup = new PopupMenu(context, v); + Menu getPopupMenu = popup.getMenu(); + getPopupMenu.add(0, R.string.font_size_huge, 0, R.string.font_size_huge); + getPopupMenu.add(0, R.string.font_size_larger, 0, R.string.font_size_larger); + getPopupMenu.add(0, R.string.font_size_large, 0, R.string.font_size_large); + getPopupMenu.add(0, R.string.font_size_medium, 0, R.string.font_size_medium); + getPopupMenu.add(0, R.string.font_size_small, 0, R.string.font_size_small); + getPopupMenu.add(0, R.string.font_size_smaller, 0, R.string.font_size_smaller); + + //registering popup with OnMenuItemClickListener + popup.setOnMenuItemClickListener(item -> { + newFontPrefs.setCommentFontStyle( + FontPreferences.FontStyleComment.valueOf(getFontName(item.getItemId()))); + fontCommentFontView.setText(newFontPrefs.getCommentFontStyle().getTitle()); + SettingsThemeFragment.changed = true; + return true; + }); + popup.show(); + }); + fontCommentFontView.setText(newFontPrefs.getCommentFontStyle().getTitle()); + + switch (newFontPrefs.getFontTypeComment()) { + case Regular: + fontCommentStyleRegularButton.setChecked(true); + break; + case Slab: + fontCommentStyleSlabButton.setChecked(true); + break; + case Condensed: + fontCommentStyleCondensedButton.setChecked(true); + break; + case Light: + fontCommentStyleLightButton.setChecked(true); + break; + case System: + fontCommentStyleSystemButton.setChecked(true); + break; + } + setCommentFontTypeListener(newFontPrefs, fontCommentStyleRegularButton, FontTypeComment.Regular); + setCommentFontTypeListener(newFontPrefs, fontCommentStyleSlabButton, FontTypeComment.Slab); + setCommentFontTypeListener(newFontPrefs, fontCommentStyleCondensedButton, FontTypeComment.Condensed); + setCommentFontTypeListener(newFontPrefs, fontCommentStyleLightButton, FontTypeComment.Light); + setCommentFontTypeListener(newFontPrefs, fontCommentStyleSystemButton, FontTypeComment.System); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + fontPostFontSizeLayout.setOnClickListener(v -> { + PopupMenu popup = new PopupMenu(context, v); + Menu getPopupMenu = popup.getMenu(); + getPopupMenu.add(0, R.string.font_size_huge, 0, R.string.font_size_huge); + getPopupMenu.add(0, R.string.font_size_larger, 0, R.string.font_size_larger); + getPopupMenu.add(0, R.string.font_size_large, 0, R.string.font_size_large); + getPopupMenu.add(0, R.string.font_size_medium, 0, R.string.font_size_medium); + getPopupMenu.add(0, R.string.font_size_small, 0, R.string.font_size_small); + getPopupMenu.add(0, R.string.font_size_smaller, 0, R.string.font_size_smaller); + getPopupMenu.add(0, R.string.font_size_tiny, 0, R.string.font_size_tiny); + + //registering popup with OnMenuItemClickListener + popup.setOnMenuItemClickListener(item -> { + newFontPrefs.setPostFontStyle( + FontPreferences.FontStyle.valueOf(getFontName(item.getItemId()))); + fontPostFontView.setText(newFontPrefs.getPostFontStyle().getTitle()); + SettingsThemeFragment.changed = true; + return true; + }); + popup.show(); + }); + fontPostFontView.setText(newFontPrefs.getPostFontStyle().getTitle()); + + switch (newFontPrefs.getFontTypeTitle()) { + case Regular: + fontPostStyleRegularButton.setChecked(true); + break; + case Bold: + fontPostStyleBoldButton.setChecked(true); + break; + case Medium: + fontPostStyleMediumButton.setChecked(true); + break; + case Light: + fontPostStyleLightButton.setChecked(true); + break; + case SlabRegular: + fontPostStyleSlabButton.setChecked(true); + break; + case SlabLight: + fontPostStyleSlabLightButton.setChecked(true); + break; + case CondensedRegular: + fontPostStyleCondensedButton.setChecked(true); + break; + case CondensedLight: + fontPostStyleCondensedLightButton.setChecked(true); + break; + case CondensedBold: + fontPostStyleCondensedBoldButton.setChecked(true); + break; + case System: + fontPostStyleSystemButton.setChecked(true); + break; + } + setTitleFontTypeListener(newFontPrefs, fontPostStyleRegularButton, FontTypeTitle.Regular); + setTitleFontTypeListener(newFontPrefs, fontPostStyleBoldButton, FontTypeTitle.Bold); + setTitleFontTypeListener(newFontPrefs, fontPostStyleMediumButton, FontTypeTitle.Medium); + setTitleFontTypeListener(newFontPrefs, fontPostStyleLightButton, FontTypeTitle.Light); + setTitleFontTypeListener(newFontPrefs, fontPostStyleSlabButton, FontTypeTitle.SlabRegular); + setTitleFontTypeListener(newFontPrefs, fontPostStyleSlabLightButton, FontTypeTitle.SlabLight); + setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedButton, FontTypeTitle.CondensedRegular); + setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedLightButton, FontTypeTitle.CondensedLight); + setTitleFontTypeListener(newFontPrefs, fontPostStyleCondensedBoldButton, FontTypeTitle.CondensedBold); + setTitleFontTypeListener(newFontPrefs, fontPostStyleSystemButton, FontTypeTitle.System); + } + + private void setCommentFontTypeListener(final FontPreferences newFontPrefs, + final RobotoRadioButton button, final FontTypeComment fontTypeComment) { + button.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + SettingsThemeFragment.changed = true; + newFontPrefs.setCommentFont(fontTypeComment); + } + }); + } + + private void setTitleFontTypeListener(final FontPreferences newFontPrefs, + final RobotoRadioButton button, final FontTypeTitle fontTypeTitle) { + button.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + SettingsThemeFragment.changed = true; + newFontPrefs.setTitleFont(fontTypeTitle); + } + }); + } + + private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { + SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneral.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneral.java index bf6fd42ff..c2e6dc89b 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneral.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneral.java @@ -1,49 +1,49 @@ -package me.ccrama.redditslide.ui.settings; - -import android.os.Bundle; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; - -import java.io.File; - -import me.ccrama.redditslide.Activities.BaseActivityAnim; -import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate; -import me.ccrama.redditslide.R; - -/** - * Created by ccrama on 3/5/2015. - */ -public class SettingsGeneral extends BaseActivityAnim - implements FolderChooserDialogCreate.FolderCallback { - - private SettingsGeneralFragment fragment = new SettingsGeneralFragment(this); - - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - applyColorTheme(); - setContentView(R.layout.activity_settings_general); - setupAppBar(R.id.toolbar, R.string.settings_title_general, true, true); - - ((ViewGroup) findViewById(R.id.settings_general)).addView( - getLayoutInflater().inflate(R.layout.activity_settings_general_child, null)); - - fragment.Bind(); - } - - @Override - public void onFolderSelection(@NonNull FolderChooserDialogCreate dialog, - @NonNull File folder, boolean isSaveToLocation) { - fragment.onFolderSelection(dialog, folder, false); - } - - @Override - public void onFolderChooserDismissed(@NonNull FolderChooserDialogCreate dialog) { - } - - @Override - public void onResume(){ - super.onResume(); - SettingsGeneralFragment.doNotifText(this); - } -} +package me.ccrama.redditslide.ui.settings; + +import android.os.Bundle; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; + +import java.io.File; + +import me.ccrama.redditslide.Activities.BaseActivityAnim; +import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate; +import me.ccrama.redditslide.R; + +/** + * Created by ccrama on 3/5/2015. + */ +public class SettingsGeneral extends BaseActivityAnim + implements FolderChooserDialogCreate.FolderCallback { + + private SettingsGeneralFragment fragment = new SettingsGeneralFragment(this); + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + applyColorTheme(); + setContentView(R.layout.activity_settings_general); + setupAppBar(R.id.toolbar, R.string.settings_title_general, true, true); + + ((ViewGroup) findViewById(R.id.settings_general)).addView( + getLayoutInflater().inflate(R.layout.activity_settings_general_child, null)); + + fragment.Bind(); + } + + @Override + public void onFolderSelection(@NonNull FolderChooserDialogCreate dialog, + @NonNull File folder, boolean isSaveToLocation) { + fragment.onFolderSelection(dialog, folder, false); + } + + @Override + public void onFolderChooserDismissed(@NonNull FolderChooserDialogCreate dialog) { + } + + @Override + public void onResume(){ + super.onResume(); + SettingsGeneralFragment.doNotifText(this); + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneralFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneralFragment.java index 564ffa870..474512bb5 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneralFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsGeneralFragment.java @@ -1,1074 +1,1074 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Activity; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.os.AsyncTask; -import android.os.Build; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.PopupMenu; -import androidx.appcompat.widget.SwitchCompat; - -import com.afollestad.materialdialogs.DialogAction; -import com.afollestad.materialdialogs.MaterialDialog; -import com.google.android.material.snackbar.Snackbar; -import com.rey.material.widget.Slider; - -import net.dean.jraw.models.CommentSort; -import net.dean.jraw.models.Subreddit; -import net.dean.jraw.paginators.Sorting; -import net.dean.jraw.paginators.TimePeriod; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; - -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.CaseInsensitiveArrayList; -import me.ccrama.redditslide.Fragments.DrawerItemsDialog; -import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate; -import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate.FolderCallback; -import me.ccrama.redditslide.Notifications.CheckForMail; -import me.ccrama.redditslide.Notifications.NotificationJobScheduler; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.Reddit; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.UserSubscriptions; -import me.ccrama.redditslide.Visuals.Palette; -import me.ccrama.redditslide.util.DialogUtil; -import me.ccrama.redditslide.util.ImageLoaderUtils; -import me.ccrama.redditslide.util.OnSingleClickListener; -import me.ccrama.redditslide.util.SortingUtil; -import me.ccrama.redditslide.util.StringUtil; -import me.ccrama.redditslide.util.TimeUtils; - -import static me.ccrama.redditslide.Constants.BackButtonBehaviorOptions; -import static me.ccrama.redditslide.Constants.FAB_DISMISS; -import static me.ccrama.redditslide.Constants.FAB_POST; -import static me.ccrama.redditslide.Constants.FAB_SEARCH; -import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_BOTH; -import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_DRAWER; -import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_TOOLBAR; - -/** - * Created by ccrama on 3/5/2015. - */ -public class SettingsGeneralFragment - implements FolderCallback { - - public static boolean searchChanged; //whether or not the subreddit search method changed - private final ActivityType context; - private String input; - - public SettingsGeneralFragment(ActivityType context) { - this.context = context; - } - - public static void setupNotificationSettings(View dialoglayout, final Activity context) { - final Slider landscape = dialoglayout.findViewById(R.id.landscape); - final CheckBox checkBox = dialoglayout.findViewById(R.id.load); - final CheckBox sound = dialoglayout.findViewById(R.id.sound); - final TextView notifCurrentView = context.findViewById(R.id.settings_general_notifications_current); - - sound.setChecked(SettingValues.notifSound); - sound.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_SOUND_NOTIFS, isChecked) - .apply(); - SettingValues.notifSound = isChecked; - } - }); - - if (Reddit.notificationTime == -1) { - checkBox.setChecked(false); - checkBox.setText(context.getString(R.string.settings_mail_check)); - } else { - checkBox.setChecked(true); - landscape.setValue(Reddit.notificationTime / 15.0f, false); - checkBox.setText(context.getString(R.string.settings_notification_newline, - TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, - context.getBaseContext()))); - } - landscape.setOnPositionChangeListener(new Slider.OnPositionChangeListener() { - @Override - public void onPositionChanged(Slider slider, boolean b, float v, float v1, int i, - int i1) { - if (checkBox.isChecked()) { - checkBox.setText(context.getString(R.string.settings_notification, - TimeUtils.getTimeInHoursAndMins(i1 * 15, context.getBaseContext()))); - } - } - }); - - checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (!isChecked) { - Reddit.notificationTime = -1; - Reddit.colors.edit().putInt("notificationOverride", -1).apply(); - checkBox.setText(context.getString(R.string.settings_mail_check)); - landscape.setValue(0, true); - if (Reddit.notifications != null) { - Reddit.notifications.cancel(); - } - } else { - Reddit.notificationTime = 60; - landscape.setValue(4, true); - checkBox.setText(context.getString(R.string.settings_notification, - TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, - context.getBaseContext()))); - } - } - }); - - dialoglayout.findViewById(R.id.title).setBackgroundColor(Palette.getDefaultColor()); - //todo final Slider portrait = (Slider) dialoglayout.findViewById(R.id.portrait); - - //todo portrait.setBackgroundColor(Palette.getDefaultColor()); - - final AlertDialog.Builder builder = new AlertDialog.Builder(context) - .setView(dialoglayout); - final Dialog dialog = builder.create(); - dialog.show(); - dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - if (checkBox.isChecked()) { - Reddit.notificationTime = landscape.getValue() * 15; - Reddit.colors.edit() - .putInt("notificationOverride", landscape.getValue() * 15) - .apply(); - if (Reddit.notifications == null) { - Reddit.notifications = - new NotificationJobScheduler(context.getApplication()); - } - Reddit.notifications.cancel(); - Reddit.notifications.start(); - } - } - }); - - - dialoglayout.findViewById(R.id.save).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View d) { - if (checkBox.isChecked()) { - Reddit.notificationTime = landscape.getValue() * 15; - Reddit.colors.edit() - .putInt("notificationOverride", landscape.getValue() * 15) - .apply(); - if (Reddit.notifications == null) { - Reddit.notifications = - new NotificationJobScheduler(context.getApplication()); - } - Reddit.notifications.cancel(); - Reddit.notifications.start(); - dialog.dismiss(); - if (context instanceof SettingsGeneral) { - notifCurrentView.setText(context.getString(R.string.settings_notification_short, - TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, - context.getBaseContext()))); - } - } else { - Reddit.notificationTime = -1; - Reddit.colors.edit().putInt("notificationOverride", -1).apply(); - if (Reddit.notifications == null) { - Reddit.notifications = - new NotificationJobScheduler(context.getApplication()); - } - Reddit.notifications.cancel(); - dialog.dismiss(); - if (context instanceof SettingsGeneral) { - notifCurrentView.setText(R.string.settings_notifdisabled); - } - - } - } - }); - } - - public static void doNotifText(final Activity context) { - { - View notifs = context.findViewById(R.id.settings_general_redditnotifs); - if (notifs != null) { - if (!Reddit.isPackageInstalled("com.reddit.frontpage") || - Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { - notifs.setVisibility(View.GONE); - if (context.findViewById(R.id.settings_general_installreddit) != null) { - context.findViewById(R.id.settings_general_installreddit).setVisibility(View.VISIBLE); - } - } else { - if (((Reddit) context.getApplication()).isNotificationAccessEnabled()) { - SwitchCompat single = context.findViewById(R.id.settings_general_piggyback); - if (single != null) { - single.setChecked(true); - single.setEnabled(false); - } - } else { - final SwitchCompat single = context.findViewById(R.id.settings_general_piggyback); - if (single != null) { - single.setChecked(false); - single.setEnabled(true); - single.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - single.setChecked(false); - Snackbar s = Snackbar.make(single, "Give Slide notification access", Snackbar.LENGTH_LONG); - s.setAction("Go to settings", new View.OnClickListener() { - @Override - public void onClick(View view) { - context.startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); - - } - }); - s.show(); - } - }); - } - } - } - } - } - } - - /* Allow SettingsGeneral and Settings Activity classes to use the same XML functionality */ - public void Bind() { - final RelativeLayout notifLayout = context.findViewById(R.id.settings_general_notifications); - final TextView notifCurrentView = context.findViewById(R.id.settings_general_notifications_current); - final RelativeLayout subNotifLayout = context.findViewById(R.id.settings_general_sub_notifications); - final TextView defaultSortingCurrentView = context.findViewById(R.id.settings_general_sorting_current); - - context.findViewById(R.id.settings_general_drawer_items) - .setOnClickListener(v -> - new DrawerItemsDialog(new MaterialDialog.Builder(context)).show()); - - { - SwitchCompat immersiveModeSwitch = context.findViewById(R.id.settings_general_immersivemode); - if (immersiveModeSwitch != null) { - immersiveModeSwitch.setChecked(SettingValues.immersiveMode); - immersiveModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsThemeFragment.changed = true; - SettingValues.immersiveMode = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_IMMERSIVE_MODE, isChecked) - .apply(); - }); - } - } - { - SwitchCompat highClrSpaceSwitch = context.findViewById(R.id.settings_general_high_colorspace); - if (highClrSpaceSwitch != null) { - highClrSpaceSwitch.setChecked(SettingValues.highColorspaceImages); - highClrSpaceSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsThemeFragment.changed = true; - SettingValues.highColorspaceImages = isChecked; - - Reddit application = (Reddit) context.getApplication(); - ImageLoaderUtils.initImageLoader(application.getApplicationContext()); - application.defaultImageLoader = ImageLoaderUtils.imageLoader; - - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_HIGH_COLORSPACE_IMAGES, isChecked) - .apply(); - }); - } - } - - { - SwitchCompat forceLangSwitch = context.findViewById(R.id.settings_general_forcelanguage); - - if (forceLangSwitch != null) { - forceLangSwitch.setChecked(SettingValues.overrideLanguage); - forceLangSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SettingsThemeFragment.changed = true; - SettingValues.overrideLanguage = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_OVERRIDE_LANGUAGE, isChecked) - .apply(); - } - }); - } - } - - //hide fab while scrolling - { - SwitchCompat alwaysShowFabSwitch = context.findViewById(R.id.settings_general_always_show_fab); - - if (alwaysShowFabSwitch != null) { - alwaysShowFabSwitch.setChecked(SettingValues.alwaysShowFAB); - alwaysShowFabSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SettingsThemeFragment.changed = true; - SettingValues.alwaysShowFAB = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_ALWAYS_SHOW_FAB, isChecked) - .apply(); - } - }); - } - } - - // Show image download button - { - SwitchCompat showDownloadBtnSwitch = context.findViewById(R.id.settings_general_show_download_button); - - if (showDownloadBtnSwitch != null) { - showDownloadBtnSwitch.setChecked(SettingValues.imageDownloadButton); - showDownloadBtnSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SettingValues.imageDownloadButton = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_IMAGE_DOWNLOAD_BUTTON, isChecked) - .apply(); - } - }); - } - } - - { - SwitchCompat subfolderSwitch = context.findViewById(R.id.settings_general_subfolder); - - if (subfolderSwitch != null) { - subfolderSwitch.setChecked(SettingValues.imageSubfolders); - subfolderSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - SettingValues.imageSubfolders = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_IMAGE_SUBFOLDERS, isChecked) - .apply(); - } - }); - } - } - - final RelativeLayout setSaveLocationLayout = context.findViewById(R.id.settings_general_set_save_location); - if (setSaveLocationLayout != null) { - setSaveLocationLayout.setOnClickListener(v -> - DialogUtil.showFolderChooserDialog(context)); - } - - - TextView setSaveLocationView = context.findViewById(R.id.settings_general_set_save_location_view); - if (setSaveLocationView != null) { - String loc = Reddit.appRestart.getString("imagelocation", - context.getString(R.string.settings_image_location_unset)); - setSaveLocationView.setText(loc); - } - - final SwitchCompat expandedMenuSwitch = context.findViewById(R.id.settings_general_expandedmenu); - if (expandedMenuSwitch != null) { - expandedMenuSwitch.setChecked(SettingValues.expandedToolbar); - expandedMenuSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.expandedToolbar = isChecked; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_EXPANDED_TOOLBAR, isChecked) - .apply(); - }); - } - - final RelativeLayout viewTypeLayout = context.findViewById(R.id.settings_general_viewtype); - if (viewTypeLayout != null) { - viewTypeLayout.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View v) { - Intent i = new Intent(context, SettingsViewType.class); - context.startActivity(i); - } - }); - } - - //FAB multi choice// - final RelativeLayout fabLayout = context.findViewById(R.id.settings_general_fab); - final TextView currentFabView = context.findViewById(R.id.settings_general_fab_current); - if (currentFabView != null && fabLayout != null) { - currentFabView.setText( - SettingValues.fab - ? SettingValues.fabType == FAB_DISMISS - ? context.getString(R.string.fab_hide) - : context.getString(R.string.fab_create) - : context.getString(R.string.fab_disabled)); - - fabLayout.setOnClickListener(v -> { - PopupMenu popup = new PopupMenu(context, v); - popup.getMenuInflater().inflate(R.menu.fab_settings, popup.getMenu()); - - popup.setOnMenuItemClickListener(item -> { - switch (item.getItemId()) { - case R.id.disabled: - SettingValues.fab = false; - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_FAB, false) - .apply(); - break; - case R.id.hide: - SettingValues.fab = true; - SettingValues.fabType = FAB_DISMISS; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_FAB_TYPE, FAB_DISMISS) - .apply(); - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_FAB, true) - .apply(); - break; - case R.id.create: - SettingValues.fab = true; - SettingValues.fabType = FAB_POST; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_FAB_TYPE, FAB_POST) - .apply(); - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_FAB, true) - .apply(); - break; - case R.id.search: - SettingValues.fab = true; - SettingValues.fabType = FAB_SEARCH; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_FAB_TYPE, FAB_SEARCH) - .apply(); - SettingValues.prefs.edit() - .putBoolean(SettingValues.PREF_FAB, true) - .apply(); - break; - } - if (SettingValues.fab) { - if (SettingValues.fabType == FAB_DISMISS) { - currentFabView.setText(R.string.fab_hide); - } else if (SettingValues.fabType == FAB_POST) { - currentFabView.setText(R.string.fab_create); - } else { - currentFabView.setText(R.string.fab_search); - } - } else { - currentFabView.setText(R.string.fab_disabled); - } - - return true; - }); - - popup.show(); - }); - } - - //SettingValues.subredditSearchMethod == 1 for drawer, 2 for toolbar, 3 for both - final TextView currentMethodTitle = context.findViewById(R.id.settings_general_subreddit_search_method_current); - if (currentMethodTitle != null) { - switch (SettingValues.subredditSearchMethod) { - case SUBREDDIT_SEARCH_METHOD_DRAWER: - currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_drawer)); - break; - case SUBREDDIT_SEARCH_METHOD_TOOLBAR: - currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_toolbar)); - break; - case SUBREDDIT_SEARCH_METHOD_BOTH: - currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_both)); - break; - } - } - - final RelativeLayout currentMethodLayout = context.findViewById(R.id.settings_general_subreddit_search_method); - if (currentMethodLayout != null) { - currentMethodLayout.setOnClickListener(v -> { - final PopupMenu popup = new PopupMenu(SettingsGeneralFragment.this.context, v); - popup.getMenuInflater().inflate(R.menu.subreddit_search_settings, popup.getMenu()); - popup.setOnMenuItemClickListener(item -> { - switch (item.getItemId()) { - case R.id.subreddit_search_drawer: - SettingValues.subredditSearchMethod = - SUBREDDIT_SEARCH_METHOD_DRAWER; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, - SUBREDDIT_SEARCH_METHOD_DRAWER) - .apply(); - searchChanged = true; - break; - case R.id.subreddit_search_toolbar: - SettingValues.subredditSearchMethod = - SUBREDDIT_SEARCH_METHOD_TOOLBAR; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, - SUBREDDIT_SEARCH_METHOD_TOOLBAR) - .apply(); - searchChanged = true; - break; - case R.id.subreddit_search_both: - SettingValues.subredditSearchMethod = - SUBREDDIT_SEARCH_METHOD_BOTH; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, - SUBREDDIT_SEARCH_METHOD_BOTH) - .apply(); - searchChanged = true; - break; - } - - switch (SettingValues.subredditSearchMethod) { - case SUBREDDIT_SEARCH_METHOD_DRAWER: - currentMethodTitle.setText( - context.getString(R.string.subreddit_search_method_drawer)); - break; - case SUBREDDIT_SEARCH_METHOD_TOOLBAR: - currentMethodTitle.setText( - context.getString(R.string.subreddit_search_method_toolbar)); - break; - case SUBREDDIT_SEARCH_METHOD_BOTH: - currentMethodTitle.setText( - context.getString(R.string.subreddit_search_method_both)); - break; - } - return true; - }); - popup.show(); - }); - } - - final TextView currentBackButtonTitle = - context.findViewById(R.id.settings_general_back_button_behavior_current); - if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.ConfirmExit.getValue()) { - currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_confirm_exit)); - } else if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.OpenDrawer.getValue()) { - currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_drawer)); - } else if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.GotoFirst.getValue()) { - currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_goto_first)); - } else { - currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_default)); - } - - final RelativeLayout currentBackButtonLayout = context.findViewById(R.id.settings_general_back_button_behavior); - currentBackButtonLayout.setOnClickListener(v -> { - final PopupMenu popup = new PopupMenu(context, v); - popup.getMenuInflater().inflate(R.menu.back_button_behavior_settings, popup.getMenu()); - - popup.setOnMenuItemClickListener(item -> { - switch (item.getItemId()) { - case R.id.back_button_behavior_default: - SettingValues.backButtonBehavior = - BackButtonBehaviorOptions.Default.getValue(); - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, - BackButtonBehaviorOptions.Default.getValue()) - .apply(); - break; - case R.id.back_button_behavior_confirm_exit: - SettingValues.backButtonBehavior = - BackButtonBehaviorOptions.ConfirmExit.getValue(); - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, - BackButtonBehaviorOptions.ConfirmExit.getValue()) - .apply(); - break; - case R.id.back_button_behavior_open_drawer: - SettingValues.backButtonBehavior = - BackButtonBehaviorOptions.OpenDrawer.getValue(); - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, - BackButtonBehaviorOptions.OpenDrawer.getValue()) - .apply(); - break; - case R.id.back_button_behavior_goto_first: - SettingValues.backButtonBehavior = - BackButtonBehaviorOptions.GotoFirst.getValue(); - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, - BackButtonBehaviorOptions.GotoFirst.getValue()) - .apply(); - break; - } - - if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.ConfirmExit.getValue()) { - currentBackButtonTitle.setText( - context.getString(R.string.back_button_behavior_confirm_exit)); - } else if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.OpenDrawer.getValue()) { - currentBackButtonTitle.setText( - context.getString(R.string.back_button_behavior_drawer)); - } else if (SettingValues.backButtonBehavior - == BackButtonBehaviorOptions.GotoFirst.getValue()) { - currentBackButtonTitle.setText( - context.getString(R.string.back_button_behavior_goto_first)); - } else { - currentBackButtonTitle.setText( - context.getString(R.string.back_button_behavior_default)); - } - return true; - }); - popup.show(); - }); - - if (notifCurrentView != null && - context.findViewById(R.id.settings_general_sub_notifs_current) != null) { - if (Reddit.notificationTime > 0) { - notifCurrentView.setText(context.getString(R.string.settings_notification_short, - TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, - context.getBaseContext()))); - setSubText(); - } else { - notifCurrentView.setText(R.string.settings_notifdisabled); - ((TextView) context.findViewById(R.id.settings_general_sub_notifs_current)).setText( - R.string.settings_enable_notifs); - } - } - - if (Authentication.isLoggedIn) { - if (notifLayout != null) { - notifLayout.setOnClickListener(v -> { - final LayoutInflater inflater = context.getLayoutInflater(); - final View dialoglayout = inflater.inflate(R.layout.inboxfrequency, null); - setupNotificationSettings(dialoglayout, SettingsGeneralFragment.this.context); - }); - } - if (subNotifLayout != null) { - subNotifLayout.setOnClickListener(v -> showSelectDialog()); - } - } else { - if (notifLayout != null) { - notifLayout.setEnabled(false); - notifLayout.setAlpha(0.25f); - } - if (subNotifLayout != null) { - subNotifLayout.setEnabled(false); - subNotifLayout.setAlpha(0.25f); - } - } - - if (defaultSortingCurrentView != null) { - defaultSortingCurrentView.setText( - SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")]); - } - - { - if (context.findViewById(R.id.settings_general_sorting) != null) { - context.findViewById(R.id.settings_general_sorting).setOnClickListener(v -> { - final DialogInterface.OnClickListener l2 = (dialogInterface, i) -> { - switch (i) { - case 0: - SortingUtil.defaultSorting = Sorting.HOT; - break; - case 1: - SortingUtil.defaultSorting = Sorting.NEW; - break; - case 2: - SortingUtil.defaultSorting = Sorting.RISING; - break; - case 3: - SortingUtil.defaultSorting = Sorting.TOP; - askTimePeriod(); - return; - case 4: - SortingUtil.defaultSorting = Sorting.CONTROVERSIAL; - askTimePeriod(); - return; - } - SettingValues.prefs.edit() - .putString("defaultSorting", - SortingUtil.defaultSorting.name()) - .apply(); - SettingValues.defaultSorting = SortingUtil.defaultSorting; - - if (defaultSortingCurrentView != null) { - defaultSortingCurrentView.setText( - SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")]); - } - }; - - // Remove the "Best" sorting option from settings because it is only supported on the frontpage. - int skip = -1; - List sortingStrings = new ArrayList<>(Arrays.asList(SortingUtil.getSortingStrings())); - for (int i = 0; i < sortingStrings.size(); i++) { - if (sortingStrings.get(i).equals(context.getString(R.string.sorting_best))) { - skip = i; - break; - } - } - if (skip != -1) { - sortingStrings.remove(skip); - } - - new AlertDialog.Builder(SettingsGeneralFragment.this.context) - .setTitle(R.string.sorting_choose) - .setSingleChoiceItems( - sortingStrings.toArray(new String[0]), - SortingUtil.getSortingId(""), - l2) - .show(); - }); - } - } - doNotifText(context); - { - final int i2 = SettingValues.defaultCommentSorting == CommentSort.CONFIDENCE ? 0 - : SettingValues.defaultCommentSorting == CommentSort.TOP ? 1 - : SettingValues.defaultCommentSorting == CommentSort.NEW ? 2 - : SettingValues.defaultCommentSorting - == CommentSort.CONTROVERSIAL ? 3 - : SettingValues.defaultCommentSorting == CommentSort.OLD - ? 4 : SettingValues.defaultCommentSorting - == CommentSort.QA ? 5 : 0; - - final TextView sortingCurrentCommentView = context.findViewById(R.id.settings_general_sorting_current_comment); - if (sortingCurrentCommentView != null) { - sortingCurrentCommentView.setText( - SortingUtil.getSortingCommentsStrings()[i2]); - } - - if (context.findViewById(R.id.settings_general_sorting_comment) != null) { - context.findViewById(R.id.settings_general_sorting_comment).setOnClickListener(v -> { - final DialogInterface.OnClickListener l2 = (dialogInterface, i) -> { - CommentSort commentSorting = - SettingValues.defaultCommentSorting; - switch (i) { - case 0: - commentSorting = CommentSort.CONFIDENCE; - break; - case 1: - commentSorting = CommentSort.TOP; - break; - case 2: - commentSorting = CommentSort.NEW; - break; - case 3: - commentSorting = CommentSort.CONTROVERSIAL; - break; - case 4: - commentSorting = CommentSort.OLD; - break; - case 5: - commentSorting = CommentSort.QA; - break; - } - SettingValues.prefs.edit() - .putString("defaultCommentSortingNew", - commentSorting.name()) - .apply(); - SettingValues.defaultCommentSorting = commentSorting; - if (sortingCurrentCommentView != null) { - sortingCurrentCommentView.setText( - SortingUtil.getSortingCommentsStrings()[i]); - } - }; - - Resources res = context.getBaseContext().getResources(); - - new AlertDialog.Builder(SettingsGeneralFragment.this.context) - .setTitle(R.string.sorting_choose) - .setSingleChoiceItems( - new String[]{ - res.getString(R.string.sorting_best), - res.getString(R.string.sorting_top), - res.getString(R.string.sorting_new), - res.getString(R.string.sorting_controversial), - res.getString(R.string.sorting_old), - res.getString(R.string.sorting_ama) - }, i2, l2) - .show(); - }); - } - } - } - - private void askTimePeriod() { - final TextView defaultSortingCurrentView = context.findViewById(R.id.settings_general_sorting_current); - final DialogInterface.OnClickListener l2 = new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialogInterface, int i) { - switch (i) { - case 0: - SortingUtil.timePeriod = TimePeriod.HOUR; - break; - case 1: - SortingUtil.timePeriod = TimePeriod.DAY; - break; - case 2: - SortingUtil.timePeriod = TimePeriod.WEEK; - break; - case 3: - SortingUtil.timePeriod = TimePeriod.MONTH; - break; - case 4: - SortingUtil.timePeriod = TimePeriod.YEAR; - break; - case 5: - SortingUtil.timePeriod = TimePeriod.ALL; - break; - } - SettingValues.prefs.edit() - .putString("defaultSorting", SortingUtil.defaultSorting.name()) - .apply(); - SettingValues.prefs.edit().putString("timePeriod", SortingUtil.timePeriod.name()) - .apply(); - SettingValues.defaultSorting = SortingUtil.defaultSorting; - SettingValues.timePeriod = SortingUtil.timePeriod; - defaultSortingCurrentView.setText( - SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")] - + " > " - + SortingUtil.getSortingTimesStrings()[SortingUtil.getSortingTimeId( - "")]); - } - }; - - new AlertDialog.Builder(SettingsGeneralFragment.this.context) - .setTitle(R.string.sorting_choose) - .setSingleChoiceItems( - SortingUtil.getSortingTimesStrings(), - SortingUtil.getSortingTimeId(""), - l2) - .show(); - } - - private void setSubText() { - ArrayList rawSubs = - StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); - String subText = context.getString(R.string.sub_post_notifs_settings_none); - StringBuilder subs = new StringBuilder(); - for (String s : rawSubs) { - if (!s.isEmpty()) { - try { - String[] split = s.split(":"); - subs.append(split[0]); - subs.append("(+").append(split[1]).append(")"); - subs.append(", "); - } catch (Exception ignored) { - - } - } - } - if (!subs.toString().isEmpty()) { - subText = subs.substring(0, subs.toString().length() - 2); - } - ((TextView) context.findViewById(R.id.settings_general_sub_notifs_current)).setText(subText); - } - - private void showSelectDialog() { - ArrayList rawSubs = - StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); - HashMap subThresholds = new HashMap<>(); - for (String s : rawSubs) { - try { - String[] split = s.split(":"); - subThresholds.put(split[0].toLowerCase(Locale.ENGLISH), Integer.valueOf(split[1])); - } catch (Exception ignored) { - - } - } - - // Get list of user's subscriptions - CaseInsensitiveArrayList subs = UserSubscriptions.getSubscriptions(context); - // Add any subs that the user has notifications for but isn't subscribed to - for (String s : subThresholds.keySet()) { - if (!subs.contains(s)) { - subs.add(s); - } - } - - List sorted = UserSubscriptions.sort(subs); - - //Array of all subs - String[] all = new String[sorted.size()]; - //Contains which subreddits are checked - boolean[] checked = new boolean[all.length]; - - - //Remove special subreddits from list and store it in "all" - int i = 0; - for (String s : sorted) { - if (!s.equals("all") - && !s.equals("frontpage") - && !s.contains("+") - && !s.contains(".") - && !s.contains("/m/")) { - all[i] = s.toLowerCase(Locale.ENGLISH); - i++; - } - } - - //Remove empty entries & store which subreddits are checked - List list = new ArrayList<>(); - i = 0; - for (String s : all) { - if (s != null && !s.isEmpty()) { - list.add(s); - if (subThresholds.containsKey(s)) { - checked[i] = true; - } - i++; - } - } - - //Convert List back to Array - all = list.toArray(new String[0]); - - final ArrayList toCheck = new ArrayList<>(subThresholds.keySet()); - final String[] finalAll = all; - new AlertDialog.Builder(SettingsGeneralFragment.this.context) - .setMultiChoiceItems(finalAll, checked, (dialog, which, isChecked) -> { - if (!isChecked) { - toCheck.remove(finalAll[which]); - } else { - toCheck.add(finalAll[which]); - } - }) - .setTitle(R.string.sub_post_notifs_title_settings) - .setPositiveButton(context.getString(R.string.btn_add).toUpperCase(), (dialog, which) -> - showThresholdDialog(toCheck, false)) - .setNegativeButton(R.string.sub_post_notifs_settings_search, (dialog, which) -> - new MaterialDialog.Builder(SettingsGeneralFragment.this.context) - .title(R.string.reorder_add_subreddit) - .inputRangeRes(2, 21, R.color.md_red_500) - .alwaysCallInputCallback() - .input(context.getString(R.string.reorder_subreddit_name), null, - false, new MaterialDialog.InputCallback() { - @Override - public void onInput(MaterialDialog dialog, - CharSequence raw) { - input = raw.toString() - .replaceAll("\\s", - ""); //remove whitespace from input - } - }) - .positiveText(R.string.btn_add) - .onPositive(new MaterialDialog.SingleButtonCallback() { - @Override - public void onClick(@NonNull MaterialDialog dialog, - @NonNull DialogAction which) { - new AsyncGetSubreddit().execute(input); - } - }) - .negativeText(R.string.btn_cancel) - .show()) - .show(); - } - - private void showThresholdDialog(ArrayList strings, boolean search) { - final ArrayList subsRaw = - StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); - - if (!search) { - //NOT a sub searched for, was instead a list of all subs - for (String raw : new ArrayList<>(subsRaw)) { - if (!strings.contains(raw.split(":")[0])) { - subsRaw.remove(raw); - } - } - } - - final ArrayList subs = new ArrayList<>(); - for (String s : subsRaw) { - try { - subs.add(s.split(":")[0].toLowerCase(Locale.ENGLISH)); - } catch (Exception e) { - - } - } - - final ArrayList toAdd = new ArrayList<>(); - for (String s : strings) { - if (!subs.contains(s.toLowerCase(Locale.ENGLISH))) { - toAdd.add(s.toLowerCase(Locale.ENGLISH)); - } - } - if (!toAdd.isEmpty()) { - new MaterialDialog.Builder(SettingsGeneralFragment.this.context).title( - R.string.sub_post_notifs_threshold) - .items(new String[]{"1", "5", "10", "20", "40", "50"}) - .alwaysCallSingleChoiceCallback() - .itemsCallbackSingleChoice(0, new MaterialDialog.ListCallbackSingleChoice() { - @Override - public boolean onSelection(MaterialDialog dialog, View itemView, int which, - CharSequence text) { - for (String s : toAdd) { - subsRaw.add(s + ":" + text); - } - saveAndUpdateSubs(subsRaw); - return true; - } - }) - .cancelable(false) - .show(); - } else { - saveAndUpdateSubs(subsRaw); - } - } - - private void saveAndUpdateSubs(ArrayList subs) { - Reddit.appRestart.edit() - .putString(CheckForMail.SUBS_TO_GET, StringUtil.arrayToString(subs)) - .commit(); - setSubText(); - } - - @Override - public void onFolderSelection(@NonNull FolderChooserDialogCreate dialog, - @NonNull File folder, boolean isSaveToLocation) { - Reddit.appRestart.edit().putString("imagelocation", folder.getAbsolutePath()).apply(); - Toast.makeText(context, - context.getString(R.string.settings_set_image_location, folder.getAbsolutePath()), - Toast.LENGTH_LONG).show(); - ((TextView) context.findViewById(R.id.settings_general_set_save_location_view)).setText(folder.getAbsolutePath()); - } - - @Override - public void onFolderChooserDismissed(@NonNull FolderChooserDialogCreate dialog) { - } - - private class AsyncGetSubreddit extends AsyncTask { - @Override - public void onPostExecute(Subreddit subreddit) { - if (subreddit != null || input.equalsIgnoreCase("friends") || input.equalsIgnoreCase( - "mod")) { - ArrayList singleSub = new ArrayList<>(); - singleSub.add(subreddit.getDisplayName().toLowerCase(Locale.ENGLISH)); - showThresholdDialog(singleSub, true); - } - } - - @Override - protected Subreddit doInBackground(final String... params) { - try { - return Authentication.reddit.getSubreddit(params[0]); - } catch (Exception e) { - context.runOnUiThread(() -> { - try { - new AlertDialog.Builder(SettingsGeneralFragment.this.context) - .setTitle(R.string.subreddit_err) - .setMessage(context.getString(R.string.subreddit_err_msg, params[0])) - .setPositiveButton(R.string.btn_ok, (dialog, which) -> - dialog.dismiss()) - .setOnDismissListener(null) - .show(); - } catch (Exception ignored) { - } - }); - - return null; - } - } - } - -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Activity; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.res.Resources; +import android.os.AsyncTask; +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.PopupMenu; +import androidx.appcompat.widget.SwitchCompat; + +import com.afollestad.materialdialogs.DialogAction; +import com.afollestad.materialdialogs.MaterialDialog; +import com.google.android.material.snackbar.Snackbar; +import com.rey.material.widget.Slider; + +import net.dean.jraw.models.CommentSort; +import net.dean.jraw.models.Subreddit; +import net.dean.jraw.paginators.Sorting; +import net.dean.jraw.paginators.TimePeriod; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.CaseInsensitiveArrayList; +import me.ccrama.redditslide.Fragments.DrawerItemsDialog; +import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate; +import me.ccrama.redditslide.Fragments.FolderChooserDialogCreate.FolderCallback; +import me.ccrama.redditslide.Notifications.CheckForMail; +import me.ccrama.redditslide.Notifications.NotificationJobScheduler; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.Reddit; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.UserSubscriptions; +import me.ccrama.redditslide.Visuals.Palette; +import me.ccrama.redditslide.util.DialogUtil; +import me.ccrama.redditslide.util.ImageLoaderUtils; +import me.ccrama.redditslide.util.OnSingleClickListener; +import me.ccrama.redditslide.util.SortingUtil; +import me.ccrama.redditslide.util.StringUtil; +import me.ccrama.redditslide.util.TimeUtils; + +import static me.ccrama.redditslide.Constants.BackButtonBehaviorOptions; +import static me.ccrama.redditslide.Constants.FAB_DISMISS; +import static me.ccrama.redditslide.Constants.FAB_POST; +import static me.ccrama.redditslide.Constants.FAB_SEARCH; +import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_BOTH; +import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_DRAWER; +import static me.ccrama.redditslide.Constants.SUBREDDIT_SEARCH_METHOD_TOOLBAR; + +/** + * Created by ccrama on 3/5/2015. + */ +public class SettingsGeneralFragment + implements FolderCallback { + + public static boolean searchChanged; //whether or not the subreddit search method changed + private final ActivityType context; + private String input; + + public SettingsGeneralFragment(ActivityType context) { + this.context = context; + } + + public static void setupNotificationSettings(View dialoglayout, final Activity context) { + final Slider landscape = dialoglayout.findViewById(R.id.landscape); + final CheckBox checkBox = dialoglayout.findViewById(R.id.load); + final CheckBox sound = dialoglayout.findViewById(R.id.sound); + final TextView notifCurrentView = context.findViewById(R.id.settings_general_notifications_current); + + sound.setChecked(SettingValues.notifSound); + sound.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_SOUND_NOTIFS, isChecked) + .apply(); + SettingValues.notifSound = isChecked; + } + }); + + if (Reddit.notificationTime == -1) { + checkBox.setChecked(false); + checkBox.setText(context.getString(R.string.settings_mail_check)); + } else { + checkBox.setChecked(true); + landscape.setValue(Reddit.notificationTime / 15.0f, false); + checkBox.setText(context.getString(R.string.settings_notification_newline, + TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, + context.getBaseContext()))); + } + landscape.setOnPositionChangeListener(new Slider.OnPositionChangeListener() { + @Override + public void onPositionChanged(Slider slider, boolean b, float v, float v1, int i, + int i1) { + if (checkBox.isChecked()) { + checkBox.setText(context.getString(R.string.settings_notification, + TimeUtils.getTimeInHoursAndMins(i1 * 15, context.getBaseContext()))); + } + } + }); + + checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (!isChecked) { + Reddit.notificationTime = -1; + Reddit.colors.edit().putInt("notificationOverride", -1).apply(); + checkBox.setText(context.getString(R.string.settings_mail_check)); + landscape.setValue(0, true); + if (Reddit.notifications != null) { + Reddit.notifications.cancel(); + } + } else { + Reddit.notificationTime = 60; + landscape.setValue(4, true); + checkBox.setText(context.getString(R.string.settings_notification, + TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, + context.getBaseContext()))); + } + } + }); + + dialoglayout.findViewById(R.id.title).setBackgroundColor(Palette.getDefaultColor()); + //todo final Slider portrait = (Slider) dialoglayout.findViewById(R.id.portrait); + + //todo portrait.setBackgroundColor(Palette.getDefaultColor()); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setView(dialoglayout); + final Dialog dialog = builder.create(); + dialog.show(); + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + if (checkBox.isChecked()) { + Reddit.notificationTime = landscape.getValue() * 15; + Reddit.colors.edit() + .putInt("notificationOverride", landscape.getValue() * 15) + .apply(); + if (Reddit.notifications == null) { + Reddit.notifications = + new NotificationJobScheduler(context.getApplication()); + } + Reddit.notifications.cancel(); + Reddit.notifications.start(); + } + } + }); + + + dialoglayout.findViewById(R.id.save).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View d) { + if (checkBox.isChecked()) { + Reddit.notificationTime = landscape.getValue() * 15; + Reddit.colors.edit() + .putInt("notificationOverride", landscape.getValue() * 15) + .apply(); + if (Reddit.notifications == null) { + Reddit.notifications = + new NotificationJobScheduler(context.getApplication()); + } + Reddit.notifications.cancel(); + Reddit.notifications.start(); + dialog.dismiss(); + if (context instanceof SettingsGeneral) { + notifCurrentView.setText(context.getString(R.string.settings_notification_short, + TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, + context.getBaseContext()))); + } + } else { + Reddit.notificationTime = -1; + Reddit.colors.edit().putInt("notificationOverride", -1).apply(); + if (Reddit.notifications == null) { + Reddit.notifications = + new NotificationJobScheduler(context.getApplication()); + } + Reddit.notifications.cancel(); + dialog.dismiss(); + if (context instanceof SettingsGeneral) { + notifCurrentView.setText(R.string.settings_notifdisabled); + } + + } + } + }); + } + + public static void doNotifText(final Activity context) { + { + View notifs = context.findViewById(R.id.settings_general_redditnotifs); + if (notifs != null) { + if (!Reddit.isPackageInstalled("com.reddit.frontpage") || + Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { + notifs.setVisibility(View.GONE); + if (context.findViewById(R.id.settings_general_installreddit) != null) { + context.findViewById(R.id.settings_general_installreddit).setVisibility(View.VISIBLE); + } + } else { + if (((Reddit) context.getApplication()).isNotificationAccessEnabled()) { + SwitchCompat single = context.findViewById(R.id.settings_general_piggyback); + if (single != null) { + single.setChecked(true); + single.setEnabled(false); + } + } else { + final SwitchCompat single = context.findViewById(R.id.settings_general_piggyback); + if (single != null) { + single.setChecked(false); + single.setEnabled(true); + single.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + single.setChecked(false); + Snackbar s = Snackbar.make(single, "Give Slide notification access", Snackbar.LENGTH_LONG); + s.setAction("Go to settings", new View.OnClickListener() { + @Override + public void onClick(View view) { + context.startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); + + } + }); + s.show(); + } + }); + } + } + } + } + } + } + + /* Allow SettingsGeneral and Settings Activity classes to use the same XML functionality */ + public void Bind() { + final RelativeLayout notifLayout = context.findViewById(R.id.settings_general_notifications); + final TextView notifCurrentView = context.findViewById(R.id.settings_general_notifications_current); + final RelativeLayout subNotifLayout = context.findViewById(R.id.settings_general_sub_notifications); + final TextView defaultSortingCurrentView = context.findViewById(R.id.settings_general_sorting_current); + + context.findViewById(R.id.settings_general_drawer_items) + .setOnClickListener(v -> + new DrawerItemsDialog(new MaterialDialog.Builder(context)).show()); + + { + SwitchCompat immersiveModeSwitch = context.findViewById(R.id.settings_general_immersivemode); + if (immersiveModeSwitch != null) { + immersiveModeSwitch.setChecked(SettingValues.immersiveMode); + immersiveModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsThemeFragment.changed = true; + SettingValues.immersiveMode = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_IMMERSIVE_MODE, isChecked) + .apply(); + }); + } + } + { + SwitchCompat highClrSpaceSwitch = context.findViewById(R.id.settings_general_high_colorspace); + if (highClrSpaceSwitch != null) { + highClrSpaceSwitch.setChecked(SettingValues.highColorspaceImages); + highClrSpaceSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsThemeFragment.changed = true; + SettingValues.highColorspaceImages = isChecked; + + Reddit application = (Reddit) context.getApplication(); + ImageLoaderUtils.initImageLoader(application.getApplicationContext()); + application.defaultImageLoader = ImageLoaderUtils.imageLoader; + + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_HIGH_COLORSPACE_IMAGES, isChecked) + .apply(); + }); + } + } + + { + SwitchCompat forceLangSwitch = context.findViewById(R.id.settings_general_forcelanguage); + + if (forceLangSwitch != null) { + forceLangSwitch.setChecked(SettingValues.overrideLanguage); + forceLangSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SettingsThemeFragment.changed = true; + SettingValues.overrideLanguage = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_OVERRIDE_LANGUAGE, isChecked) + .apply(); + } + }); + } + } + + //hide fab while scrolling + { + SwitchCompat alwaysShowFabSwitch = context.findViewById(R.id.settings_general_always_show_fab); + + if (alwaysShowFabSwitch != null) { + alwaysShowFabSwitch.setChecked(SettingValues.alwaysShowFAB); + alwaysShowFabSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SettingsThemeFragment.changed = true; + SettingValues.alwaysShowFAB = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_ALWAYS_SHOW_FAB, isChecked) + .apply(); + } + }); + } + } + + // Show image download button + { + SwitchCompat showDownloadBtnSwitch = context.findViewById(R.id.settings_general_show_download_button); + + if (showDownloadBtnSwitch != null) { + showDownloadBtnSwitch.setChecked(SettingValues.imageDownloadButton); + showDownloadBtnSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SettingValues.imageDownloadButton = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_IMAGE_DOWNLOAD_BUTTON, isChecked) + .apply(); + } + }); + } + } + + { + SwitchCompat subfolderSwitch = context.findViewById(R.id.settings_general_subfolder); + + if (subfolderSwitch != null) { + subfolderSwitch.setChecked(SettingValues.imageSubfolders); + subfolderSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SettingValues.imageSubfolders = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_IMAGE_SUBFOLDERS, isChecked) + .apply(); + } + }); + } + } + + final RelativeLayout setSaveLocationLayout = context.findViewById(R.id.settings_general_set_save_location); + if (setSaveLocationLayout != null) { + setSaveLocationLayout.setOnClickListener(v -> + DialogUtil.showFolderChooserDialog(context)); + } + + + TextView setSaveLocationView = context.findViewById(R.id.settings_general_set_save_location_view); + if (setSaveLocationView != null) { + String loc = Reddit.appRestart.getString("imagelocation", + context.getString(R.string.settings_image_location_unset)); + setSaveLocationView.setText(loc); + } + + final SwitchCompat expandedMenuSwitch = context.findViewById(R.id.settings_general_expandedmenu); + if (expandedMenuSwitch != null) { + expandedMenuSwitch.setChecked(SettingValues.expandedToolbar); + expandedMenuSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.expandedToolbar = isChecked; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_EXPANDED_TOOLBAR, isChecked) + .apply(); + }); + } + + final RelativeLayout viewTypeLayout = context.findViewById(R.id.settings_general_viewtype); + if (viewTypeLayout != null) { + viewTypeLayout.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View v) { + Intent i = new Intent(context, SettingsViewType.class); + context.startActivity(i); + } + }); + } + + //FAB multi choice// + final RelativeLayout fabLayout = context.findViewById(R.id.settings_general_fab); + final TextView currentFabView = context.findViewById(R.id.settings_general_fab_current); + if (currentFabView != null && fabLayout != null) { + currentFabView.setText( + SettingValues.fab + ? SettingValues.fabType == FAB_DISMISS + ? context.getString(R.string.fab_hide) + : context.getString(R.string.fab_create) + : context.getString(R.string.fab_disabled)); + + fabLayout.setOnClickListener(v -> { + PopupMenu popup = new PopupMenu(context, v); + popup.getMenuInflater().inflate(R.menu.fab_settings, popup.getMenu()); + + popup.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.disabled: + SettingValues.fab = false; + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_FAB, false) + .apply(); + break; + case R.id.hide: + SettingValues.fab = true; + SettingValues.fabType = FAB_DISMISS; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_FAB_TYPE, FAB_DISMISS) + .apply(); + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_FAB, true) + .apply(); + break; + case R.id.create: + SettingValues.fab = true; + SettingValues.fabType = FAB_POST; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_FAB_TYPE, FAB_POST) + .apply(); + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_FAB, true) + .apply(); + break; + case R.id.search: + SettingValues.fab = true; + SettingValues.fabType = FAB_SEARCH; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_FAB_TYPE, FAB_SEARCH) + .apply(); + SettingValues.prefs.edit() + .putBoolean(SettingValues.PREF_FAB, true) + .apply(); + break; + } + if (SettingValues.fab) { + if (SettingValues.fabType == FAB_DISMISS) { + currentFabView.setText(R.string.fab_hide); + } else if (SettingValues.fabType == FAB_POST) { + currentFabView.setText(R.string.fab_create); + } else { + currentFabView.setText(R.string.fab_search); + } + } else { + currentFabView.setText(R.string.fab_disabled); + } + + return true; + }); + + popup.show(); + }); + } + + //SettingValues.subredditSearchMethod == 1 for drawer, 2 for toolbar, 3 for both + final TextView currentMethodTitle = context.findViewById(R.id.settings_general_subreddit_search_method_current); + if (currentMethodTitle != null) { + switch (SettingValues.subredditSearchMethod) { + case SUBREDDIT_SEARCH_METHOD_DRAWER: + currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_drawer)); + break; + case SUBREDDIT_SEARCH_METHOD_TOOLBAR: + currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_toolbar)); + break; + case SUBREDDIT_SEARCH_METHOD_BOTH: + currentMethodTitle.setText(context.getString(R.string.subreddit_search_method_both)); + break; + } + } + + final RelativeLayout currentMethodLayout = context.findViewById(R.id.settings_general_subreddit_search_method); + if (currentMethodLayout != null) { + currentMethodLayout.setOnClickListener(v -> { + final PopupMenu popup = new PopupMenu(SettingsGeneralFragment.this.context, v); + popup.getMenuInflater().inflate(R.menu.subreddit_search_settings, popup.getMenu()); + popup.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.subreddit_search_drawer: + SettingValues.subredditSearchMethod = + SUBREDDIT_SEARCH_METHOD_DRAWER; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, + SUBREDDIT_SEARCH_METHOD_DRAWER) + .apply(); + searchChanged = true; + break; + case R.id.subreddit_search_toolbar: + SettingValues.subredditSearchMethod = + SUBREDDIT_SEARCH_METHOD_TOOLBAR; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, + SUBREDDIT_SEARCH_METHOD_TOOLBAR) + .apply(); + searchChanged = true; + break; + case R.id.subreddit_search_both: + SettingValues.subredditSearchMethod = + SUBREDDIT_SEARCH_METHOD_BOTH; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_SUBREDDIT_SEARCH_METHOD, + SUBREDDIT_SEARCH_METHOD_BOTH) + .apply(); + searchChanged = true; + break; + } + + switch (SettingValues.subredditSearchMethod) { + case SUBREDDIT_SEARCH_METHOD_DRAWER: + currentMethodTitle.setText( + context.getString(R.string.subreddit_search_method_drawer)); + break; + case SUBREDDIT_SEARCH_METHOD_TOOLBAR: + currentMethodTitle.setText( + context.getString(R.string.subreddit_search_method_toolbar)); + break; + case SUBREDDIT_SEARCH_METHOD_BOTH: + currentMethodTitle.setText( + context.getString(R.string.subreddit_search_method_both)); + break; + } + return true; + }); + popup.show(); + }); + } + + final TextView currentBackButtonTitle = + context.findViewById(R.id.settings_general_back_button_behavior_current); + if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.ConfirmExit.getValue()) { + currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_confirm_exit)); + } else if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.OpenDrawer.getValue()) { + currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_drawer)); + } else if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.GotoFirst.getValue()) { + currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_goto_first)); + } else { + currentBackButtonTitle.setText(context.getString(R.string.back_button_behavior_default)); + } + + final RelativeLayout currentBackButtonLayout = context.findViewById(R.id.settings_general_back_button_behavior); + currentBackButtonLayout.setOnClickListener(v -> { + final PopupMenu popup = new PopupMenu(context, v); + popup.getMenuInflater().inflate(R.menu.back_button_behavior_settings, popup.getMenu()); + + popup.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.back_button_behavior_default: + SettingValues.backButtonBehavior = + BackButtonBehaviorOptions.Default.getValue(); + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, + BackButtonBehaviorOptions.Default.getValue()) + .apply(); + break; + case R.id.back_button_behavior_confirm_exit: + SettingValues.backButtonBehavior = + BackButtonBehaviorOptions.ConfirmExit.getValue(); + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, + BackButtonBehaviorOptions.ConfirmExit.getValue()) + .apply(); + break; + case R.id.back_button_behavior_open_drawer: + SettingValues.backButtonBehavior = + BackButtonBehaviorOptions.OpenDrawer.getValue(); + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, + BackButtonBehaviorOptions.OpenDrawer.getValue()) + .apply(); + break; + case R.id.back_button_behavior_goto_first: + SettingValues.backButtonBehavior = + BackButtonBehaviorOptions.GotoFirst.getValue(); + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_BACK_BUTTON_BEHAVIOR, + BackButtonBehaviorOptions.GotoFirst.getValue()) + .apply(); + break; + } + + if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.ConfirmExit.getValue()) { + currentBackButtonTitle.setText( + context.getString(R.string.back_button_behavior_confirm_exit)); + } else if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.OpenDrawer.getValue()) { + currentBackButtonTitle.setText( + context.getString(R.string.back_button_behavior_drawer)); + } else if (SettingValues.backButtonBehavior + == BackButtonBehaviorOptions.GotoFirst.getValue()) { + currentBackButtonTitle.setText( + context.getString(R.string.back_button_behavior_goto_first)); + } else { + currentBackButtonTitle.setText( + context.getString(R.string.back_button_behavior_default)); + } + return true; + }); + popup.show(); + }); + + if (notifCurrentView != null && + context.findViewById(R.id.settings_general_sub_notifs_current) != null) { + if (Reddit.notificationTime > 0) { + notifCurrentView.setText(context.getString(R.string.settings_notification_short, + TimeUtils.getTimeInHoursAndMins(Reddit.notificationTime, + context.getBaseContext()))); + setSubText(); + } else { + notifCurrentView.setText(R.string.settings_notifdisabled); + ((TextView) context.findViewById(R.id.settings_general_sub_notifs_current)).setText( + R.string.settings_enable_notifs); + } + } + + if (Authentication.isLoggedIn) { + if (notifLayout != null) { + notifLayout.setOnClickListener(v -> { + final LayoutInflater inflater = context.getLayoutInflater(); + final View dialoglayout = inflater.inflate(R.layout.inboxfrequency, null); + setupNotificationSettings(dialoglayout, SettingsGeneralFragment.this.context); + }); + } + if (subNotifLayout != null) { + subNotifLayout.setOnClickListener(v -> showSelectDialog()); + } + } else { + if (notifLayout != null) { + notifLayout.setEnabled(false); + notifLayout.setAlpha(0.25f); + } + if (subNotifLayout != null) { + subNotifLayout.setEnabled(false); + subNotifLayout.setAlpha(0.25f); + } + } + + if (defaultSortingCurrentView != null) { + defaultSortingCurrentView.setText( + SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")]); + } + + { + if (context.findViewById(R.id.settings_general_sorting) != null) { + context.findViewById(R.id.settings_general_sorting).setOnClickListener(v -> { + final DialogInterface.OnClickListener l2 = (dialogInterface, i) -> { + switch (i) { + case 0: + SortingUtil.defaultSorting = Sorting.HOT; + break; + case 1: + SortingUtil.defaultSorting = Sorting.NEW; + break; + case 2: + SortingUtil.defaultSorting = Sorting.RISING; + break; + case 3: + SortingUtil.defaultSorting = Sorting.TOP; + askTimePeriod(); + return; + case 4: + SortingUtil.defaultSorting = Sorting.CONTROVERSIAL; + askTimePeriod(); + return; + } + SettingValues.prefs.edit() + .putString("defaultSorting", + SortingUtil.defaultSorting.name()) + .apply(); + SettingValues.defaultSorting = SortingUtil.defaultSorting; + + if (defaultSortingCurrentView != null) { + defaultSortingCurrentView.setText( + SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")]); + } + }; + + // Remove the "Best" sorting option from settings because it is only supported on the frontpage. + int skip = -1; + List sortingStrings = new ArrayList<>(Arrays.asList(SortingUtil.getSortingStrings())); + for (int i = 0; i < sortingStrings.size(); i++) { + if (sortingStrings.get(i).equals(context.getString(R.string.sorting_best))) { + skip = i; + break; + } + } + if (skip != -1) { + sortingStrings.remove(skip); + } + + new AlertDialog.Builder(SettingsGeneralFragment.this.context) + .setTitle(R.string.sorting_choose) + .setSingleChoiceItems( + sortingStrings.toArray(new String[0]), + SortingUtil.getSortingId(""), + l2) + .show(); + }); + } + } + doNotifText(context); + { + final int i2 = SettingValues.defaultCommentSorting == CommentSort.CONFIDENCE ? 0 + : SettingValues.defaultCommentSorting == CommentSort.TOP ? 1 + : SettingValues.defaultCommentSorting == CommentSort.NEW ? 2 + : SettingValues.defaultCommentSorting + == CommentSort.CONTROVERSIAL ? 3 + : SettingValues.defaultCommentSorting == CommentSort.OLD + ? 4 : SettingValues.defaultCommentSorting + == CommentSort.QA ? 5 : 0; + + final TextView sortingCurrentCommentView = context.findViewById(R.id.settings_general_sorting_current_comment); + if (sortingCurrentCommentView != null) { + sortingCurrentCommentView.setText( + SortingUtil.getSortingCommentsStrings()[i2]); + } + + if (context.findViewById(R.id.settings_general_sorting_comment) != null) { + context.findViewById(R.id.settings_general_sorting_comment).setOnClickListener(v -> { + final DialogInterface.OnClickListener l2 = (dialogInterface, i) -> { + CommentSort commentSorting = + SettingValues.defaultCommentSorting; + switch (i) { + case 0: + commentSorting = CommentSort.CONFIDENCE; + break; + case 1: + commentSorting = CommentSort.TOP; + break; + case 2: + commentSorting = CommentSort.NEW; + break; + case 3: + commentSorting = CommentSort.CONTROVERSIAL; + break; + case 4: + commentSorting = CommentSort.OLD; + break; + case 5: + commentSorting = CommentSort.QA; + break; + } + SettingValues.prefs.edit() + .putString("defaultCommentSortingNew", + commentSorting.name()) + .apply(); + SettingValues.defaultCommentSorting = commentSorting; + if (sortingCurrentCommentView != null) { + sortingCurrentCommentView.setText( + SortingUtil.getSortingCommentsStrings()[i]); + } + }; + + Resources res = context.getBaseContext().getResources(); + + new AlertDialog.Builder(SettingsGeneralFragment.this.context) + .setTitle(R.string.sorting_choose) + .setSingleChoiceItems( + new String[]{ + res.getString(R.string.sorting_best), + res.getString(R.string.sorting_top), + res.getString(R.string.sorting_new), + res.getString(R.string.sorting_controversial), + res.getString(R.string.sorting_old), + res.getString(R.string.sorting_ama) + }, i2, l2) + .show(); + }); + } + } + } + + private void askTimePeriod() { + final TextView defaultSortingCurrentView = context.findViewById(R.id.settings_general_sorting_current); + final DialogInterface.OnClickListener l2 = new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialogInterface, int i) { + switch (i) { + case 0: + SortingUtil.timePeriod = TimePeriod.HOUR; + break; + case 1: + SortingUtil.timePeriod = TimePeriod.DAY; + break; + case 2: + SortingUtil.timePeriod = TimePeriod.WEEK; + break; + case 3: + SortingUtil.timePeriod = TimePeriod.MONTH; + break; + case 4: + SortingUtil.timePeriod = TimePeriod.YEAR; + break; + case 5: + SortingUtil.timePeriod = TimePeriod.ALL; + break; + } + SettingValues.prefs.edit() + .putString("defaultSorting", SortingUtil.defaultSorting.name()) + .apply(); + SettingValues.prefs.edit().putString("timePeriod", SortingUtil.timePeriod.name()) + .apply(); + SettingValues.defaultSorting = SortingUtil.defaultSorting; + SettingValues.timePeriod = SortingUtil.timePeriod; + defaultSortingCurrentView.setText( + SortingUtil.getSortingStrings()[SortingUtil.getSortingId("")] + + " > " + + SortingUtil.getSortingTimesStrings()[SortingUtil.getSortingTimeId( + "")]); + } + }; + + new AlertDialog.Builder(SettingsGeneralFragment.this.context) + .setTitle(R.string.sorting_choose) + .setSingleChoiceItems( + SortingUtil.getSortingTimesStrings(), + SortingUtil.getSortingTimeId(""), + l2) + .show(); + } + + private void setSubText() { + ArrayList rawSubs = + StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); + String subText = context.getString(R.string.sub_post_notifs_settings_none); + StringBuilder subs = new StringBuilder(); + for (String s : rawSubs) { + if (!s.isEmpty()) { + try { + String[] split = s.split(":"); + subs.append(split[0]); + subs.append("(+").append(split[1]).append(")"); + subs.append(", "); + } catch (Exception ignored) { + + } + } + } + if (!subs.toString().isEmpty()) { + subText = subs.substring(0, subs.toString().length() - 2); + } + ((TextView) context.findViewById(R.id.settings_general_sub_notifs_current)).setText(subText); + } + + private void showSelectDialog() { + ArrayList rawSubs = + StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); + HashMap subThresholds = new HashMap<>(); + for (String s : rawSubs) { + try { + String[] split = s.split(":"); + subThresholds.put(split[0].toLowerCase(Locale.ENGLISH), Integer.valueOf(split[1])); + } catch (Exception ignored) { + + } + } + + // Get list of user's subscriptions + CaseInsensitiveArrayList subs = UserSubscriptions.getSubscriptions(context); + // Add any subs that the user has notifications for but isn't subscribed to + for (String s : subThresholds.keySet()) { + if (!subs.contains(s)) { + subs.add(s); + } + } + + List sorted = UserSubscriptions.sort(subs); + + //Array of all subs + String[] all = new String[sorted.size()]; + //Contains which subreddits are checked + boolean[] checked = new boolean[all.length]; + + + //Remove special subreddits from list and store it in "all" + int i = 0; + for (String s : sorted) { + if (!s.equals("all") + && !s.equals("frontpage") + && !s.contains("+") + && !s.contains(".") + && !s.contains("/m/")) { + all[i] = s.toLowerCase(Locale.ENGLISH); + i++; + } + } + + //Remove empty entries & store which subreddits are checked + List list = new ArrayList<>(); + i = 0; + for (String s : all) { + if (s != null && !s.isEmpty()) { + list.add(s); + if (subThresholds.containsKey(s)) { + checked[i] = true; + } + i++; + } + } + + //Convert List back to Array + all = list.toArray(new String[0]); + + final ArrayList toCheck = new ArrayList<>(subThresholds.keySet()); + final String[] finalAll = all; + new AlertDialog.Builder(SettingsGeneralFragment.this.context) + .setMultiChoiceItems(finalAll, checked, (dialog, which, isChecked) -> { + if (!isChecked) { + toCheck.remove(finalAll[which]); + } else { + toCheck.add(finalAll[which]); + } + }) + .setTitle(R.string.sub_post_notifs_title_settings) + .setPositiveButton(context.getString(R.string.btn_add).toUpperCase(), (dialog, which) -> + showThresholdDialog(toCheck, false)) + .setNegativeButton(R.string.sub_post_notifs_settings_search, (dialog, which) -> + new MaterialDialog.Builder(SettingsGeneralFragment.this.context) + .title(R.string.reorder_add_subreddit) + .inputRangeRes(2, 21, R.color.md_red_500) + .alwaysCallInputCallback() + .input(context.getString(R.string.reorder_subreddit_name), null, + false, new MaterialDialog.InputCallback() { + @Override + public void onInput(MaterialDialog dialog, + CharSequence raw) { + input = raw.toString() + .replaceAll("\\s", + ""); //remove whitespace from input + } + }) + .positiveText(R.string.btn_add) + .onPositive(new MaterialDialog.SingleButtonCallback() { + @Override + public void onClick(@NonNull MaterialDialog dialog, + @NonNull DialogAction which) { + new AsyncGetSubreddit().execute(input); + } + }) + .negativeText(R.string.btn_cancel) + .show()) + .show(); + } + + private void showThresholdDialog(ArrayList strings, boolean search) { + final ArrayList subsRaw = + StringUtil.stringToArray(Reddit.appRestart.getString(CheckForMail.SUBS_TO_GET, "")); + + if (!search) { + //NOT a sub searched for, was instead a list of all subs + for (String raw : new ArrayList<>(subsRaw)) { + if (!strings.contains(raw.split(":")[0])) { + subsRaw.remove(raw); + } + } + } + + final ArrayList subs = new ArrayList<>(); + for (String s : subsRaw) { + try { + subs.add(s.split(":")[0].toLowerCase(Locale.ENGLISH)); + } catch (Exception e) { + + } + } + + final ArrayList toAdd = new ArrayList<>(); + for (String s : strings) { + if (!subs.contains(s.toLowerCase(Locale.ENGLISH))) { + toAdd.add(s.toLowerCase(Locale.ENGLISH)); + } + } + if (!toAdd.isEmpty()) { + new MaterialDialog.Builder(SettingsGeneralFragment.this.context).title( + R.string.sub_post_notifs_threshold) + .items(new String[]{"1", "5", "10", "20", "40", "50"}) + .alwaysCallSingleChoiceCallback() + .itemsCallbackSingleChoice(0, new MaterialDialog.ListCallbackSingleChoice() { + @Override + public boolean onSelection(MaterialDialog dialog, View itemView, int which, + CharSequence text) { + for (String s : toAdd) { + subsRaw.add(s + ":" + text); + } + saveAndUpdateSubs(subsRaw); + return true; + } + }) + .cancelable(false) + .show(); + } else { + saveAndUpdateSubs(subsRaw); + } + } + + private void saveAndUpdateSubs(ArrayList subs) { + Reddit.appRestart.edit() + .putString(CheckForMail.SUBS_TO_GET, StringUtil.arrayToString(subs)) + .commit(); + setSubText(); + } + + @Override + public void onFolderSelection(@NonNull FolderChooserDialogCreate dialog, + @NonNull File folder, boolean isSaveToLocation) { + Reddit.appRestart.edit().putString("imagelocation", folder.getAbsolutePath()).apply(); + Toast.makeText(context, + context.getString(R.string.settings_set_image_location, folder.getAbsolutePath()), + Toast.LENGTH_LONG).show(); + ((TextView) context.findViewById(R.id.settings_general_set_save_location_view)).setText(folder.getAbsolutePath()); + } + + @Override + public void onFolderChooserDismissed(@NonNull FolderChooserDialogCreate dialog) { + } + + private class AsyncGetSubreddit extends AsyncTask { + @Override + public void onPostExecute(Subreddit subreddit) { + if (subreddit != null || input.equalsIgnoreCase("friends") || input.equalsIgnoreCase( + "mod")) { + ArrayList singleSub = new ArrayList<>(); + singleSub.add(subreddit.getDisplayName().toLowerCase(Locale.ENGLISH)); + showThresholdDialog(singleSub, true); + } + } + + @Override + protected Subreddit doInBackground(final String... params) { + try { + return Authentication.reddit.getSubreddit(params[0]); + } catch (Exception e) { + context.runOnUiThread(() -> { + try { + new AlertDialog.Builder(SettingsGeneralFragment.this.context) + .setTitle(R.string.subreddit_err) + .setMessage(context.getString(R.string.subreddit_err_msg, params[0])) + .setPositiveButton(R.string.btn_ok, (dialog, which) -> + dialog.dismiss()) + .setOnDismissListener(null) + .show(); + } catch (Exception ignored) { + } + }); + + return null; + } + } + } + +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsRedditFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsRedditFragment.java index fe6117e53..5b4baa2e3 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsRedditFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsRedditFragment.java @@ -1,106 +1,106 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Activity; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.appcompat.widget.SwitchCompat; - -import me.ccrama.redditslide.Authentication; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.Visuals.Palette; -import me.ccrama.redditslide.util.LinkUtil; - -public class SettingsRedditFragment { - - private final Activity context; - - public SettingsRedditFragment(Activity context) { - this.context = context; - } - - public void Bind() { - final SwitchCompat wantToSeeNsfwSwitch = context.findViewById(R.id.settings_reddit_wantToSeeNsfwContent); - final SwitchCompat hideAllNsfwSwitch = context.findViewById(R.id.settings_reddit_hideAllNsfw); - final TextView hideAllNsfwText = context.findViewById(R.id.settings_reddit_hideAllNsfw_text); - final SwitchCompat hideNsfwPrevCollectionsSwitch = context.findViewById(R.id.settings_reddit_hideNsfwPreviewCollections); - final TextView hideNsfwPrevCollectionsText = context.findViewById(R.id.settings_reddit_hideNsfwPreviewCollections_text); - final SwitchCompat ignoreSubMediaPrefsSwitch = context.findViewById(R.id.settings_reddit_ignoreSubMediaPrefs); - - final RelativeLayout viewRedditPrefsLayout = context.findViewById(R.id.settings_reddit_viewRedditPrefs); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* NSFW Content */ - wantToSeeNsfwSwitch.setChecked(SettingValues.showNSFWContent); - wantToSeeNsfwSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.showNSFWContent = isChecked; - SettingsActivity.changed = true; - - if (isChecked) { - hideAllNsfwSwitch.setEnabled(true); - hideAllNsfwText.setAlpha(1f); - hideAllNsfwSwitch.setChecked(SettingValues.getIsNSFWEnabled()); - - hideNsfwPrevCollectionsSwitch.setEnabled(true); - hideNsfwPrevCollectionsText.setAlpha(1f); - hideNsfwPrevCollectionsSwitch.setChecked(SettingValues.hideNSFWCollection); - - } else { - hideAllNsfwSwitch.setChecked(false); - hideAllNsfwSwitch.setEnabled(false); - hideAllNsfwText.setAlpha(0.25f); - - hideNsfwPrevCollectionsSwitch.setChecked(false); - hideNsfwPrevCollectionsSwitch.setEnabled(false); - hideNsfwPrevCollectionsText.setAlpha(0.25f); - } - editSharedBooleanPreference(SettingValues.PREF_SHOW_NSFW_CONTENT, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if (!wantToSeeNsfwSwitch.isChecked()) { - hideAllNsfwSwitch.setChecked(true); - hideAllNsfwSwitch.setEnabled(false); - hideAllNsfwText.setAlpha(0.25f); - } else { - hideAllNsfwSwitch.setChecked(SettingValues.getIsNSFWEnabled()); - } - hideAllNsfwSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsActivity.changed = true; - editSharedBooleanPreference(SettingValues.PREF_HIDE_NSFW_PREVIEW + Authentication.name, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if (!wantToSeeNsfwSwitch.isChecked()) { - hideNsfwPrevCollectionsSwitch.setChecked(true); - hideNsfwPrevCollectionsSwitch.setEnabled(false); - hideNsfwPrevCollectionsText.setAlpha(0.25f); - } else { - hideNsfwPrevCollectionsSwitch.setChecked(SettingValues.hideNSFWCollection); - } - hideNsfwPrevCollectionsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsActivity.changed = true; - SettingValues.hideNSFWCollection = isChecked; - editSharedBooleanPreference(SettingValues.PREF_HIDE_NSFW_COLLECTION, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ignoreSubMediaPrefsSwitch.setChecked(SettingValues.ignoreSubSetting); - ignoreSubMediaPrefsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsActivity.changed = true; - SettingValues.ignoreSubSetting = isChecked; - editSharedBooleanPreference(SettingValues.PREF_IGNORE_SUB_SETTINGS, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Open Reddit settings in browser */ - viewRedditPrefsLayout.setOnClickListener(v -> - LinkUtil.openUrl( - "https://www.reddit.com/prefs/", Palette.getDefaultColor(), context)); - } - - private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { - SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); - } -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Activity; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.appcompat.widget.SwitchCompat; + +import me.ccrama.redditslide.Authentication; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.Visuals.Palette; +import me.ccrama.redditslide.util.LinkUtil; + +public class SettingsRedditFragment { + + private final Activity context; + + public SettingsRedditFragment(Activity context) { + this.context = context; + } + + public void Bind() { + final SwitchCompat wantToSeeNsfwSwitch = context.findViewById(R.id.settings_reddit_wantToSeeNsfwContent); + final SwitchCompat hideAllNsfwSwitch = context.findViewById(R.id.settings_reddit_hideAllNsfw); + final TextView hideAllNsfwText = context.findViewById(R.id.settings_reddit_hideAllNsfw_text); + final SwitchCompat hideNsfwPrevCollectionsSwitch = context.findViewById(R.id.settings_reddit_hideNsfwPreviewCollections); + final TextView hideNsfwPrevCollectionsText = context.findViewById(R.id.settings_reddit_hideNsfwPreviewCollections_text); + final SwitchCompat ignoreSubMediaPrefsSwitch = context.findViewById(R.id.settings_reddit_ignoreSubMediaPrefs); + + final RelativeLayout viewRedditPrefsLayout = context.findViewById(R.id.settings_reddit_viewRedditPrefs); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* NSFW Content */ + wantToSeeNsfwSwitch.setChecked(SettingValues.showNSFWContent); + wantToSeeNsfwSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.showNSFWContent = isChecked; + SettingsActivity.changed = true; + + if (isChecked) { + hideAllNsfwSwitch.setEnabled(true); + hideAllNsfwText.setAlpha(1f); + hideAllNsfwSwitch.setChecked(SettingValues.getIsNSFWEnabled()); + + hideNsfwPrevCollectionsSwitch.setEnabled(true); + hideNsfwPrevCollectionsText.setAlpha(1f); + hideNsfwPrevCollectionsSwitch.setChecked(SettingValues.hideNSFWCollection); + + } else { + hideAllNsfwSwitch.setChecked(false); + hideAllNsfwSwitch.setEnabled(false); + hideAllNsfwText.setAlpha(0.25f); + + hideNsfwPrevCollectionsSwitch.setChecked(false); + hideNsfwPrevCollectionsSwitch.setEnabled(false); + hideNsfwPrevCollectionsText.setAlpha(0.25f); + } + editSharedBooleanPreference(SettingValues.PREF_SHOW_NSFW_CONTENT, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if (!wantToSeeNsfwSwitch.isChecked()) { + hideAllNsfwSwitch.setChecked(true); + hideAllNsfwSwitch.setEnabled(false); + hideAllNsfwText.setAlpha(0.25f); + } else { + hideAllNsfwSwitch.setChecked(SettingValues.getIsNSFWEnabled()); + } + hideAllNsfwSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsActivity.changed = true; + editSharedBooleanPreference(SettingValues.PREF_HIDE_NSFW_PREVIEW + Authentication.name, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if (!wantToSeeNsfwSwitch.isChecked()) { + hideNsfwPrevCollectionsSwitch.setChecked(true); + hideNsfwPrevCollectionsSwitch.setEnabled(false); + hideNsfwPrevCollectionsText.setAlpha(0.25f); + } else { + hideNsfwPrevCollectionsSwitch.setChecked(SettingValues.hideNSFWCollection); + } + hideNsfwPrevCollectionsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsActivity.changed = true; + SettingValues.hideNSFWCollection = isChecked; + editSharedBooleanPreference(SettingValues.PREF_HIDE_NSFW_COLLECTION, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ignoreSubMediaPrefsSwitch.setChecked(SettingValues.ignoreSubSetting); + ignoreSubMediaPrefsSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsActivity.changed = true; + SettingValues.ignoreSubSetting = isChecked; + editSharedBooleanPreference(SettingValues.PREF_IGNORE_SUB_SETTINGS, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Open Reddit settings in browser */ + viewRedditPrefsLayout.setOnClickListener(v -> + LinkUtil.openUrl( + "https://www.reddit.com/prefs/", Palette.getDefaultColor(), context)); + } + + private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { + SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsThemeFragment.java b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsThemeFragment.java index 368dfc70d..fdef40fd1 100644 --- a/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsThemeFragment.java +++ b/app/src/main/java/me/ccrama/redditslide/ui/settings/SettingsThemeFragment.java @@ -1,515 +1,515 @@ -package me.ccrama.redditslide.ui.settings; - -import android.app.Dialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.pm.PackageManager; -import android.graphics.Color; -import android.os.Build; -import android.util.Pair; -import android.view.View; -import android.view.Window; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import android.widget.RelativeLayout; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.ArrayRes; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.AppCompatSpinner; -import androidx.appcompat.widget.PopupMenu; -import androidx.appcompat.widget.SwitchCompat; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; - -import org.apache.commons.lang3.ArrayUtils; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import me.ccrama.redditslide.Activities.BaseActivity; -import me.ccrama.redditslide.Activities.Slide; -import me.ccrama.redditslide.R; -import me.ccrama.redditslide.Reddit; -import me.ccrama.redditslide.SettingValues; -import me.ccrama.redditslide.Visuals.ColorPreferences; -import me.ccrama.redditslide.Visuals.Palette; -import me.ccrama.redditslide.databinding.ChooseaccentBinding; -import me.ccrama.redditslide.databinding.ChoosemainBinding; -import me.ccrama.redditslide.databinding.ChoosethemesmallBinding; -import me.ccrama.redditslide.databinding.NightmodeBinding; -import me.ccrama.redditslide.util.LogUtil; -import me.ccrama.redditslide.util.OnSingleClickListener; -import me.ccrama.redditslide.util.ProUtil; -import uz.shift.colorpicker.LineColorPicker; - -public class SettingsThemeFragment { - - public static boolean changed; - private final ActivityType context; - int back; - - public SettingsThemeFragment(final ActivityType context) { - this.context = context; - } - - public void Bind() { - final RelativeLayout colorTintModeLayout = (RelativeLayout) context.findViewById(R.id.settings_theme_colorTintMode); - final TextView currentTintTextView = (TextView) context.findViewById(R.id.settings_theme_tint_current); - final SwitchCompat tintEverywhereSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_tint_everywhere); - final SwitchCompat colorNavbarSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_colorNavbar); - final SwitchCompat colorIconSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_colorAppIcon); - - back = new ColorPreferences(context).getFontStyle().getThemeType(); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* App Theme */ - setupSettingsThemePrimary(); - setupSettingsThemeAccent(); - setupSettingsThemeBase(); - setupSettingsThemeNight(); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//* Tinting */ - - colorTintModeLayout.setOnClickListener(v -> { - final PopupMenu popup = new PopupMenu(context, v); - popup.getMenuInflater().inflate(R.menu.color_tinting_mode_settings, popup.getMenu()); - - popup.setOnMenuItemClickListener(item -> { - switch (item.getItemId()) { - case R.id.none: - setTintingMode(false, false); - break; - case R.id.background: - setTintingMode(true, false); - break; - case R.id.name: - setTintingMode(true, true); - break; - } - currentTintTextView.setText( - SettingValues.colorBack - ? SettingValues.colorSubName - ? context.getString(R.string.subreddit_name_tint) - : context.getString(R.string.card_background_tint) - : context.getString(R.string.misc_none)); - boolean enabled = !currentTintTextView.getText().equals(context.getString(R.string.misc_none)); - tintEverywhereSwitch.setEnabled(enabled); - tintEverywhereSwitch.setChecked(SettingValues.colorEverywhere); - tintEverywhereSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.colorEverywhere = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLOR_EVERYWHERE, isChecked); - }); - return true; - }); - - popup.show(); - }); - - //Color tinting mode - currentTintTextView.setText( - SettingValues.colorBack - ? SettingValues.colorSubName - ? context.getString(R.string.subreddit_name_tint) - : context.getString(R.string.card_background_tint) - : context.getString(R.string.misc_none)); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - boolean enabled = !currentTintTextView.getText().equals(context.getString(R.string.misc_none)); - tintEverywhereSwitch.setEnabled(enabled); - tintEverywhereSwitch.setChecked(SettingValues.colorEverywhere); - tintEverywhereSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.colorEverywhere = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLOR_EVERYWHERE, isChecked); - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - colorNavbarSwitch.setChecked(SettingValues.colorNavBar); - colorNavbarSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingsThemeFragment.changed = true; - SettingValues.colorNavBar = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLOR_NAV_BAR, isChecked); - context.themeSystemBars(""); - if (!isChecked) { - context.getWindow().setNavigationBarColor(Color.TRANSPARENT); - } - }); - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - colorIconSwitch.setChecked(SettingValues.colorIcon); - colorIconSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { - SettingValues.colorIcon = isChecked; - editSharedBooleanPreference(SettingValues.PREF_COLOR_ICON, isChecked); - if (isChecked) { - setComponentState( - Slide.class.getPackage().getName() + ".Slide", - PackageManager.COMPONENT_ENABLED_STATE_DISABLED); - - setComponentState( - ColorPreferences.getIconName(context, - Reddit.colors.getInt("DEFAULTCOLOR", 0)), - PackageManager.COMPONENT_ENABLED_STATE_ENABLED); - } else { - setComponentState( - ColorPreferences.getIconName(context, - Reddit.colors.getInt("DEFAULTCOLOR", 0)), - PackageManager.COMPONENT_ENABLED_STATE_DISABLED); - - setComponentState( - Slide.class.getPackage().getName() + ".Slide", - PackageManager.COMPONENT_ENABLED_STATE_ENABLED); - } - }); - - } - - private void setupSettingsThemePrimary() { - final LinearLayout mainTheme = (LinearLayout) context.findViewById(R.id.settings_theme_main); - mainTheme.setOnClickListener(v -> { - final ChoosemainBinding choosemainBinding = ChoosemainBinding.inflate(context.getLayoutInflater()); - final TextView title = choosemainBinding.title; - title.setBackgroundColor(Palette.getDefaultColor()); - - final LineColorPicker colorPicker = choosemainBinding.picker; - final LineColorPicker colorPicker2 = choosemainBinding.picker2; - - colorPicker.setColors(ColorPreferences.getBaseColors(context)); - int currentColor = Palette.getDefaultColor(); - for (int i : colorPicker.getColors()) { - for (int i2 : ColorPreferences.getColors(context.getBaseContext(), i)) { - if (i2 == currentColor) { - colorPicker.setSelectedColor(i); - colorPicker2.setColors(ColorPreferences.getColors(context.getBaseContext(), i)); - colorPicker2.setSelectedColor(i2); - break; - } - } - } - - colorPicker.setOnColorChangedListener(c -> { - SettingsThemeFragment.changed = true; - colorPicker2.setColors(ColorPreferences.getColors(context.getBaseContext(), c)); - colorPicker2.setSelectedColor(c); - }); - - colorPicker2.setOnColorChangedListener(i -> { - SettingsThemeFragment.changed = true; - title.setBackgroundColor(colorPicker2.getColor()); - final Toolbar toolbar = (Toolbar) context.findViewById(R.id.toolbar); - if (toolbar != null) - toolbar.setBackgroundColor(colorPicker2.getColor()); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - Window window = context.getWindow(); - window.setStatusBarColor( - Palette.getDarkerColor(colorPicker2.getColor())); - } - context.setRecentBar(context.getString(R.string.title_theme_settings), - colorPicker2.getColor()); - }); - - choosemainBinding.ok.setOnClickListener(v1 -> { - if (SettingValues.colorIcon) { - setComponentState( - ColorPreferences.getIconName(context, - Reddit.colors.getInt("DEFAULTCOLOR", 0)), - PackageManager.COMPONENT_ENABLED_STATE_DISABLED); - - setComponentState( - ColorPreferences.getIconName(context, colorPicker2.getColor()), - PackageManager.COMPONENT_ENABLED_STATE_ENABLED); - } - Reddit.colors.edit() - .putInt("DEFAULTCOLOR", colorPicker2.getColor()) - .apply(); - context.restartActivity(); - }); - - new AlertDialog.Builder(context) - .setView(choosemainBinding.getRoot()) - .show(); - }); - } - - private void setupSettingsThemeAccent() { - final LinearLayout accentLayout = (LinearLayout) context.findViewById(R.id.settings_theme_accent); - accentLayout.setOnClickListener(v -> { - final ChooseaccentBinding chooseaccentBinding = ChooseaccentBinding.inflate(context.getLayoutInflater()); - final TextView title = chooseaccentBinding.title; - title.setBackgroundColor(Palette.getDefaultColor()); - - final LineColorPicker colorPicker = chooseaccentBinding.picker3; - - int[] arrs = new int[ColorPreferences.getNumColorsFromThemeType(0)]; - int i = 0; - for (ColorPreferences.Theme type : ColorPreferences.Theme.values()) { - if (type.getThemeType() == ColorPreferences.ColorThemeOptions.Dark.getValue()) { - arrs[i] = ContextCompat.getColor(context, type.getColor()); - i++; - } - } - - colorPicker.setColors(arrs); - colorPicker.setSelectedColor(ContextCompat.getColor(context, - new ColorPreferences(context).getFontStyle().getColor())); - - chooseaccentBinding.ok.setOnClickListener(v1 -> { - SettingsThemeFragment.changed = true; - int color = colorPicker.getColor(); - ColorPreferences.Theme t = null; - for (ColorPreferences.Theme type : ColorPreferences.Theme.values()) { - if (ContextCompat.getColor(context, type.getColor()) == color - && back == type.getThemeType()) { - t = type; - LogUtil.v("Setting to " + t.getTitle()); - break; - } - } - new ColorPreferences(context).setFontStyle(t); - context.restartActivity(); - }); - - new AlertDialog.Builder(context) - .setView(chooseaccentBinding.getRoot()) - .show(); - }); - } - - void setupSettingsThemeBase() { - final LinearLayout themeBase = (LinearLayout) context.findViewById(R.id.settings_theme_base); - themeBase.setOnClickListener(v -> { - final ChoosethemesmallBinding choosethemesmallBinding - = ChoosethemesmallBinding.inflate(context.getLayoutInflater()); - final View root = choosethemesmallBinding.getRoot(); - final TextView title = choosethemesmallBinding.title; - - title.setBackgroundColor(Palette.getDefaultColor()); - - if (SettingValues.isNight()) { - choosethemesmallBinding.nightmsg.setVisibility(View.VISIBLE); - } - - for (final Pair pair : ColorPreferences.themePairList) { - root.findViewById(pair.first) - .setOnClickListener(v1 -> { - SettingsThemeFragment.changed = true; - final String[] names = new ColorPreferences(context).getFontStyle() - .getTitle() - .split("_"); - final String name = names[names.length - 1]; - final String newName = name.replace("(", ""); - for (final ColorPreferences.Theme theme : ColorPreferences.Theme.values()) { - if (theme.toString().contains(newName) - && theme.getThemeType() == pair.second) { - back = theme.getThemeType(); - new ColorPreferences(context).setFontStyle(theme); - context.restartActivity(); - break; - } - } - }); - } - - new AlertDialog.Builder(context) - .setView(root) - .show(); - }); - } - - private void setupSettingsThemeNight() { - final LinearLayout nightMode = (LinearLayout) context.findViewById(R.id.settings_theme_night); - nightMode.setOnClickListener(new OnSingleClickListener() { - @Override - public void onSingleClick(View view) { - if (SettingValues.isPro) { - final NightmodeBinding nightmodeBinding = NightmodeBinding.inflate(context.getLayoutInflater()); - - final View root = nightmodeBinding.getRoot(); - final AlertDialog.Builder builder = new AlertDialog.Builder(context) - .setView(root); - final Dialog dialog = builder.create(); - dialog.show(); - dialog.setOnDismissListener(dialog1 -> { - //todo save - }); - final Spinner startSpinner = nightmodeBinding.startSpinner; - final Spinner endSpinner = nightmodeBinding.endSpinner; - final AppCompatSpinner nightModeStateSpinner = nightmodeBinding.nightModeState; - - nightModeStateSpinner.setAdapter(NightModeArrayAdapter.createFromResource( - dialog.getContext(), R.array.night_mode_state, android.R.layout.simple_spinner_dropdown_item)); - nightModeStateSpinner.setSelection(SettingValues.nightModeState); - nightModeStateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - startSpinner.setEnabled(position == SettingValues.NightModeState.MANUAL.ordinal()); - endSpinner.setEnabled(position == SettingValues.NightModeState.MANUAL.ordinal()); - SettingValues.nightModeState = position; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_NIGHT_MODE_STATE, position) - .apply(); - SettingsThemeFragment.changed = true; - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - for (final Pair pair : ColorPreferences.themePairList) { - final RadioButton radioButton = root.findViewById(pair.first); - if (radioButton != null) { - if (SettingValues.nightTheme == pair.second) { - radioButton.setChecked(true); - } - radioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { - if (isChecked) { - SettingsThemeFragment.changed = true; - SettingValues.nightTheme = pair.second; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_NIGHT_THEME, - pair.second) - .apply(); - } - }); - } - } - - boolean nightState = SettingValues.nightModeState == SettingValues.NightModeState.MANUAL.ordinal(); - startSpinner.setEnabled(nightState); - endSpinner.setEnabled(nightState); - final List timesStart = new ArrayList() {{ - add("6pm"); - add("7pm"); - add("8pm"); - add("9pm"); - add("10pm"); - add("11pm"); - }}; - nightmodeBinding.startSpinnerLayout.setVisibility(View.VISIBLE); - final ArrayAdapter startAdapter = new ArrayAdapter<>(context, - android.R.layout.simple_spinner_item, timesStart); - startAdapter.setDropDownViewResource( - android.R.layout.simple_spinner_dropdown_item); - startSpinner.setAdapter(startAdapter); - - //set the currently selected pref - startSpinner.setSelection(startAdapter.getPosition( - SettingValues.nightStart + "pm")); - - startSpinner.setOnItemSelectedListener( - new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, - int position, long id) { - //get the time, but remove the "pm" from the string when parsing - final int time = Integer.parseInt( - ((String) startSpinner.getItemAtPosition( - position)).replaceAll("pm", "")); - - SettingValues.nightStart = time; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_NIGHT_START, time) - .apply(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - - final List timesEnd = new ArrayList() {{ - add("12am"); - add("1am"); - add("2am"); - add("3am"); - add("4am"); - add("5am"); - add("6am"); - add("7am"); - add("8am"); - add("9am"); - add("10am"); - }}; - nightmodeBinding.endSpinnerLayout.setVisibility(View.VISIBLE); - final ArrayAdapter endAdapter = new ArrayAdapter<>(context, - android.R.layout.simple_spinner_item, timesEnd); - endAdapter.setDropDownViewResource( - android.R.layout.simple_spinner_dropdown_item); - endSpinner.setAdapter(endAdapter); - - //set the currently selected pref - endSpinner.setSelection(endAdapter.getPosition( - SettingValues.nightEnd + "am")); - - endSpinner.setOnItemSelectedListener( - new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, - int position, long id) { - //get the time, but remove the "am" from the string when parsing - final int time = Integer.parseInt( - ((String) endSpinner.getItemAtPosition( - position)).replaceAll("am", "")); - - SettingValues.nightEnd = time; - SettingValues.prefs.edit() - .putInt(SettingValues.PREF_NIGHT_END, time) - .apply(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - - nightmodeBinding.ok.setOnClickListener(v -> - dialog.dismiss()); - - } else { - ProUtil.proUpgradeMsg(context, R.string.general_nighttheme_ispro) - .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> - dialog.dismiss()) - .show(); - } - } - }); - } - - private void setComponentState(final String cls, final int componentEnabledState) { - context.getPackageManager().setComponentEnabledSetting( - new ComponentName(context, cls), - componentEnabledState, - PackageManager.DONT_KILL_APP); - } - - private void setTintingMode(boolean colorBack, boolean subName) { - SettingValues.colorBack = colorBack; - SettingValues.colorSubName = subName; - editSharedBooleanPreference(SettingValues.PREF_COLOR_BACK, colorBack); - editSharedBooleanPreference(SettingValues.PREF_COLOR_SUB_NAME, subName); - } - - private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { - SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); - } - - private static class NightModeArrayAdapter { - public static ArrayAdapter createFromResource(@NonNull Context context, - @ArrayRes int textArrayResId, - @LayoutRes int layoutTypeResId) { - CharSequence[] strings = context.getResources().getTextArray(textArrayResId); - if (!Reddit.canUseNightModeAuto) { - strings = ArrayUtils.remove(strings, SettingValues.NightModeState.AUTOMATIC.ordinal()); - } - return new ArrayAdapter<>(context, layoutTypeResId, Arrays.asList(strings)); - } - } -} +package me.ccrama.redditslide.ui.settings; + +import android.app.Dialog; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageManager; +import android.graphics.Color; +import android.os.Build; +import android.util.Pair; +import android.view.View; +import android.view.Window; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.RelativeLayout; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.ArrayRes; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.AppCompatSpinner; +import androidx.appcompat.widget.PopupMenu; +import androidx.appcompat.widget.SwitchCompat; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; + +import org.apache.commons.lang3.ArrayUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import me.ccrama.redditslide.Activities.BaseActivity; +import me.ccrama.redditslide.Activities.Slide; +import me.ccrama.redditslide.R; +import me.ccrama.redditslide.Reddit; +import me.ccrama.redditslide.SettingValues; +import me.ccrama.redditslide.Visuals.ColorPreferences; +import me.ccrama.redditslide.Visuals.Palette; +import me.ccrama.redditslide.databinding.ChooseaccentBinding; +import me.ccrama.redditslide.databinding.ChoosemainBinding; +import me.ccrama.redditslide.databinding.ChoosethemesmallBinding; +import me.ccrama.redditslide.databinding.NightmodeBinding; +import me.ccrama.redditslide.util.LogUtil; +import me.ccrama.redditslide.util.OnSingleClickListener; +import me.ccrama.redditslide.util.ProUtil; +import uz.shift.colorpicker.LineColorPicker; + +public class SettingsThemeFragment { + + public static boolean changed; + private final ActivityType context; + int back; + + public SettingsThemeFragment(final ActivityType context) { + this.context = context; + } + + public void Bind() { + final RelativeLayout colorTintModeLayout = (RelativeLayout) context.findViewById(R.id.settings_theme_colorTintMode); + final TextView currentTintTextView = (TextView) context.findViewById(R.id.settings_theme_tint_current); + final SwitchCompat tintEverywhereSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_tint_everywhere); + final SwitchCompat colorNavbarSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_colorNavbar); + final SwitchCompat colorIconSwitch = (SwitchCompat) context.findViewById(R.id.settings_theme_colorAppIcon); + + back = new ColorPreferences(context).getFontStyle().getThemeType(); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* App Theme */ + setupSettingsThemePrimary(); + setupSettingsThemeAccent(); + setupSettingsThemeBase(); + setupSettingsThemeNight(); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//* Tinting */ + + colorTintModeLayout.setOnClickListener(v -> { + final PopupMenu popup = new PopupMenu(context, v); + popup.getMenuInflater().inflate(R.menu.color_tinting_mode_settings, popup.getMenu()); + + popup.setOnMenuItemClickListener(item -> { + switch (item.getItemId()) { + case R.id.none: + setTintingMode(false, false); + break; + case R.id.background: + setTintingMode(true, false); + break; + case R.id.name: + setTintingMode(true, true); + break; + } + currentTintTextView.setText( + SettingValues.colorBack + ? SettingValues.colorSubName + ? context.getString(R.string.subreddit_name_tint) + : context.getString(R.string.card_background_tint) + : context.getString(R.string.misc_none)); + boolean enabled = !currentTintTextView.getText().equals(context.getString(R.string.misc_none)); + tintEverywhereSwitch.setEnabled(enabled); + tintEverywhereSwitch.setChecked(SettingValues.colorEverywhere); + tintEverywhereSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.colorEverywhere = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLOR_EVERYWHERE, isChecked); + }); + return true; + }); + + popup.show(); + }); + + //Color tinting mode + currentTintTextView.setText( + SettingValues.colorBack + ? SettingValues.colorSubName + ? context.getString(R.string.subreddit_name_tint) + : context.getString(R.string.card_background_tint) + : context.getString(R.string.misc_none)); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + boolean enabled = !currentTintTextView.getText().equals(context.getString(R.string.misc_none)); + tintEverywhereSwitch.setEnabled(enabled); + tintEverywhereSwitch.setChecked(SettingValues.colorEverywhere); + tintEverywhereSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.colorEverywhere = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLOR_EVERYWHERE, isChecked); + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + colorNavbarSwitch.setChecked(SettingValues.colorNavBar); + colorNavbarSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingsThemeFragment.changed = true; + SettingValues.colorNavBar = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLOR_NAV_BAR, isChecked); + context.themeSystemBars(""); + if (!isChecked) { + context.getWindow().setNavigationBarColor(Color.TRANSPARENT); + } + }); + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + colorIconSwitch.setChecked(SettingValues.colorIcon); + colorIconSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + SettingValues.colorIcon = isChecked; + editSharedBooleanPreference(SettingValues.PREF_COLOR_ICON, isChecked); + if (isChecked) { + setComponentState( + Slide.class.getPackage().getName() + ".Slide", + PackageManager.COMPONENT_ENABLED_STATE_DISABLED); + + setComponentState( + ColorPreferences.getIconName(context, + Reddit.colors.getInt("DEFAULTCOLOR", 0)), + PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + } else { + setComponentState( + ColorPreferences.getIconName(context, + Reddit.colors.getInt("DEFAULTCOLOR", 0)), + PackageManager.COMPONENT_ENABLED_STATE_DISABLED); + + setComponentState( + Slide.class.getPackage().getName() + ".Slide", + PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + } + }); + + } + + private void setupSettingsThemePrimary() { + final LinearLayout mainTheme = (LinearLayout) context.findViewById(R.id.settings_theme_main); + mainTheme.setOnClickListener(v -> { + final ChoosemainBinding choosemainBinding = ChoosemainBinding.inflate(context.getLayoutInflater()); + final TextView title = choosemainBinding.title; + title.setBackgroundColor(Palette.getDefaultColor()); + + final LineColorPicker colorPicker = choosemainBinding.picker; + final LineColorPicker colorPicker2 = choosemainBinding.picker2; + + colorPicker.setColors(ColorPreferences.getBaseColors(context)); + int currentColor = Palette.getDefaultColor(); + for (int i : colorPicker.getColors()) { + for (int i2 : ColorPreferences.getColors(context.getBaseContext(), i)) { + if (i2 == currentColor) { + colorPicker.setSelectedColor(i); + colorPicker2.setColors(ColorPreferences.getColors(context.getBaseContext(), i)); + colorPicker2.setSelectedColor(i2); + break; + } + } + } + + colorPicker.setOnColorChangedListener(c -> { + SettingsThemeFragment.changed = true; + colorPicker2.setColors(ColorPreferences.getColors(context.getBaseContext(), c)); + colorPicker2.setSelectedColor(c); + }); + + colorPicker2.setOnColorChangedListener(i -> { + SettingsThemeFragment.changed = true; + title.setBackgroundColor(colorPicker2.getColor()); + final Toolbar toolbar = (Toolbar) context.findViewById(R.id.toolbar); + if (toolbar != null) + toolbar.setBackgroundColor(colorPicker2.getColor()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Window window = context.getWindow(); + window.setStatusBarColor( + Palette.getDarkerColor(colorPicker2.getColor())); + } + context.setRecentBar(context.getString(R.string.title_theme_settings), + colorPicker2.getColor()); + }); + + choosemainBinding.ok.setOnClickListener(v1 -> { + if (SettingValues.colorIcon) { + setComponentState( + ColorPreferences.getIconName(context, + Reddit.colors.getInt("DEFAULTCOLOR", 0)), + PackageManager.COMPONENT_ENABLED_STATE_DISABLED); + + setComponentState( + ColorPreferences.getIconName(context, colorPicker2.getColor()), + PackageManager.COMPONENT_ENABLED_STATE_ENABLED); + } + Reddit.colors.edit() + .putInt("DEFAULTCOLOR", colorPicker2.getColor()) + .apply(); + context.restartActivity(); + }); + + new AlertDialog.Builder(context) + .setView(choosemainBinding.getRoot()) + .show(); + }); + } + + private void setupSettingsThemeAccent() { + final LinearLayout accentLayout = (LinearLayout) context.findViewById(R.id.settings_theme_accent); + accentLayout.setOnClickListener(v -> { + final ChooseaccentBinding chooseaccentBinding = ChooseaccentBinding.inflate(context.getLayoutInflater()); + final TextView title = chooseaccentBinding.title; + title.setBackgroundColor(Palette.getDefaultColor()); + + final LineColorPicker colorPicker = chooseaccentBinding.picker3; + + int[] arrs = new int[ColorPreferences.getNumColorsFromThemeType(0)]; + int i = 0; + for (ColorPreferences.Theme type : ColorPreferences.Theme.values()) { + if (type.getThemeType() == ColorPreferences.ColorThemeOptions.Dark.getValue()) { + arrs[i] = ContextCompat.getColor(context, type.getColor()); + i++; + } + } + + colorPicker.setColors(arrs); + colorPicker.setSelectedColor(ContextCompat.getColor(context, + new ColorPreferences(context).getFontStyle().getColor())); + + chooseaccentBinding.ok.setOnClickListener(v1 -> { + SettingsThemeFragment.changed = true; + int color = colorPicker.getColor(); + ColorPreferences.Theme t = null; + for (ColorPreferences.Theme type : ColorPreferences.Theme.values()) { + if (ContextCompat.getColor(context, type.getColor()) == color + && back == type.getThemeType()) { + t = type; + LogUtil.v("Setting to " + t.getTitle()); + break; + } + } + new ColorPreferences(context).setFontStyle(t); + context.restartActivity(); + }); + + new AlertDialog.Builder(context) + .setView(chooseaccentBinding.getRoot()) + .show(); + }); + } + + void setupSettingsThemeBase() { + final LinearLayout themeBase = (LinearLayout) context.findViewById(R.id.settings_theme_base); + themeBase.setOnClickListener(v -> { + final ChoosethemesmallBinding choosethemesmallBinding + = ChoosethemesmallBinding.inflate(context.getLayoutInflater()); + final View root = choosethemesmallBinding.getRoot(); + final TextView title = choosethemesmallBinding.title; + + title.setBackgroundColor(Palette.getDefaultColor()); + + if (SettingValues.isNight()) { + choosethemesmallBinding.nightmsg.setVisibility(View.VISIBLE); + } + + for (final Pair pair : ColorPreferences.themePairList) { + root.findViewById(pair.first) + .setOnClickListener(v1 -> { + SettingsThemeFragment.changed = true; + final String[] names = new ColorPreferences(context).getFontStyle() + .getTitle() + .split("_"); + final String name = names[names.length - 1]; + final String newName = name.replace("(", ""); + for (final ColorPreferences.Theme theme : ColorPreferences.Theme.values()) { + if (theme.toString().contains(newName) + && theme.getThemeType() == pair.second) { + back = theme.getThemeType(); + new ColorPreferences(context).setFontStyle(theme); + context.restartActivity(); + break; + } + } + }); + } + + new AlertDialog.Builder(context) + .setView(root) + .show(); + }); + } + + private void setupSettingsThemeNight() { + final LinearLayout nightMode = (LinearLayout) context.findViewById(R.id.settings_theme_night); + nightMode.setOnClickListener(new OnSingleClickListener() { + @Override + public void onSingleClick(View view) { + if (SettingValues.isPro) { + final NightmodeBinding nightmodeBinding = NightmodeBinding.inflate(context.getLayoutInflater()); + + final View root = nightmodeBinding.getRoot(); + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setView(root); + final Dialog dialog = builder.create(); + dialog.show(); + dialog.setOnDismissListener(dialog1 -> { + //todo save + }); + final Spinner startSpinner = nightmodeBinding.startSpinner; + final Spinner endSpinner = nightmodeBinding.endSpinner; + final AppCompatSpinner nightModeStateSpinner = nightmodeBinding.nightModeState; + + nightModeStateSpinner.setAdapter(NightModeArrayAdapter.createFromResource( + dialog.getContext(), R.array.night_mode_state, android.R.layout.simple_spinner_dropdown_item)); + nightModeStateSpinner.setSelection(SettingValues.nightModeState); + nightModeStateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + startSpinner.setEnabled(position == SettingValues.NightModeState.MANUAL.ordinal()); + endSpinner.setEnabled(position == SettingValues.NightModeState.MANUAL.ordinal()); + SettingValues.nightModeState = position; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_NIGHT_MODE_STATE, position) + .apply(); + SettingsThemeFragment.changed = true; + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + for (final Pair pair : ColorPreferences.themePairList) { + final RadioButton radioButton = root.findViewById(pair.first); + if (radioButton != null) { + if (SettingValues.nightTheme == pair.second) { + radioButton.setChecked(true); + } + radioButton.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (isChecked) { + SettingsThemeFragment.changed = true; + SettingValues.nightTheme = pair.second; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_NIGHT_THEME, + pair.second) + .apply(); + } + }); + } + } + + boolean nightState = SettingValues.nightModeState == SettingValues.NightModeState.MANUAL.ordinal(); + startSpinner.setEnabled(nightState); + endSpinner.setEnabled(nightState); + final List timesStart = new ArrayList() {{ + add("6pm"); + add("7pm"); + add("8pm"); + add("9pm"); + add("10pm"); + add("11pm"); + }}; + nightmodeBinding.startSpinnerLayout.setVisibility(View.VISIBLE); + final ArrayAdapter startAdapter = new ArrayAdapter<>(context, + android.R.layout.simple_spinner_item, timesStart); + startAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + startSpinner.setAdapter(startAdapter); + + //set the currently selected pref + startSpinner.setSelection(startAdapter.getPosition( + SettingValues.nightStart + "pm")); + + startSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, + int position, long id) { + //get the time, but remove the "pm" from the string when parsing + final int time = Integer.parseInt( + ((String) startSpinner.getItemAtPosition( + position)).replaceAll("pm", "")); + + SettingValues.nightStart = time; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_NIGHT_START, time) + .apply(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + + final List timesEnd = new ArrayList() {{ + add("12am"); + add("1am"); + add("2am"); + add("3am"); + add("4am"); + add("5am"); + add("6am"); + add("7am"); + add("8am"); + add("9am"); + add("10am"); + }}; + nightmodeBinding.endSpinnerLayout.setVisibility(View.VISIBLE); + final ArrayAdapter endAdapter = new ArrayAdapter<>(context, + android.R.layout.simple_spinner_item, timesEnd); + endAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + endSpinner.setAdapter(endAdapter); + + //set the currently selected pref + endSpinner.setSelection(endAdapter.getPosition( + SettingValues.nightEnd + "am")); + + endSpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, + int position, long id) { + //get the time, but remove the "am" from the string when parsing + final int time = Integer.parseInt( + ((String) endSpinner.getItemAtPosition( + position)).replaceAll("am", "")); + + SettingValues.nightEnd = time; + SettingValues.prefs.edit() + .putInt(SettingValues.PREF_NIGHT_END, time) + .apply(); + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + nightmodeBinding.ok.setOnClickListener(v -> + dialog.dismiss()); + + } else { + ProUtil.proUpgradeMsg(context, R.string.general_nighttheme_ispro) + .setNegativeButton(R.string.btn_no_thanks, (dialog, whichButton) -> + dialog.dismiss()) + .show(); + } + } + }); + } + + private void setComponentState(final String cls, final int componentEnabledState) { + context.getPackageManager().setComponentEnabledSetting( + new ComponentName(context, cls), + componentEnabledState, + PackageManager.DONT_KILL_APP); + } + + private void setTintingMode(boolean colorBack, boolean subName) { + SettingValues.colorBack = colorBack; + SettingValues.colorSubName = subName; + editSharedBooleanPreference(SettingValues.PREF_COLOR_BACK, colorBack); + editSharedBooleanPreference(SettingValues.PREF_COLOR_SUB_NAME, subName); + } + + private void editSharedBooleanPreference(final String settingValueString, final boolean isChecked) { + SettingValues.prefs.edit().putBoolean(settingValueString, isChecked).apply(); + } + + private static class NightModeArrayAdapter { + public static ArrayAdapter createFromResource(@NonNull Context context, + @ArrayRes int textArrayResId, + @LayoutRes int layoutTypeResId) { + CharSequence[] strings = context.getResources().getTextArray(textArrayResId); + if (!Reddit.canUseNightModeAuto) { + strings = ArrayUtils.remove(strings, SettingValues.NightModeState.AUTOMATIC.ordinal()); + } + return new ArrayAdapter<>(context, layoutTypeResId, Arrays.asList(strings)); + } + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/util/CustomTabsHelper.java b/app/src/main/java/me/ccrama/redditslide/util/CustomTabsHelper.java index b4246c0b8..716afd618 100644 --- a/app/src/main/java/me/ccrama/redditslide/util/CustomTabsHelper.java +++ b/app/src/main/java/me/ccrama/redditslide/util/CustomTabsHelper.java @@ -1,145 +1,145 @@ -// Copyright 2015 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package me.ccrama.redditslide.util; - -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -import me.ccrama.redditslide.SettingValues; - -import static me.ccrama.redditslide.ui.settings.SettingsHandlingFragment.LinkHandlingMode; - -/** - * Helper class for Custom Tabs. - */ -public class CustomTabsHelper { - private static final String TAG = "CustomTabsHelper"; - static final String STABLE_PACKAGE = "com.android.chrome"; - static final String BETA_PACKAGE = "com.chrome.beta"; - static final String DEV_PACKAGE = "com.chrome.dev"; - static final String LOCAL_PACKAGE = "com.google.android.apps.chrome"; - private static final String EXTRA_CUSTOM_TABS_KEEP_ALIVE = - "android.support.customtabs.extra.KEEP_ALIVE"; - private static final String ACTION_CUSTOM_TABS_CONNECTION = - "android.support.customtabs.action.CustomTabsService"; - - private static String sPackageNameToUse; - - private CustomTabsHelper() {} - - /** - * Goes through all apps that handle VIEW intents and have a warmup service. Picks - * the one chosen by the user if there is one, otherwise makes a best effort to return a - * valid package name. - * - * This is not threadsafe. - * - * @param context {@link Context} to use for accessing {@link PackageManager}. - * @return The package name recommended to use for connecting to custom tabs related components. - */ - public static String getPackageNameToUse(Context context) { - if (SettingValues.linkHandlingMode != LinkHandlingMode.CUSTOM_TABS.getValue()) return null; - if (sPackageNameToUse != null) return sPackageNameToUse; - - PackageManager pm = context.getPackageManager(); - // Get default VIEW intent handler. - Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com")); - ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0); - String defaultViewHandlerPackageName = null; - if (defaultViewHandlerInfo != null) { - defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName; - } - - // Get all apps that can handle VIEW intents. - List resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); - List packagesSupportingCustomTabs = new ArrayList<>(); - for (ResolveInfo info : resolvedActivityList) { - Intent serviceIntent = new Intent(); - serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION); - serviceIntent.setPackage(info.activityInfo.packageName); - // Samsung browser custom tabs has a bug that harms user experience, pressing back - // navigates between pages rather than exiting back to Slide - // TODO: Reevaluate at a later date - if (pm.resolveService(serviceIntent, 0) != null - && !info.activityInfo.packageName.equals("com.sec.android.app.sbrowser")) { - packagesSupportingCustomTabs.add(info.activityInfo.packageName); - } - } - - // Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents - // and service calls. - if (packagesSupportingCustomTabs.isEmpty()) { - sPackageNameToUse = null; - } else if (packagesSupportingCustomTabs.size() == 1) { - sPackageNameToUse = packagesSupportingCustomTabs.get(0); - } else if (!TextUtils.isEmpty(defaultViewHandlerPackageName) - && !hasSpecializedHandlerIntents(context, activityIntent) - && packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) { - sPackageNameToUse = defaultViewHandlerPackageName; - } else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) { - sPackageNameToUse = STABLE_PACKAGE; - } else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) { - sPackageNameToUse = BETA_PACKAGE; - } else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) { - sPackageNameToUse = DEV_PACKAGE; - } else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) { - sPackageNameToUse = LOCAL_PACKAGE; - } - return sPackageNameToUse; - } - - /** - * Used to check whether there is a specialized handler for a given intent. - * @param intent The intent to check with. - * @return Whether there is a specialized handler for the given intent. - */ - private static boolean hasSpecializedHandlerIntents(Context context, Intent intent) { - try { - PackageManager pm = context.getPackageManager(); - List handlers = pm.queryIntentActivities( - intent, - PackageManager.GET_RESOLVED_FILTER); - if (handlers == null || handlers.isEmpty()) { - return false; - } - for (ResolveInfo resolveInfo : handlers) { - IntentFilter filter = resolveInfo.filter; - if (filter == null) continue; - if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) continue; - if (resolveInfo.activityInfo == null) continue; - return true; - } - } catch (RuntimeException e) { - Log.e(TAG, "Runtime exception while getting specialized handlers"); - } - return false; - } - - /** - * @return All possible chrome package names that provide custom tabs feature. - */ - public static String[] getPackages() { - return new String[]{"", STABLE_PACKAGE, BETA_PACKAGE, DEV_PACKAGE, LOCAL_PACKAGE}; - } -} +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package me.ccrama.redditslide.util; + +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; + +import me.ccrama.redditslide.SettingValues; + +import static me.ccrama.redditslide.ui.settings.SettingsHandlingFragment.LinkHandlingMode; + +/** + * Helper class for Custom Tabs. + */ +public class CustomTabsHelper { + private static final String TAG = "CustomTabsHelper"; + static final String STABLE_PACKAGE = "com.android.chrome"; + static final String BETA_PACKAGE = "com.chrome.beta"; + static final String DEV_PACKAGE = "com.chrome.dev"; + static final String LOCAL_PACKAGE = "com.google.android.apps.chrome"; + private static final String EXTRA_CUSTOM_TABS_KEEP_ALIVE = + "android.support.customtabs.extra.KEEP_ALIVE"; + private static final String ACTION_CUSTOM_TABS_CONNECTION = + "android.support.customtabs.action.CustomTabsService"; + + private static String sPackageNameToUse; + + private CustomTabsHelper() {} + + /** + * Goes through all apps that handle VIEW intents and have a warmup service. Picks + * the one chosen by the user if there is one, otherwise makes a best effort to return a + * valid package name. + * + * This is not threadsafe. + * + * @param context {@link Context} to use for accessing {@link PackageManager}. + * @return The package name recommended to use for connecting to custom tabs related components. + */ + public static String getPackageNameToUse(Context context) { + if (SettingValues.linkHandlingMode != LinkHandlingMode.CUSTOM_TABS.getValue()) return null; + if (sPackageNameToUse != null) return sPackageNameToUse; + + PackageManager pm = context.getPackageManager(); + // Get default VIEW intent handler. + Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com")); + ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0); + String defaultViewHandlerPackageName = null; + if (defaultViewHandlerInfo != null) { + defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName; + } + + // Get all apps that can handle VIEW intents. + List resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); + List packagesSupportingCustomTabs = new ArrayList<>(); + for (ResolveInfo info : resolvedActivityList) { + Intent serviceIntent = new Intent(); + serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION); + serviceIntent.setPackage(info.activityInfo.packageName); + // Samsung browser custom tabs has a bug that harms user experience, pressing back + // navigates between pages rather than exiting back to Slide + // TODO: Reevaluate at a later date + if (pm.resolveService(serviceIntent, 0) != null + && !info.activityInfo.packageName.equals("com.sec.android.app.sbrowser")) { + packagesSupportingCustomTabs.add(info.activityInfo.packageName); + } + } + + // Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents + // and service calls. + if (packagesSupportingCustomTabs.isEmpty()) { + sPackageNameToUse = null; + } else if (packagesSupportingCustomTabs.size() == 1) { + sPackageNameToUse = packagesSupportingCustomTabs.get(0); + } else if (!TextUtils.isEmpty(defaultViewHandlerPackageName) + && !hasSpecializedHandlerIntents(context, activityIntent) + && packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) { + sPackageNameToUse = defaultViewHandlerPackageName; + } else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) { + sPackageNameToUse = STABLE_PACKAGE; + } else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) { + sPackageNameToUse = BETA_PACKAGE; + } else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) { + sPackageNameToUse = DEV_PACKAGE; + } else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) { + sPackageNameToUse = LOCAL_PACKAGE; + } + return sPackageNameToUse; + } + + /** + * Used to check whether there is a specialized handler for a given intent. + * @param intent The intent to check with. + * @return Whether there is a specialized handler for the given intent. + */ + private static boolean hasSpecializedHandlerIntents(Context context, Intent intent) { + try { + PackageManager pm = context.getPackageManager(); + List handlers = pm.queryIntentActivities( + intent, + PackageManager.GET_RESOLVED_FILTER); + if (handlers == null || handlers.isEmpty()) { + return false; + } + for (ResolveInfo resolveInfo : handlers) { + IntentFilter filter = resolveInfo.filter; + if (filter == null) continue; + if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) continue; + if (resolveInfo.activityInfo == null) continue; + return true; + } + } catch (RuntimeException e) { + Log.e(TAG, "Runtime exception while getting specialized handlers"); + } + return false; + } + + /** + * @return All possible chrome package names that provide custom tabs feature. + */ + public static String[] getPackages() { + return new String[]{"", STABLE_PACKAGE, BETA_PACKAGE, DEV_PACKAGE, LOCAL_PACKAGE}; + } +} diff --git a/app/src/main/java/me/ccrama/redditslide/util/UpgradeUtil.java b/app/src/main/java/me/ccrama/redditslide/util/UpgradeUtil.java index 405057023..d1e3e1c29 100644 --- a/app/src/main/java/me/ccrama/redditslide/util/UpgradeUtil.java +++ b/app/src/main/java/me/ccrama/redditslide/util/UpgradeUtil.java @@ -1,135 +1,135 @@ -/* - * Copyright (c) 2016. ccrama - * - * Slide 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. - * - * This program 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 this program. If not, see . - */ - -package me.ccrama.redditslide.util; - -import android.content.Context; -import android.content.SharedPreferences; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Locale; -import java.util.Set; - -import me.ccrama.redditslide.SettingValues; - -public class UpgradeUtil { - // Increment for each needed change - private static final int VERSION = 2; - - private UpgradeUtil() { - } - - /** - * Runs any upgrade actions required between versions in an organised way - */ - public static void upgrade(Context context) { - SharedPreferences colors = context.getSharedPreferences("COLOR", 0); - SharedPreferences upgradePrefs = context.getSharedPreferences("upgradeUtil", 0); - - // Exit if this is the first start - if (colors != null && !colors.contains("Tutorial")) { - upgradePrefs.edit().putInt("VERSION", VERSION).apply(); - return; - } - - final int CURRENT = upgradePrefs.getInt("VERSION", 0); - - // Exit if we're up to date - if (CURRENT == VERSION) return; - - if (CURRENT < 1) { - SharedPreferences prefs = context.getSharedPreferences("SETTINGS", 0); - String domains = prefs.getString(SettingValues.PREF_ALWAYS_EXTERNAL, ""); - - domains = domains - .replaceFirst("(?<=^|,)youtube.co(?=$|,)", "youtube.com") - .replaceFirst("(?<=^|,)play.google.co(?=$|,)", "play.google.com"); - - prefs.edit().putString(SettingValues.PREF_ALWAYS_EXTERNAL, domains).apply(); - } - - // migrate old filters - if (CURRENT < 2) { - SharedPreferences prefs = context.getSharedPreferences("SETTINGS", 0); - SharedPreferences.Editor prefsEditor = prefs.edit(); - String titleFilterStr = prefs.getString(SettingValues.PREF_TITLE_FILTERS, ""); - String textFilterStr = prefs.getString(SettingValues.PREF_TEXT_FILTERS, ""); - String flairFilterStr = prefs.getString(SettingValues.PREF_FLAIR_FILTERS, ""); - String subredditFilterStr = prefs.getString(SettingValues.PREF_SUBREDDIT_FILTERS, ""); - String domainFilterStr = prefs.getString(SettingValues.PREF_DOMAIN_FILTERS, ""); - String usersFilterStr = prefs.getString(SettingValues.PREF_USER_FILTERS, ""); - String alwaysExternalStr = prefs.getString(SettingValues.PREF_ALWAYS_EXTERNAL, ""); - - prefsEditor.remove(SettingValues.PREF_TITLE_FILTERS); - prefsEditor.remove(SettingValues.PREF_TEXT_FILTERS); - prefsEditor.remove(SettingValues.PREF_FLAIR_FILTERS); - prefsEditor.remove(SettingValues.PREF_SUBREDDIT_FILTERS); - prefsEditor.remove(SettingValues.PREF_DOMAIN_FILTERS); - prefsEditor.remove(SettingValues.PREF_USER_FILTERS); - prefsEditor.remove(SettingValues.PREF_ALWAYS_EXTERNAL); - - Set titleFilters = titleFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(titleFilterStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - Set textFilters = textFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(textFilterStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - Set flairFilters = flairFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(flairFilterStr.replaceAll("^[,]+", "") - .toLowerCase(Locale.ENGLISH).split("[,]+"))); - // verify flairs filters are valid - HashSet invalid = new HashSet<>(); - for (String s : flairFilters) { - if (!s.contains(":")) { - invalid.add(s); - } - } - flairFilters.removeAll(invalid); - - Set subredditFilters = subredditFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(subredditFilterStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - Set domainFilters = domainFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(domainFilterStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - Set usersFilters = usersFilterStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(usersFilterStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - Set alwaysExternal = alwaysExternalStr.isEmpty() ? new HashSet<>() : - new HashSet<>(Arrays.asList(alwaysExternalStr.replaceAll("^[,\\s]+", "") - .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); - - prefsEditor.putStringSet(SettingValues.PREF_TITLE_FILTERS, titleFilters); - prefsEditor.putStringSet(SettingValues.PREF_TEXT_FILTERS, textFilters); - prefsEditor.putStringSet(SettingValues.PREF_FLAIR_FILTERS, flairFilters); - prefsEditor.putStringSet(SettingValues.PREF_SUBREDDIT_FILTERS, subredditFilters); - prefsEditor.putStringSet(SettingValues.PREF_DOMAIN_FILTERS, domainFilters); - prefsEditor.putStringSet(SettingValues.PREF_USER_FILTERS, usersFilters); - prefsEditor.putStringSet(SettingValues.PREF_ALWAYS_EXTERNAL, alwaysExternal); - - prefsEditor.apply(); - } - - upgradePrefs.edit().putInt("VERSION", VERSION).apply(); - } -} +/* + * Copyright (c) 2016. ccrama + * + * Slide 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. + * + * This program 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 this program. If not, see . + */ + +package me.ccrama.redditslide.util; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +import me.ccrama.redditslide.SettingValues; + +public class UpgradeUtil { + // Increment for each needed change + private static final int VERSION = 2; + + private UpgradeUtil() { + } + + /** + * Runs any upgrade actions required between versions in an organised way + */ + public static void upgrade(Context context) { + SharedPreferences colors = context.getSharedPreferences("COLOR", 0); + SharedPreferences upgradePrefs = context.getSharedPreferences("upgradeUtil", 0); + + // Exit if this is the first start + if (colors != null && !colors.contains("Tutorial")) { + upgradePrefs.edit().putInt("VERSION", VERSION).apply(); + return; + } + + final int CURRENT = upgradePrefs.getInt("VERSION", 0); + + // Exit if we're up to date + if (CURRENT == VERSION) return; + + if (CURRENT < 1) { + SharedPreferences prefs = context.getSharedPreferences("SETTINGS", 0); + String domains = prefs.getString(SettingValues.PREF_ALWAYS_EXTERNAL, ""); + + domains = domains + .replaceFirst("(?<=^|,)youtube.co(?=$|,)", "youtube.com") + .replaceFirst("(?<=^|,)play.google.co(?=$|,)", "play.google.com"); + + prefs.edit().putString(SettingValues.PREF_ALWAYS_EXTERNAL, domains).apply(); + } + + // migrate old filters + if (CURRENT < 2) { + SharedPreferences prefs = context.getSharedPreferences("SETTINGS", 0); + SharedPreferences.Editor prefsEditor = prefs.edit(); + String titleFilterStr = prefs.getString(SettingValues.PREF_TITLE_FILTERS, ""); + String textFilterStr = prefs.getString(SettingValues.PREF_TEXT_FILTERS, ""); + String flairFilterStr = prefs.getString(SettingValues.PREF_FLAIR_FILTERS, ""); + String subredditFilterStr = prefs.getString(SettingValues.PREF_SUBREDDIT_FILTERS, ""); + String domainFilterStr = prefs.getString(SettingValues.PREF_DOMAIN_FILTERS, ""); + String usersFilterStr = prefs.getString(SettingValues.PREF_USER_FILTERS, ""); + String alwaysExternalStr = prefs.getString(SettingValues.PREF_ALWAYS_EXTERNAL, ""); + + prefsEditor.remove(SettingValues.PREF_TITLE_FILTERS); + prefsEditor.remove(SettingValues.PREF_TEXT_FILTERS); + prefsEditor.remove(SettingValues.PREF_FLAIR_FILTERS); + prefsEditor.remove(SettingValues.PREF_SUBREDDIT_FILTERS); + prefsEditor.remove(SettingValues.PREF_DOMAIN_FILTERS); + prefsEditor.remove(SettingValues.PREF_USER_FILTERS); + prefsEditor.remove(SettingValues.PREF_ALWAYS_EXTERNAL); + + Set titleFilters = titleFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(titleFilterStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + Set textFilters = textFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(textFilterStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + Set flairFilters = flairFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(flairFilterStr.replaceAll("^[,]+", "") + .toLowerCase(Locale.ENGLISH).split("[,]+"))); + // verify flairs filters are valid + HashSet invalid = new HashSet<>(); + for (String s : flairFilters) { + if (!s.contains(":")) { + invalid.add(s); + } + } + flairFilters.removeAll(invalid); + + Set subredditFilters = subredditFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(subredditFilterStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + Set domainFilters = domainFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(domainFilterStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + Set usersFilters = usersFilterStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(usersFilterStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + Set alwaysExternal = alwaysExternalStr.isEmpty() ? new HashSet<>() : + new HashSet<>(Arrays.asList(alwaysExternalStr.replaceAll("^[,\\s]+", "") + .toLowerCase(Locale.ENGLISH).split("[,\\s]+"))); + + prefsEditor.putStringSet(SettingValues.PREF_TITLE_FILTERS, titleFilters); + prefsEditor.putStringSet(SettingValues.PREF_TEXT_FILTERS, textFilters); + prefsEditor.putStringSet(SettingValues.PREF_FLAIR_FILTERS, flairFilters); + prefsEditor.putStringSet(SettingValues.PREF_SUBREDDIT_FILTERS, subredditFilters); + prefsEditor.putStringSet(SettingValues.PREF_DOMAIN_FILTERS, domainFilters); + prefsEditor.putStringSet(SettingValues.PREF_USER_FILTERS, usersFilters); + prefsEditor.putStringSet(SettingValues.PREF_ALWAYS_EXTERNAL, alwaysExternal); + + prefsEditor.apply(); + } + + upgradePrefs.edit().putInt("VERSION", VERSION).apply(); + } +}