mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Merge branch 'master' into pro
* master: (28 commits) Bumping up node images size. Android v11.3.0. #1600 Mark story as read button width Cleaning up preferences on android Merge master into sictiru #1600 Mark story read timer WIP #1600 Mark story read immediately or manually. #1634 Update infrequent logo #1606 Adjust story title length based on story content preview style. #1628 Handle feed missing metadata. Merge master into sictiru #1618 Handle multi window mode lifecycle. #1624 Offer context before potentially logging out. Android v11.2.2. #1598 Add immutable flag for PendingIntents Android v11.2.1. Fix reading pager fragment transaction. Open billing connection for the subscription sync service. Android v11.2 Finishing up PostgreSQL migration. Needs to test backups. ...
This commit is contained in:
commit
d231499672
32 changed files with 364 additions and 165 deletions
|
@ -15,6 +15,7 @@ groups:
|
||||||
|
|
||||||
node: inventory_hostname.startswith('node')
|
node: inventory_hostname.startswith('node')
|
||||||
node_socket: inventory_hostname.startswith('node-socket')
|
node_socket: inventory_hostname.startswith('node-socket')
|
||||||
|
node_images: inventory_hostname.startswith('node-images')
|
||||||
|
|
||||||
# debugs: inventory_hostname.startswith('debug')
|
# debugs: inventory_hostname.startswith('debug')
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'androidx.fragment:fragment-ktx:1.4.0'
|
implementation 'androidx.fragment:fragment-ktx:1.4.1'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
|
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
|
||||||
|
@ -40,7 +40,7 @@ dependencies {
|
||||||
implementation "androidx.browser:browser:1.4.0"
|
implementation "androidx.browser:browser:1.4.0"
|
||||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
|
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
|
||||||
implementation 'androidx.lifecycle:lifecycle-process:2.4.0'
|
implementation 'androidx.lifecycle:lifecycle-process:2.4.0'
|
||||||
implementation 'androidx.core:core-splashscreen:1.0.0-alpha02'
|
implementation 'androidx.core:core-splashscreen:1.0.0-beta01'
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
@ -49,8 +49,8 @@ android {
|
||||||
applicationId "com.newsblur"
|
applicationId "com.newsblur"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 199
|
versionCode 202
|
||||||
versionName "11.2"
|
versionName "11.3.0"
|
||||||
}
|
}
|
||||||
compileOptions.with {
|
compileOptions.with {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
|
@ -211,7 +211,7 @@
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:scrollbars="none" />
|
android:scrollbars="none" />
|
||||||
|
|
||||||
<include layout="@layout/include_reading_item_comment" />
|
<include layout="@layout/reading_item_actions" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -2,26 +2,39 @@
|
||||||
<merge xmlns:app="http://schemas.android.com/apk/res-auto"
|
<merge xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<LinearLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginTop="15dp"
|
android:layout_marginTop="15dp"
|
||||||
android:layout_marginBottom="15dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:baselineAligned="false" >
|
android:gravity="center_horizontal"
|
||||||
|
android:layout_gravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/mark_read_story_button"
|
||||||
|
style="?storyButtons"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:layout_alignStart="@+id/train_story_button"
|
||||||
|
android:layout_alignEnd="@+id/save_story_button"
|
||||||
|
android:text="@string/story_mark_read_state"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/train_story_button"
|
android:id="@+id/train_story_button"
|
||||||
style="?storyButtons"
|
style="?storyButtons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
|
android:layout_below="@+id/mark_read_story_button"
|
||||||
android:text="@string/train_this"
|
android:text="@string/train_this"
|
||||||
app:icon="@drawable/ic_train"/>
|
app:icon="@drawable/ic_train" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/share_story_button"
|
android:id="@+id/share_story_button"
|
||||||
style="?storyButtons"
|
style="?storyButtons"
|
||||||
|
android:layout_marginHorizontal="12dp"
|
||||||
|
android:layout_toEndOf="@+id/train_story_button"
|
||||||
|
android:layout_below="@+id/mark_read_story_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:text="@string/share_this"
|
android:text="@string/share_this"
|
||||||
|
@ -30,12 +43,14 @@
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/save_story_button"
|
android:id="@+id/save_story_button"
|
||||||
style="?storyButtons"
|
style="?storyButtons"
|
||||||
|
android:layout_toEndOf="@+id/share_story_button"
|
||||||
|
android:layout_below="@+id/mark_read_story_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:text="@string/save_this"
|
android:text="@string/save_this"
|
||||||
app:icon="@drawable/ic_clock" />
|
app:icon="@drawable/ic_clock" />
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
|
@ -109,7 +109,7 @@
|
||||||
android:paddingTop="6dp"
|
android:paddingTop="6dp"
|
||||||
android:paddingBottom="6dp"
|
android:paddingBottom="6dp"
|
||||||
android:paddingRight="4dp"
|
android:paddingRight="4dp"
|
||||||
android:maxLines="2"
|
android:maxLines="3"
|
||||||
android:ellipsize="end" />
|
android:ellipsize="end" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
android:layout_marginLeft="26dp"
|
android:layout_marginLeft="26dp"
|
||||||
android:layout_marginRight="2dp"
|
android:layout_marginRight="2dp"
|
||||||
android:layout_marginBottom="2dp"
|
android:layout_marginBottom="2dp"
|
||||||
android:maxLines="2"
|
android:maxLines="3"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
<attr name="chip" format="string" />
|
<attr name="chip" format="string" />
|
||||||
<attr name="actionButtons" format="string" />
|
<attr name="actionButtons" format="string" />
|
||||||
<attr name="storyButtons" format="string" />
|
<attr name="storyButtons" format="string" />
|
||||||
|
<attr name="storyButtonsDimmed" format="string" />
|
||||||
<attr name="shareBarBackground" format="string" />
|
<attr name="shareBarBackground" format="string" />
|
||||||
<attr name="shareBarText" format="string" />
|
<attr name="shareBarText" format="string" />
|
||||||
<attr name="commentsHeader" format="string" />
|
<attr name="commentsHeader" format="string" />
|
||||||
|
|
|
@ -5,26 +5,26 @@
|
||||||
<string name="login_username_hint">username</string>
|
<string name="login_username_hint">username</string>
|
||||||
<string name="login_password_hint">password</string>
|
<string name="login_password_hint">password</string>
|
||||||
<string name="login_registration_email_hint">email address</string>
|
<string name="login_registration_email_hint">email address</string>
|
||||||
<string name="login_button_login">Log In</string>
|
<string name="login_button_login">Login</string>
|
||||||
<string name="login_forgot_password"><u>I forgot my password</u></string>
|
<string name="login_forgot_password"><u>Forgot password</u></string>
|
||||||
<string name="login_custom_server"><u>I have a custom server</u></string>
|
<string name="login_custom_server"><u>Self-hosted custom server</u></string>
|
||||||
<string name="login_custom_server_hint">https://www.newsblur.com</string>
|
<string name="login_custom_server_hint">https://www.newsblur.com</string>
|
||||||
<string name="login_message_error">There was problem logging in to NewsBlur.</string>
|
<string name="login_message_error">There was problem logging in to NewsBlur.</string>
|
||||||
<string name="login_logging_in">Logging in…</string>
|
<string name="login_logging_in">Logging in…</string>
|
||||||
<string name="login_logged_in">Logged in!</string>
|
<string name="login_logged_in">Reticulating splines…</string>
|
||||||
<string name="login_retrieving_feeds">Retrieving feeds…</string>
|
<string name="login_retrieving_feeds">Retrieving feeds…</string>
|
||||||
<string name="login_next">Next</string>
|
<string name="login_next">Next</string>
|
||||||
<string name="login_custom_server_scheme_error">Expected \'https://\' custom server URL</string>
|
<string name="login_custom_server_scheme_error">Expected \'https://\' in custom server URL</string>
|
||||||
|
|
||||||
<string name="search_for_feed">Search for feeds</string>
|
<string name="search_for_feed">Search for feeds</string>
|
||||||
|
|
||||||
<string name="loading">Loading…</string>
|
<string name="loading">Loading…</string>
|
||||||
<string name="orig_text_loading">Fetching story text…</string>
|
<string name="orig_text_loading">Fetching story text…</string>
|
||||||
|
|
||||||
<string name="follow_error">There was a problem following the user. Check your internet connection and try again.</string>
|
<string name="follow_error">There was a problem following the user.</string>
|
||||||
<string name="unfollow_error">There was a problem unfollowing the user. Check your internet connection and try again.</string>
|
<string name="unfollow_error">There was a problem unfollowing the user.</string>
|
||||||
|
|
||||||
<string name="description_login_button">Press to log in.</string>
|
<string name="description_login_button">Press to log in</string>
|
||||||
<string name="description_login_logo">NewsBlur Logo</string>
|
<string name="description_login_logo">NewsBlur Logo</string>
|
||||||
<string name="description_profile_picture">The user\'s profile picture</string>
|
<string name="description_profile_picture">The user\'s profile picture</string>
|
||||||
<string name="description_row_folder_icon">folder icon</string>
|
<string name="description_row_folder_icon">folder icon</string>
|
||||||
|
@ -36,9 +36,9 @@
|
||||||
<string name="description_empty_list_image">Empty list placeholder</string>
|
<string name="description_empty_list_image">Empty list placeholder</string>
|
||||||
<string name="description_menu">Menu</string>
|
<string name="description_menu">Menu</string>
|
||||||
|
|
||||||
<string name="title_choose_folders">Choose Folders for Feed %s</string>
|
<string name="title_choose_folders">Choose folders for feed %s</string>
|
||||||
<string name="title_rename_feed">Rename Feed %s</string>
|
<string name="title_rename_feed">Rename feed %s</string>
|
||||||
<string name="title_rename_folder">Rename Folder %s</string>
|
<string name="title_rename_folder">Rename folder %s</string>
|
||||||
|
|
||||||
<string name="all_stories_title">All Stories</string>
|
<string name="all_stories_title">All Stories</string>
|
||||||
<string name="infrequent_title">Infrequent Site Stories</string>
|
<string name="infrequent_title">Infrequent Site Stories</string>
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
<string name="top_level">TOP LEVEL</string>
|
<string name="top_level">TOP LEVEL</string>
|
||||||
|
|
||||||
<string name="send_full">%1$s \n\%2$s \n\n%3$s \n\n—\nShared with NewsBlur.com</string>
|
<string name="send_full">%1$s \n\%2$s \n\n%3$s \n\n—\nShared with NewsBlur</string>
|
||||||
<string name="share_comment_hint">Comment (Optional)</string>
|
<string name="share_comment_hint">Comment (Optional)</string>
|
||||||
<string name="share_newsblur">Share \"%s\" to your Blurblog?</string>
|
<string name="share_newsblur">Share \"%s\" to your Blurblog?</string>
|
||||||
<string name="share_this">Share</string>
|
<string name="share_this">Share</string>
|
||||||
|
@ -64,6 +64,8 @@
|
||||||
<string name="save_this">Save</string>
|
<string name="save_this">Save</string>
|
||||||
<string name="unsave_this">Unsave</string>
|
<string name="unsave_this">Unsave</string>
|
||||||
<string name="train_this">Train</string>
|
<string name="train_this">Train</string>
|
||||||
|
<string name="story_mark_unread_state">Read</string>
|
||||||
|
<string name="story_mark_read_state">Mark story read</string>
|
||||||
|
|
||||||
<string name="overlay_next">Next</string>
|
<string name="overlay_next">Next</string>
|
||||||
<string name="overlay_done">Done</string>
|
<string name="overlay_done">Done</string>
|
||||||
|
@ -223,8 +225,8 @@
|
||||||
<string name="menu_feedback">Send app feedback</string>
|
<string name="menu_feedback">Send app feedback</string>
|
||||||
<string name="menu_feedback_post">Create a feedback post</string>
|
<string name="menu_feedback_post">Create a feedback post</string>
|
||||||
<string name="menu_feedback_email">Email a bug report</string>
|
<string name="menu_feedback_email">Email a bug report</string>
|
||||||
<string name="menu_theme_choose">Theme…</string>
|
<string name="menu_theme_choose">Theme</string>
|
||||||
<string name="menu_premium_account">Premium Account</string>
|
<string name="menu_premium_account">Premium subscription…</string>
|
||||||
|
|
||||||
<string name="description_add_new_folder_icon">Add new folder icon</string>
|
<string name="description_add_new_folder_icon">Add new folder icon</string>
|
||||||
|
|
||||||
|
@ -237,7 +239,7 @@
|
||||||
<string name="empty_list_view_no_stories_unread">No unread stories</string>
|
<string name="empty_list_view_no_stories_unread">No unread stories</string>
|
||||||
|
|
||||||
<string name="empty_list_view_no_unread_stories">You have no unread stories.</string>
|
<string name="empty_list_view_no_unread_stories">You have no unread stories.</string>
|
||||||
<string name="empty_list_view_no_focus_stories">You have no unread stories in Focus mode.\n\nSwitch to All or Unread.</string>
|
<string name="empty_list_view_no_focus_stories">You have no unread stories in Focus.\n\nSwitch to All or Unread.</string>
|
||||||
<string name="empty_list_view_no_saved_stories">You have no saved stories.\n\nSwitch to All or Unread.</string>
|
<string name="empty_list_view_no_saved_stories">You have no saved stories.\n\nSwitch to All or Unread.</string>
|
||||||
|
|
||||||
<string name="login_registration_custom_server">Custom server</string>
|
<string name="login_registration_custom_server">Custom server</string>
|
||||||
|
@ -267,9 +269,9 @@
|
||||||
<string name="feed_opens">%d opens</string>
|
<string name="feed_opens">%d opens</string>
|
||||||
<string name="feed_stories_per_month">%d stories/month</string>
|
<string name="feed_stories_per_month">%d stories/month</string>
|
||||||
|
|
||||||
<string name="settings">Preferences</string>
|
<string name="settings">Preferences…</string>
|
||||||
<string name="mute_sites">Mute Sites</string>
|
<string name="mute_sites">Mute Sites…</string>
|
||||||
<string name="widget">Widget</string>
|
<string name="widget">Widget…</string>
|
||||||
<string name="title_widget_setup">Tap to setup in NewsBlur</string>
|
<string name="title_widget_setup">Tap to setup in NewsBlur</string>
|
||||||
<string name="title_no_subscriptions">No active subscriptions detected</string>
|
<string name="title_no_subscriptions">No active subscriptions detected</string>
|
||||||
<string name="title_widget_loading">Loading…</string>
|
<string name="title_widget_loading">Loading…</string>
|
||||||
|
@ -297,14 +299,14 @@
|
||||||
<string name="premium_text_view">Text view conveniently extracts the story</string>
|
<string name="premium_text_view">Text view conveniently extracts the story</string>
|
||||||
<string name="premium_shiloh">You feed Shiloh, my poor, hungry dog, for a month</string>
|
<string name="premium_shiloh">You feed Shiloh, my poor, hungry dog, for a month</string>
|
||||||
|
|
||||||
<string name="settings_cat_offline">Offline</string>
|
<string name="settings_cat_offline">Offline reading</string>
|
||||||
<string name="settings_enable_offline">Download Stories</string>
|
<string name="settings_enable_offline">Download stories</string>
|
||||||
<string name="settings_enable_offline_sum">Periodically fetch stories in background</string>
|
<string name="settings_enable_offline_sum">Periodically fetch stories in background</string>
|
||||||
<string name="settings_enable_image_prefetch">Download Images</string>
|
<string name="settings_enable_image_prefetch">Download images</string>
|
||||||
<string name="settings_enable_image_prefetch_sum">Pre-fetch images for offline reading</string>
|
<string name="settings_enable_image_prefetch_sum">Pre-fetch images for offline reading</string>
|
||||||
<string name="settings_enable_text_prefetch">Download Text</string>
|
<string name="settings_enable_text_prefetch">Download full text</string>
|
||||||
<string name="settings_enable_text_prefetch_sum">Pre-fetch text for offline reading</string>
|
<string name="settings_enable_text_prefetch_sum">Pre-fetch full text for offline reading</string>
|
||||||
<string name="settings_keep_old_stories">Keep Stories after Reading</string>
|
<string name="settings_keep_old_stories">Keep stories after reading</string>
|
||||||
<string name="settings_keep_old_stories_sum">Disable to reduce storage usage</string>
|
<string name="settings_keep_old_stories_sum">Disable to reduce storage usage</string>
|
||||||
|
|
||||||
<string name="mute_config_title">You can follow up to 64 sites with a free standard account</string>
|
<string name="mute_config_title">You can follow up to 64 sites with a free standard account</string>
|
||||||
|
@ -313,7 +315,7 @@
|
||||||
<string name="mute_config_upgrade">UPGRADE</string>
|
<string name="mute_config_upgrade">UPGRADE</string>
|
||||||
<string name="mute_config_sites">%1$s/%2$s</string>
|
<string name="mute_config_sites">%1$s/%2$s</string>
|
||||||
|
|
||||||
<string name="menu_network_select">Download Using</string>
|
<string name="menu_network_select">Download using…</string>
|
||||||
<string name="menu_network_select_sum">Restrict background data to chosen networks</string>
|
<string name="menu_network_select_sum">Restrict background data to chosen networks</string>
|
||||||
<string name="menu_network_select_opt_any">Any Network</string>
|
<string name="menu_network_select_opt_any">Any Network</string>
|
||||||
<string name="menu_network_select_opt_nomo">Any Wifi or Ethernet</string>
|
<string name="menu_network_select_opt_nomo">Any Wifi or Ethernet</string>
|
||||||
|
@ -330,13 +332,13 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="default_network_select_value">NOMONONME</string>
|
<string name="default_network_select_value">NOMONONME</string>
|
||||||
|
|
||||||
<string name="menu_delete_offline_stories">Delete offline stories …</string>
|
<string name="menu_delete_offline_stories">Delete offline stories…</string>
|
||||||
<string name="menu_delete_offline_stories_key">delete_offline_stories</string>
|
<string name="menu_delete_offline_stories_key">delete_offline_stories</string>
|
||||||
<string name="menu_delete_offline_stories_sum">Clear all offline stories and images</string>
|
<string name="menu_delete_offline_stories_sum">Free up space by clearing stored stories and images</string>
|
||||||
<string name="menu_delete_offline_stories_confirmation">Cleared all stories and images!</string>
|
<string name="menu_delete_offline_stories_confirmation">Cleared all stories and images!</string>
|
||||||
|
|
||||||
<string name="menu_cache_age_select">Maximum Cache Age</string>
|
<string name="menu_cache_age_select">How long to keep stories…</string>
|
||||||
<string name="menu_cache_age_select_sum">Clean up cached story content after…</string>
|
<string name="menu_cache_age_select_sum">Clear stored stories for offline reading</string>
|
||||||
<string name="menu_cache_age_select_opt_2d">2 days (reduce storage use)</string>
|
<string name="menu_cache_age_select_opt_2d">2 days (reduce storage use)</string>
|
||||||
<string name="menu_cache_age_select_opt_7d">7 days</string>
|
<string name="menu_cache_age_select_opt_7d">7 days</string>
|
||||||
<string name="menu_cache_age_select_opt_14d">14 days</string>
|
<string name="menu_cache_age_select_opt_14d">14 days</string>
|
||||||
|
@ -355,9 +357,9 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="default_cache_age_select_value">CACHE_AGE_30D</string>
|
<string name="default_cache_age_select_value">CACHE_AGE_30D</string>
|
||||||
|
|
||||||
<string name="settings_cat_feed_list">Feed List</string>
|
<string name="settings_cat_feed_list">Feed list</string>
|
||||||
|
|
||||||
<string name="setting_feed_list_order">Feed list order</string>
|
<string name="setting_feed_list_order">Feed list order…</string>
|
||||||
<string name="settings_enable_row_global_shared">Show Global Shared Stories</string>
|
<string name="settings_enable_row_global_shared">Show Global Shared Stories</string>
|
||||||
<string name="settings_enable_row_global_shared_sum">Show the Global Shared Stories folder</string>
|
<string name="settings_enable_row_global_shared_sum">Show the Global Shared Stories folder</string>
|
||||||
<string name="settings_enable_row_infrequent_stories">Show Infrequent Stories</string>
|
<string name="settings_enable_row_infrequent_stories">Show Infrequent Stories</string>
|
||||||
|
@ -366,8 +368,8 @@
|
||||||
<string name="settings_cat_story_list">Story List</string>
|
<string name="settings_cat_story_list">Story List</string>
|
||||||
|
|
||||||
<string name="oldest">Oldest</string>
|
<string name="oldest">Oldest</string>
|
||||||
<string name="newest">Newest First</string>
|
<string name="newest">Newest first</string>
|
||||||
<string name="menu_story_order">Story Order</string>
|
<string name="menu_story_order">Story order…</string>
|
||||||
<string-array name="default_story_order_entries">
|
<string-array name="default_story_order_entries">
|
||||||
<item>@string/newest</item>
|
<item>@string/newest</item>
|
||||||
<item>@string/oldest</item>
|
<item>@string/oldest</item>
|
||||||
|
@ -390,12 +392,12 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="default_feed_list_order_value">ALPHABETICAL</string>
|
<string name="default_feed_list_order_value">ALPHABETICAL</string>
|
||||||
|
|
||||||
<string name="all_stories">All Stories</string>
|
<string name="all_stories">All stories</string>
|
||||||
<string name="unread_only">Unread Only</string>
|
<string name="unread_only">Unread only</string>
|
||||||
<string name="menu_story_content_preview">Content Preview</string>
|
<string name="menu_story_content_preview">Story content preview</string>
|
||||||
<string name="menu_story_thumbnail_preview">Thumbnail Preview</string>
|
<string name="menu_story_thumbnail_preview">Thumbnail preview</string>
|
||||||
<string name="menu_mark_read_on_scroll">Mark Read On Scroll</string>
|
<string name="menu_mark_read_on_scroll">Mark read on scroll</string>
|
||||||
<string name="menu_read_filter">Read Filter</string>
|
<string name="menu_read_filter">Read story filter…</string>
|
||||||
<string-array name="default_read_filter_entries">
|
<string-array name="default_read_filter_entries">
|
||||||
<item>@string/all_stories</item>
|
<item>@string/all_stories</item>
|
||||||
<item>@string/unread_only</item>
|
<item>@string/unread_only</item>
|
||||||
|
@ -419,19 +421,52 @@
|
||||||
<item>Cancel</item>
|
<item>Cancel</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string name="settings_auto_open_first_unread">Auto-Open First Story</string>
|
<string name="settings_auto_open_first_unread">Auto-open first story</string>
|
||||||
<string name="settings_auto_open_first_unread_sum">Automatically open first unread story from story list</string>
|
<string name="settings_auto_open_first_unread_sum">Automatically open first unread story in the story list</string>
|
||||||
|
|
||||||
<string name="settings_mark_read_on_scroll">Mark Stories Read On Scroll</string>
|
<string name="settings_mark_read_on_feed_scroll">Mark story titles read on scroll</string>
|
||||||
<string name="settings_mark_read_on_scroll_sum">Automatically mark stories as read when scrolled past</string>
|
<string name="settings_mark_read_on_feed_scroll_sum">Automatically mark stories as read when scrolled past</string>
|
||||||
|
|
||||||
<string name="settings_social">Social</string>
|
<string name="settings_mark_story_read">Mark a story as read…</string>
|
||||||
<string name="settings_show_public_comments">Show Public Comments</string>
|
<string name="mark_story_read_immediately">Immediately</string>
|
||||||
|
<!-- <string name="mark_story_read_5_seconds">After 5 seconds</string>-->
|
||||||
|
<!-- <string name="mark_story_read_10_seconds">After 10 seconds</string>-->
|
||||||
|
<!-- <string name="mark_story_read_20_seconds">After 20 seconds</string>-->
|
||||||
|
<!-- <string name="mark_story_read_30_seconds">After 30 seconds</string>-->
|
||||||
|
<!-- <string name="mark_story_read_45_seconds">After 45 seconds</string>-->
|
||||||
|
<!-- <string name="mark_story_read_60_seconds">After 60 seconds</string>-->
|
||||||
|
<string name="mark_story_read_manually">Manually</string>
|
||||||
|
<string-array name="mark_story_read_entries">
|
||||||
|
<item>@string/mark_story_read_immediately</item>
|
||||||
|
<!-- <item>@string/mark_story_read_5_seconds</item>-->
|
||||||
|
<!-- <item>@string/mark_story_read_10_seconds</item>-->
|
||||||
|
<!-- <item>@string/mark_story_read_20_seconds</item>-->
|
||||||
|
<!-- <item>@string/mark_story_read_30_seconds</item>-->
|
||||||
|
<!-- <item>@string/mark_story_read_45_seconds</item>-->
|
||||||
|
<!-- <item>@string/mark_story_read_60_seconds</item>-->
|
||||||
|
<item>@string/mark_story_read_manually</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="mark_story_read_values">
|
||||||
|
<item>IMMEDIATELY</item>
|
||||||
|
<!-- <item>SECONDS_5</item>-->
|
||||||
|
<!-- <item>SECONDS_10</item>-->
|
||||||
|
<!-- <item>SECONDS_20</item>-->
|
||||||
|
<!-- <item>SECONDS_30</item>-->
|
||||||
|
<!-- <item>SECONDS_45</item>-->
|
||||||
|
<!-- <item>SECONDS_60</item>-->
|
||||||
|
<item>MANUALLY</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string name="mark_story_read_default_value">IMMEDIATELY</string>
|
||||||
|
|
||||||
|
<string name="settings_social">Sharing stories</string>
|
||||||
|
<string name="settings_show_public_comments">Show public comments</string>
|
||||||
<string name="settings_reading">Reading</string>
|
<string name="settings_reading">Reading</string>
|
||||||
<string name="settings_content_preview">Content Preview Text</string>
|
<string name="settings_content_preview">Content preview text…</string>
|
||||||
<string name="settings_thumbnails_style">Image Preview Thumbnails</string>
|
<string name="settings_thumbnails_style">Image preview thumbnails…</string>
|
||||||
<string name="settings_notifications">Notifications</string>
|
<string name="settings_notifications">Notifications</string>
|
||||||
<string name="settings_enable_notifications">Enable Notifications</string>
|
<string name="settings_enable_notifications">Enable notifications</string>
|
||||||
|
|
||||||
<string-array name="show_content_preview_entries">
|
<string-array name="show_content_preview_entries">
|
||||||
<item>@string/story_content_preview_none</item>
|
<item>@string/story_content_preview_none</item>
|
||||||
|
@ -509,10 +544,10 @@
|
||||||
<string name="sync_status_offline">Offline</string>
|
<string name="sync_status_offline">Offline</string>
|
||||||
<string name="sync_status_feed_add">Adding feed …</string>
|
<string name="sync_status_feed_add">Adding feed …</string>
|
||||||
|
|
||||||
<string name="volume_key_navigation">Volume Key Navigation</string>
|
<string name="volume_key_navigation">Volume key navigation…</string>
|
||||||
<string name="off">Off</string>
|
<string name="off">Off</string>
|
||||||
<string name="volume_up_next">Up = Next Story</string>
|
<string name="volume_up_next">Up = next story</string>
|
||||||
<string name="volume_down_next">Down = Next Story</string>
|
<string name="volume_down_next">Down = next story</string>
|
||||||
<string-array name="volume_key_navigation_entries">
|
<string-array name="volume_key_navigation_entries">
|
||||||
<item>@string/off</item>
|
<item>@string/off</item>
|
||||||
<item>@string/volume_up_next</item>
|
<item>@string/volume_up_next</item>
|
||||||
|
@ -525,10 +560,10 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="default_volume_key_navigation_value">OFF</string>
|
<string name="default_volume_key_navigation_value">OFF</string>
|
||||||
|
|
||||||
<string name="settings_confirm_mark_all_read">Confirm Mark All Read</string>
|
<string name="settings_confirm_mark_all_read">Confirm mark all read on…</string>
|
||||||
<string name="none">None</string>
|
<string name="none">Neither</string>
|
||||||
<string name="feed_and_folder">Feeds and Folders</string>
|
<string name="feed_and_folder">Feeds and folders</string>
|
||||||
<string name="folder_only">Folders Only</string>
|
<string name="folder_only">Folders only</string>
|
||||||
<string-array name="confirm_mark_all_read_entries">
|
<string-array name="confirm_mark_all_read_entries">
|
||||||
<item>@string/feed_and_folder</item>
|
<item>@string/feed_and_folder</item>
|
||||||
<item>@string/folder_only</item>
|
<item>@string/folder_only</item>
|
||||||
|
@ -541,15 +576,15 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="confirm_mark_all_read_value">FOLDER_ONLY</string>
|
<string name="confirm_mark_all_read_value">FOLDER_ONLY</string>
|
||||||
|
|
||||||
<string name="settings_confirm_mark_range_read">Confirm Mark Older/Newer Read</string>
|
<string name="settings_confirm_mark_range_read">Confirm mark older/newer read</string>
|
||||||
|
|
||||||
<string name="settings_ltr_gesture_action">Rightward Swipe on Story Title</string>
|
<string name="settings_ltr_gesture_action">Rightward swipe on story title…</string>
|
||||||
<string name="gest_action_none">No Action</string>
|
<string name="gest_action_none">No action</string>
|
||||||
<string name="gest_action_markread">Mark Story Read</string>
|
<string name="gest_action_markread">Mark story as read</string>
|
||||||
<string name="gest_action_markunread">Mark Story Unread</string>
|
<string name="gest_action_markunread">Mark story as unread</string>
|
||||||
<string name="gest_action_save">Save Story</string>
|
<string name="gest_action_save">Save story</string>
|
||||||
<string name="gest_action_unsave">Unsave Story</string>
|
<string name="gest_action_unsave">Unsave story</string>
|
||||||
<string name="gest_action_statistics">Statistics</string>
|
<string name="gest_action_statistics">Site statistics</string>
|
||||||
<string-array name="ltr_gesture_action_entries">
|
<string-array name="ltr_gesture_action_entries">
|
||||||
<item>@string/gest_action_none</item>
|
<item>@string/gest_action_none</item>
|
||||||
<item>@string/gest_action_markread</item>
|
<item>@string/gest_action_markread</item>
|
||||||
|
@ -568,7 +603,7 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="ltr_gesture_action_value">GEST_ACTION_MARKREAD</string>
|
<string name="ltr_gesture_action_value">GEST_ACTION_MARKREAD</string>
|
||||||
|
|
||||||
<string name="settings_rtl_gesture_action">Leftward Swipe on Story Title</string>
|
<string name="settings_rtl_gesture_action">Leftward swipe on story title…</string>
|
||||||
<string-array name="rtl_gesture_action_entries">
|
<string-array name="rtl_gesture_action_entries">
|
||||||
<item>@string/gest_action_none</item>
|
<item>@string/gest_action_none</item>
|
||||||
<item>@string/gest_action_markread</item>
|
<item>@string/gest_action_markread</item>
|
||||||
|
@ -587,8 +622,8 @@
|
||||||
</string-array>
|
</string-array>
|
||||||
<string name="rtl_gesture_action_value">GEST_ACTION_MARKUNREAD</string>
|
<string name="rtl_gesture_action_value">GEST_ACTION_MARKUNREAD</string>
|
||||||
|
|
||||||
<string name="default_browser">Default browser</string>
|
<string name="default_browser">Default browser…</string>
|
||||||
<string name="font">Font</string>
|
<string name="font">Font…</string>
|
||||||
<string name="default_font">Default</string>
|
<string name="default_font">Default</string>
|
||||||
<string name="gotham_narrow_font">Gotham Narrow</string>
|
<string name="gotham_narrow_font">Gotham Narrow</string>
|
||||||
<string name="chronicle_font">Chronicle</string>
|
<string name="chronicle_font">Chronicle</string>
|
||||||
|
@ -649,7 +684,7 @@
|
||||||
<string name="default_default_browser">@string/system_default_prefvalue</string>
|
<string name="default_default_browser">@string/system_default_prefvalue</string>
|
||||||
|
|
||||||
<string name="story_notification_channel_id">story_notification_channel</string>
|
<string name="story_notification_channel_id">story_notification_channel</string>
|
||||||
<string name="story_notification_channel_name">New Stories</string>
|
<string name="story_notification_channel_name">New stories</string>
|
||||||
<string name="go_to_feed">Go to feed</string>
|
<string name="go_to_feed">Go to feed</string>
|
||||||
|
|
||||||
<string name="js_get_selection">(function(){return window.getSelection().toString()})()</string>
|
<string name="js_get_selection">(function(){return window.getSelection().toString()})()</string>
|
||||||
|
|
|
@ -184,8 +184,6 @@
|
||||||
|
|
||||||
<style name="storyButtons" parent="Widget.MaterialComponents.Button.OutlinedButton">
|
<style name="storyButtons" parent="Widget.MaterialComponents.Button.OutlinedButton">
|
||||||
<item name="android:textSize">14sp</item>
|
<item name="android:textSize">14sp</item>
|
||||||
<item name="android:layout_marginLeft">8dp</item>
|
|
||||||
<item name="android:layout_marginRight">8dp</item>
|
|
||||||
<item name="android:textColor">@color/gray75</item>
|
<item name="android:textColor">@color/gray75</item>
|
||||||
<item name="android:textAllCaps">false</item>
|
<item name="android:textAllCaps">false</item>
|
||||||
<item name="android:letterSpacing">0</item>
|
<item name="android:letterSpacing">0</item>
|
||||||
|
@ -195,8 +193,6 @@
|
||||||
</style>
|
</style>
|
||||||
<style name="storyButtons.dark" parent="Widget.MaterialComponents.Button.OutlinedButton">
|
<style name="storyButtons.dark" parent="Widget.MaterialComponents.Button.OutlinedButton">
|
||||||
<item name="android:textSize">14sp</item>
|
<item name="android:textSize">14sp</item>
|
||||||
<item name="android:layout_marginLeft">8dp</item>
|
|
||||||
<item name="android:layout_marginRight">8dp</item>
|
|
||||||
<item name="android:textColor">@color/gray46</item>
|
<item name="android:textColor">@color/gray46</item>
|
||||||
<item name="android:textAllCaps">false</item>
|
<item name="android:textAllCaps">false</item>
|
||||||
<item name="android:letterSpacing">0</item>
|
<item name="android:letterSpacing">0</item>
|
||||||
|
@ -205,6 +201,13 @@
|
||||||
<item name="iconSize">16dp</item>
|
<item name="iconSize">16dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="storyButtonsDimmed" parent="storyButtons">
|
||||||
|
<item name="android:textColor">@color/gray85</item>
|
||||||
|
</style>
|
||||||
|
<style name="storyButtonsDimmed.dark" parent="storyButtons.dark">
|
||||||
|
<item name="android:textColor">@color/gray30</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="shareBarBackground">
|
<style name="shareBarBackground">
|
||||||
<item name="android:background">@color/share_bar_background</item>
|
<item name="android:background">@color/share_bar_background</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<item name="chip">@style/chip</item>
|
<item name="chip">@style/chip</item>
|
||||||
<item name="actionButtons">@style/actionButtons</item>
|
<item name="actionButtons">@style/actionButtons</item>
|
||||||
<item name="storyButtons">@style/storyButtons</item>
|
<item name="storyButtons">@style/storyButtons</item>
|
||||||
|
<item name="storyButtonsDimmed">@style/storyButtonsDimmed</item>
|
||||||
<item name="shareBarBackground">@style/shareBarBackground</item>
|
<item name="shareBarBackground">@style/shareBarBackground</item>
|
||||||
<item name="shareBarText">@style/shareBarText</item>
|
<item name="shareBarText">@style/shareBarText</item>
|
||||||
<item name="commentsHeader">@style/commentsHeader</item>
|
<item name="commentsHeader">@style/commentsHeader</item>
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
<item name="chip">@style/chip.dark</item>
|
<item name="chip">@style/chip.dark</item>
|
||||||
<item name="actionButtons">@style/actionButtons.dark</item>
|
<item name="actionButtons">@style/actionButtons.dark</item>
|
||||||
<item name="storyButtons">@style/storyButtons.dark</item>
|
<item name="storyButtons">@style/storyButtons.dark</item>
|
||||||
|
<item name="storyButtonsDimmed">@style/storyButtonsDimmed.dark</item>
|
||||||
<item name="shareBarBackground">@style/shareBarBackground.dark</item>
|
<item name="shareBarBackground">@style/shareBarBackground.dark</item>
|
||||||
<item name="shareBarText">@style/shareBarText.dark</item>
|
<item name="shareBarText">@style/shareBarText.dark</item>
|
||||||
<item name="commentsHeader">@style/commentsHeader.dark</item>
|
<item name="commentsHeader">@style/commentsHeader.dark</item>
|
||||||
|
@ -135,6 +137,7 @@
|
||||||
<item name="chip">@style/chip.dark</item>
|
<item name="chip">@style/chip.dark</item>
|
||||||
<item name="actionButtons">@style/actionButtons.dark</item>
|
<item name="actionButtons">@style/actionButtons.dark</item>
|
||||||
<item name="storyButtons">@style/storyButtons.dark</item>
|
<item name="storyButtons">@style/storyButtons.dark</item>
|
||||||
|
<item name="storyButtonsDimmed">@style/storyButtonsDimmed.dark</item>
|
||||||
<item name="shareBarBackground">@style/shareBarBackground.black</item>
|
<item name="shareBarBackground">@style/shareBarBackground.black</item>
|
||||||
<item name="shareBarText">@style/shareBarText.dark</item>
|
<item name="shareBarText">@style/shareBarText.dark</item>
|
||||||
<item name="commentsHeader">@style/commentsHeader.black</item>
|
<item name="commentsHeader">@style/commentsHeader.black</item>
|
||||||
|
|
|
@ -57,15 +57,11 @@
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="enable_row_global_shared"
|
android:key="enable_row_global_shared"
|
||||||
android:title="@string/settings_enable_row_global_shared"
|
android:title="@string/settings_enable_row_global_shared" />
|
||||||
android:summary="@string/settings_enable_row_global_shared_sum"
|
|
||||||
/>
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="enable_row_infrequent_stories"
|
android:key="enable_row_infrequent_stories"
|
||||||
android:title="@string/settings_enable_row_infrequent_stories"
|
android:title="@string/settings_enable_row_infrequent_stories" />
|
||||||
android:summary="@string/settings_enable_row_infrequent_stories_sum"
|
|
||||||
/>
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
@ -100,6 +96,11 @@
|
||||||
android:key="pref_auto_open_first_unread"
|
android:key="pref_auto_open_first_unread"
|
||||||
android:title="@string/settings_auto_open_first_unread"
|
android:title="@string/settings_auto_open_first_unread"
|
||||||
android:summary="@string/settings_auto_open_first_unread_sum" />
|
android:summary="@string/settings_auto_open_first_unread_sum" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="pref_mark_read_on_scroll"
|
||||||
|
android:title="@string/settings_mark_read_on_feed_scroll"
|
||||||
|
android:summary="@string/settings_mark_read_on_feed_scroll_sum" />
|
||||||
<ListPreference
|
<ListPreference
|
||||||
android:key="pref_show_content_preview_style"
|
android:key="pref_show_content_preview_style"
|
||||||
android:title="@string/settings_content_preview"
|
android:title="@string/settings_content_preview"
|
||||||
|
@ -114,11 +115,13 @@
|
||||||
android:entries="@array/thumbnail_style_entries"
|
android:entries="@array/thumbnail_style_entries"
|
||||||
android:entryValues="@array/thumbnail_style_values"
|
android:entryValues="@array/thumbnail_style_values"
|
||||||
android:defaultValue="@string/thumbnail_style_default_value" />
|
android:defaultValue="@string/thumbnail_style_default_value" />
|
||||||
<CheckBoxPreference
|
<ListPreference
|
||||||
android:defaultValue="false"
|
android:key="pref_story_mark_read_behavior"
|
||||||
android:key="pref_mark_read_on_scroll"
|
android:title="@string/settings_mark_story_read"
|
||||||
android:title="@string/settings_mark_read_on_scroll"
|
android:dialogTitle="@string/settings_mark_story_read"
|
||||||
android:summary="@string/settings_mark_read_on_scroll_sum" />
|
android:entries="@array/mark_story_read_entries"
|
||||||
|
android:entryValues="@array/mark_story_read_values"
|
||||||
|
android:defaultValue="@string/mark_story_read_default_value" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|
|
@ -196,21 +196,32 @@ public class FeedChooserAdapter extends BaseExpandableListAdapter {
|
||||||
|
|
||||||
private Comparator<Feed> getListComparator() {
|
private Comparator<Feed> getListComparator() {
|
||||||
return (o1, o2) -> {
|
return (o1, o2) -> {
|
||||||
|
// some feeds have missing data
|
||||||
|
if (o1.title == null) o1.title = "";
|
||||||
|
if (o2.title == null) o2.title = "";
|
||||||
if (feedOrderFilter == FeedOrderFilter.NAME && listOrderFilter == ListOrderFilter.ASCENDING) {
|
if (feedOrderFilter == FeedOrderFilter.NAME && listOrderFilter == ListOrderFilter.ASCENDING) {
|
||||||
return o1.title.compareTo(o2.title);
|
return o1.title.compareTo(o2.title);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.NAME && listOrderFilter == ListOrderFilter.DESCENDING) {
|
} else if (feedOrderFilter == FeedOrderFilter.NAME && listOrderFilter == ListOrderFilter.DESCENDING) {
|
||||||
return o2.title.compareTo(o1.title);
|
return o2.title.compareTo(o1.title);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.SUBSCRIBERS && listOrderFilter == ListOrderFilter.ASCENDING) {
|
} else if (o1.subscribers != null && o2.subscribers != null &&
|
||||||
|
feedOrderFilter == FeedOrderFilter.SUBSCRIBERS &&
|
||||||
|
listOrderFilter == ListOrderFilter.ASCENDING) {
|
||||||
return Integer.valueOf(o1.subscribers).compareTo(Integer.valueOf(o2.subscribers));
|
return Integer.valueOf(o1.subscribers).compareTo(Integer.valueOf(o2.subscribers));
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.SUBSCRIBERS && listOrderFilter == ListOrderFilter.DESCENDING) {
|
} else if (o1.subscribers != null && o2.subscribers != null &&
|
||||||
|
feedOrderFilter == FeedOrderFilter.SUBSCRIBERS &&
|
||||||
|
listOrderFilter == ListOrderFilter.DESCENDING) {
|
||||||
return Integer.valueOf(o2.subscribers).compareTo(Integer.valueOf(o1.subscribers));
|
return Integer.valueOf(o2.subscribers).compareTo(Integer.valueOf(o1.subscribers));
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.OPENS && listOrderFilter == ListOrderFilter.ASCENDING) {
|
} else if (feedOrderFilter == FeedOrderFilter.OPENS && listOrderFilter == ListOrderFilter.ASCENDING) {
|
||||||
return Integer.compare(o1.feedOpens, o2.feedOpens);
|
return Integer.compare(o1.feedOpens, o2.feedOpens);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.OPENS && listOrderFilter == ListOrderFilter.DESCENDING) {
|
} else if (feedOrderFilter == FeedOrderFilter.OPENS && listOrderFilter == ListOrderFilter.DESCENDING) {
|
||||||
return Integer.compare(o2.feedOpens, o1.feedOpens);
|
return Integer.compare(o2.feedOpens, o1.feedOpens);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.RECENT_STORY && listOrderFilter == ListOrderFilter.ASCENDING) {
|
} else if (o1.lastStoryDate != null && o2.lastStoryDate != null &&
|
||||||
|
feedOrderFilter == FeedOrderFilter.RECENT_STORY &&
|
||||||
|
listOrderFilter == ListOrderFilter.ASCENDING) {
|
||||||
return compareLastStoryDateTimes(o1.lastStoryDate, o2.lastStoryDate, listOrderFilter);
|
return compareLastStoryDateTimes(o1.lastStoryDate, o2.lastStoryDate, listOrderFilter);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.RECENT_STORY && listOrderFilter == ListOrderFilter.DESCENDING) {
|
} else if (o1.lastStoryDate != null && o2.lastStoryDate != null &&
|
||||||
|
feedOrderFilter == FeedOrderFilter.RECENT_STORY &&
|
||||||
|
listOrderFilter == ListOrderFilter.DESCENDING) {
|
||||||
return compareLastStoryDateTimes(o1.lastStoryDate, o2.lastStoryDate, listOrderFilter);
|
return compareLastStoryDateTimes(o1.lastStoryDate, o2.lastStoryDate, listOrderFilter);
|
||||||
} else if (feedOrderFilter == FeedOrderFilter.STORIES_MONTH && listOrderFilter == ListOrderFilter.ASCENDING) {
|
} else if (feedOrderFilter == FeedOrderFilter.STORIES_MONTH && listOrderFilter == ListOrderFilter.ASCENDING) {
|
||||||
return Integer.compare(o1.storiesPerMonth, o2.storiesPerMonth);
|
return Integer.compare(o1.storiesPerMonth, o2.storiesPerMonth);
|
||||||
|
|
|
@ -16,7 +16,7 @@ public class InfrequentItemsList extends ItemsList implements InfrequentCutoffCh
|
||||||
protected void onCreate(Bundle bundle) {
|
protected void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
UIUtils.setupToolbar(this, R.drawable.ak_icon_allstories, getResources().getString(R.string.infrequent_title), false);
|
UIUtils.setupToolbar(this, R.drawable.ak_icon_infrequent, getResources().getString(R.string.infrequent_title), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class InfrequentReading extends Reading {
|
||||||
protected void onCreate(Bundle savedInstanceBundle) {
|
protected void onCreate(Bundle savedInstanceBundle) {
|
||||||
super.onCreate(savedInstanceBundle);
|
super.onCreate(savedInstanceBundle);
|
||||||
|
|
||||||
UIUtils.setupToolbar(this, R.drawable.ak_icon_allstories, getResources().getString(R.string.infrequent_title), false);
|
UIUtils.setupToolbar(this, R.drawable.ak_icon_infrequent, getResources().getString(R.string.infrequent_title), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class InitActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
installSplashScreen().also {
|
installSplashScreen().also {
|
||||||
it.setKeepVisibleCondition {
|
it.setKeepOnScreenCondition() {
|
||||||
// keep showing the splash screen until FeedUtils.offerInitContext(...)
|
// keep showing the splash screen until FeedUtils.offerInitContext(...)
|
||||||
// finishes and UI ready to display
|
// finishes and UI ready to display
|
||||||
FeedUtils.dbHelper != null || FeedUtils.thumbnailLoader != null
|
FeedUtils.dbHelper != null || FeedUtils.thumbnailLoader != null
|
||||||
|
|
|
@ -266,7 +266,7 @@ public abstract class ItemsList extends NbActivity implements StoryOrderChangedL
|
||||||
menu.findItem(R.id.menu_story_thumbnail_no_preview).setChecked(true);
|
menu.findItem(R.id.menu_story_thumbnail_no_preview).setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isMarkReadOnScroll = PrefsUtils.isMarkReadOnScroll(this);
|
boolean isMarkReadOnScroll = PrefsUtils.isMarkReadOnFeedScroll(this);
|
||||||
if (isMarkReadOnScroll) {
|
if (isMarkReadOnScroll) {
|
||||||
menu.findItem(R.id.menu_mark_read_on_scroll_enabled).setChecked(true);
|
menu.findItem(R.id.menu_mark_read_on_scroll_enabled).setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,6 +36,9 @@ open class NbActivity : AppCompatActivity() {
|
||||||
PrefsUtils.applyThemePreference(this)
|
PrefsUtils.applyThemePreference(this)
|
||||||
lastTheme = PrefsUtils.getSelectedTheme(this)
|
lastTheme = PrefsUtils.getSelectedTheme(this)
|
||||||
|
|
||||||
|
super.onCreate(bundle)
|
||||||
|
offerInitContext(this)
|
||||||
|
|
||||||
// in rare cases of process interruption or DB corruption, an activity can launch without valid
|
// in rare cases of process interruption or DB corruption, an activity can launch without valid
|
||||||
// login creds. redirect the user back to the loging workflow.
|
// login creds. redirect the user back to the loging workflow.
|
||||||
if (PrefsUtils.getUserId(this) == null) {
|
if (PrefsUtils.getUserId(this) == null) {
|
||||||
|
@ -44,9 +47,6 @@ open class NbActivity : AppCompatActivity() {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onCreate(bundle)
|
|
||||||
offerInitContext(this)
|
|
||||||
|
|
||||||
bundle?.let {
|
bundle?.let {
|
||||||
uniqueLoginKey = it.getString(UNIQUE_LOGIN_KEY)
|
uniqueLoginKey = it.getString(UNIQUE_LOGIN_KEY)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import com.newsblur.util.PrefConstants.ThemeValue
|
||||||
import com.newsblur.view.ReadingScrollView.ScrollChangeListener
|
import com.newsblur.view.ReadingScrollView.ScrollChangeListener
|
||||||
import com.newsblur.viewModel.StoriesViewModel
|
import com.newsblur.viewModel.StoriesViewModel
|
||||||
import java.lang.Runnable
|
import java.lang.Runnable
|
||||||
import java.util.*
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeListener,
|
abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeListener,
|
||||||
|
@ -52,6 +51,8 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
private var readingAdapter: ReadingAdapter? = null
|
private var readingAdapter: ReadingAdapter? = null
|
||||||
private var stopLoading = false
|
private var stopLoading = false
|
||||||
private var unreadSearchActive = false
|
private var unreadSearchActive = false
|
||||||
|
// marking a story as read immediately on reading page scroll
|
||||||
|
private var isMarkStoryReadImmediately = false
|
||||||
|
|
||||||
// unread count for the circular progress overlay. set to nonzero to activate the progress indicator overlay
|
// unread count for the circular progress overlay. set to nonzero to activate the progress indicator overlay
|
||||||
private var startingUnreadCount = 0
|
private var startingUnreadCount = 0
|
||||||
|
@ -59,6 +60,14 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
private var overlayRangeBotPx = 0f
|
private var overlayRangeBotPx = 0f
|
||||||
private var lastVScrollPos = 0
|
private var lastVScrollPos = 0
|
||||||
|
|
||||||
|
// enabling multi window mode from recent apps on the device
|
||||||
|
// creates a different activity lifecycle compared to a device rotation
|
||||||
|
// resulting in onPause being called when the app is actually on the screen.
|
||||||
|
// calling onPause sets stopLoading as true and content wouldn't be loaded.
|
||||||
|
// track the multi window mode config change and skip stopLoading in first onPause call.
|
||||||
|
// refactor stopLoading mechanism as a cancellation signal tied to the view lifecycle.
|
||||||
|
private var isMultiWindowModeHack = false
|
||||||
|
|
||||||
private val pageHistory = mutableListOf<Story>()
|
private val pageHistory = mutableListOf<Story>()
|
||||||
|
|
||||||
private lateinit var volumeKeyNavigation: VolumeKeyNavigation
|
private lateinit var volumeKeyNavigation: VolumeKeyNavigation
|
||||||
|
@ -107,6 +116,7 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
|
|
||||||
intelState = PrefsUtils.getStateFilter(this)
|
intelState = PrefsUtils.getStateFilter(this)
|
||||||
volumeKeyNavigation = PrefsUtils.getVolumeKeyNavigation(this)
|
volumeKeyNavigation = PrefsUtils.getVolumeKeyNavigation(this)
|
||||||
|
isMarkStoryReadImmediately = PrefsUtils.isMarkStoryReadImmediately(this)
|
||||||
|
|
||||||
setupViews()
|
setupViews()
|
||||||
setupListeners()
|
setupListeners()
|
||||||
|
@ -143,8 +153,17 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
stopLoading = true
|
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
if (isMultiWindowModeHack) {
|
||||||
|
isMultiWindowModeHack = false
|
||||||
|
} else {
|
||||||
|
stopLoading = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration?) {
|
||||||
|
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
|
||||||
|
isMultiWindowModeHack = isInMultiWindowMode
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupViews() {
|
private fun setupViews() {
|
||||||
|
@ -164,12 +183,10 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
enableProgressCircle(binding.readingOverlayProgressLeft, false)
|
enableProgressCircle(binding.readingOverlayProgressLeft, false)
|
||||||
enableProgressCircle(binding.readingOverlayProgressRight, false)
|
enableProgressCircle(binding.readingOverlayProgressRight, false)
|
||||||
|
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.findFragmentByTag(ReadingPagerFragment::class.java.name)
|
||||||
val fragment =
|
?: supportFragmentManager.commit {
|
||||||
supportFragmentManager.findFragmentByTag(ReadingPagerFragment::class.java.name) as ReadingPagerFragment?
|
add(R.id.activity_reading_container, ReadingPagerFragment.newInstance(), ReadingPagerFragment::class.java.name)
|
||||||
?: ReadingPagerFragment.newInstance()
|
}
|
||||||
add(R.id.activity_reading_container, fragment, ReadingPagerFragment::class.java.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupListeners() {
|
private fun setupListeners() {
|
||||||
|
@ -371,13 +388,15 @@ abstract class Reading : NbActivity(), OnPageChangeListener, OnSeekBarChangeList
|
||||||
readingAdapter?.let { readingAdapter ->
|
readingAdapter?.let { readingAdapter ->
|
||||||
val story = readingAdapter.getStory(position)
|
val story = readingAdapter.getStory(position)
|
||||||
if (story != null) {
|
if (story != null) {
|
||||||
FeedUtils.markStoryAsRead(story, this@Reading)
|
|
||||||
synchronized(pageHistory) {
|
synchronized(pageHistory) {
|
||||||
// if the history is just starting out or the last entry in it isn't this page, add this page
|
// if the history is just starting out or the last entry in it isn't this page, add this page
|
||||||
if (pageHistory.size < 1 || story != pageHistory[pageHistory.size - 1]) {
|
if (pageHistory.size < 1 || story != pageHistory[pageHistory.size - 1]) {
|
||||||
pageHistory.add(story)
|
pageHistory.add(story)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isMarkStoryReadImmediately) {
|
||||||
|
FeedUtils.markStoryAsRead(story, this@Reading)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
checkStoryCount(position)
|
checkStoryCount(position)
|
||||||
updateOverlayText()
|
updateOverlayText()
|
||||||
|
|
|
@ -570,13 +570,6 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||||
vh.intelDot.setImageResource(android.R.color.transparent);
|
vh.intelDot.setImageResource(android.R.color.transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// M text size equals to 1.0
|
|
||||||
if (textSize > 1.0) {
|
|
||||||
vh.storyTitleView.setMaxLines(3);
|
|
||||||
} else {
|
|
||||||
vh.storyTitleView.setMaxLines(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
vh.storyTitleView.setText(UIUtils.fromHtml(story.title));
|
vh.storyTitleView.setText(UIUtils.fromHtml(story.title));
|
||||||
vh.storyDate.setText(StoryUtils.formatShortDate(context, story.timestamp));
|
vh.storyDate.setText(StoryUtils.formatShortDate(context, story.timestamp));
|
||||||
|
|
||||||
|
@ -659,6 +652,7 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||||
private void bindRow(StoryRowViewHolder vh, int position, Story story) {
|
private void bindRow(StoryRowViewHolder vh, int position, Story story) {
|
||||||
StoryContentPreviewStyle storyContentPreviewStyle = PrefsUtils.getStoryContentPreviewStyle(context);
|
StoryContentPreviewStyle storyContentPreviewStyle = PrefsUtils.getStoryContentPreviewStyle(context);
|
||||||
if (storyContentPreviewStyle != StoryContentPreviewStyle.NONE) {
|
if (storyContentPreviewStyle != StoryContentPreviewStyle.NONE) {
|
||||||
|
vh.storyTitleView.setMaxLines(3);
|
||||||
if (storyContentPreviewStyle == StoryContentPreviewStyle.LARGE) {
|
if (storyContentPreviewStyle == StoryContentPreviewStyle.LARGE) {
|
||||||
vh.storySnippet.setMaxLines(6);
|
vh.storySnippet.setMaxLines(6);
|
||||||
} else if (storyContentPreviewStyle == StoryContentPreviewStyle.MEDIUM) {
|
} else if (storyContentPreviewStyle == StoryContentPreviewStyle.MEDIUM) {
|
||||||
|
@ -669,6 +663,7 @@ public class StoryViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
||||||
vh.storySnippet.setVisibility(View.VISIBLE);
|
vh.storySnippet.setVisibility(View.VISIBLE);
|
||||||
vh.storySnippet.setText(story.shortContent);
|
vh.storySnippet.setText(story.shortContent);
|
||||||
} else {
|
} else {
|
||||||
|
vh.storyTitleView.setMaxLines(6);
|
||||||
vh.storySnippet.setVisibility(View.GONE);
|
vh.storySnippet.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,7 +441,7 @@ public class ItemSetFragment extends NbFragment {
|
||||||
indexOfLastUnread = -1;
|
indexOfLastUnread = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PrefsUtils.isMarkReadOnScroll(getActivity())) {
|
if (PrefsUtils.isMarkReadOnFeedScroll(requireContext())) {
|
||||||
// we want the top row of stories that is partially obscured. go back one from the first fully visible
|
// we want the top row of stories that is partially obscured. go back one from the first fully visible
|
||||||
int markEnd = layoutManager.findFirstCompletelyVisibleItemPosition() - 1;
|
int markEnd = layoutManager.findFirstCompletelyVisibleItemPosition() - 1;
|
||||||
if (markEnd > lastAutoMarkIndex) {
|
if (markEnd > lastAutoMarkIndex) {
|
||||||
|
@ -451,7 +451,7 @@ public class ItemSetFragment extends NbFragment {
|
||||||
int index = markEnd - i;
|
int index = markEnd - i;
|
||||||
Story story = adapter.getStory(index);
|
Story story = adapter.getStory(index);
|
||||||
if (story != null) {
|
if (story != null) {
|
||||||
FeedUtils.markStoryAsRead(story, getActivity());
|
FeedUtils.markStoryAsRead(story, requireContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.res.Configuration
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
@ -16,12 +17,13 @@ import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.newsblur.R
|
import com.newsblur.R
|
||||||
import com.newsblur.activity.FeedItemsList
|
import com.newsblur.activity.FeedItemsList
|
||||||
import com.newsblur.activity.Reading
|
import com.newsblur.activity.Reading
|
||||||
import com.newsblur.databinding.FragmentReadingitemBinding
|
import com.newsblur.databinding.FragmentReadingitemBinding
|
||||||
import com.newsblur.databinding.IncludeReadingItemCommentBinding
|
import com.newsblur.databinding.ReadingItemActionsBinding
|
||||||
import com.newsblur.domain.Classifier
|
import com.newsblur.domain.Classifier
|
||||||
import com.newsblur.domain.Story
|
import com.newsblur.domain.Story
|
||||||
import com.newsblur.domain.UserDetails
|
import com.newsblur.domain.UserDetails
|
||||||
|
@ -33,7 +35,6 @@ import com.newsblur.service.NBSyncReceiver.Companion.UPDATE_TEXT
|
||||||
import com.newsblur.service.OriginalTextService
|
import com.newsblur.service.OriginalTextService
|
||||||
import com.newsblur.util.*
|
import com.newsblur.util.*
|
||||||
import com.newsblur.util.PrefConstants.ThemeValue
|
import com.newsblur.util.PrefConstants.ThemeValue
|
||||||
import java.util.*
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
@ -81,7 +82,9 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
private val webViewContentMutex = Any()
|
private val webViewContentMutex = Any()
|
||||||
|
|
||||||
private lateinit var binding: FragmentReadingitemBinding
|
private lateinit var binding: FragmentReadingitemBinding
|
||||||
private lateinit var itemCommentBinding: IncludeReadingItemCommentBinding
|
private lateinit var readingItemActionsBinding: ReadingItemActionsBinding
|
||||||
|
|
||||||
|
private lateinit var markStoryReadBehavior: MarkStoryReadBehavior
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
@ -97,7 +100,8 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
classifier = requireArguments().getSerializable("classifier") as Classifier?
|
classifier = requireArguments().getSerializable("classifier") as Classifier?
|
||||||
sourceUserId = requireArguments().getString("sourceUserId")
|
sourceUserId = requireArguments().getString("sourceUserId")
|
||||||
|
|
||||||
user = PrefsUtils.getUserDetails(requireActivity())
|
user = PrefsUtils.getUserDetails(requireContext())
|
||||||
|
markStoryReadBehavior = PrefsUtils.getMarkStoryReadBehavior(requireContext())
|
||||||
textSizeReceiver = TextSizeReceiver()
|
textSizeReceiver = TextSizeReceiver()
|
||||||
|
|
||||||
requireActivity().registerReceiver(textSizeReceiver, IntentFilter(TEXT_SIZE_CHANGED))
|
requireActivity().registerReceiver(textSizeReceiver, IntentFilter(TEXT_SIZE_CHANGED))
|
||||||
|
@ -142,7 +146,7 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_readingitem, container, false)
|
val view = inflater.inflate(R.layout.fragment_readingitem, container, false)
|
||||||
binding = FragmentReadingitemBinding.bind(view)
|
binding = FragmentReadingitemBinding.bind(view)
|
||||||
itemCommentBinding = IncludeReadingItemCommentBinding.bind(binding.root)
|
readingItemActionsBinding = ReadingItemActionsBinding.bind(binding.root)
|
||||||
|
|
||||||
val readingActivity = requireActivity() as Reading
|
val readingActivity = requireActivity() as Reading
|
||||||
fs = readingActivity.fs
|
fs = readingActivity.fs
|
||||||
|
@ -160,6 +164,7 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
updateTrainButton()
|
updateTrainButton()
|
||||||
updateShareButton()
|
updateShareButton()
|
||||||
updateSaveButton()
|
updateSaveButton()
|
||||||
|
updateMarkReadButton()
|
||||||
setupItemCommentsAndShares()
|
setupItemCommentsAndShares()
|
||||||
|
|
||||||
binding.readingScrollview.registerScrollChangeListener(readingActivity)
|
binding.readingScrollview.registerScrollChangeListener(readingActivity)
|
||||||
|
@ -170,9 +175,10 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.storyContextMenuButton.setOnClickListener { onClickMenuButton() }
|
binding.storyContextMenuButton.setOnClickListener { onClickMenuButton() }
|
||||||
itemCommentBinding.trainStoryButton.setOnClickListener { clickTrain() }
|
readingItemActionsBinding.markReadStoryButton.setOnClickListener { clickMarkStoryRead() }
|
||||||
itemCommentBinding.saveStoryButton.setOnClickListener { clickSave() }
|
readingItemActionsBinding.trainStoryButton.setOnClickListener { clickTrain() }
|
||||||
itemCommentBinding.shareStoryButton.setOnClickListener { clickShare() }
|
readingItemActionsBinding.saveStoryButton.setOnClickListener { clickSave() }
|
||||||
|
readingItemActionsBinding.shareStoryButton.setOnClickListener { clickShare() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo?) {
|
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo?) {
|
||||||
|
@ -330,13 +336,27 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clickMarkStoryRead() {
|
||||||
|
if (story!!.read) FeedUtils.markStoryUnread(story!!, requireContext())
|
||||||
|
else FeedUtils.markStoryAsRead(story!!, requireContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateMarkReadButton() {
|
||||||
|
if (markStoryReadBehavior == MarkStoryReadBehavior.MANUALLY) {
|
||||||
|
readingItemActionsBinding.markReadStoryButton.visibility = View.VISIBLE
|
||||||
|
readingItemActionsBinding.markReadStoryButton.setStoryReadState(requireContext(), story!!.read)
|
||||||
|
} else {
|
||||||
|
readingItemActionsBinding.markReadStoryButton.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun clickTrain() {
|
private fun clickTrain() {
|
||||||
val intelFrag = StoryIntelTrainerFragment.newInstance(story, fs)
|
val intelFrag = StoryIntelTrainerFragment.newInstance(story, fs)
|
||||||
intelFrag.show(requireActivity().supportFragmentManager, StoryIntelTrainerFragment::class.java.name)
|
intelFrag.show(requireActivity().supportFragmentManager, StoryIntelTrainerFragment::class.java.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTrainButton() {
|
private fun updateTrainButton() {
|
||||||
itemCommentBinding.trainStoryButton.visibility = if (story!!.feedId == "0") View.GONE else View.VISIBLE
|
readingItemActionsBinding.trainStoryButton.visibility = if (story!!.feedId == "0") View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clickSave() {
|
private fun clickSave() {
|
||||||
|
@ -348,7 +368,7 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSaveButton() {
|
private fun updateSaveButton() {
|
||||||
itemCommentBinding.saveStoryButton.setText(if (story!!.starred) R.string.unsave_this else R.string.save_this)
|
readingItemActionsBinding.saveStoryButton.setText(if (story!!.starred) R.string.unsave_this else R.string.save_this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clickShare() {
|
private fun clickShare() {
|
||||||
|
@ -359,11 +379,11 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
private fun updateShareButton() {
|
private fun updateShareButton() {
|
||||||
for (userId in story!!.sharedUserIds) {
|
for (userId in story!!.sharedUserIds) {
|
||||||
if (TextUtils.equals(userId, user!!.id)) {
|
if (TextUtils.equals(userId, user!!.id)) {
|
||||||
itemCommentBinding.shareStoryButton.setText(R.string.already_shared)
|
readingItemActionsBinding.shareStoryButton.setText(R.string.already_shared)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemCommentBinding.shareStoryButton.setText(R.string.share_this)
|
readingItemActionsBinding.shareStoryButton.setText(R.string.share_this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupItemCommentsAndShares() {
|
private fun setupItemCommentsAndShares() {
|
||||||
|
@ -603,6 +623,7 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
if (updateType and UPDATE_STORY != 0) {
|
if (updateType and UPDATE_STORY != 0) {
|
||||||
updateSaveButton()
|
updateSaveButton()
|
||||||
updateShareButton()
|
updateShareButton()
|
||||||
|
updateMarkReadButton()
|
||||||
setupItemCommentsAndShares()
|
setupItemCommentsAndShares()
|
||||||
}
|
}
|
||||||
if (updateType and UPDATE_TEXT != 0) {
|
if (updateType and UPDATE_TEXT != 0) {
|
||||||
|
@ -908,4 +929,27 @@ class ReadingItemFragment : NbFragment(), PopupMenu.OnMenuItemClickListener {
|
||||||
private val altSniff4 = Pattern.compile("<img[^>]*title=(['\"])((?:(?!\\1).)*)\\1[^>]*src=(['\"])((?:(?!\\3).)*)\\3[^>]*>", Pattern.CASE_INSENSITIVE)
|
private val altSniff4 = Pattern.compile("<img[^>]*title=(['\"])((?:(?!\\1).)*)\\1[^>]*src=(['\"])((?:(?!\\3).)*)\\3[^>]*>", Pattern.CASE_INSENSITIVE)
|
||||||
private val imgSniff = Pattern.compile("<img[^>]*(src\\s*=\\s*)\"([^\"]*)\"[^>]*>", Pattern.CASE_INSENSITIVE)
|
private val imgSniff = Pattern.compile("<img[^>]*(src\\s*=\\s*)\"([^\"]*)\"[^>]*>", Pattern.CASE_INSENSITIVE)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MaterialButton.setStoryReadState(context: Context, isRead: Boolean) {
|
||||||
|
var selectedTheme = PrefsUtils.getSelectedTheme(context)
|
||||||
|
if (selectedTheme == ThemeValue.AUTO) {
|
||||||
|
selectedTheme = when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
|
||||||
|
Configuration.UI_MODE_NIGHT_YES -> ThemeValue.DARK
|
||||||
|
else -> ThemeValue.LIGHT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val styleResId: Int = when (selectedTheme) {
|
||||||
|
ThemeValue.LIGHT -> if (isRead) R.style.storyButtonsDimmed else R.style.storyButtons
|
||||||
|
else -> if (isRead) R.style.storyButtonsDimmed_dark else R.style.storyButtons_dark
|
||||||
|
}
|
||||||
|
val stringResId: Int = if (isRead) R.string.story_mark_unread_state else R.string.story_mark_read_state
|
||||||
|
this.text = context.getString(stringResId)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
this.setTextAppearance(styleResId)
|
||||||
|
} else {
|
||||||
|
this.setTextAppearance(context, styleResId)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,11 +7,11 @@ import android.app.job.JobService
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.newsblur.subscription.SubscriptionManagerImpl
|
import com.newsblur.subscription.SubscriptionManagerImpl
|
||||||
|
import com.newsblur.subscription.SubscriptionsListener
|
||||||
import com.newsblur.util.AppConstants
|
import com.newsblur.util.AppConstants
|
||||||
import com.newsblur.util.Log
|
import com.newsblur.util.Log
|
||||||
import com.newsblur.util.NBScope
|
import com.newsblur.util.NBScope
|
||||||
import com.newsblur.util.PrefsUtils
|
import com.newsblur.util.PrefsUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,8 @@ import kotlinx.coroutines.launch
|
||||||
*/
|
*/
|
||||||
class SubscriptionSyncService : JobService() {
|
class SubscriptionSyncService : JobService() {
|
||||||
|
|
||||||
|
private val scope = NBScope
|
||||||
|
|
||||||
override fun onStartJob(params: JobParameters?): Boolean {
|
override fun onStartJob(params: JobParameters?): Boolean {
|
||||||
Log.d(this, "onStartJob")
|
Log.d(this, "onStartJob")
|
||||||
if (!PrefsUtils.hasCookie(this)) {
|
if (!PrefsUtils.hasCookie(this)) {
|
||||||
|
@ -31,15 +33,22 @@ class SubscriptionSyncService : JobService() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
NBScope.launch(Dispatchers.Default) {
|
val subscriptionManager = SubscriptionManagerImpl(this@SubscriptionSyncService, scope)
|
||||||
val subscriptionManager = SubscriptionManagerImpl(this@SubscriptionSyncService, this)
|
subscriptionManager.startBillingConnection(object : SubscriptionsListener {
|
||||||
val job = subscriptionManager.syncActiveSubscription()
|
override fun onBillingConnectionReady() {
|
||||||
job.invokeOnCompletion {
|
scope.launch {
|
||||||
Log.d(this, "sync active subscription completed.")
|
subscriptionManager.syncActiveSubscription()
|
||||||
// manually trigger jobFinished after work is done
|
Log.d(this, "sync active subscription completed.")
|
||||||
|
// manually call jobFinished after work is done
|
||||||
|
jobFinished(params, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBillingConnectionError(message: String?) {
|
||||||
|
// manually call jobFinished on error
|
||||||
jobFinished(params, false)
|
jobFinished(params, false)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
return true // returning true due to background thread work
|
return true // returning true due to background thread work
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ interface SubscriptionManager {
|
||||||
/**
|
/**
|
||||||
* Sync subscription state between NewsBlur and Play Store.
|
* Sync subscription state between NewsBlur and Play Store.
|
||||||
*/
|
*/
|
||||||
fun syncActiveSubscription(): Job
|
suspend fun syncActiveSubscription(): Job
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify backend of active Play Store subscription.
|
* Notify backend of active Play Store subscription.
|
||||||
|
@ -70,13 +70,13 @@ interface SubscriptionManager {
|
||||||
|
|
||||||
interface SubscriptionsListener {
|
interface SubscriptionsListener {
|
||||||
|
|
||||||
fun onActiveSubscription(renewalMessage: String?)
|
fun onActiveSubscription(renewalMessage: String?) {}
|
||||||
|
|
||||||
fun onAvailableSubscription(skuDetails: SkuDetails)
|
fun onAvailableSubscription(skuDetails: SkuDetails) {}
|
||||||
|
|
||||||
fun onBillingConnectionReady()
|
fun onBillingConnectionReady() {}
|
||||||
|
|
||||||
fun onBillingConnectionError(message: String? = null)
|
fun onBillingConnectionError(message: String? = null) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SubscriptionManagerImpl(
|
class SubscriptionManagerImpl(
|
||||||
|
@ -90,7 +90,9 @@ class SubscriptionManagerImpl(
|
||||||
when (billingResult.responseCode) {
|
when (billingResult.responseCode) {
|
||||||
BillingClient.BillingResponseCode.OK -> {
|
BillingClient.BillingResponseCode.OK -> {
|
||||||
Log.d(this, "acknowledgePurchaseResponseListener OK")
|
Log.d(this, "acknowledgePurchaseResponseListener OK")
|
||||||
syncActiveSubscription()
|
scope.launch(Dispatchers.Default) {
|
||||||
|
syncActiveSubscription()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> {
|
BillingClient.BillingResponseCode.BILLING_UNAVAILABLE -> {
|
||||||
// Billing API version is not supported for the type requested.
|
// Billing API version is not supported for the type requested.
|
||||||
|
@ -174,7 +176,7 @@ class SubscriptionManagerImpl(
|
||||||
billingClient.launchBillingFlow(activity, billingFlowParams)
|
billingClient.launchBillingFlow(activity, billingFlowParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun syncActiveSubscription() = scope.launch(Dispatchers.Default) {
|
override suspend fun syncActiveSubscription() = scope.launch(Dispatchers.Default) {
|
||||||
val hasNewsBlurSubscription = PrefsUtils.getIsPremium(context)
|
val hasNewsBlurSubscription = PrefsUtils.getIsPremium(context)
|
||||||
val activePlayStoreSubscription = getActiveSubscriptionAsync().await()
|
val activePlayStoreSubscription = getActiveSubscriptionAsync().await()
|
||||||
|
|
||||||
|
@ -258,7 +260,9 @@ class SubscriptionManagerImpl(
|
||||||
private fun handlePurchase(purchase: Purchase) {
|
private fun handlePurchase(purchase: Purchase) {
|
||||||
Log.d(this, "handlePurchase: ${purchase.orderId}")
|
Log.d(this, "handlePurchase: ${purchase.orderId}")
|
||||||
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED && purchase.isAcknowledged) {
|
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED && purchase.isAcknowledged) {
|
||||||
syncActiveSubscription()
|
scope.launch(Dispatchers.Default) {
|
||||||
|
syncActiveSubscription()
|
||||||
|
}
|
||||||
} else if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged) {
|
} else if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED && !purchase.isAcknowledged) {
|
||||||
// need to acknowledge first time sub otherwise it will void
|
// need to acknowledge first time sub otherwise it will void
|
||||||
Log.d(this, "acknowledge purchase: ${purchase.orderId}")
|
Log.d(this, "acknowledge purchase: ${purchase.orderId}")
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.newsblur.util
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same values as R.string.mark_story_read_values
|
||||||
|
*/
|
||||||
|
enum class MarkStoryReadBehavior {
|
||||||
|
IMMEDIATELY,
|
||||||
|
SECONDS_5,
|
||||||
|
SECONDS_10,
|
||||||
|
SECONDS_20,
|
||||||
|
SECONDS_30,
|
||||||
|
SECONDS_45,
|
||||||
|
SECONDS_60,
|
||||||
|
MANUALLY,
|
||||||
|
}
|
|
@ -114,19 +114,19 @@ public class NotificationUtils {
|
||||||
// UI on some devices.
|
// UI on some devices.
|
||||||
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
// set the requestCode to the story hashcode to prevent the PI re-using the wrong Intent
|
// set the requestCode to the story hashcode to prevent the PI re-using the wrong Intent
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, story.hashCode(), i, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingIntent = PendingIntentUtils.getImmutableActivity(context, story.hashCode(), i, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
Intent dismissIntent = new Intent(context, NotifyDismissReceiver.class);
|
Intent dismissIntent = new Intent(context, NotifyDismissReceiver.class);
|
||||||
dismissIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
dismissIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
||||||
PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), story.hashCode(), dismissIntent, 0);
|
PendingIntent dismissPendingIntent = PendingIntentUtils.getImmutableBroadcast(context.getApplicationContext(), story.hashCode(), dismissIntent, 0);
|
||||||
|
|
||||||
Intent saveIntent = new Intent(context, NotifySaveReceiver.class);
|
Intent saveIntent = new Intent(context, NotifySaveReceiver.class);
|
||||||
saveIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
saveIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
||||||
PendingIntent savePendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), story.hashCode(), saveIntent, 0);
|
PendingIntent savePendingIntent = PendingIntentUtils.getImmutableBroadcast(context.getApplicationContext(), story.hashCode(), saveIntent, 0);
|
||||||
|
|
||||||
Intent markreadIntent = new Intent(context, NotifyMarkreadReceiver.class);
|
Intent markreadIntent = new Intent(context, NotifyMarkreadReceiver.class);
|
||||||
markreadIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
markreadIntent.putExtra(Reading.EXTRA_STORY_HASH, story.storyHash);
|
||||||
PendingIntent markreadPendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), story.hashCode(), markreadIntent, 0);
|
PendingIntent markreadPendingIntent = PendingIntentUtils.getImmutableBroadcast(context.getApplicationContext(), story.hashCode(), markreadIntent, 0);
|
||||||
|
|
||||||
String feedTitle = cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_TITLE));
|
String feedTitle = cursor.getString(cursor.getColumnIndex(DatabaseConstants.FEED_TITLE));
|
||||||
StringBuilder title = new StringBuilder();
|
StringBuilder title = new StringBuilder();
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.newsblur.util
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
|
||||||
|
object PendingIntentUtils {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getImmutableActivity(
|
||||||
|
context: Context, requestCode: Int,
|
||||||
|
intent: Intent, flags: Int): PendingIntent? =
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
PendingIntent.getActivity(context, requestCode, intent, flags or PendingIntent.FLAG_IMMUTABLE, null)
|
||||||
|
} else {
|
||||||
|
PendingIntent.getActivity(context, requestCode, intent, flags, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getImmutableBroadcast(
|
||||||
|
context: Context, requestCode: Int,
|
||||||
|
intent: Intent, flags: Int): PendingIntent? =
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
PendingIntent.getBroadcast(context, requestCode, intent, flags or PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
} else {
|
||||||
|
PendingIntent.getBroadcast(context, requestCode, intent, flags)
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,7 @@ public class PrefConstants {
|
||||||
public static final String STORIES_MARK_READ_ON_SCROLL = "pref_mark_read_on_scroll";
|
public static final String STORIES_MARK_READ_ON_SCROLL = "pref_mark_read_on_scroll";
|
||||||
public static final String STORIES_SHOW_PREVIEWS_STYLE = "pref_show_content_preview_style";
|
public static final String STORIES_SHOW_PREVIEWS_STYLE = "pref_show_content_preview_style";
|
||||||
public static final String STORIES_THUMBNAIL_STYLE = "pref_thumbnail_style";
|
public static final String STORIES_THUMBNAIL_STYLE = "pref_thumbnail_style";
|
||||||
|
public static final String STORY_MARK_READ_BEHAVIOR = "pref_story_mark_read_behavior";
|
||||||
|
|
||||||
public static final String ENABLE_OFFLINE = "enable_offline";
|
public static final String ENABLE_OFFLINE = "enable_offline";
|
||||||
public static final String ENABLE_IMAGE_PREFETCH = "enable_image_prefetch";
|
public static final String ENABLE_IMAGE_PREFETCH = "enable_image_prefetch";
|
||||||
|
|
|
@ -734,7 +734,7 @@ public class PrefsUtils {
|
||||||
return prefs.getBoolean(PrefConstants.STORIES_AUTO_OPEN_FIRST, false);
|
return prefs.getBoolean(PrefConstants.STORIES_AUTO_OPEN_FIRST, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isMarkReadOnScroll(Context context) {
|
public static boolean isMarkReadOnFeedScroll(Context context) {
|
||||||
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
SharedPreferences prefs = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||||
return prefs.getBoolean(PrefConstants.STORIES_MARK_READ_ON_SCROLL, false);
|
return prefs.getBoolean(PrefConstants.STORIES_MARK_READ_ON_SCROLL, false);
|
||||||
}
|
}
|
||||||
|
@ -1040,4 +1040,13 @@ public class PrefsUtils {
|
||||||
SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, Context.MODE_PRIVATE);
|
SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, Context.MODE_PRIVATE);
|
||||||
return preferences.getString(PrefConstants.PREF_COOKIE, null) != null;
|
return preferences.getString(PrefConstants.PREF_COOKIE, null) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MarkStoryReadBehavior getMarkStoryReadBehavior(Context context) {
|
||||||
|
SharedPreferences preferences = context.getSharedPreferences(PrefConstants.PREFERENCES, 0);
|
||||||
|
return MarkStoryReadBehavior.valueOf(preferences.getString(PrefConstants.STORY_MARK_READ_BEHAVIOR, MarkStoryReadBehavior.IMMEDIATELY.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMarkStoryReadImmediately(Context context) {
|
||||||
|
return getMarkStoryReadBehavior(context).equals(MarkStoryReadBehavior.IMMEDIATELY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.newsblur.activity.AllStoriesItemsList;
|
||||||
import com.newsblur.activity.ItemsList;
|
import com.newsblur.activity.ItemsList;
|
||||||
import com.newsblur.activity.WidgetConfig;
|
import com.newsblur.activity.WidgetConfig;
|
||||||
import com.newsblur.util.FeedSet;
|
import com.newsblur.util.FeedSet;
|
||||||
|
import com.newsblur.util.PendingIntentUtils;
|
||||||
import com.newsblur.util.PrefsUtils;
|
import com.newsblur.util.PrefsUtils;
|
||||||
import com.newsblur.util.WidgetBackground;
|
import com.newsblur.util.WidgetBackground;
|
||||||
|
|
||||||
|
@ -88,8 +89,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
||||||
|
|
||||||
Intent configIntent = new Intent(context, WidgetProvider.class);
|
Intent configIntent = new Intent(context, WidgetProvider.class);
|
||||||
configIntent.setAction(WidgetUtils.ACTION_OPEN_CONFIG);
|
configIntent.setAction(WidgetUtils.ACTION_OPEN_CONFIG);
|
||||||
PendingIntent configIntentTemplate = PendingIntent.getBroadcast(context, WidgetUtils.RC_WIDGET_CONFIG, configIntent,
|
PendingIntent configIntentTemplate = PendingIntentUtils.getImmutableBroadcast(context, WidgetUtils.RC_WIDGET_CONFIG, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
rv.setOnClickPendingIntent(R.id.widget_empty_view, configIntentTemplate);
|
rv.setOnClickPendingIntent(R.id.widget_empty_view, configIntentTemplate);
|
||||||
|
|
||||||
// This section makes it possible for items to have individualized behavior.
|
// This section makes it possible for items to have individualized behavior.
|
||||||
|
@ -104,7 +104,7 @@ public class WidgetProvider extends AppWidgetProvider {
|
||||||
touchIntent.setAction(WidgetUtils.ACTION_OPEN_STORY);
|
touchIntent.setAction(WidgetUtils.ACTION_OPEN_STORY);
|
||||||
touchIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
touchIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||||
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||||
PendingIntent touchIntentTemplate = PendingIntent.getBroadcast(context, WidgetUtils.RC_WIDGET_STORY, touchIntent,
|
PendingIntent touchIntentTemplate = PendingIntentUtils.getImmutableBroadcast(context, WidgetUtils.RC_WIDGET_STORY, touchIntent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
rv.setPendingIntentTemplate(R.id.widget_list, touchIntentTemplate);
|
rv.setPendingIntentTemplate(R.id.widget_list, touchIntentTemplate);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
import com.newsblur.util.PendingIntentUtils;
|
||||||
import com.newsblur.util.Log;
|
import com.newsblur.util.Log;
|
||||||
import com.newsblur.util.PrefsUtils;
|
import com.newsblur.util.PrefsUtils;
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ public class WidgetUtils {
|
||||||
Log.d(TAG, "enableWidgetUpdate");
|
Log.d(TAG, "enableWidgetUpdate");
|
||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
Intent intent = getUpdateIntent(context);
|
Intent intent = getUpdateIntent(context);
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, RC_WIDGET_UPDATE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingIntent = PendingIntentUtils.getImmutableBroadcast(context, RC_WIDGET_UPDATE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
int widgetUpdateInterval = 1000 * 60 * 5;
|
int widgetUpdateInterval = 1000 * 60 * 5;
|
||||||
long startAlarmAt = SystemClock.currentThreadTimeMillis() + widgetUpdateInterval;
|
long startAlarmAt = SystemClock.currentThreadTimeMillis() + widgetUpdateInterval;
|
||||||
|
@ -38,7 +39,7 @@ public class WidgetUtils {
|
||||||
public static void disableWidgetUpdate(Context context) {
|
public static void disableWidgetUpdate(Context context) {
|
||||||
Log.d(TAG, "disableWidgetUpdate");
|
Log.d(TAG, "disableWidgetUpdate");
|
||||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, RC_WIDGET_UPDATE, getUpdateIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent pendingIntent = PendingIntentUtils.getImmutableBroadcast(context, RC_WIDGET_UPDATE, getUpdateIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
alarmManager.cancel(pendingIntent);
|
alarmManager.cancel(pendingIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ public class WidgetUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkWidgetUpdateAlarm(Context context) {
|
public static void checkWidgetUpdateAlarm(Context context) {
|
||||||
boolean hasActiveUpdates = PendingIntent.getBroadcast(context, RC_WIDGET_UPDATE, getUpdateIntent(context), PendingIntent.FLAG_NO_CREATE) != null;
|
boolean hasActiveUpdates = PendingIntentUtils.getImmutableBroadcast(context, RC_WIDGET_UPDATE, getUpdateIntent(context), PendingIntent.FLAG_NO_CREATE) != null;
|
||||||
if (!hasActiveUpdates) {
|
if (!hasActiveUpdates) {
|
||||||
enableWidgetUpdate(context);
|
enableWidgetUpdate(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ DEBUG = True
|
||||||
# DEBUG_ASSETS controls JS/CSS asset packaging. Turning this off requires you to run
|
# DEBUG_ASSETS controls JS/CSS asset packaging. Turning this off requires you to run
|
||||||
# `./manage.py collectstatic` first. Turn this on for development so you can see
|
# `./manage.py collectstatic` first. Turn this on for development so you can see
|
||||||
# changes in your JS/CSS.
|
# changes in your JS/CSS.
|
||||||
|
DEBUG_ASSETS = False # Make sure to run `./manage.py collectstatic` first
|
||||||
DEBUG_ASSETS = False # Make sure to run `./manage.py collectstatic` first
|
DEBUG_ASSETS = False # Make sure to run `./manage.py collectstatic` first
|
||||||
DEBUG_ASSETS = True
|
DEBUG_ASSETS = True
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,7 @@ resource "digitalocean_droplet" "node-images" {
|
||||||
image = var.droplet_os
|
image = var.droplet_os
|
||||||
name = "node-images"
|
name = "node-images"
|
||||||
region = var.droplet_region
|
region = var.droplet_region
|
||||||
size = var.droplet_size
|
size = var.droplet_size_15
|
||||||
ssh_keys = [digitalocean_ssh_key.default.fingerprint]
|
ssh_keys = [digitalocean_ssh_key.default.fingerprint]
|
||||||
provisioner "local-exec" {
|
provisioner "local-exec" {
|
||||||
command = "/srv/newsblur/ansible/utils/generate_inventory.py; sleep 120"
|
command = "/srv/newsblur/ansible/utils/generate_inventory.py; sleep 120"
|
||||||
|
|
Loading…
Add table
Reference in a new issue