diff options
56 files changed, 1237 insertions, 750 deletions
diff --git a/build.gradle b/build.gradle index f0411ebb..fd48ba51 100755 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.0' + classpath 'com.android.tools.build:gradle:2.0.0' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 754c2b19..77340c2f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Jan 27 11:47:07 AST 2015 +#Mon Apr 11 22:43:55 MSK 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip diff --git a/org.fox.ttrss/build.gradle b/org.fox.ttrss/build.gradle index a5aec718..94373e3a 100755 --- a/org.fox.ttrss/build.gradle +++ b/org.fox.ttrss/build.gradle @@ -31,7 +31,7 @@ dependencies { compile files('libs/universal-image-loader-1.9.3.jar') compile 'com.android.support:cardview-v7:23.1.1' compile 'com.android.support:support-v4:23.1.1' - compile 'com.google.code.gson:gson:2.3' + compile 'com.google.code.gson:gson:2.4' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.shamanland:fab:0.0.5' compile 'ch.acra:acra:4.5.0' diff --git a/org.fox.ttrss/src/main/AndroidManifest.xml b/org.fox.ttrss/src/main/AndroidManifest.xml index 06db6351..beaef47b 100755 --- a/org.fox.ttrss/src/main/AndroidManifest.xml +++ b/org.fox.ttrss/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.fox.ttrss" - android:versionCode="386" - android:versionName="1.158" > + android:versionCode="412" + android:versionName="1.178" > <uses-sdk android:minSdkVersion="16" @@ -17,6 +17,7 @@ android:name=".Application" android:allowBackup="true" android:backupAgent=".util.PrefsBackupAgent" + android:fullBackupOnly="true" android:hardwareAccelerated="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > @@ -254,6 +255,7 @@ <activity android:name=".ArticleImagesPagerActivity" + android:configChanges="keyboardHidden|orientation|screenSize" android:label="Article Images" > </activity> <activity diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java index 8f7e556d..1c0afca8 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java @@ -2,14 +2,13 @@ package org.fox.ttrss; import android.annotation.SuppressLint; import android.app.Activity; -import android.content.Intent; import android.content.SharedPreferences; +import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; -import android.support.v4.widget.NestedScrollView; import android.support.v7.app.ActionBar; import android.text.Html; import android.util.Log; @@ -28,16 +27,16 @@ import android.webkit.WebView.HitTestResult; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.ScrollView; import android.widget.TextView; import com.shamanland.fab.ShowHideOnScroll; import org.fox.ttrss.types.Article; import org.fox.ttrss.types.Attachment; -import org.fox.ttrss.util.NoChildFocusScrollView; +import org.fox.ttrss.util.NotifyingScrollView; import java.net.MalformedURLException; -import java.net.URI; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -183,7 +182,7 @@ public class ArticleFragment extends Fragment { m_contentView = view.findViewById(R.id.article_scrollview); m_customViewContainer = (FrameLayout) view.findViewById(R.id.article_fullscreen_video); - if (m_article.id == HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED) { + /* if (m_article.id == HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED) { TextView statusMessage = (TextView) view.findViewById(R.id.article_status_message); statusMessage.setText(R.string.headlines_row_top_changed); statusMessage.setVisibility(View.VISIBLE); @@ -192,17 +191,17 @@ public class ArticleFragment extends Fragment { view.findViewById(R.id.article_fab).setVisibility(View.GONE); return view; - } + } */ - NoChildFocusScrollView scrollView = (NoChildFocusScrollView) view.findViewById(R.id.article_scrollview); + NotifyingScrollView scrollView = (NotifyingScrollView) view.findViewById(R.id.article_scrollview); m_fab = view.findViewById(R.id.article_fab); if (scrollView != null && m_activity.isSmallScreen()) { view.findViewById(R.id.article_heading_spacer).setVisibility(View.VISIBLE); - scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { + scrollView.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() { @Override - public void onScrollChange(NestedScrollView who, int l, int t, int oldl, int oldt) { + public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) { ActionBar ab = m_activity.getSupportActionBar(); if (t >= oldt && t >= ab.getHeight()) { @@ -223,12 +222,7 @@ public class ArticleFragment extends Fragment { @Override public void onClick(View view) { try { - URL url = new URL(m_article.link.trim()); - String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), - url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString(); - - m_activity.openUri(Uri.parse(uri)); - + m_activity.openUri(Uri.parse(m_article.link)); } catch (Exception e) { e.printStackTrace(); m_activity.toast(R.string.error_other_error); @@ -262,11 +256,7 @@ public class ArticleFragment extends Fragment { @Override public void onClick(View v) { try { - URL url = new URL(m_article.link.trim()); - String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), - url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString(); - - m_activity.openUri(Uri.parse(uri)); + m_activity.openUri(Uri.parse(m_article.link)); } catch (Exception e) { e.printStackTrace(); m_activity.toast(R.string.error_other_error); @@ -274,7 +264,6 @@ public class ArticleFragment extends Fragment { } }); - registerForContextMenu(title); } ImageView share = (ImageView)view.findViewById(R.id.share); @@ -301,12 +290,10 @@ public class ArticleFragment extends Fragment { @Override public void onClick(View v) { try { - URL url = new URL((m_article.comments_link != null && m_article.comments_link.length() > 0) ? - m_article.comments_link : m_article.link); - String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), - url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString(); + String url = (m_article.comments_link != null && m_article.comments_link.length() > 0) ? + m_article.comments_link : m_article.link; - m_activity.openUri(Uri.parse(uri)); + m_activity.openUri(Uri.parse(url)); } catch (Exception e) { e.printStackTrace(); m_activity.toast(R.string.error_other_error); @@ -341,21 +328,6 @@ public class ArticleFragment extends Fragment { dv.setText(df.format(d)); } - TextView author = (TextView)view.findViewById(R.id.author); - - boolean hasAuthor = false; - - if (author != null) { - author.setTextSize(TypedValue.COMPLEX_UNIT_SP, m_articleSmallFontSize); - - if (m_article.author != null && m_article.author.length() > 0) { - author.setText(getString(R.string.author_formatted, m_article.author)); - } else { - author.setVisibility(View.GONE); - } - hasAuthor = true; - } - TextView tagv = (TextView)view.findViewById(R.id.tags); if (tagv != null) { @@ -364,7 +336,7 @@ public class ArticleFragment extends Fragment { if (m_article.feed_title != null) { String fTitle = m_article.feed_title; - if (!hasAuthor && m_article.author != null && m_article.author.length() > 0) { + if (m_article.author != null && m_article.author.length() > 0) { fTitle += " (" + getString(R.string.author_formatted, m_article.author) + ")"; } @@ -476,6 +448,10 @@ public class ArticleFragment extends Fragment { ws.setMediaPlaybackRequiresUserGesture(false); } + if (CommonActivity.THEME_DARK.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) { + m_web.setBackgroundColor(Color.BLACK); + } + if (m_prefs.getBoolean("justify_article_text", true)) { cssOverride += "body { text-align : justify; } "; } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java index 39aa8fe4..2e60e6d1 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleImagesPagerActivity.java @@ -20,11 +20,14 @@ import android.view.ContextMenu; import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.FrameLayout; +import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.TextView; @@ -60,14 +63,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur @Override public boolean onSingleTapConfirmed(MotionEvent motionEvent) { - ActionBar bar = getSupportActionBar(); - - if (bar.isShowing()) { - bar.hide(); - } else { - bar.show(); - } - return false; } @@ -90,10 +85,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur m_urls = urls; } - public ArticleImagesPagerAdapter() { - super(); - } - @Override public int getCount() { return m_urls.size(); @@ -106,7 +97,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur @Override public Object instantiateItem(ViewGroup container, int position) { - String url = m_urls.get(position); + final String url = m_urls.get(position); Log.d(TAG, "called for URL: " + url); @@ -131,11 +122,30 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur }); if (position == 0) { - ViewCompat.setTransitionName(imgView, "TRANSITION:ARTICLE_IMAGES_PAGER"); + ViewCompat.setTransitionName(imgView, "gallery:" + url); } registerForContextMenu(imgView); + view.findViewById(R.id.flavor_image_overflow).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(ArticleImagesPagerActivity.this, v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onImageMenuItemSelected(item, url); + } + }); + + popup.show(); + + } + }); + DisplayImageOptions options = new DisplayImageOptions.Builder() .cacheInMemory(true) .resetViewBeforeLoading(true) @@ -173,7 +183,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur } }); - ((ViewPager) container).addView(view, 0); + container.addView(view, 0); if (position == 0) { ActivityCompat.startPostponedEnterTransition(ArticleImagesPagerActivity.this); @@ -329,6 +339,7 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur m_pager = (ViewPager) findViewById(R.id.article_images_pager); m_pager.setAdapter(m_adapter); m_pager.setPageTransformer(true, new DepthPageTransformer()); + } @SuppressLint("NewApi") @@ -337,7 +348,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur super.onResume(); } - @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { @@ -347,7 +357,6 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur super.onCreateContextMenu(menu, v, menuInfo); } - @Override public void onSaveInstanceState(Bundle out) { super.onSaveInstanceState(out); @@ -358,32 +367,18 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur } @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.context_article_content_img, menu); - - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return onContextItemSelected(item); // this is really bad :() + public boolean onContextItemSelected(MenuItem item) { + int position = m_pager.getCurrentItem(); + String url = m_checkedUrls.get(position); + + if (!onImageMenuItemSelected(item, url)) + return super.onContextItemSelected(item); + else + return true; } - @Override - public boolean onContextItemSelected(android.view.MenuItem item) { - ViewPager pager = (ViewPager) findViewById(R.id.article_images_pager); - String url = null; - - if (pager != null) { - int currentItem = pager.getCurrentItem(); - url = m_urls.get(currentItem); - } - + public boolean onImageMenuItemSelected(MenuItem item, String url) { switch (item.getItemId()) { - case android.R.id.home: - onBackPressed(); - return true; case R.id.article_img_open: if (url != null) { try { @@ -401,56 +396,18 @@ public class ArticleImagesPagerActivity extends CommonActivity implements Gestur return true; case R.id.article_img_share: if (url != null) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("image/png"); - intent.putExtra(Intent.EXTRA_SUBJECT, url); - intent.putExtra(Intent.EXTRA_TEXT, url); - - startActivity(Intent.createChooser(intent, url)); + shareText(url); } return true; - // TODO: this needs access to article text, I'm afraid case R.id.article_img_view_caption: if (url != null) { - - // Android doesn't give us an easy way to access title tags; - // we'll use Jsoup on the body text to grab the title text - // from the first image tag with this url. This will show - // the wrong text if an image is used multiple times. - Document doc = Jsoup.parse(m_content); - Elements es = doc.getElementsByAttributeValue("src", url); - if (es.size() > 0) { - if (es.get(0).hasAttr("title")) { - Dialog dia = new Dialog(this); - if (es.get(0).hasAttr("alt")) { - dia.setTitle(es.get(0).attr("alt")); - } else { - dia.setTitle(es.get(0).attr("title")); - } - TextView titleText = new TextView(this); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - titleText.setPaddingRelative(24, 24, 24, 24); - } else { - titleText.setPadding(24, 24, 24, 24); - } - - titleText.setTextSize(16); - titleText.setText(es.get(0).attr("title")); - dia.setContentView(titleText); - dia.show(); - } else { - toast(R.string.no_caption_to_display); - } - } else { - toast(R.string.no_caption_to_display); - } + displayImageCaption(url, m_content); } return true; default: - Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); + Log.d(TAG, "onImageMenuItemSelected, unhandled id=" + item.getItemId()); + return false; } } + } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java index 6c3f90da..f1c9eab0 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java @@ -81,7 +81,13 @@ public class ArticlePager extends Fragment { if (savedInstanceState != null) { m_article = savedInstanceState.getParcelable("article"); - m_articles = ((DetailActivity)m_activity).m_articles; + + if (! (m_activity instanceof DetailActivity)) { + m_articles = savedInstanceState.getParcelable("articles"); + } else { + m_articles = ((DetailActivity)m_activity).m_articles; + } + m_feed = savedInstanceState.getParcelable("feed"); m_firstId = savedInstanceState.getInt("firstId"); } @@ -159,8 +165,11 @@ public class ArticlePager extends Fragment { if (result != null) { - if (m_firstIdChanged) { - m_articles.add(new Article(HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED)); + if (m_firstIdChanged && !(m_activity instanceof DetailActivity && !m_activity.isPortrait())) { + // TODO: show an information message in viewpager without modifying m_articles + //m_articles.add(new Article(HeadlinesFragment.ARTICLE_SPECIAL_TOP_CHANGED)); + + m_activity.toast(R.string.headlines_row_top_changed); } ArticlePager.this.m_firstId = m_firstId; @@ -175,7 +184,7 @@ public class ArticlePager extends Fragment { } if (m_article != null) { - if (m_article.id == 0 || m_articles.indexOf(m_article) == -1) { + if (m_article.id == 0 || !m_articles.containsId(m_article.id)) { if (m_articles.size() > 0) { m_article = m_articles.get(0); m_listener.onArticleSelected(m_article, false); @@ -273,6 +282,7 @@ public class ArticlePager extends Fragment { out.setClassLoader(getClass().getClassLoader()); out.putParcelable("article", m_article); + out.putParcelable("articles", m_articles); out.putParcelable("feed", m_feed); out.putInt("firstId", m_firstId); } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java index d70ee8c8..51df75e3 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/BaseFeedlistFragment.java @@ -3,6 +3,8 @@ package org.fox.ttrss; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.app.Fragment; import android.support.v7.widget.SwitchCompat; import android.util.TypedValue; @@ -29,6 +31,8 @@ public abstract class BaseFeedlistFragment extends Fragment { if (true /*m_activity.findViewById(R.id.headlines_drawer) != null*/) { try { + boolean needSettingsFooter = false; + if (activity.isSmallScreen()) { View layout = inflater.inflate(R.layout.drawer_header, list, false); list.addHeaderView(layout, null, false); @@ -51,12 +55,19 @@ public abstract class BaseFeedlistFragment extends Fragment { try { Intent intent = new Intent(getActivity(), PreferencesActivity.class); - startActivityForResult(intent, 0); - } catch (Exception e) { + ActivityOptionsCompat options = ActivityOptionsCompat + .makeSceneTransitionAnimation(getActivity(), v, "SETTINGS_REVEAL"); + + ActivityCompat.startActivityForResult(getActivity(), intent, 0, options.toBundle()); + + } catch (Exception e) { + e.printStackTrace(); } } }); + } else { + needSettingsFooter = true; } /* deal with ~material~ footers */ @@ -101,6 +112,41 @@ public abstract class BaseFeedlistFragment extends Fragment { }); if (isRoot) { + if (needSettingsFooter) { + // settings (as a list footer row) + + footer = inflater.inflate(R.layout.feeds_row, list, false); + footer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + Intent intent = new Intent(getActivity(), + PreferencesActivity.class); + + ActivityOptionsCompat options = ActivityOptionsCompat + .makeSceneTransitionAnimation(getActivity(), v, "SETTINGS_REVEAL"); + + ActivityCompat.startActivityForResult(getActivity(), intent, 0, options.toBundle()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + list.addFooterView(footer); + text = (TextView) footer.findViewById(R.id.title); + text.setText(R.string.action_settings); + + icon = (ImageView) footer.findViewById(R.id.icon); + tv = new TypedValue(); + getActivity().getTheme().resolveAttribute(R.attr.ic_settings, tv, true); + icon.setImageResource(tv.resourceId); + + TextView counter = (TextView) footer.findViewById(R.id.unread_counter); + counter.setText(R.string.blank); + } + // offline footer = inflater.inflate(R.layout.feeds_row, list, false); footer.setOnClickListener(new View.OnClickListener() { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java index 9fd90eb5..5811a7f9 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/CommonActivity.java @@ -28,10 +28,21 @@ import android.util.TypedValue; import android.view.Display; import android.view.View; import android.widget.CheckBox; +import android.widget.TextView; import android.widget.Toast; +import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiscCache; +import com.nostra13.universalimageloader.core.DefaultConfigurationFactory; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; + import org.fox.ttrss.util.DatabaseHelper; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import java.io.File; +import java.io.IOException; import java.util.Arrays; public class CommonActivity extends ActionBarActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -51,6 +62,8 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc public static final int EXCERPT_MAX_LENGTH = 256; public static final int EXCERPT_MAX_QUERY_LENGTH = 2048; + public static final int PENDING_INTENT_CHROME_SHARE = 1; + private DatabaseHelper m_databaseHelper; //private SQLiteDatabase m_readableDb; @@ -154,6 +167,23 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc CustomTabsClient.bindCustomTabsService(this, "com.android.chrome", m_customTabServiceConnection); + if (!ImageLoader.getInstance().isInited()) { + ImageLoaderConfiguration config; + + try { + config = new ImageLoaderConfiguration.Builder(getApplicationContext()) + .diskCache( + new LruDiscCache(new File(getCacheDir(), "article-images"), + DefaultConfigurationFactory.createFileNameGenerator(), + 100 * 1024 * 1024)) + .build(); + } catch (IOException e) { + config = new ImageLoaderConfiguration.Builder(getApplicationContext()) + .build(); + } + ImageLoader.getInstance().init(config); + } + super.onCreate(savedInstanceState); } @@ -237,6 +267,26 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc } } + protected Intent getShareIntent(String text, String subject) { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, text); + + if (subject != null) { + shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject); + } + + return shareIntent; + } + + protected void shareText(String text) { + startActivity(Intent.createChooser(getShareIntent(text, null), text)); + } + + protected void shareText(String text, String subject) { + startActivity(Intent.createChooser(getShareIntent(text, subject), text)); + } + private void openUriWithCustomTab(Uri uri) { if (m_customTabClient != null) { TypedValue tvBackground = new TypedValue(); @@ -249,27 +299,40 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc builder.setToolbarColor(tvBackground.data); - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, uri.toString()); - shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString()); + Intent shareIntent = getShareIntent(uri.toString(), null); - PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, shareIntent, 0); + PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), + CommonActivity.PENDING_INTENT_CHROME_SHARE, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setActionButton(BitmapFactory.decodeResource(getResources(), R.drawable.ic_share), getString(R.string.share_article), pendingIntent); CustomTabsIntent intent = builder.build(); - intent.launchUrl(this, uri); + try { + intent.launchUrl(this, uri); + } catch (Exception e) { + e.printStackTrace(); + toast(e.getMessage()); + } } } // uses chrome custom tabs when available - public void openUri(final Uri uri) { + public void openUri(Uri uri) { boolean enableCustomTabs = m_prefs.getBoolean("enable_custom_tabs", true); final boolean askEveryTime = m_prefs.getBoolean("custom_tabs_ask_always", true); + if (uri.getScheme() == null) { + try { + uri = Uri.parse("https:" + uri.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + final Uri finalUri = uri; + if (enableCustomTabs && m_customTabClient != null) { if (askEveryTime) { @@ -279,7 +342,6 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc AlertDialog.Builder builder = new AlertDialog.Builder( CommonActivity.this) - .setTitle(R.string.open_link) .setView(dialogView) .setMessage(uri.toString()) .setPositiveButton(R.string.quick_preview, @@ -293,11 +355,11 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc editor.apply(); } - openUriWithCustomTab(uri); + openUriWithCustomTab(finalUri); } }) - .setNegativeButton(R.string.open_with_app, + .setNegativeButton(R.string.open_with, new Dialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { @@ -309,9 +371,14 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc editor.apply(); } - Intent intent = new Intent(Intent.ACTION_VIEW, uri); + Intent intent = new Intent(Intent.ACTION_VIEW, finalUri); - startActivity(intent); + try { + startActivity(intent); + } catch (Exception e) { + e.printStackTrace(); + toast(e.getMessage()); + } } }); @@ -339,7 +406,43 @@ public class CommonActivity extends ActionBarActivity implements SharedPreferenc } else { Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); + try { + startActivity(intent); + } catch (Exception e) { + toast(e.getMessage()); + } + } + } + + public void displayImageCaption(String url, String htmlContent) { + // Android doesn't give us an easy way to access title tags; + // we'll use Jsoup on the body text to grab the title text + // from the first image tag with this url. This will show + // the wrong text if an image is used multiple times. + Document doc = Jsoup.parse(htmlContent); + Elements es = doc.getElementsByAttributeValue("src", url); + if (es.size() > 0) { + if (es.get(0).hasAttr("title")) { + + AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setCancelable(true) + .setMessage(es.get(0).attr("title")) + .setPositiveButton(R.string.dialog_close, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + } + ); + + AlertDialog dialog = builder.create(); + dialog.show(); + + } else { + toast(R.string.no_caption_to_display); + } + } else { + toast(R.string.no_caption_to_display); } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java index 8cab4845..dafcbe66 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java @@ -279,6 +279,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList Article article = hf.getActiveArticle(); if (article == null && hf.getAllArticles().size() > 0) { + article = hf.getAllArticles().get(0); hf.setActiveArticle(article); @@ -304,7 +305,12 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList setResult(Activity.RESULT_OK, resultIntent); - super.onBackPressed(); + try { + super.onBackPressed(); + } catch (IllegalStateException e) { + // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState + e.printStackTrace(); + } } @Override diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java index 02fd7985..24be6292 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedCategoriesFragment.java @@ -315,7 +315,7 @@ public class FeedCategoriesFragment extends BaseFeedlistFragment implements OnIt @Override protected void onPostExecute(JsonElement result) { - if (isDetached()) return; + if (isDetached() || !isAdded()) return; if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java index 41c0f69c..6d567ff8 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java @@ -496,7 +496,7 @@ public class FeedsFragment extends BaseFeedlistFragment implements OnItemClickLi @Override protected void onPostExecute(JsonElement result) { - if (isDetached()) return; + if (isDetached() || !isAdded()) return; if (getView() != null) { View loadingBar = getView().findViewById(R.id.feeds_loading_bar); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java index 90f432b4..118d28b8 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java @@ -29,6 +29,7 @@ import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Display; import android.view.LayoutInflater; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; @@ -43,6 +44,7 @@ import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.ListView; +import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; @@ -68,7 +70,6 @@ import org.fox.ttrss.types.Article; import org.fox.ttrss.types.ArticleList; import org.fox.ttrss.types.Feed; import org.fox.ttrss.util.HeadlinesRequest; -import org.jsoup.Jsoup; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -79,7 +80,7 @@ import java.util.List; import java.util.TimeZone; public class HeadlinesFragment extends Fragment implements OnItemClickListener, OnScrollListener { - public static enum ArticlesSelection { ALL, NONE, UNREAD } + public enum ArticlesSelection { ALL, NONE, UNREAD } public static final int FLAVOR_IMG_MIN_SIZE = 128; public static final int THUMB_IMG_MIN_SIZE = 32; @@ -87,8 +88,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public static final int HEADLINES_REQUEST_SIZE = 30; public static final int HEADLINES_BUFFER_MAX = 500; - public static final int ARTICLE_SPECIAL_LOADMORE = -1; - public static final int ARTICLE_SPECIAL_TOP_CHANGED = -3; + //public static final int ARTICLE_SPECIAL_LOADMORE = -1; + //public static final int ARTICLE_SPECIAL_TOP_CHANGED = -3; private final String TAG = this.getClass().getSimpleName(); @@ -98,6 +99,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private boolean m_refreshInProgress = false; private boolean m_autoCatchupDisabled = false; private int m_firstId = 0; + private boolean m_lazyLoadDisabled = false; private SharedPreferences m_prefs; @@ -114,6 +116,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, private int m_listPreviousVisibleItem; private ListView m_list; private ImageLoader m_imageLoader = ImageLoader.getInstance(); + private View m_listLoadingView; + private View m_topChangedView; + private View m_amrFooterView; public ArticleList getSelectedArticles() { ArticleList tmp = new ArticleList(); @@ -142,7 +147,77 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } } - @Override + public boolean onArticleMenuItemSelected(MenuItem item, Article article) { + + if (article == null) return false; + + switch (item.getItemId()) { + case R.id.set_labels: + m_activity.editArticleLabels(article); + return true; + case R.id.article_set_note: + m_activity.editArticleNote(article); + return true; + case R.id.headlines_article_unread: + article.unread = !article.unread; + m_activity.saveArticleUnread(article); + m_adapter.notifyDataSetChanged(); + return true; + case R.id.headlines_article_link_copy: + m_activity.copyToClipboard(article.link); + return true; + case R.id.headlines_article_link_open: + m_activity.openUri(Uri.parse(article.link)); + + if (article.unread) { + article.unread = false; + m_activity.saveArticleUnread(article); + + m_adapter.notifyDataSetChanged(); + } + return true; + case R.id.headlines_share_article: + m_activity.shareArticle(article); + return true; + case R.id.catchup_above: + if (true) { + ArticleList articles = getAllArticles(); + ArticleList tmp = new ArticleList(); + for (Article a : articles) { + if (article.id == a.id) + break; + + if (a.unread) { + a.unread = false; + tmp.add(a); + } + } + if (tmp.size() > 0) { + m_activity.toggleArticlesUnread(tmp); + //updateHeadlines(); + } + m_adapter.notifyDataSetChanged(); + } + return true; + default: + Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId()); + return false; + } + } + + public boolean onContextItemSelected(MenuItem item) { + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item + .getMenuInfo(); + + Article article = getArticleAtPosition(info.position); + + if (!onArticleMenuItemSelected(item, article)) + return super.onContextItemSelected(item); + else + return true; + } + + /*@Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo(); @@ -291,7 +366,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); return super.onContextItemSelected(item); } - } + } */ public HeadlinesFragment() { super(); @@ -310,22 +385,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu); - if (getSelectedArticles().size() > 0) { - menu.setHeaderTitle(R.string.headline_context_multiple); - menu.setGroupVisible(R.id.menu_group_single_article, false); - } else { - AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - Article article = getArticleAtPosition(info.position); - - menu.setHeaderTitle(Html.fromHtml(article.title)); - menu.setGroupVisible(R.id.menu_group_single_article, true); - } - menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); super.onCreateContextMenu(menu, v, menuInfo); - } @Override @@ -345,6 +408,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_searchQuery = (String) savedInstanceState.getCharSequence("searchQuery"); m_compactLayoutMode = savedInstanceState.getBoolean("compactLayoutMode"); m_firstId = savedInstanceState.getInt("firstId"); + m_lazyLoadDisabled = savedInstanceState.getBoolean("lazyLoadDisabled"); } String headlineMode = m_prefs.getString("headline_mode", "HL_DEFAULT"); @@ -372,24 +436,37 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_list = (ListView)view.findViewById(R.id.headlines_list); FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.headlines_fab); - m_list.setOnTouchListener(new ShowHideOnScroll(fab)); - fab.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - refresh(false); - } - }); - if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) { + if (! (getActivity() instanceof DetailActivity)) { + + m_list.setOnTouchListener(new ShowHideOnScroll(fab)); + fab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + refresh(false); + } + }); + } else { + fab.setVisibility(View.GONE); + } + + m_listLoadingView = inflater.inflate(R.layout.headlines_row_loadmore, m_list, false); + //m_list.addFooterView(m_listLoadingView, null, false); + //m_listLoadingView.setVisibility(View.GONE); + + m_topChangedView = inflater.inflate(R.layout.headlines_row_top_changed, m_list, false); + //m_list.addFooterView(m_topChangedView, null, false); + //m_topChangedView.setVisibility(View.GONE);*/ + + if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) { WindowManager wm = (WindowManager) m_activity.getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); int screenHeight = display.getHeight(); - View layout = inflater.inflate(R.layout.headlines_footer, container, false); - - layout.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, screenHeight)); + m_amrFooterView = inflater.inflate(R.layout.headlines_footer, container, false); + m_amrFooterView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT, screenHeight)); - m_list.addFooterView(layout, null, false); + m_list.addFooterView(m_amrFooterView, null, false); } if (m_activity.isSmallScreen()) { @@ -401,7 +478,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_activity.getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_padding_end_material)); } - m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, (ArrayList<Article>)m_articles); + m_adapter = new ArticleListAdapter(getActivity(), R.layout.headlines_row, m_articles); m_animationAdapter = new SwingBottomInAnimationAdapter(m_adapter); m_animationAdapter.setAbsListView(m_list); @@ -492,6 +569,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, @SuppressWarnings({ "serial" }) public void refresh(boolean append, boolean userInitiated) { + m_list.removeFooterView(m_listLoadingView); + m_list.removeFooterView(m_topChangedView); + m_list.removeFooterView(m_amrFooterView); + + if (!append) m_lazyLoadDisabled = false; + if (m_activity != null && m_feed != null) { m_refreshInProgress = true; @@ -530,18 +613,33 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, super.onPostExecute(result); - if (isAdded()) { - if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false); - } + if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false); + + //m_listLoadingView.setVisibility(View.GONE); + m_list.removeFooterView(m_listLoadingView); + m_list.removeFooterView(m_topChangedView); + m_list.removeFooterView(m_amrFooterView); if (result != null) { m_refreshInProgress = false; - if (m_articles.indexOf(m_activeArticle) == -1) + if (m_activeArticle != null && !m_articles.containsId(m_activeArticle.id)) { m_activeArticle = null; + } if (m_firstIdChanged) { - m_articles.add(new Article(ARTICLE_SPECIAL_TOP_CHANGED)); + m_lazyLoadDisabled = true; + + //m_activity.toast(R.string.headlines_row_top_changed); + + //m_topChangedView.setVisibility(View.VISIBLE); + //m_articles.add(new Article(ARTICLE_SPECIAL_TOP_CHANGED)); + + m_list.addFooterView(m_topChangedView, null, false); + } + + if (m_amountLoaded < HEADLINES_REQUEST_SIZE) { + m_lazyLoadDisabled = true; } HeadlinesFragment.this.m_firstId = m_firstId; @@ -552,7 +650,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, // not sure why but listview sometimes gets positioned while ignoring the header so // top headline content becomes partially obscured by the toolbar on phones // (not reproducible on avd) - if (!fappend) m_list.smoothScrollToPosition(0); + if (!fappend) { + m_list.smoothScrollToPosition(0); + } + + //m_listLoadingView.setVisibility(m_amountLoaded == HEADLINES_REQUEST_SIZE ? View.VISIBLE : View.GONE); } else { if (m_lastError == ApiError.LOGIN_FAILED) { @@ -568,6 +670,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, //m_activity.setLoadingStatus(getErrorMessage(), false); } } + + if (m_amrFooterView != null) m_list.addFooterView(m_amrFooterView, null, false); } }; @@ -596,7 +700,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } else { skip = numAll; } - + + if (skip > 0) { + m_list.addFooterView(m_listLoadingView, null, false); + //m_listLoadingView.setVisibility(View.VISIBLE); + } + } else { //m_activity.setLoadingStatus(R.string.blank, true); } @@ -666,6 +775,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, out.putCharSequence("searchQuery", m_searchQuery); out.putBoolean("compactLayoutMode", m_compactLayoutMode); out.putInt("firstId", m_firstId); + out.putBoolean("lazyLoadDisabled", m_lazyLoadDisabled); } static class HeadlineViewHolder { @@ -687,6 +797,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public ImageView textChecked; public View headlineHeader; public View topChangedMessage; + public View flavorImageOverflow; public int position; public boolean flavorImageEmbedded; } @@ -698,10 +809,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public static final int VIEW_UNREAD = 1; public static final int VIEW_SELECTED = 2; public static final int VIEW_SELECTED_UNREAD = 3; - public static final int VIEW_LOADMORE = 4; - public static final int VIEW_TOP_CHANGED = 5; + //public static final int VIEW_LOADMORE = 4; + //public static final int VIEW_TOP_CHANGED = 4; - public static final int VIEW_COUNT = VIEW_TOP_CHANGED+1; + public static final int VIEW_COUNT = VIEW_SELECTED_UNREAD + 1; private final Integer[] origTitleColors = new Integer[VIEW_COUNT]; private final int titleHighScoreUnreadColor; @@ -754,11 +865,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public int getItemViewType(int position) { Article a = items.get(position); - if (a.id == ARTICLE_SPECIAL_LOADMORE) { - return VIEW_LOADMORE; - } else if (a.id == ARTICLE_SPECIAL_TOP_CHANGED) { + /*if (a.id == ARTICLE_SPECIAL_LOADMORE) { + return VIEW_LOADMORE; */ + /*if (a.id == ARTICLE_SPECIAL_TOP_CHANGED) { return VIEW_TOP_CHANGED; - } else if (m_activeArticle != null && a.id == m_activeArticle.id && a.unread) { + } else */ if (m_activeArticle != null && a.id == m_activeArticle.id && a.unread) { return VIEW_SELECTED_UNREAD; } else if (m_activeArticle != null && a.id == m_activeArticle.id) { return VIEW_SELECTED; @@ -769,7 +880,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } } - private void updateTextCheckedState(final HeadlineViewHolder holder, final Article article, int position) { + private void updateTextCheckedState(final HeadlineViewHolder holder, final Article article, final int position) { String tmp = article.title.length() > 0 ? article.title.substring(0, 1).toUpperCase() : "?"; if (article.selected) { @@ -791,7 +902,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } else { if (!article.flavorImageUri.equals(holder.textImage.getTag())) { - final int loadingPosition = position; ImageAware imageAware = new ImageViewAware(holder.textImage, false); DisplayImageOptions options = new DisplayImageOptions.Builder() @@ -817,7 +927,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, @Override public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) { - if (loadingPosition == holder.position && bitmap != null) { + if (position == holder.position && bitmap != null) { holder.textImage.setTag(article.flavorImageUri); if (bitmap.getWidth() < THUMB_IMG_MIN_SIZE || bitmap.getHeight() < THUMB_IMG_MIN_SIZE) { @@ -841,7 +951,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } @Override - public View getView(final int position, View convertView, ViewGroup parent) { + public View getView(final int position, final View convertView, ViewGroup parent) { View v = convertView; @@ -855,12 +965,12 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, int layoutId = m_compactLayoutMode ? R.layout.headlines_row_compact : R.layout.headlines_row; switch (getItemViewType(position)) { - case VIEW_LOADMORE: + /*case VIEW_LOADMORE: layoutId = R.layout.headlines_row_loadmore; break; case VIEW_TOP_CHANGED: layoutId = R.layout.headlines_row_top_changed; - break; + break;*/ case VIEW_UNREAD: layoutId = m_compactLayoutMode ? R.layout.headlines_row_unread_compact : R.layout.headlines_row_unread; break; @@ -895,6 +1005,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, holder.textChecked = (ImageView) v.findViewById(R.id.text_checked); holder.headlineHeader = v.findViewById(R.id.headline_header); holder.topChangedMessage = v.findViewById(R.id.headlines_row_top_changed); + holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow); v.setTag(holder); @@ -904,6 +1015,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, holder = (HeadlineViewHolder) v.getTag(); } + //Log.d(TAG, "getView: " + position + ":" + article.title); + holder.position = position; // block footer clicks to make button/selection clicking easier @@ -942,7 +1055,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Log.d(TAG, "num selected: " + getSelectedArticles().size()); } }); - ViewCompat.setTransitionName(holder.textImage, "TRANSITION:ARTICLE_IMAGES_PAGER"); + ViewCompat.setTransitionName(holder.textImage, "gallery:" + article.flavorImageUri); if (article.flavorImage != null) { @@ -1034,11 +1147,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, String excerpt; try { - if (m_activity.getApiLevel() >= 11) { - excerpt = article.excerpt != null ? article.excerpt : ""; - excerpt = excerpt.replace("…", "…"); - excerpt = excerpt.replace("]]>", ""); - excerpt = Jsoup.parse(excerpt).text(); + if (article.excerpt != null) { + excerpt = article.excerpt; } else { excerpt = article.articleDoc.text(); @@ -1068,16 +1178,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, holder.flavorImageLoadingBar.setVisibility(View.GONE); holder.flavorImageView.setVisibility(View.GONE); holder.flavorVideoKindView.setVisibility(View.GONE); + holder.flavorImageOverflow.setVisibility(View.GONE); holder.headlineHeader.setBackgroundDrawable(null); - holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - m_activity.openContextMenu(v); - return true; - } - }); - + // this is needed if our flavor image goes behind base listview element holder.headlineHeader.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -1085,22 +1189,66 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } }); - holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() { + holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { m_activity.openContextMenu(v); + return true; } }); if (showFlavorImage && article.flavorImageUri != null && holder.flavorImageView != null) { + if (holder.flavorImageOverflow != null) { + holder.flavorImageOverflow.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(getActivity(), holder.flavorImageOverflow); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_article_content_img, popup.getMenu()); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.article_img_open: + m_activity.openUri(Uri.parse(article.flavorImageUri)); + return true; + case R.id.article_img_copy: + m_activity.copyToClipboard(article.flavorImageUri); + return true; + case R.id.article_img_share: + m_activity.shareText(article.flavorImageUri); + return true; + case R.id.article_img_view_caption: + m_activity.displayImageCaption(article.flavorImageUri, article.content); + return true; + default: + return false; + } + } + }); + + popup.show(); + } + }); + + holder.flavorImageView.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + + m_activity.openContextMenu(v); + + return true; + } + }); + } if (!article.flavorImageUri.equals(holder.flavorImageView.getTag())) { //Log.d(TAG, "IMG: " + article.flavorImageUri + " STREAM: " + article.flavorStreamUri); ImageAware imageAware = new ImageViewAware(holder.flavorImageView, false); - final int loadingPosition = position; m_imageLoader.displayImage(article.flavorImageUri, imageAware, displayImageOptions, new ImageLoadingListener() { @Override @@ -1117,13 +1265,15 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, @Override public void onLoadingComplete(String imageUri, View view, Bitmap bitmap) { - if (loadingPosition == holder.position && bitmap != null) { + if (position == holder.position && bitmap != null) { holder.flavorImageLoadingBar.setVisibility(View.GONE); - holder.flavorImageView.setTag(article.flavorImageUri); if (bitmap.getWidth() > FLAVOR_IMG_MIN_SIZE && bitmap.getHeight() > FLAVOR_IMG_MIN_SIZE) { + holder.flavorImageView.setTag(article.flavorImageUri); + holder.flavorImageView.setVisibility(View.VISIBLE); + holder.flavorImageOverflow.setVisibility(View.VISIBLE); maybeRepositionFlavorImage(view, bitmap, holder); adjustVideoKindView(holder, article); @@ -1142,7 +1292,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, @Override public void onProgressUpdate(String s, View view, int current, int total) { if (total != 0) { - int p = (int)((float)current/total*100); + int p = (int) ((float) current / total * 100); holder.flavorImageLoadingBar.setIndeterminate(false); holder.flavorImageLoadingBar.setProgress(p); @@ -1154,6 +1304,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, } else { // already tagged holder.flavorImageView.setVisibility(View.VISIBLE); + holder.flavorImageOverflow.setVisibility(View.VISIBLE); adjustVideoKindView(holder, article); @@ -1162,6 +1313,8 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, if (m_activity.getTheme().resolveAttribute(R.attr.headlineHeaderBackground, tv, true)) { holder.headlineHeader.setBackgroundColor(tv.data); } + } else { + holder.headlineHeader.setBackgroundDrawable(null); } } } @@ -1215,11 +1368,7 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public void onClick(View view) { CheckBox cb = (CheckBox)view; - if (cb.isChecked()) { - article.selected = true; - } else { - article.selected = false; - } + article.selected = cb.isChecked(); m_listener.onArticleListSelectionChange(getSelectedArticles()); @@ -1235,7 +1384,22 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, holder.menuButtonView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - getActivity().openContextMenu(v); + + PopupMenu popup = new PopupMenu(getActivity(), v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_headlines, popup.getMenu()); + + popup.getMenu().findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); + popup.getMenu().findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onArticleMenuItemSelected(item, article); + } + }); + + popup.show(); } }); } @@ -1264,9 +1428,17 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, Intent intent = new Intent(m_activity, VideoPlayerActivity.class); intent.putExtra("streamUri", article.flavorStreamUri); intent.putExtra("title", article.title); + intent.putExtra("coverSrc", article.flavorImageUri); - startActivity(intent); - m_activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + //startActivity(intent); + //m_activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); + + ActivityOptionsCompat options = + ActivityOptionsCompat.makeSceneTransitionAnimation(m_activity, + transitionView != null ? transitionView : holder.flavorImageView, + "gallery:" + article.flavorImageUri); + + ActivityCompat.startActivity(m_activity, intent, options.toBundle()); } else { @@ -1278,9 +1450,9 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(m_activity, - transitionView != null ? transitionView : holder.flavorImageView, // The view which starts the transition - "TRANSITION:ARTICLE_IMAGES_PAGER" // The transitionName of the view we’re transitioning to - ); + transitionView != null ? transitionView : holder.flavorImageView, + "gallery:" + article.flavorImageUri); + ActivityCompat.startActivity(m_activity, intent, options.toBundle()); } @@ -1444,10 +1616,6 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - if (!m_refreshInProgress && m_articles.findById(ARTICLE_SPECIAL_LOADMORE) != null && firstVisibleItem + visibleItemCount == m_articles.size()) { - refresh(true); - } - if (m_prefs.getBoolean("headlines_mark_read_scroll", false) && firstVisibleItem > (m_activity.isSmallScreen() ? 1 : 0) && !m_autoCatchupDisabled) { Article a = (Article) view.getItemAtPosition(firstVisibleItem - 1); @@ -1473,6 +1641,10 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, m_listPreviousVisibleItem = firstVisibleItem; } + + if (!m_refreshInProgress && !m_lazyLoadDisabled && /*m_articles.findById(ARTICLE_SPECIAL_LOADMORE) != null &&*/ firstVisibleItem + visibleItemCount == m_articles.size()) { + refresh(true); + } } @Override @@ -1521,7 +1693,11 @@ public class HeadlinesFragment extends Fragment implements OnItemClickListener, public void setSearchQuery(String query) { if (!m_searchQuery.equals(query)) { m_searchQuery = query; - refresh(false); + + // could be called before fragment view has been initialized + if (m_list != null) { + refresh(false); + } } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java index 1515883c..51781582 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java @@ -387,7 +387,12 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList m_drawerLayout.openDrawer(Gravity.START); } else { - super.onBackPressed(); + try { + super.onBackPressed(); + } catch (IllegalStateException e) { + // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState + e.printStackTrace(); + } } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java index 0039d3ea..355c5a58 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java @@ -168,23 +168,6 @@ public class OnlineActivity extends CommonActivity { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); - if (!ImageLoader.getInstance().isInited()) { - ImageLoaderConfiguration config; - - try { - config = new ImageLoaderConfiguration.Builder(getApplicationContext()) - .diskCache( - new LruDiscCache(new File(getCacheDir(), "article-images"), - DefaultConfigurationFactory.createFileNameGenerator(), - 100 * 1024 * 1024)) - .build(); - } catch (IOException e) { - config = new ImageLoaderConfiguration.Builder(getApplicationContext()) - .build(); - } - ImageLoader.getInstance().init(config); - } - //m_pullToRefreshAttacher = PullToRefreshAttacher.get(this); if (isOffline) { @@ -289,8 +272,12 @@ public class OnlineActivity extends CommonActivity { @Override public void onPause() { super.onPause(); - - unregisterReceiver(m_broadcastReceiver); + + try { + unregisterReceiver(m_broadcastReceiver); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } } @Override @@ -546,50 +533,12 @@ public class OnlineActivity extends CommonActivity { return true; case R.id.article_img_share: if (getLastContentImageHitTestUrl() != null) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("image/png"); - intent.putExtra(Intent.EXTRA_SUBJECT, getLastContentImageHitTestUrl()); - intent.putExtra(Intent.EXTRA_TEXT, getLastContentImageHitTestUrl()); - - startActivity(Intent.createChooser(intent, getLastContentImageHitTestUrl())); + shareText(getLastContentImageHitTestUrl()); } return true; case R.id.article_img_view_caption: if (getLastContentImageHitTestUrl() != null) { - - // Android doesn't give us an easy way to access title tags; - // we'll use Jsoup on the body text to grab the title text - // from the first image tag with this url. This will show - // the wrong text if an image is used multiple times. - Document doc = Jsoup.parse(ap.getSelectedArticle().content); - Elements es = doc.getElementsByAttributeValue("src", getLastContentImageHitTestUrl()); - if (es.size() > 0){ - if (es.get(0).hasAttr("title")){ - Dialog dia = new Dialog(this); - if (es.get(0).hasAttr("alt")){ - dia.setTitle(es.get(0).attr("alt")); - } else { - dia.setTitle(es.get(0).attr("title")); - } - TextView titleText = new TextView(this); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - titleText.setPaddingRelative(24, 24, 24, 24); - } else { - titleText.setPadding(24, 24, 24, 24); - } - - titleText.setTextSize(16); - titleText.setText(es.get(0).attr("title")); - dia.setContentView(titleText); - dia.show(); - } else { - toast(R.string.no_caption_to_display); - } - } else { - toast(R.string.no_caption_to_display); - } + displayImageCaption(getLastContentImageHitTestUrl(), ap.getSelectedArticle().content); } return true; case R.id.article_link_share: @@ -598,7 +547,6 @@ public class OnlineActivity extends CommonActivity { } return true; case R.id.article_link_copy: - Log.d(TAG, "article_link_copy"); if (ap != null && ap.getSelectedArticle() != null) { copyToClipboard(ap.getSelectedArticle().link); } @@ -1362,36 +1310,12 @@ public class OnlineActivity extends CommonActivity { return tmp.replaceAll(",$", ""); } - public void shareText(String text) { - - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, text); - - startActivity(Intent.createChooser(intent, text)); - } - public void shareArticle(Article article) { if (article != null) { - - Intent intent = getShareIntent(article); - - startActivity(Intent.createChooser(intent, - getString(R.string.share_article))); + shareText(article.link, article.title); } } - - protected Intent getShareIntent(Article article) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, article.title); - intent.putExtra(Intent.EXTRA_TEXT, article.link); - - return intent; - } - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (m_prefs.getBoolean("use_volume_keys", false)) { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java index 9e030748..61f914bd 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesActivity.java @@ -23,6 +23,7 @@ public class PreferencesActivity extends CommonActivity { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().hide(); android.app.FragmentTransaction ft = getFragmentManager().beginTransaction(); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java index 4b89905b..348f36c9 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/VideoPlayerActivity.java @@ -2,21 +2,33 @@ package org.fox.ttrss; import android.content.Intent;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.WindowCompat;
import android.support.v7.widget.Toolbar;
+import android.transition.Explode;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Display;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.MediaController;
+import android.widget.PopupMenu;
+
+import com.nostra13.universalimageloader.core.ImageLoader;
+import com.nostra13.universalimageloader.core.assist.FailReason;
+import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import java.io.IOException;
@@ -27,6 +39,7 @@ public class VideoPlayerActivity extends CommonActivity { private String m_streamUri;
private MediaPlayer mediaPlayer;
private SurfaceView surfaceView;
+ private String m_coverUri;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -40,9 +53,7 @@ public class VideoPlayerActivity extends CommonActivity { setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
-
- if (!isPortrait())
- getSupportActionBar().hide();
+ getSupportActionBar().hide();
surfaceView = (SurfaceView) findViewById(R.id.video_player);
registerForContextMenu(surfaceView);
@@ -51,10 +62,66 @@ public class VideoPlayerActivity extends CommonActivity { if (savedInstanceState == null) {
m_streamUri = getIntent().getStringExtra("streamUri");
+ m_coverUri = getIntent().getStringExtra("coverSrc");
} else {
m_streamUri = savedInstanceState.getString("streamUri");
+ m_coverUri = savedInstanceState.getString("coverSrc");
}
+ ImageView coverView = (ImageView)findViewById(R.id.video_player_cover);
+
+ if (m_coverUri != null) {
+ ActivityCompat.postponeEnterTransition(VideoPlayerActivity.this);
+
+ ViewCompat.setTransitionName(coverView, "gallery:" + m_coverUri);
+
+ ImageLoader imageLoader = ImageLoader.getInstance();
+ imageLoader.displayImage(m_coverUri, coverView, new ImageLoadingListener() {
+ @Override
+ public void onLoadingStarted(String s, View view) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingFailed(String s, View view, FailReason failReason) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingComplete(String s, View view, Bitmap bitmap) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+
+ @Override
+ public void onLoadingCancelled(String s, View view) {
+ ActivityCompat.startPostponedEnterTransition(VideoPlayerActivity.this);
+ }
+ });
+
+
+ } else {
+ coverView.setVisibility(View.GONE);
+ }
+
+ findViewById(R.id.video_player_overflow).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ PopupMenu popup = new PopupMenu(VideoPlayerActivity.this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.activity_video_player, popup.getMenu());
+
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return onVideoMenuItemSelected(item);
+ }
+ });
+
+ popup.show();
+
+ }
+ });
+
final MediaController mediaController = new MediaController(this);
surfaceView.setOnClickListener(new View.OnClickListener() {
@@ -149,17 +216,22 @@ public class VideoPlayerActivity extends CommonActivity { e.printStackTrace();
}
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mp) {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+
+ View loadingBar = findViewById(R.id.video_loading);
+ if (loadingBar != null)
+ loadingBar.setVisibility(View.GONE);
- View loadingBar = findViewById(R.id.video_loading);
- if (loadingBar != null) loadingBar.setVisibility(View.GONE);
+ View coverView = findViewById(R.id.video_player_cover);
+ if (coverView != null)
+ coverView.setVisibility(View.GONE);
- resizeSurface();
- mp.setLooping(true);
- mp.start();
- }
- }
+ resizeSurface();
+ mp.setLooping(true);
+ mp.start();
+ }
+ }
);
}
@@ -176,17 +248,13 @@ public class VideoPlayerActivity extends CommonActivity { });
- mediaController.setAnchorView(surfaceView);
+ mediaController.setAnchorView(surfaceView);
+
}
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- if (!isPortrait())
- getSupportActionBar().hide();
- else
- getSupportActionBar().show();
-
resizeSurface();
}
@@ -195,13 +263,7 @@ public class VideoPlayerActivity extends CommonActivity { super.onSaveInstanceState(out);
out.putString("streamUri", m_streamUri);
- }
-
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.activity_video_player, menu);
- return true;
+ out.putString("coverSrc", m_coverUri);
}
@@ -216,16 +278,15 @@ public class VideoPlayerActivity extends CommonActivity { @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return onContextItemSelected(item); // this is really bad :()
+ public boolean onContextItemSelected(MenuItem item) {
+ if (!onVideoMenuItemSelected(item))
+ return super.onContextItemSelected(item);
+ else
+ return true;
}
- @Override
- public boolean onContextItemSelected(android.view.MenuItem item) {
+ public boolean onVideoMenuItemSelected(android.view.MenuItem item) {
switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
case R.id.article_vid_open:
if (m_streamUri != null) {
try {
@@ -236,20 +297,19 @@ public class VideoPlayerActivity extends CommonActivity { }
}
return true;
+ case R.id.article_vid_copy:
+ if (m_streamUri != null) {
+ copyToClipboard(m_streamUri);
+ }
+ return true;
case R.id.article_vid_share:
if (m_streamUri != null) {
- Intent intent = new Intent(Intent.ACTION_SEND);
-
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri);
- intent.putExtra(Intent.EXTRA_TEXT, m_streamUri);
-
- startActivity(Intent.createChooser(intent, m_streamUri));
+ shareText(m_streamUri);
}
return true;
default:
- Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
- return super.onContextItemSelected(item);
+ Log.d(TAG, "onVideoMenuItemSelected, unhandled id=" + item.getItemId());
+ return false;
}
}
@@ -278,14 +338,13 @@ public class VideoPlayerActivity extends CommonActivity { surfaceView.setLayoutParams(lp);
}
- @Override
+ /*@Override
public void onPause() {
super.onPause();
if (isFinishing()) {
- overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
- }
- }
+ }
+ }*/
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java index fc26e38e..a120f761 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/YoutubePlayerActivity.java @@ -112,13 +112,7 @@ public class YoutubePlayerActivity extends CommonActivity implements YouTubePlay return true; case R.id.article_vid_share: if (m_streamUri != null) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, m_streamUri); - intent.putExtra(Intent.EXTRA_TEXT, m_streamUri); - - startActivity(Intent.createChooser(intent, m_streamUri)); + shareText(m_streamUri); } return true; default: diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java index 4575dd22..762d85d2 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineActivity.java @@ -97,13 +97,7 @@ public class OfflineActivity extends CommonActivity { return true; case R.id.article_img_share: if (getLastContentImageHitTestUrl() != null) { - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("image/png"); - intent.putExtra(Intent.EXTRA_SUBJECT, getLastContentImageHitTestUrl()); - intent.putExtra(Intent.EXTRA_TEXT, getLastContentImageHitTestUrl()); - - startActivity(Intent.createChooser(intent, getLastContentImageHitTestUrl())); + shareText(getLastContentImageHitTestUrl()); } return true; case R.id.article_img_view_caption: @@ -117,39 +111,8 @@ public class OfflineActivity extends CommonActivity { content = article.getString(article.getColumnIndex("content")); article.close(); } - - // Android doesn't give us an easy way to access title tags; - // we'll use Jsoup on the body text to grab the title text - // from the first image tag with this url. This will show - // the wrong text if an image is used multiple times. - Document doc = Jsoup.parse(content); - Elements es = doc.getElementsByAttributeValue("src", getLastContentImageHitTestUrl()); - if (es.size() > 0){ - if (es.get(0).hasAttr("title")){ - Dialog dia = new Dialog(this); - if (es.get(0).hasAttr("alt")){ - dia.setTitle(es.get(0).attr("alt")); - } else { - dia.setTitle(es.get(0).attr("title")); - } - TextView titleText = new TextView(this); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - titleText.setPaddingRelative(24, 24, 24, 24); - } else { - titleText.setPadding(24, 24, 24, 24); - } - - titleText.setTextSize(16); - titleText.setText(es.get(0).attr("title")); - dia.setContentView(titleText); - dia.show(); - } else { - toast(R.string.no_caption_to_display); - } - } else { - toast(R.string.no_caption_to_display); - } + + displayImageCaption(getLastContentImageHitTestUrl(), content); } return true; default: @@ -697,14 +660,8 @@ public class OfflineActivity extends CommonActivity { if (article != null) { String title = article.getString(article.getColumnIndex("title")); String link = article.getString(article.getColumnIndex("link")); - - Intent intent = new Intent(Intent.ACTION_SEND); - - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, title); - intent.putExtra(Intent.EXTRA_TEXT, link); - - return intent; + + return getShareIntent(link, title); } else { return null; } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java index d71d38b6..9c7974ea 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineArticleFragment.java @@ -2,15 +2,14 @@ package org.fox.ttrss.offline; import android.annotation.SuppressLint; import android.app.Activity; -import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; +import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.support.v4.app.Fragment; -import android.support.v4.widget.NestedScrollView; import android.support.v7.app.ActionBar; import android.util.Log; import android.util.TypedValue; @@ -31,9 +30,10 @@ import android.widget.TextView; import com.shamanland.fab.ShowHideOnScroll; +import org.fox.ttrss.CommonActivity; import org.fox.ttrss.R; import org.fox.ttrss.util.ImageCacheService; -import org.fox.ttrss.util.NoChildFocusScrollView; +import org.fox.ttrss.util.NotifyingScrollView; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; @@ -136,25 +136,25 @@ public class OfflineArticleFragment extends Fragment { if (m_cursor.isFirst()) { final String link = m_cursor.getString(m_cursor.getColumnIndex("link")); - NoChildFocusScrollView scrollView = (NoChildFocusScrollView) view.findViewById(R.id.article_scrollview); + NotifyingScrollView scrollView = (NotifyingScrollView) view.findViewById(R.id.article_scrollview); View fab = view.findViewById(R.id.article_fab); if (scrollView != null && m_activity.isSmallScreen()) { view.findViewById(R.id.article_heading_spacer).setVisibility(View.VISIBLE); - scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { - @Override - public void onScrollChange(NestedScrollView who, int l, int t, int oldl, int oldt) { - ActionBar ab = m_activity.getSupportActionBar(); + scrollView.setOnScrollChangedListener(new NotifyingScrollView.OnScrollChangedListener() { + @Override + public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) { + ActionBar ab = m_activity.getSupportActionBar(); - if (t >= oldt && t >= ab.getHeight()) { - ab.hide(); - } else if (t <= ab.getHeight() || oldt - t >= 10) { - ab.show(); - } + if (t >= oldt && t >= ab.getHeight()) { + ab.hide(); + } else if (t <= ab.getHeight() || oldt - t >= 10) { + ab.show(); + } - } - }); + } + }); } if (scrollView != null && fab != null) { @@ -199,23 +199,18 @@ public class OfflineArticleFragment extends Fragment { title.setText(titleStr); //title.setPaintFlags(title.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); - title.setOnClickListener(new OnClickListener() { + title.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { - URL url = new URL(link.trim()); - String uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), - url.getPort(), url.getPath(), url.getQuery(), url.getRef()).toString(); - - m_activity.openUri(Uri.parse(uri)); + m_activity.openUri(Uri.parse(link)); } catch (Exception e) { e.printStackTrace(); m_activity.toast(R.string.error_other_error); } } }); - - registerForContextMenu(title); + } ImageView share = (ImageView)view.findViewById(R.id.share); @@ -245,6 +240,9 @@ public class OfflineArticleFragment extends Fragment { final WebView web = (WebView)view.findViewById(R.id.article_content); if (web != null) { + if (CommonActivity.THEME_DARK.equals(m_prefs.getString("theme", CommonActivity.THEME_DEFAULT))) { + web.setBackgroundColor(Color.BLACK); + } web.setWebViewClient(new WebViewClient() { @Override @@ -391,22 +389,6 @@ public class OfflineArticleFragment extends Fragment { dv.setText(df.format(d)); } - TextView author = (TextView)view.findViewById(R.id.author); - - boolean hasAuthor = false; - - if (author != null) { - author.setTextSize(TypedValue.COMPLEX_UNIT_SP, articleSmallFontSize); - - int authorIndex = m_cursor.getColumnIndex("author"); - if (authorIndex >= 0) - author.setText(m_cursor.getString(authorIndex)); - else - author.setVisibility(View.GONE); - - hasAuthor = true; - } - TextView tagv = (TextView)view.findViewById(R.id.tags); if (tagv != null) { @@ -419,8 +401,12 @@ public class OfflineArticleFragment extends Fragment { int authorIndex = m_cursor.getColumnIndex("author"); - if (!hasAuthor && authorIndex >= 0) { - fTitle += " (" + getString(R.string.author_formatted, m_cursor.getString(authorIndex)) + ")"; + if (authorIndex >= 0) { + String authorStr = m_cursor.getString(authorIndex); + + if (authorStr != null && authorStr.length() > 0) { + fTitle += " (" + getString(R.string.author_formatted, m_cursor.getString(authorIndex)) + ")"; + } } tagv.setText(fTitle); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java index 6031d730..4b484566 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineDetailActivity.java @@ -201,7 +201,12 @@ public class OfflineDetailActivity extends OfflineActivity implements OfflineHea @Override public void onBackPressed() { - super.onBackPressed(); + try { + super.onBackPressed(); + } catch (IllegalStateException e) { + // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState + e.printStackTrace(); + } } @Override diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java index 90bcd93e..f1827d21 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineFeedCategoriesFragment.java @@ -47,7 +47,7 @@ public class OfflineFeedCategoriesFragment extends BaseFeedlistFragment implemen menu.findItem(R.id.create_shortcut).setEnabled(false); AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; - Cursor cursor = (Cursor)getCatAtPosition(info.position); + Cursor cursor = getCatAtPosition(info.position); if (cursor != null) menu.setHeaderTitle(cursor.getString(cursor.getColumnIndex("title"))); @@ -57,7 +57,7 @@ public class OfflineFeedCategoriesFragment extends BaseFeedlistFragment implemen } public Cursor createCursor() { - String unreadOnly = BaseColumns._ID + "> 0 AND " + (m_activity.getUnreadOnly() ? "unread > 0" : "1"); + String unreadOnly = BaseColumns._ID + ">= 0 AND " + (m_activity.getUnreadOnly() ? "unread > 0" : "1"); String order = m_prefs.getBoolean("sort_feeds_by_unread", false) ? "unread DESC, title" : "title"; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java index 4fe21f93..b2ce09a1 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java @@ -7,6 +7,7 @@ import android.content.res.Resources.Theme; import android.database.Cursor; import android.database.sqlite.SQLiteStatement; import android.graphics.Paint; +import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.BaseColumns; @@ -20,6 +21,7 @@ import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Display; import android.view.LayoutInflater; +import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; @@ -32,6 +34,7 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.ListView; +import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.TextView; @@ -53,7 +56,7 @@ import java.util.Date; import java.util.TimeZone; public class OfflineHeadlinesFragment extends Fragment implements OnItemClickListener, AbsListView.OnScrollListener { - public static enum ArticlesSelection { ALL, NONE, UNREAD } + public enum ArticlesSelection { ALL, NONE, UNREAD } private final String TAG = this.getClass().getSimpleName(); @@ -101,143 +104,91 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis } @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + + getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu); + + menu.findItem(R.id.set_labels).setVisible(false); + menu.findItem(R.id.article_set_note).setVisible(false); + menu.findItem(R.id.headlines_article_unread).setVisible(false); // TODO: implement + + super.onCreateContextMenu(menu, v, menuInfo); + } + + @Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item .getMenuInfo(); - + + int articleId = getArticleIdAtPosition(info.position); + + if (!onArticleMenuItemSelected(item, articleId)) + return super.onContextItemSelected(item); + else + return true; + } + + private boolean onArticleMenuItemSelected(MenuItem item, int articleId) { switch (item.getItemId()) { - case R.id.article_link_copy: - if (true) { - int articleId = getArticleIdAtPosition(info.position); - - Cursor article = m_activity.getArticleById(articleId); - - if (article != null) { - m_activity.copyToClipboard(article.getString(article.getColumnIndex("link"))); - article.close(); + case R.id.headlines_article_link_copy: + if (true) { + Cursor article = m_activity.getArticleById(articleId); + + if (article != null) { + m_activity.copyToClipboard(article.getString(article.getColumnIndex("link"))); + article.close(); + } } - } - return true; - case R.id.selection_toggle_marked: - if (getSelectedArticleCount() > 0) { - SQLiteStatement stmt = m_activity.getDatabase() - .compileStatement( - "UPDATE articles SET modified = 1, marked = NOT marked WHERE selected = 1"); - stmt.execute(); - stmt.close(); - } else { - int articleId = getArticleIdAtPosition(info.position); - - SQLiteStatement stmt = m_activity.getDatabase().compileStatement( - "UPDATE articles SET modified = 1, marked = NOT marked WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - } - refresh(); - return true; - case R.id.selection_toggle_published: - if (getSelectedArticleCount() > 0) { - SQLiteStatement stmt = m_activity.getDatabase() - .compileStatement( - "UPDATE articles SET modified = 1, published = NOT published WHERE selected = 1"); - stmt.execute(); - stmt.close(); - } else { - int articleId = getArticleIdAtPosition(info.position); - - SQLiteStatement stmt = m_activity.getDatabase().compileStatement( - "UPDATE articles SET modified = 1, published = NOT published WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - } - refresh(); - return true; - case R.id.selection_toggle_unread: - if (getSelectedArticleCount() > 0) { - SQLiteStatement stmt = m_activity.getDatabase() - .compileStatement( - "UPDATE articles SET modified = 1, unread = NOT unread WHERE selected = 1"); - stmt.execute(); - stmt.close(); - } else { - int articleId = getArticleIdAtPosition(info.position); - - SQLiteStatement stmt = m_activity.getDatabase().compileStatement( - "UPDATE articles SET modified = 1, unread = NOT unread WHERE " - + BaseColumns._ID + " = ?"); - stmt.bindLong(1, articleId); - stmt.execute(); - stmt.close(); - } - refresh(); - return true; - case R.id.headlines_share_article: - if (true) { - int articleId = getArticleIdAtPosition(info.position); + return true; + case R.id.headlines_article_link_open: + if (true) { + Cursor article = m_activity.getArticleById(articleId); + + if (article != null) { + m_activity.openUri(Uri.parse(article.getString(article.getColumnIndex("link")))); + + // TODO: mark article as read, set modified = 1, refresh + + article.close(); + } + } + return true; + case R.id.headlines_share_article: m_activity.shareArticle(articleId); - } - return true; - case R.id.catchup_above: - if (true) { - int articleId = getArticleIdAtPosition(info.position); - - SQLiteStatement stmt = null; - - String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">"; - - if (m_feedIsCat) { - stmt = m_activity.getDatabase().compileStatement( - "UPDATE articles SET modified = 1, unread = 0 WHERE " + - "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + - "AND unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"); - } else { - stmt = m_activity.getDatabase().compileStatement( - "UPDATE articles SET modified = 1, unread = 0 WHERE " + - "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + - "AND unread = 1 AND feed_id = ?"); + return true; + case R.id.catchup_above: + if (true) { + SQLiteStatement stmt = null; + + String updatedOperator = (m_prefs.getBoolean("offline_oldest_first", false)) ? "<" : ">"; + + if (m_feedIsCat) { + stmt = m_activity.getDatabase().compileStatement( + "UPDATE articles SET modified = 1, unread = 0 WHERE " + + "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + + "AND unread = 1 AND feed_id IN (SELECT "+BaseColumns._ID+" FROM feeds WHERE cat_id = ?)"); + } else { + stmt = m_activity.getDatabase().compileStatement( + "UPDATE articles SET modified = 1, unread = 0 WHERE " + + "updated "+updatedOperator+" (SELECT updated FROM articles WHERE " + BaseColumns._ID + " = ?) " + + "AND unread = 1 AND feed_id = ?"); + } + + stmt.bindLong(1, articleId); + stmt.bindLong(2, m_feedId); + stmt.execute(); + stmt.close(); } - - stmt.bindLong(1, articleId); - stmt.bindLong(2, m_feedId); - stmt.execute(); - stmt.close(); - } - refresh(); - return true; - default: - Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); - return super.onContextItemSelected(item); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, - ContextMenuInfo menuInfo) { - - getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu); - - if (getSelectedArticleCount() > 0) { - menu.setHeaderTitle(R.string.headline_context_multiple); - menu.setGroupVisible(R.id.menu_group_single_article, false); - } else { - AdapterContextMenuInfo info = (AdapterContextMenuInfo)menuInfo; - Cursor c = getArticleAtPosition(info.position); - menu.setHeaderTitle(c.getString(c.getColumnIndex("title"))); - //c.close(); - menu.setGroupVisible(R.id.menu_group_single_article, true); - - menu.findItem(R.id.set_labels).setVisible(false); - menu.findItem(R.id.article_set_note).setVisible(false); + refresh(); + return true; + default: + Log.d(TAG, "onArticleMenuItemSelected, unhandled id=" + item.getItemId()); + return false; } - - super.onCreateContextMenu(menu, v, menuInfo); - + } - + @Override public void onResume() { super.onResume(); @@ -462,6 +413,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis public ImageView textImage; public ImageView textChecked; public ImageView flavorVideoKindView; + public View flavorImageOverflow; public View headlineHeader; } @@ -583,6 +535,7 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis holder.textChecked = (ImageView) v.findViewById(R.id.text_checked); holder.flavorVideoKindView = (ImageView) v.findViewById(R.id.flavor_video_kind); holder.headlineHeader = v.findViewById(R.id.headline_header); + holder.flavorImageOverflow = v.findViewById(R.id.flavor_image_overflow); v.setTag(holder); @@ -770,8 +723,26 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis holder.flavorImageLoadingBar.setVisibility(View.GONE); holder.flavorImageView.setVisibility(View.GONE); holder.flavorVideoKindView.setVisibility(View.GONE); + holder.flavorImageOverflow.setVisibility(View.GONE); holder.headlineHeader.setBackgroundDrawable(null); + + // this is needed if our flavor image goes behind base listview element + holder.headlineHeader.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + m_listener.onArticleSelected(articleId); + } + }); + + holder.headlineHeader.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + m_activity.openContextMenu(v); + + return true; + } + }); } if (holder.menuButtonView != null) { @@ -781,7 +752,23 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis holder.menuButtonView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - getActivity().openContextMenu(v); + + PopupMenu popup = new PopupMenu(getActivity(), v); + MenuInflater inflater = popup.getMenuInflater(); + inflater.inflate(R.menu.context_headlines, popup.getMenu()); + + popup.getMenu().findItem(R.id.set_labels).setVisible(false); + popup.getMenu().findItem(R.id.article_set_note).setVisible(false); + popup.getMenu().findItem(R.id.headlines_article_unread).setVisible(false); // TODO: implement + + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + return onArticleMenuItemSelected(item, articleId); + } + }); + + popup.show(); } }); } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java index 1823d133..ed146845 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineMasterActivity.java @@ -275,7 +275,12 @@ public class OfflineMasterActivity extends OfflineActivity implements OfflineHea m_drawerLayout.openDrawer(Gravity.START); } else { - super.onBackPressed(); + try { + super.onBackPressed(); + } catch (IllegalStateException e) { + // java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState + e.printStackTrace(); + } } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java index f1eafe8f..bffcb8da 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java @@ -2,7 +2,6 @@ package org.fox.ttrss.types; import android.os.Parcel; import android.os.Parcelable; -import android.util.Log; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; @@ -39,16 +38,13 @@ public class Article implements Parcelable { public boolean selected; /* not serialized */ - public Document articleDoc; - public Element flavorImage; + transient public Document articleDoc; + transient public Element flavorImage; - public String flavorImageUri; - public String flavorStreamUri; - public String youtubeVid; - - //public int flavorImageCount; - - public List<Element> mediaList = new ArrayList<>(); + transient public String flavorImageUri; + transient public String flavorStreamUri; + transient public String youtubeVid; + transient public List<Element> mediaList = new ArrayList<>(); public Article(Parcel in) { readFromParcel(in); @@ -58,6 +54,14 @@ public class Article implements Parcelable { } + public void cleanupExcerpt() { + if (excerpt != null) { + excerpt = excerpt.replace("…", "…"); + excerpt = excerpt.replace("]]>", ""); + excerpt = Jsoup.parse(excerpt).text(); + } + } + public void collectMediaInfo() { articleDoc = Jsoup.parse(content); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java index bf9d48d8..ff433074 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/EnlargingImageView.java @@ -34,7 +34,7 @@ import android.view.View; * @author Tomáš Procházka <<a href="mailto:[email protected]">[email protected]</a>> * @version $Revision: 0$ ($Date: 6.6.2011 18:16:52$) */ -public class EnlargingImageView extends android.widget.ImageView { +public class EnlargingImageView extends ForegroundImageView { private int mDrawableWidth; private int mDrawableHeight; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java new file mode 100644 index 00000000..f02158e9 --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ForegroundImageView.java @@ -0,0 +1,121 @@ +package org.fox.ttrss.util; + +// https://gist.github.com/JakeWharton/0a251d67649305d84e8a + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.AttributeSet; +import android.widget.ImageView; + +import org.fox.ttrss.R; + +public class ForegroundImageView extends ImageView { + private Drawable foreground; + + public ForegroundImageView(Context context) { + this(context, null); + } + + public ForegroundImageView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public ForegroundImageView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ForegroundImageView); + Drawable foreground = a.getDrawable(R.styleable.ForegroundImageView_android_foreground); + if (foreground != null) { + setForeground(foreground); + } + a.recycle(); + } + + /** + * Supply a drawable resource that is to be rendered on top of all of the child + * views in the frame layout. + * + * @param drawableResId The drawable resource to be drawn on top of the children. + */ + public void setForegroundResource(int drawableResId) { + setForeground(getContext().getResources().getDrawable(drawableResId)); + } + + /** + * Supply a Drawable that is to be rendered on top of all of the child + * views in the frame layout. + * + * @param drawable The Drawable to be drawn on top of the children. + */ + public void setForeground(Drawable drawable) { + if (foreground == drawable) { + return; + } + if (foreground != null) { + foreground.setCallback(null); + unscheduleDrawable(foreground); + } + + foreground = drawable; + + if (drawable != null) { + drawable.setCallback(this); + if (drawable.isStateful()) { + drawable.setState(getDrawableState()); + } + } + requestLayout(); + invalidate(); + } + + @Override protected boolean verifyDrawable(Drawable who) { + return super.verifyDrawable(who) || who == foreground; + } + + @Override public void jumpDrawablesToCurrentState() { + super.jumpDrawablesToCurrentState(); + if (foreground != null) foreground.jumpToCurrentState(); + } + + @Override protected void drawableStateChanged() { + super.drawableStateChanged(); + if (foreground != null && foreground.isStateful()) { + foreground.setState(getDrawableState()); + } + } + + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (foreground != null) { + foreground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); + invalidate(); + } + } + + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (foreground != null) { + foreground.setBounds(0, 0, w, h); + invalidate(); + } + } + + @Override public void draw(Canvas canvas) { + super.draw(canvas); + + if (foreground != null) { + foreground.draw(canvas); + } + } + + @Override public void drawableHotspotChanged(float x, float y) { + super.drawableHotspotChanged(x, y); + + if (foreground != null && android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + foreground.setHotspot(x, y); + } + } +}
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java index 8581addc..54df9da4 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesRequest.java @@ -32,6 +32,7 @@ public class HeadlinesRequest extends ApiRequest { protected boolean m_firstIdChanged = false; protected int m_firstId = 0; + protected int m_amountLoaded = 0; public HeadlinesRequest(Context context, OnlineActivity activity, final Feed feed, ArticleList articles) { super(context); @@ -86,22 +87,25 @@ public class HeadlinesRequest extends ApiRequest { m_articles.remove(0); } - if (m_articles.get(m_articles.size()-1).id == HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE) { + /*if (m_articles.get(m_articles.size()-1).id == HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE) { m_articles.remove(m_articles.size()-1); // remove previous placeholder - } + }*/ } - + + m_amountLoaded = articles.size(); + for (Article f : articles) if (!m_articles.containsId(f.id)) { f.collectMediaInfo(); + f.cleanupExcerpt(); m_articles.add(f); } - if (articles.size() == HEADLINES_REQUEST_SIZE) { + /*if (articles.size() == HEADLINES_REQUEST_SIZE) { Article placeholder = new Article(HeadlinesFragment.ARTICLE_SPECIAL_LOADMORE); m_articles.add(placeholder); - } + }*/ /* if (m_articles.size() == 0) m_activity.setLoadingStatus(R.string.no_headlines_to_display, false); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java index af0454fa..5e5c8c48 100755..100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NoChildFocusScrollView.java @@ -1,13 +1,12 @@ package org.fox.ttrss.util; import android.content.Context; -import android.support.v4.widget.NestedScrollView; import android.util.AttributeSet; import android.view.View; import android.webkit.WebView; import android.widget.ScrollView; -public class NoChildFocusScrollView extends NestedScrollView { +public class NoChildFocusScrollView extends NotifyingScrollView { public NoChildFocusScrollView(Context context) { super(context); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java new file mode 100644 index 00000000..e128856f --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/NotifyingScrollView.java @@ -0,0 +1,45 @@ +package org.fox.ttrss.util; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ScrollView; + +/** + * @author Cyril Mottier + */ +public class NotifyingScrollView extends ScrollView { + + /** + * @author Cyril Mottier + */ + public interface OnScrollChangedListener { + void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt); + } + + private OnScrollChangedListener mOnScrollChangedListener; + + public NotifyingScrollView(Context context) { + super(context); + } + + public NotifyingScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NotifyingScrollView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onScrollChanged(int l, int t, int oldl, int oldt) { + super.onScrollChanged(l, t, oldl, oldt); + if (mOnScrollChangedListener != null) { + mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt); + } + } + + public void setOnScrollChangedListener(OnScrollChangedListener listener) { + mOnScrollChangedListener = listener; + } + +}
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png Binary files differdeleted file mode 100644 index efacbcfa..00000000 --- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_bg_pressed.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png Binary files differdeleted file mode 100644 index 02ee4401..00000000 --- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png b/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png Binary files differdeleted file mode 100644 index ccc01774..00000000 --- a/org.fox.ttrss/src/main/res/drawable-hdpi/appwidget_dark_bg_focused.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png Binary files differdeleted file mode 100644 index 97a3ba09..00000000 --- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_bg_pressed.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png Binary files differdeleted file mode 100644 index 7ccb762b..00000000 --- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png b/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png Binary files differdeleted file mode 100644 index da9289e6..00000000 --- a/org.fox.ttrss/src/main/res/drawable-xhdpi/appwidget_dark_bg_focused.9.png +++ /dev/null diff --git a/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml b/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml deleted file mode 100644 index 7cfc9d2b..00000000 --- a/org.fox.ttrss/src/main/res/drawable/appwidget_dark_bg_clickable.xml +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - Copyright 2011 Google Inc. - - 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. - --> - -<selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@drawable/appwidget_bg_pressed" android:state_pressed="true" /> - <item android:drawable="@drawable/appwidget_dark_bg_focused" - android:state_focused="true" - android:state_enabled="true" - android:state_window_focused="true" /> - <item android:drawable="@drawable/appwidget_dark_bg" /> -</selector> diff --git a/org.fox.ttrss/src/main/res/layout/activity_preferences.xml b/org.fox.ttrss/src/main/res/layout/activity_preferences.xml index 431b7da4..bd37a3ce 100644 --- a/org.fox.ttrss/src/main/res/layout/activity_preferences.xml +++ b/org.fox.ttrss/src/main/res/layout/activity_preferences.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:transitionName="SETTINGS_REVEAL" android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="match_parent"> diff --git a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml index 2f81860c..1fbeb587 100644 --- a/org.fox.ttrss/src/main/res/layout/activity_video_player.xml +++ b/org.fox.ttrss/src/main/res/layout/activity_video_player.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
- android:background="?android:colorBackground"
+ android:background="@android:color/black"
tools:context="org.fox.ttrss.VideoPlayerActivity">
<FrameLayout
@@ -14,8 +14,12 @@ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:id="@+id/video_player"
- android:transitionName="TRANSITION:ARTICLE_VIDEO_PLAYER" />
+ android:id="@+id/video_player" />
+
+ <ImageView
+ android:id="@+id/video_player_cover"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
<ProgressBar
android:layout_width="wrap_content"
@@ -23,6 +27,18 @@ android:id="@+id/video_loading"
android:layout_gravity="center"
android:indeterminate="true" />
+
+ <ImageView
+ android:id="@+id/video_player_overflow"
+ android:clickable="true"
+ android:layout_width="wrap_content"
+ android:layout_height="26dp"
+ android:layout_weight="0"
+ android:background="@drawable/ripple"
+ android:src="@drawable/ic_dots_vertical"
+ android:layout_gravity="top|right"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="@dimen/activity_vertical_margin" />
</FrameLayout>
<include layout="@layout/toolbar" android:id="@+id/toolbar" />
diff --git a/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml index afd37335..3d2c9c9a 100644 --- a/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml +++ b/org.fox.ttrss/src/main/res/layout/activity_youtube_player.xml @@ -2,7 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" - android:background="?android:colorBackground" + android:background="@android:color/black" tools:context="org.fox.ttrss.VideoPlayerActivity"> <FrameLayout diff --git a/org.fox.ttrss/src/main/res/layout/article_images_image.xml b/org.fox.ttrss/src/main/res/layout/article_images_image.xml index 2b6d5856..37f44c38 100644 --- a/org.fox.ttrss/src/main/res/layout/article_images_image.xml +++ b/org.fox.ttrss/src/main/res/layout/article_images_image.xml @@ -26,4 +26,16 @@ android:layout_gravity="center" android:scaleType="fitCenter" /> + <ImageView + android:id="@+id/flavor_image_overflow" + android:clickable="true" + android:layout_width="wrap_content" + android:layout_height="26dp" + android:layout_weight="0" + android:background="@drawable/ripple" + android:src="@drawable/ic_dots_vertical" + android:layout_gravity="top|right" + android:layout_marginRight="8dp" + android:layout_marginTop="@dimen/activity_vertical_margin" /> + </FrameLayout>
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml b/org.fox.ttrss/src/main/res/layout/article_images_pager.xml index 8744af67..eaaca37a 100755 --- a/org.fox.ttrss/src/main/res/layout/article_images_pager.xml +++ b/org.fox.ttrss/src/main/res/layout/article_images_pager.xml @@ -3,7 +3,7 @@ android:id="@+id/article_images" android:layout_width="fill_parent" android:animateLayoutChanges="true" - android:background="?headlinesBackground" + android:background="@android:color/black" android:layout_height="fill_parent"> <org.fox.ttrss.ArticleImagesPager diff --git a/org.fox.ttrss/src/main/res/layout/drawer_header.xml b/org.fox.ttrss/src/main/res/layout/drawer_header.xml index d2ea0660..d39cdad0 100755 --- a/org.fox.ttrss/src/main/res/layout/drawer_header.xml +++ b/org.fox.ttrss/src/main/res/layout/drawer_header.xml @@ -28,6 +28,7 @@ android:clickable="true" android:layout_marginBottom="16dp" android:layout_marginRight="12dp" + android:transitionName="SETTINGS_REVEAL" android:background="@drawable/ripple" /> <LinearLayout diff --git a/org.fox.ttrss/src/main/res/layout/fragment_article.xml b/org.fox.ttrss/src/main/res/layout/fragment_article.xml index 04fd22b2..3db6adc3 100644 --- a/org.fox.ttrss/src/main/res/layout/fragment_article.xml +++ b/org.fox.ttrss/src/main/res/layout/fragment_article.xml @@ -14,6 +14,7 @@ <org.fox.ttrss.util.NoChildFocusScrollView android:id="@+id/article_scrollview" + android:scrollbars="vertical|horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="false" > @@ -137,6 +138,7 @@ <org.fox.ttrss.util.LessBrokenWebView android:layout_margin="16dp" android:id="@+id/article_content" + android:scrollbars="none" android:layout_width="match_parent" android:layout_height="wrap_content" /> diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row.xml b/org.fox.ttrss/src/main/res/layout/headlines_row.xml index f06e1d40..87734749 100755 --- a/org.fox.ttrss/src/main/res/layout/headlines_row.xml +++ b/org.fox.ttrss/src/main/res/layout/headlines_row.xml @@ -44,6 +44,7 @@ <org.fox.ttrss.util.EnlargingImageView android:id="@+id/flavor_image" + android:foreground="@drawable/ripple" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" @@ -57,6 +58,7 @@ <RelativeLayout android:id="@+id/headline_header" + android:clickable="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?headlineHeaderBackground" @@ -64,6 +66,7 @@ <TextView android:id="@+id/title" + android:background="@drawable/ripple" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_span="2" @@ -120,15 +123,28 @@ android:id="@+id/flavor_video_kind" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="bottom|right" + android:layout_gravity="left|bottom" android:scaleType="fitXY" android:src="@drawable/ic_play_circle" android:visibility="visible" android:layout_below="@+id/headline_header" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" - android:layout_marginRight="8dp" - android:layout_marginBottom="8dp" /> + android:layout_marginBottom="8dp" + android:layout_marginLeft="8dp" /> + + <ImageView + android:id="@+id/flavor_image_overflow" + android:clickable="true" + android:layout_width="wrap_content" + android:layout_height="24dp" + android:layout_weight="0" + android:background="@drawable/ripple" + android:paddingLeft="4dp" + android:paddingRight="4dp" + android:src="@drawable/ic_dots_vertical" + android:layout_gravity="bottom|right" + android:layout_marginBottom="10dp" /> </FrameLayout> </TableRow> diff --git a/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml b/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml index cca55565..f9347788 100755 --- a/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml +++ b/org.fox.ttrss/src/main/res/layout/headlines_row_unread.xml @@ -45,6 +45,7 @@ <org.fox.ttrss.util.EnlargingImageView android:id="@+id/flavor_image" + android:foreground="@drawable/ripple" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" @@ -58,6 +59,7 @@ <RelativeLayout android:id="@+id/headline_header" + android:clickable="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?headlineHeaderBackground" @@ -65,6 +67,7 @@ <TextView android:id="@+id/title" + android:background="@drawable/ripple" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_span="2" @@ -121,16 +124,29 @@ android:id="@+id/flavor_video_kind" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="bottom|right" + android:layout_gravity="bottom|left" android:scaleType="fitXY" android:src="@drawable/ic_play_circle" android:visibility="visible" android:layout_below="@+id/headline_header" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" - android:layout_marginRight="8dp" + android:layout_marginLeft="8dp" android:layout_marginBottom="8dp" /> + <ImageView + android:id="@+id/flavor_image_overflow" + android:clickable="true" + android:layout_width="wrap_content" + android:layout_height="24dp" + android:layout_weight="0" + android:background="@drawable/ripple" + android:paddingLeft="4dp" + android:paddingRight="4dp" + android:src="@drawable/ic_dots_vertical" + android:layout_gravity="bottom|right" + android:layout_marginBottom="10dp" /> + </FrameLayout> </TableRow> diff --git a/org.fox.ttrss/src/main/res/layout/widget_small.xml b/org.fox.ttrss/src/main/res/layout/widget_small.xml index f1a90491..99124a3c 100755 --- a/org.fox.ttrss/src/main/res/layout/widget_small.xml +++ b/org.fox.ttrss/src/main/res/layout/widget_small.xml @@ -5,28 +5,29 @@ android:padding="@dimen/widget_margin" > <LinearLayout - android:background="@drawable/appwidget_dark_bg_clickable" + android:background="@android:color/white" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:padding="8dp" android:orientation="vertical" > <ImageView - android:layout_width="36dp" - android:layout_height="36dp" + android:padding="8dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_horizontal" android:src="@drawable/ic_launcher" /> <TextView + android:padding="4dp" + android:background="#6482af" android:id="@+id/widget_unread_counter" android:layout_weight="0" - android:layout_width="wrap_content" + android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom|center" android:gravity="center_horizontal" android:text="" - android:textAppearance="?android:attr/textAppearanceSmall" android:textColor="@android:color/primary_text_dark" android:textSize="13sp" /> diff --git a/org.fox.ttrss/src/main/res/menu/activity_video_player.xml b/org.fox.ttrss/src/main/res/menu/activity_video_player.xml index 0b5d1ae6..b323d3b7 100644 --- a/org.fox.ttrss/src/main/res/menu/activity_video_player.xml +++ b/org.fox.ttrss/src/main/res/menu/activity_video_player.xml @@ -6,7 +6,12 @@ <item
android:id="@+id/article_vid_open"
app:showAsAction=""
- android:title="@string/video_player_open"/>
+ android:title="@string/open_with"/>
+ <item
+ android:id="@+id/article_vid_copy"
+ app:showAsAction=""
+ android:icon="@drawable/ic_content_copy"
+ android:title="@string/article_link_copy"/>
<item
android:id="@+id/article_vid_share"
android:icon="@drawable/ic_share"
diff --git a/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml b/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml index 52855d14..33b60653 100644 --- a/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml +++ b/org.fox.ttrss/src/main/res/menu/context_article_content_img.xml @@ -3,7 +3,7 @@ <item android:id="@+id/article_img_open" app:showAsAction="" - android:title="@string/article_img_open"/> + android:title="@string/open_with"/> <item android:id="@+id/article_img_copy" app:showAsAction="" diff --git a/org.fox.ttrss/src/main/res/menu/context_headlines.xml b/org.fox.ttrss/src/main/res/menu/context_headlines.xml index fafac872..dffc9e47 100644 --- a/org.fox.ttrss/src/main/res/menu/context_headlines.xml +++ b/org.fox.ttrss/src/main/res/menu/context_headlines.xml @@ -1,42 +1,32 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item - android:id="@+id/selection_toggle_unread" + android:id="@+id/headlines_article_link_open" app:showAsAction="" - android:title="@string/context_selection_toggle_unread"/> + android:title="@string/open_with"/> <item - android:id="@+id/selection_toggle_marked" + android:id="@+id/headlines_share_article" app:showAsAction="" - android:title="@string/context_selection_toggle_marked"/> + android:title="@string/share_article"/> + <item - android:id="@+id/selection_toggle_published" + android:id="@+id/headlines_article_link_copy" app:showAsAction="" - android:title="@string/context_selection_toggle_published"/> - - <group android:id="@+id/menu_group_single_article" > - <item - android:id="@+id/headlines_share_article" - app:showAsAction="" - android:title="@string/share_article"/> - <item - android:id="@+id/headlines_article_link_open" - app:showAsAction="" - android:title="@string/open_article_in_web_browser"/> - <item - android:id="@+id/headlines_article_link_copy" - app:showAsAction="" - android:title="@string/article_link_copy"/> - <item - android:id="@+id/catchup_above" - app:showAsAction="" - android:title="@string/article_mark_read_above"/> - <item - android:id="@+id/set_labels" - android:title="@string/article_set_labels"/> - <item - android:id="@+id/article_set_note" - app:showAsAction="" - android:title="@string/article_set_note"/> - </group> + android:title="@string/article_link_copy"/> + <item + android:id="@+id/catchup_above" + app:showAsAction="" + android:title="@string/article_mark_read_above"/> + <item + android:id="@+id/set_labels" + android:title="@string/article_set_labels"/> + <item + android:id="@+id/article_set_note" + app:showAsAction="" + android:title="@string/article_set_note"/> + <item + android:id="@+id/headlines_article_unread" + app:showAsAction="" + android:title="@string/context_selection_toggle_unread"/> </menu>
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/values-it/strings.xml b/org.fox.ttrss/src/main/res/values-it/strings.xml index a170ccf3..511186d2 100755 --- a/org.fox.ttrss/src/main/res/values-it/strings.xml +++ b/org.fox.ttrss/src/main/res/values-it/strings.xml @@ -233,4 +233,12 @@ <string name="flavor_image_prompt">(più immagini…)</string> <string name="headlines_row_top_changed">Nuovi articoli trovati, ricarica il notiziario per visualizzarli.</string> + <string name="prefs_custom_tabs_summary">Apri i link esterni con una Chrome custom tabs (più veloce, usato se disponibile)</string> + <string name="prefs_use_custom_tabs">Usa preview rapida</string> + <string name="ask_me_every_time">Chiedimelo ogni volta</string> + <string name="open_link">Apri link</string> + <string name="quick_preview">Preview rapida</string> + <string name="open_with_app">Apri con app</string> + <string name="prefs_opening_links">Apertura link</string> + <string name="open_with">Apri con…</string> </resources> diff --git a/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml b/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml index 231b6d24..fd5113a4 100755 --- a/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml +++ b/org.fox.ttrss/src/main/res/values-pt-rBR/strings.xml @@ -7,45 +7,47 @@ <string name="login_ready">Pronto para conectar.</string> <string name="login_login">Conectar</string> <string name="logout">Desconectar</string> - <string name="login">Conectar</string> - <string name="debugging">Debugando</string> + <string name="login">Nome de usuário</string> + <string name="debugging">Depuração</string> <string name="password">Senha</string> <string name="default_url">http://example.domain/tt-rss/</string> <string name="look_and_feel">Aparência</string> <string name="pref_theme">Tema</string> <string name="ttrss_url">URL do Tiny Tiny RSS</string> + <string name="theme_light">Claro</string> <string name="theme_dark">Escuro</string> <string name="preferences">Configurações</string> - <string name="theme_light">Claro</string> - <string name="connection">Conecção</string> + <string name="connection">Conexão</string> <string name="headline_context_multiple">Artigos selecionados</string> <string name="http_authentication">Autenticação HTTP</string> - <string name="loading_message">Carregando, aguarde...</string> + <string name="loading_message">Carregando, aguarde…</string> <string name="menu_unread_feeds">Mostrar feeds não lidos</string> <string name="menu_all_feeds">Mostrar todos os feeds</string> + <string name="unread_only">Apenas não lidos</string> <string name="update_feeds">Atualizar</string> <string name="share_article">Compartilhar artigo</string> <string name="catchup">Marcar como lido</string> - <string name="sort_feeds_by_unread">Ordenar por não lidos</string> + <string name="sort_feeds_by_unread">Ordenar por número de não lidos</string> <string name="ssl_trust_any">Aceitar qualquer certificado</string> <string name="category_browse_feeds">Navegar pelos feeds</string> - <string name="blank"></string> + <string name="blank"/> <string name="transport_debugging">Registrar no log os dados enviados e recebidos</string> <string name="article_toggle_marked">Colocar/Retirar estrela</string> + <string name="article_toggle_unread">Marcar como lido/não-lido</string> <string name="article_toggle_published">Publicar/Não publicar</string> <string name="headlines_select">Selecionar artigos</string> <string name="headlines_select_dialog">Selecionar artigos</string> - <string name="headlines_select_all">Tudo</string> + <string name="headlines_select_all">Todos</string> <string name="headlines_select_unread">Não lidos</string> - <string name="headlines_select_none">Deselecionar tudo</string> + <string name="headlines_select_none">Nenhum</string> <string name="selection_toggle_marked">Colocar/Retirar estrela</string> <string name="selection_toggle_published">Publicar/Não publicar</string> - <string name="selection_toggle_unread">Lido/Não lido</string> + <string name="selection_toggle_unread">Marcar como lido/não-lido</string> <string name="context_selection_toggle_marked">Colocar/Remover estrela</string> - <string name="context_selection_toggle_published">Publicar/Nâo publica</string> - <string name="context_selection_toggle_unread">Lido/Não lido</string> + <string name="context_selection_toggle_published">Publicar/Não publicar</string> + <string name="context_selection_toggle_unread">Marcar como lido/não-lido</string> <string name="article_mark_read_above">Marcar acima como lido</string> - <string name="http_login_summary">Opcional. Preencha este campo se sua instalação do tt-rss usa autenticação básica por http</string> + <string name="http_login_summary">Opcional. Preencha este campo se sua instalação do tt-rss usa autenticação básica HTTP</string> <string name="login_summary">Seu usuário tt-rss. Não é necessário no modo mono usuário</string> <string name="ttrss_url_summary">URL da sua instalação tt-rss, por exemplo http://site.com/tt-rss/</string> <string name="enable_cats">Habilitar categorias</string> @@ -61,9 +63,9 @@ <string name="error_http_other_error">Erro: Outro erro HTTP (veja log)</string> <string name="error_ssl_rejected">Erro: Certificado SSL foi rejeitado</string> <string name="error_parse_error">Erro: Falha ao converter string JSON</string> - <string name="error_io_error">Erro: Falha de I/O (Servidor fora?)</string> + <string name="error_io_error">Erro: Falha de I/O (Servidor fora do ar?)</string> <string name="error_other_error">Erro: Erro desconhecido (veja log)</string> - <string name="error_api_disabled">Erro: Habilite o acesso por API externa na configuração do avançada do tt-rss</string> + <string name="error_api_disabled">Erro: Habilite o acesso por API externa na configuração tt-rss (seção Avançado)</string> <string name="error_api_unknown">Erro: Erro desconhecido na API (veja log)</string> <string name="error_api_incorrect_usage">Erro: Uso incorreto da API</string> <string name="error_login_failed">Erro: Usuário ou senha inválidos</string> @@ -71,15 +73,16 @@ <string name="go_offline">Modo offline</string> <string name="go_online">Modo online</string> <string name="offline_switch_error">Falha ao preparar o modo offline (ver log)</string> - <string name="no_feeds">Nenhuma assinatura para mostrar</string> - <string name="dialog_offline_prompt">O Login falhou mas você tem dados armazenados, ir para modo offline?</string> + <string name="no_feeds">Nenhum feed para mostrar</string> + <string name="dialog_offline_prompt">O Login falhou, mas você tem dados armazenados. Mudar para modo offline?</string> <string name="dialog_offline_success">Modo offline está disponível</string> - <string name="dialog_offline_go">Ir para offline</string> + <string name="dialog_offline_go">Mudar para offline</string> <string name="dialog_cancel">Cancelar</string> <string name="dialog_offline_switch_prompt">Baixar artigos não lidos e mudar para offline?</string> <string name="notify_downloading_articles">Baixando artigos (%1$d)…</string> <string name="notify_downloading_init">Iniciando download…</string> - <string name="notify_downloading_feeds">Baixando assinaturas…</string> + <string name="notify_downloading_feeds">Baixando feeds…</string> + <string name="notify_downloading_categories">Baixando categorias…</string> <string name="notify_uploading_sending_data">Enviando dados para o servidor…</string> <string name="notify_downloading_title">Preparando modo offline</string> <string name="notify_uploading_title">Sincronizando dados offline</string> @@ -88,7 +91,7 @@ <string name="offline_image_cache_enabled">Armazenar imagens</string> <string name="offline_image_cache_enabled_summary">Baixar imagens para o cartão SD. Isso pode aumentar consideravelmente o tempo para o modo offline.</string> <string name="notify_downloading_images">Baixando imagens (%1$d)…</string> - <string name="article_set_labels">Definir tags</string> + <string name="article_set_labels">Definir marcadores</string> <string name="search">Pesquisar</string> <string name="cancel">Cancelar</string> <string name="pref_font_size">Tamanho do texto dos artigos</string> @@ -104,48 +107,52 @@ <string name="dialog_offline_sync_continue">Continuar</string> <string name="article_set_note">Publicar com anotação</string> <string name="dialog_open_preferences">Configuração</string> - <string name="dialog_need_configure_prompt">Preencha com a informação do servidor tt-rss como URL, login e senha.</string> + <string name="dialog_need_configure_prompt">Preencha com a informação do servidor tt-rss como URL, nome de usuário e senha.</string> <string name="update_headlines">Atualizar</string> <string name="error_network_unavailable">Erro: Rede indisponível</string> <string name="category_browse_headlines">Navegar pelos títulos</string> <string name="use_volume_keys">Usar botões de volume</string> <string name="use_volume_keys_long">Mudar entre artigos usando os botões de volume</string> - <string name="ssl_trust_any_host">Não verificar hostname</string> - <string name="error_api_unknown_method">Erro: metodo API desconhecido</string> + <string name="ssl_trust_any_host">Não verificar nome de host</string> + <string name="error_api_unknown_method">Erro: método API desconhecido</string> <string name="ssl_trust_any_long">Aceitar qualquer certificado SSL sem verificação</string> - <string name="ssl_trust_any_host_long">Não verificar o nome do servidor</string> + <string name="ssl_trust_any_host_long">Não verificar o nome de host do servidor</string> <string name="ssl">SSL</string> - <string name="error_ssl_hostname_rejected">Erro: Nome SSL não verificado</string> + <string name="error_ssl_hostname_rejected">Erro: Nome de host SSL não corresponde</string> <plurals name="article_comments"> + <item quantity="one">%1$d comentário</item> <item quantity="other">%1$d comentários</item> </plurals> <plurals name="trial_mode_prompt"> - <item quantity="other">Modo de teste, resta(m) %1$d dia(s).</item> + <item quantity="one">Modo de teste, resta um dia.</item> + <item quantity="other">Modo de teste, restam %1$d dias.</item> </plurals> + <string name="trial_purchase">Desbloquear a versão completa</string> <string name="trial_expired">Período de teste encerrado</string> <string name="trial_expired_message">Para continuar usando o Tiny Tiny RSS por favor desbloqueie a versão completa comprando a chave.</string> - <string name="theme_sepia">Sepia</string> - <string name="reading">Lendo</string> + <string name="theme_sepia">Sépia</string> + <string name="theme_amber">Âmbar</string> + <string name="reading">Leitura</string> <string name="offline_articles_to_download">Número de artigos a baixar</string> - <string name="offline_articles_to_download_long">Número de artigos a baixar para o modo Offline (mais novos primeiro).</string> + <string name="offline_articles_to_download_long">Número de artigos a baixar para o modo offline (mais novos primeiro).</string> <string name="pref_headlines_show_content_long">Mostrar prévia do conteúdo na lista de títulos</string> - <string name="pref_headlines_show_content">Prévia do conteúdos do artigo</string> + <string name="pref_headlines_show_content">Prévia do conteúdo do artigo</string> <string name="api_too_low">Esta ação precisa de uma nova versão do Tiny Tiny RSS</string> <string name="share_url_hint">URL do artigo</string> <string name="share_content_hint">Conteúdo do artigo</string> <string name="share_title_hint">Título do artigo</string> <string name="share_share_button">Compartilhar</string> <string name="share_article_posted">Artigo postado.</string> - <string name="subscribe_name">Assinar com Tiny Tiny RSS</string> - <string name="feed_url">URL da assinatura</string> - <string name="subscribe_to_feed">Assinar feed</string> - <string name="error_while_subscribing">Erro ao assinar.</string> + <string name="subscribe_name">Inscrever-se com Tiny Tiny RSS</string> + <string name="feed_url">URL do feed</string> + <string name="subscribe_to_feed">Inscrever-se feed</string> + <string name="error_while_subscribing">Erro ao increver-se.</string> <string name="category_list_updated">Lista de categorias atualizada</string> - <string name="subscribed_to_feed">Feed assinado</string> - <string name="error_feed_already_exists_">Erro: Assinatura já existe.</string> + <string name="subscribed_to_feed">Inscrito no feed</string> + <string name="error_feed_already_exists_">Erro: já inscrito neste feed.</string> <string name="error_invalid_url">Erro: URL inválida.</string> <string name="error_url_is_an_html_page_no_feeds_found">Erro: URL é de uma página HTML, nenhum feed encontrado.</string> <string name="error_url_contains_multiple_feeds">Erro: URL contém múltiplos feeds</string> @@ -160,15 +167,77 @@ <string name="article_img_open">Abrir imagem</string> <string name="article_img_share">Compartilhar imagem</string> <string name="article_img_view_caption">Ver legenda</string> - <string name="pref_headlines_mark_read_scroll">Marcar como lida ao visualizar</string> - <string name="pref_headlines_mark_read_scroll_long">Títulos serão marcados como lidos ao rodar depois deles</string> + <string name="pref_headlines_mark_read_scroll">Marcar como lido ao visualizar</string> + <string name="pref_headlines_mark_read_scroll_long">Artigos serão marcados como lidos ao rodar depois deles</string> + <plurals name="mark_num_headlines_as_read"> - <item quantity="other">Marcar %1$d artigo(s) como lido(s)?</item> + <item quantity="one">Marcar um artigos como lido?</item> + <item quantity="other">Marcar %1$d artigos como lidos?</item> </plurals> + <string name="prefs_confirm_headlines_catchup">Confirme marcação de artigos como lidos</string> <string name="author_formatted">por %1$s</string> + <plurals name="n_unread_articles"> + <item quantity="one">%1$d artigo não lido</item> <item quantity="other">%1$d artigos não lidos</item> </plurals> + <string name="pref_headline_font_size">Tamanho do texto para os títulos</string> + <string name="context_confirm_catchup">Marcar todos os artigos em %1$s como lidos?</string> + <string name="accel_webview_summary">Desabilite se vir problemas visuais</string> + <string name="accel_webview_title">Usar web views com aceleração (3.0+)</string> + <string name="place_shortcut">Criar atalho</string> + <string name="shortcut_has_been_placed_on_the_home_screen">Foi criado um atalho na tela inicial</string> + <string name="download_articles_and_go_offline">Baixar artigos e mudar para modo offline</string> + <string name="tasker_save_and_close">Salvar e fechar</string> + <string name="synchronize_read_articles_and_go_online">Sincronizar artigos lidos e voltar ao modo online</string> + <string name="font_size_dialog_suffix">sp</string> + <string name="server_function_not_available">Desculpe, esta função não está disponível na sua versão do tt-rss.</string> + <string name="unsubscribe">Cancelar inscrição</string> + <string name="unsubscribe_from_prompt">Cancelar inscrição em %1$s?</string> + <string name="open_article_in_web_browser">Abrir no navegador</string> + <string name="error_loading_image">Erro ao carregar imagem.</string> + <string name="toggle_sort_order">Alternar entre mais novo ou mais antigo primeiro</string> + <string name="headlines_sort_default">Padrão</string> + <string name="headlines_sort_newest_first">Mais novo primeiro</string> + <string name="headlines_sort_oldest_first">Mais antigo primeiro</string> + <string name="headlines_sort_title">Título</string> + <string name="headlines_sort_articles_title">Ordenar artigos</string> + <string name="fresh_articles">Artigos recentes</string> + <string name="feed_all_articles">Todos os artigos</string> + <string name="prefs_enable_fab">Habilitar BFA</string> + <string name="prefs_enable_fab_long">Exibir botão flutuante de ação durante a leitura</string> + <string name="prefs_open_fresh_on_startup">Abrir artigos recentes ao iniciar</string> + <string name="prefs_headline_display_mode">Modo de exibição dos títulos</string> + <string name="prefs_headline_display_mode_long">Padrão, sem imagens, ou modo compacto</string> + <string name="headline_display_mode_default">Padrão</string> + <string name="headline_display_mode_no_images">Sem imagens</string> + <string name="headline_display_mode_compact">Compacto</string> + <string name="headline_display_mode_compact_noimages">Compacto (sem imagens)</string> + <string name="prefs_version">%1$s (%2$d)</string> + <string name="prefs_version_title">Versão</string> + <string name="prefs_build_timestamp">%1$s</string> + <string name="prefs_build_timestamp_title">Hora da compilação</string> + <string name="crash_dialog_text">Infelizmente, o Tiny Tiny RSS parou. Enviar registro da falha para tt-rss.org?</string> + <string name="prefs_widget_show_fresh">Mostrar artigos recentes</string> + <string name="prefs_widget_show_fresh_summary">Ao invés do total de artigos não lidos, exibir a quantidade de artigos recentes</string> + <string name="prefs_widget">Widget</string> + <string name="title_activity_video_player">Reprodutor de vídeos</string> + + <string name="hello_world">Olá, mundo!</string> + <string name="action_settings">Configurações</string> + <string name="video_player_share">Compartilhar vídeo</string> + <string name="video_player_open">Abrir vídeo</string> + + <string name="flavor_image_prompt">(mais imagens…)</string> + <string name="headlines_row_top_changed">Novos artigos encontrados, recarregue o feed para continuar.</string> + <string name="prefs_custom_tabs_summary">Abrir links externos com custom tabs do Chrome (mais rápido, usado se disponível)</string> + <string name="prefs_use_custom_tabs">Usar vizualiação rápida</string> + <string name="ask_me_every_time">Perguntar toda vez</string> + <string name="open_link">Abrir link</string> + <string name="quick_preview">Vizualização rápida</string> + <string name="open_with_app">Abrir com aplicativo</string> + <string name="prefs_opening_links">Abertura de links</string> + <string name="open_with">Abrir com…</string> </resources> diff --git a/org.fox.ttrss/src/main/res/values/attrs.xml b/org.fox.ttrss/src/main/res/values/attrs.xml index e0bfb02c..3f4922d0 100755 --- a/org.fox.ttrss/src/main/res/values/attrs.xml +++ b/org.fox.ttrss/src/main/res/values/attrs.xml @@ -49,4 +49,7 @@ <attr format="reference|color" name="insetForeground"> </attr></declare-styleable> <attr name="drawer_header" format="reference" /> + <declare-styleable name="ForegroundImageView"> + <attr name="android:foreground"/> + </declare-styleable> </resources>
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/values/strings.xml b/org.fox.ttrss/src/main/res/values/strings.xml index c6fa04fc..cef96477 100755 --- a/org.fox.ttrss/src/main/res/values/strings.xml +++ b/org.fox.ttrss/src/main/res/values/strings.xml @@ -231,7 +231,7 @@ <string name="video_player_share">Share video</string> <string name="video_player_open">Open video</string> - <string name="flavor_image_prompt">(more images...)</string> + <string name="flavor_image_prompt">(more images…)</string> <string name="headlines_row_top_changed">New articles found, reload feed to continue.</string> <string name="prefs_custom_tabs_summary">Open external links with Chrome custom tabs (faster, used if available)</string> <string name="prefs_use_custom_tabs">Use quick preview</string> @@ -240,4 +240,5 @@ <string name="quick_preview">Quick preview</string> <string name="open_with_app">Open with app</string> <string name="prefs_opening_links">Opening links</string> + <string name="open_with">Open with…</string> </resources> diff --git a/org.fox.ttrss/src/main/res/values/style.xml b/org.fox.ttrss/src/main/res/values/style.xml index 74aad95a..71c8b612 100755 --- a/org.fox.ttrss/src/main/res/values/style.xml +++ b/org.fox.ttrss/src/main/res/values/style.xml @@ -18,14 +18,14 @@ <item name="headlineHeaderBackground">#ccffffff</item> <item name="headlineUnreadBackground">@android:color/white</item> <item name="feedsSelectedBackground">#dddddd</item> - <item name="feedlistTextColor">@android:color/primary_text_light</item> - <item name="feedlistSelectedTextColor">@android:color/primary_text_light</item> - <item name="headlineUnreadTextColor">@android:color/primary_text_light</item> - <item name="headlineSelectedTextColor">@android:color/primary_text_light</item> - <item name="headlineExcerptTextColor">@android:color/secondary_text_light</item> + <item name="feedlistTextColor">@android:color/black</item> + <item name="feedlistSelectedTextColor">@android:color/black</item> + <item name="headlineUnreadTextColor">@android:color/black</item> + <item name="headlineSelectedTextColor">@android:color/black</item> + <item name="headlineExcerptTextColor">#323232</item> <item name="headlineSecondaryTextColor">#909090</item> <item name="headlineSelectedSecondaryTextColor">?headlineSelectedExcerptTextColor</item> - <item name="headlineSelectedExcerptTextColor">@android:color/secondary_text_light</item> + <item name="headlineSelectedExcerptTextColor">#323232</item> <item name="headlineTitleHighScoreUnreadTextColor">#008000</item> <item name="linkColor">?colorPrimary</item> <item name="loadingBackground">@android:color/white</item> @@ -33,7 +33,7 @@ <item name="articleNoteBackground">#fff7d5</item> <item name="parentBtnBackground">#dddddd</item> <item name="articleHeader">@android:color/transparent</item> - <item name="articleHeaderTextColor">@android:color/primary_text_light</item> + <item name="articleHeaderTextColor">@android:color/black</item> <item name="articleTextColor">@android:color/black</item> <item name="floatingActionButtonStyle">@style/FabTheme</item> <item name="headlineFooterColor">?colorPrimary</item> @@ -71,34 +71,34 @@ <!-- <item name="statusBarHintColor">?colorPrimary</item> --> <item name="unreadCounterColor">#909090</item> - <item name="feedlistTextColor">@android:color/primary_text_dark</item> - <item name="headlineUnreadTextColor">@android:color/primary_text_dark</item> + <item name="feedlistTextColor">@android:color/white</item> + <item name="headlineUnreadTextColor">@android:color/white</item> <item name="headlineSelectedTextColor">@android:color/white</item> - <item name="headlineExcerptTextColor">@android:color/secondary_text_dark</item> + <item name="headlineExcerptTextColor">#bebebe</item> <item name="headlineSecondaryTextColor">#909090</item> <item name="headlineTitleHighScoreUnreadTextColor">#00FF00</item> - <item name="headlineSelectedExcerptTextColor">@android:color/secondary_text_dark</item> + <item name="headlineSelectedExcerptTextColor">#bebebe</item> <item name="headlineSelectedSecondaryTextColor">?headlineSelectedExcerptTextColor</item> <item name="headlineSelectedBackground">#1c1c1c</item> <item name="headlineHeaderBackground">#99000000</item> <item name="headlineUnreadBackground">#101010</item> <item name="linkColor">?colorPrimary</item> <item name="loadingBackground">@android:color/black</item> - <item name="articleNoteTextColor">@android:color/secondary_text_dark</item> + <item name="articleNoteTextColor">#bebebe</item> <item name="articleNoteBackground">#303030</item> <item name="parentBtnBackground">#101010</item> <item name="ttrssHorizontalDivider">@android:drawable/divider_horizontal_dark</item> <item name="feedlistBackground">#1c1d1e</item> <item name="headlinesBackground">#1c1d1e</item> - <item name="articleBackground">#1c1d1e</item> + <item name="articleBackground">@android:color/black</item> <item name="feedsSelectedBackground">#1c1c1c</item> - <item name="feedlistSelectedTextColor">@android:color/primary_text_dark</item> + <item name="feedlistSelectedTextColor">@android:color/white</item> <item name="articleHeader">@android:color/transparent</item> - <item name="articleHeaderTextColor">@android:color/primary_text_dark</item> + <item name="articleHeaderTextColor">@android:color/white</item> <item name="floatingActionButtonStyle">@style/FabTheme</item> <item name="articleTextColor">#e0e0e0</item> <item name="headlineFooterColor">?colorPrimary</item> - <item name="articleHeaderSeparator">@android:color/black</item> + <item name="articleHeaderSeparator">#303030</item> <item name="colorPrimary">#607D8B</item> <item name="colorPrimaryDark">#455A64</item> diff --git a/tt-rss-android.iml b/tt-rss-android.iml index 58a44a3e..e26286a6 100644 --- a/tt-rss-android.iml +++ b/tt-rss-android.iml @@ -9,8 +9,6 @@ </facet> </component> <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="true"> - <output url="file://$MODULE_DIR$/build/classes/main" /> - <output-test url="file://$MODULE_DIR$/build/classes/test" /> <exclude-output /> <content url="file://$MODULE_DIR$"> <excludeFolder url="file://$MODULE_DIR$/.gradle" /> |