- Android 7 以降で異なるアカウントの通知が束ねられないようにした。(タップした時にアカウント別に未読管理を行うため)
- 通知カラムの設定に(ブースト/お気に入り/フォロー)を表示しない設定を追加
This commit is contained in:
tateisu 2017-08-08 13:30:14 +09:00
parent 4d3b6eb5c9
commit 4ee8175168
9 changed files with 197 additions and 25 deletions

View File

@ -9,8 +9,8 @@ android {
applicationId "jp.juggler.subwaytooter"
minSdkVersion 21
targetSdkVersion 25
versionCode 112
versionName "1.1.2"
versionCode 113
versionName "1.1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

View File

@ -730,6 +730,11 @@ public class AlarmService extends IntentService {
.setColor( ContextCompat.getColor( this, R.color.Light_colorAccent ) ) // ここは常に白テーマの色を使う
.setWhen( item.notification.time_created_at );
// Android 7.0 ではグループを指定しないと勝手に通知が束ねられてしまう
// 束ねられた通知をタップしても pi_click が実行されないので困るため
// アカウント別にグループキーを設定する
builder.setGroup( getPackageName() + ":" + account.acct );
log.d( "showNotification[%s] creating notification(3)", account.acct );
int iv = 0;

View File

@ -120,6 +120,8 @@ class Column implements StreamReader.Callback {
static final String KEY_DONT_CLOSE = "dont_close";
private static final String KEY_WITH_ATTACHMENT = "with_attachment";
private static final String KEY_DONT_SHOW_BOOST = "dont_show_boost";
private static final String KEY_DONT_SHOW_FAVOURITE = "dont_show_favourite";
private static final String KEY_DONT_SHOW_FOLLOW = "dont_show_follow";
private static final String KEY_DONT_SHOW_REPLY = "dont_show_reply";
private static final String KEY_DONT_STREAMING = "dont_streaming";
private static final String KEY_DONT_AUTO_REFRESH = "dont_auto_refresh";
@ -176,6 +178,8 @@ class Column implements StreamReader.Callback {
boolean with_attachment;
boolean dont_show_boost;
boolean dont_show_reply;
boolean dont_show_favourite; // 通知カラムのみ
boolean dont_show_follow; // 通知カラムのみ
boolean dont_streaming;
boolean dont_auto_refresh;
boolean hide_media_default;
@ -245,6 +249,8 @@ class Column implements StreamReader.Callback {
item.put( KEY_DONT_CLOSE, dont_close );
item.put( KEY_WITH_ATTACHMENT, with_attachment );
item.put( KEY_DONT_SHOW_BOOST, dont_show_boost );
item.put( KEY_DONT_SHOW_FOLLOW, dont_show_follow );
item.put( KEY_DONT_SHOW_FAVOURITE,dont_show_favourite);
item.put( KEY_DONT_SHOW_REPLY, dont_show_reply );
item.put( KEY_DONT_STREAMING, dont_streaming );
item.put( KEY_DONT_AUTO_REFRESH, dont_auto_refresh );
@ -307,6 +313,8 @@ class Column implements StreamReader.Callback {
this.dont_close = src.optBoolean( KEY_DONT_CLOSE );
this.with_attachment = src.optBoolean( KEY_WITH_ATTACHMENT );
this.dont_show_boost = src.optBoolean( KEY_DONT_SHOW_BOOST );
this.dont_show_follow = src.optBoolean( KEY_DONT_SHOW_FOLLOW );
this.dont_show_favourite = src.optBoolean( KEY_DONT_SHOW_FAVOURITE );
this.dont_show_reply = src.optBoolean( KEY_DONT_SHOW_REPLY );
this.dont_streaming = src.optBoolean( KEY_DONT_STREAMING );
this.dont_auto_refresh = src.optBoolean( KEY_DONT_AUTO_REFRESH );
@ -957,6 +965,8 @@ class Column implements StreamReader.Callback {
private boolean isFilterEnabled(){
return ( with_attachment
|| dont_show_boost
|| dont_show_favourite
|| dont_show_follow
|| dont_show_reply
|| ! TextUtils.isEmpty( regex_text )
);
@ -1020,14 +1030,6 @@ class Column implements StreamReader.Callback {
if( ! hasMedia ) return true;
}
if( dont_show_boost ){
// MSPToot には関連パラメータはない
}
if( dont_show_reply ){
// MSPToot には関連パラメータはない
}
if( column_regex_filter != null ){
if( column_regex_filter.matcher( status.decoded_content.toString() ).find() )
return true;
@ -1061,10 +1063,25 @@ class Column implements StreamReader.Callback {
private boolean isFiltered( TootNotification item ){
if( dont_show_favourite && TootNotification.TYPE_FAVOURITE.equals( item.type ) ){
log.d("isFiltered: favourite notification filtered.");
return true;
}
if( dont_show_boost && TootNotification.TYPE_REBLOG.equals( item.type ) ){
log.d("isFiltered: reblog notification filtered.");
return true;
}
if( dont_show_follow && TootNotification.TYPE_FOLLOW.equals( item.type ) ){
log.d("isFiltered: follow notification filtered.");
return true;
}
TootStatus status = item.status;
if( status != null ){
if( status.checkMuted( muted_app, muted_word ) ){
log.d( "addWithFilter: status muted." );
log.d( "isFiltered: status muted." );
return true;
}
}
@ -1199,18 +1216,62 @@ class Column implements StreamReader.Callback {
}
TootApiResult parseNotifications( TootApiClient client, String path_base ){
long time_start = SystemClock.elapsedRealtime();
TootApiResult result = client.request( path_base );
if( result != null ){
if( result != null && result.array != null ){
saveRange( result, true, true );
//
TootNotification.List src = TootNotification.parseList( context, log, access_info, access_info.host, result.array );
list_tmp = new ArrayList<>();
list_tmp = new ArrayList<>( src.size() );
addWithFilter( list_tmp, src );
//
if( ! src.isEmpty() ){
AlarmService.injectData( context, access_info.db_id, src );
}
//
char delimiter = ( - 1 != path_base.indexOf( '?' ) ? '&' : '?' );
for( ; ; ){
if( client.isCancelled() ){
log.d( "loading-notifications: cancelled." );
break;
}
if( ! isFilterEnabled() ){
log.d( "loading-notifications: isFiltered is false." );
break;
}
if( max_id == null ){
log.d( "loading-notifications: max_id is null." );
break;
}
if( list_tmp.size() >= LOOP_READ_ENOUGH ){
log.d( "loading-notifications: read enough data." );
break;
}
if( src.isEmpty() ){
log.d( "loading-notifications: previous response is empty." );
break;
}
if( SystemClock.elapsedRealtime() - time_start > LOOP_TIMEOUT ){
log.d( "loading-notifications: timeout." );
break;
}
String path = path_base + delimiter + "max_id=" + max_id;
TootApiResult result2 = client.request( path );
if( result2 == null || result2.array == null ){
log.d( "loading-notifications: error or cancelled." );
break;
}
src = TootNotification.parseList( context, log, access_info, access_info.host, result2.array );
addWithFilter( list_tmp, src );
if( ! saveRangeEnd( result2 ) ){
log.d( "loading-notifications: missing range info." );
break;
}
}
}
return result;
}
@ -1890,11 +1951,12 @@ class Column implements StreamReader.Callback {
TootNotification.List src = TootNotification.parseList( context, log, access_info, access_info.host, result.array );
addWithFilter( list_tmp, src );
if( ! src.isEmpty() ){
AlarmService.injectData( context, access_info.db_id, src );
}
if( ! bBottom ){
if( ! src.isEmpty() ){
AlarmService.injectData( context, access_info.db_id, src );
}
for( ; ; ){
if( isCancelled() ){
log.d( "refresh-notification-top: cancelled." );
@ -1937,6 +1999,54 @@ class Column implements StreamReader.Callback {
AlarmService.injectData( context, access_info.db_id, src );
}
}
}else{
for( ; ; ){
if( isCancelled() ){
log.d( "refresh-notification-bottom: cancelled." );
break;
}
// bottomの場合フィルタなしなら繰り返さない
if( ! isFilterEnabled() ){
log.d( "refresh-notification-bottom: isFiltered is false." );
break;
}
// max_id だけを指定した場合必ずlimit個のデータが帰ってくるとは限らない
// 直前のデータが0個なら終了とみなすしかなさそう
if( src.isEmpty() ){
log.d( "refresh-notification-bottom: previous size == 0." );
break;
}
// 十分読んだらそれで終了
if( list_tmp.size() >= LOOP_READ_ENOUGH ){
log.d( "refresh-notification-bottom: read enough data." );
break;
}
if( SystemClock.elapsedRealtime() - time_start > LOOP_TIMEOUT ){
// タイムアウト
log.d( "refresh-notification-bottom: loop timeout." );
break;
}
String path = path_base + delimiter + "max_id=" + max_id;
TootApiResult result2 = client.request( path );
if( result2 == null || result2.array == null ){
log.d( "refresh-notification-bottom: error or cancelled." );
break;
}
src = TootNotification.parseList( context, log, access_info, access_info.host, result2.array );
addWithFilter( list_tmp, src );
if( ! saveRangeEnd( result2 ) ){
log.d( "refresh-notification-bottom: saveRangeEnd failed." );
break;
}
}
}
}
return result;

View File

@ -1,14 +1,12 @@
package jp.juggler.subwaytooter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.HashSet;
class ColumnPagerAdapter extends PagerAdapter {

View File

@ -73,6 +73,8 @@ class ColumnViewHolder
private final CheckBox cbDontCloseColumn;
private final CheckBox cbWithAttachment;
private final CheckBox cbDontShowBoost;
private final CheckBox cbDontShowFollow;
private final CheckBox cbDontShowFavourite;
private final CheckBox cbDontShowReply;
private final CheckBox cbDontStreaming;
private final CheckBox cbDontAutoRefresh;
@ -128,6 +130,8 @@ class ColumnViewHolder
cbDontCloseColumn = (CheckBox) root.findViewById( R.id.cbDontCloseColumn );
cbWithAttachment = (CheckBox) root.findViewById( R.id.cbWithAttachment );
cbDontShowBoost = (CheckBox) root.findViewById( R.id.cbDontShowBoost );
cbDontShowFollow = (CheckBox) root.findViewById( R.id.cbDontShowFollow );
cbDontShowFavourite = (CheckBox) root.findViewById( R.id.cbDontShowFavourite );
cbDontShowReply = (CheckBox) root.findViewById( R.id.cbDontShowReply );
cbDontStreaming = (CheckBox) root.findViewById( R.id.cbDontStreaming );
cbDontAutoRefresh = (CheckBox) root.findViewById( R.id.cbDontAutoRefresh );
@ -154,6 +158,8 @@ class ColumnViewHolder
cbDontCloseColumn.setOnCheckedChangeListener( this );
cbWithAttachment.setOnCheckedChangeListener( this );
cbDontShowBoost.setOnCheckedChangeListener( this );
cbDontShowFollow.setOnCheckedChangeListener( this );
cbDontShowFavourite.setOnCheckedChangeListener( this );
cbDontShowReply.setOnCheckedChangeListener( this );
cbDontStreaming.setOnCheckedChangeListener( this );
cbDontAutoRefresh.setOnCheckedChangeListener( this );
@ -254,6 +260,7 @@ class ColumnViewHolder
break;
}
// 添付メディアや正規表現のフィルタ
boolean bAllowFilter;
switch( column.column_type ){
default:
@ -271,6 +278,7 @@ class ColumnViewHolder
break;
}
// ブーストを表示しないフィルタ
boolean bAllowFilterBoost;
switch( column.column_type ){
default:
@ -278,15 +286,33 @@ class ColumnViewHolder
break;
case Column.TYPE_HOME:
case Column.TYPE_PROFILE:
case Column.TYPE_NOTIFICATIONS:
bAllowFilterBoost = true;
break;
}
// 返信を表示しないフィルタ
boolean bAllowFilterReply;
switch( column.column_type ){
default:
bAllowFilterReply = false;
break;
case Column.TYPE_HOME:
case Column.TYPE_PROFILE:
bAllowFilterReply = true;
break;
}
boolean isNotificationColumn = (column.column_type == Column.TYPE_NOTIFICATIONS);
llColumnSetting.setVisibility( View.GONE );
cbDontCloseColumn.setChecked( column.dont_close );
cbWithAttachment.setChecked( column.with_attachment );
cbDontShowBoost.setChecked( column.dont_show_boost );
cbDontShowFollow.setChecked( column.dont_show_follow );
cbDontShowFavourite.setChecked( column.dont_show_favourite );
cbDontShowReply.setChecked( column.dont_show_reply );
cbDontStreaming.setChecked( column.dont_streaming );
cbDontAutoRefresh.setChecked( column.dont_auto_refresh );
@ -300,9 +326,11 @@ class ColumnViewHolder
vg( cbWithAttachment, bAllowFilter );
vg( etRegexFilter, bAllowFilter );
vg( llRegexFilter, bAllowFilter );
vg( cbDontShowBoost, bAllowFilterBoost );
vg( cbDontShowReply, bAllowFilterBoost );
vg( cbDontShowReply, bAllowFilterReply );
vg( cbDontShowFavourite, isNotificationColumn );
vg( cbDontShowFollow, isNotificationColumn );
vg( cbDontStreaming, column.canStreaming() );
vg( cbDontAutoRefresh, column.canAutoRefresh() );
@ -593,6 +621,18 @@ class ColumnViewHolder
column.startLoading();
break;
case R.id.cbDontShowFavourite:
column.dont_show_favourite = isChecked;
activity.app_state.saveColumnList();
column.startLoading();
break;
case R.id.cbDontShowFollow:
column.dont_show_follow = isChecked;
activity.app_state.saveColumnList();
column.startLoading();
break;
case R.id.cbDontStreaming:
column.dont_streaming = isChecked;
activity.app_state.saveColumnList();

View File

@ -158,6 +158,19 @@
android:text="@string/dont_show_boost"
/>
<CheckBox
android:id="@+id/cbDontShowFavourite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dont_show_favourite"
/>
<CheckBox
android:id="@+id/cbDontShowFollow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dont_show_follow"
/>
<CheckBox
android:id="@+id/cbDontShowReply"
android:layout_width="match_parent"

View File

@ -404,6 +404,8 @@
<string name="token_not_specified">Please input access token.</string>
<string name="quote_name">Quote name…</string>
<string name="format_of_quote_name">Format of \'Quote name\' (set text that contains %1$s)</string>
<string name="dont_show_favourite">Masquer les favourite</string>
<string name="dont_show_follow">Masquer les follow</string>
<!--<string name="abc_action_bar_home_description">Revenir à l\'accueil</string>-->
<!--<string name="abc_action_bar_home_description_format">%1$s, %2$s</string>-->

View File

@ -691,5 +691,7 @@
<string name="token_not_specified">アクセストークンを入力してください</string>
<string name="quote_name">名前を引用…</string>
<string name="format_of_quote_name">\'名前を引用\'のフォーマット ( %1$s を含むテキストを指定する)</string>
<string name="dont_show_favourite">お気に入りを表示しない</string>
<string name="dont_show_follow">フォローを表示しない</string>
</resources>

View File

@ -173,8 +173,8 @@
<string name="ui_theme">UI theme (app restart required)</string>
<string name="theme_light">Light</string>
<string name="theme_dark">Dark</string>
<string name="dont_show_boost">Dont show boost</string>
<string name="dont_show_reply">Dont show reply</string>
<string name="dont_show_boost">Don\'t show boost</string>
<string name="dont_show_reply">Don\'t show reply</string>
<string name="regex_filter">Regex filter</string>
<string name="regex_error">Regex error</string>
<string name="notification_delete">Empty notifications</string>
@ -399,5 +399,7 @@
<string name="token_not_specified">Please input access token.</string>
<string name="quote_name">Quote name…</string>
<string name="format_of_quote_name">Format of \'Quote name\' (set text that contains %1$s)</string>
<string name="dont_show_favourite">Don\'t show favourite</string>
<string name="dont_show_follow">Don\'t show follow</string>
</resources>