Merge branch 'develop' of https://github.com/FWGS/Husky into develop
This commit is contained in:
commit
78cf552a32
|
@ -9,6 +9,7 @@ before_script:
|
||||||
- export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk-bundle
|
- export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk-bundle
|
||||||
- export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT
|
- export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT
|
||||||
- sed -i "s/blue {}//" app/build.gradle
|
- sed -i "s/blue {}//" app/build.gradle
|
||||||
|
- sed -i "s/\/\/abortOnError/abortOnError/" app/build.gradle
|
||||||
# - sed -i "s/debug {}//" app/build.gradle
|
# - sed -i "s/debug {}//" app/build.gradle
|
||||||
before_cache:
|
before_cache:
|
||||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||||
|
|
|
@ -64,6 +64,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
|
//abortOnError false
|
||||||
disable 'MissingTranslation'
|
disable 'MissingTranslation'
|
||||||
disable 'ExtraTranslation'
|
disable 'ExtraTranslation'
|
||||||
disable 'AppCompatCustomView' // I don't care about AppCompat bloat
|
disable 'AppCompatCustomView' // I don't care about AppCompat bloat
|
||||||
|
|
|
@ -129,7 +129,7 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference
|
||||||
|
|
||||||
}
|
}
|
||||||
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
|
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
|
||||||
"useBlurhash", "showCardsInTimelines", "confirmReblogs" -> {
|
"useBlurhash", "showCardsInTimelines", "confirmReblogs", "hideMutedUsers" -> {
|
||||||
restartActivitiesOnExit = true
|
restartActivitiesOnExit = true
|
||||||
}
|
}
|
||||||
"language" -> {
|
"language" -> {
|
||||||
|
|
|
@ -154,14 +154,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) {
|
||||||
bindViewHolder(viewHolder, position, payloads);
|
bindViewHolder(viewHolder, position, payloads);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fixupHiddenUsers(StatusViewData.Concrete status, View v) {
|
|
||||||
if(status.isUserMuted()) {
|
|
||||||
v.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
v.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List payloads) {
|
private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List payloads) {
|
||||||
Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null;
|
Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null;
|
||||||
|
@ -188,7 +180,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
} else {
|
} else {
|
||||||
holder.hideStatusInfo();
|
holder.hideStatusInfo();
|
||||||
}
|
}
|
||||||
fixupHiddenUsers(status, holder.itemView);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VIEW_TYPE_MUTED_STATUS: {
|
case VIEW_TYPE_MUTED_STATUS: {
|
||||||
|
@ -196,7 +187,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
StatusViewData.Concrete status = concreteNotificaton.getStatusViewData();
|
StatusViewData.Concrete status = concreteNotificaton.getStatusViewData();
|
||||||
holder.setupWithStatus(status,
|
holder.setupWithStatus(status,
|
||||||
statusListener, statusDisplayOptions, payloadForHolder);
|
statusListener, statusDisplayOptions, payloadForHolder);
|
||||||
fixupHiddenUsers(status, holder.itemView);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VIEW_TYPE_STATUS_NOTIFICATION: {
|
case VIEW_TYPE_STATUS_NOTIFICATION: {
|
||||||
|
@ -272,7 +262,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
switch (concrete.getType()) {
|
switch (concrete.getType()) {
|
||||||
case MENTION:
|
case MENTION:
|
||||||
case POLL: {
|
case POLL: {
|
||||||
if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isThreadMuted())
|
if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isMuted())
|
||||||
return VIEW_TYPE_MUTED_STATUS;
|
return VIEW_TYPE_MUTED_STATUS;
|
||||||
return VIEW_TYPE_STATUS;
|
return VIEW_TYPE_STATUS;
|
||||||
}
|
}
|
||||||
|
@ -503,13 +493,13 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
if(icon != null) {
|
if(icon != null) {
|
||||||
icon.setColorFilter(ContextCompat.getColor(context,
|
icon.setColorFilter(ContextCompat.getColor(context,
|
||||||
R.color.tusky_green), PorterDuff.Mode.SRC_ATOP);
|
R.color.tusky_green), PorterDuff.Mode.SRC_ATOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
String format = context.getString(R.string.notification_emoji_format);
|
String format = context.getString(R.string.notification_emoji_format);
|
||||||
String emojiCode = notificationViewData.getEmoji();
|
String emojiCode = notificationViewData.getEmoji();
|
||||||
wholeMessage = String.format(format, displayName, emojiCode);
|
wholeMessage = String.format(format, displayName, emojiCode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
|
message.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
|
||||||
final SpannableStringBuilder str = new SpannableStringBuilder(wholeMessage);
|
final SpannableStringBuilder str = new SpannableStringBuilder(wholeMessage);
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class StatusViewHolder extends StatusBaseViewHolder {
|
||||||
statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
|
statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status.isThreadMutedOnBackend()) {
|
if(status.isUserMuted() || status.isThreadMuted()) {
|
||||||
toggleVisibility.setVisibility(View.VISIBLE);
|
toggleVisibility.setVisibility(View.VISIBLE);
|
||||||
toggleVisibility.setOnClickListener(v -> listener.onMute(getAdapterPosition(), true));
|
toggleVisibility.setOnClickListener(v -> listener.onMute(getAdapterPosition(), true));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -111,7 +111,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter {
|
||||||
holder.setup(statusListener, ((StatusViewData.Placeholder) status).isLoading());
|
holder.setup(statusListener, ((StatusViewData.Placeholder) status).isLoading());
|
||||||
} else if (status instanceof StatusViewData.Concrete) {
|
} else if (status instanceof StatusViewData.Concrete) {
|
||||||
StatusViewData.Concrete concrete = (StatusViewData.Concrete)status;
|
StatusViewData.Concrete concrete = (StatusViewData.Concrete)status;
|
||||||
if(concrete.isThreadMuted()) {
|
if(concrete.isMuted()) {
|
||||||
MutedStatusViewHolder holder = (MutedStatusViewHolder) viewHolder;
|
MutedStatusViewHolder holder = (MutedStatusViewHolder) viewHolder;
|
||||||
holder.setupWithStatus(concrete, statusListener, statusDisplayOptions,
|
holder.setupWithStatus(concrete, statusListener, statusDisplayOptions,
|
||||||
payloads != null && !payloads.isEmpty() ? payloads.get(0) : null);
|
payloads != null && !payloads.isEmpty() ? payloads.get(0) : null);
|
||||||
|
@ -134,7 +134,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter {
|
||||||
return VIEW_TYPE_PLACEHOLDER;
|
return VIEW_TYPE_PLACEHOLDER;
|
||||||
} else {
|
} else {
|
||||||
StatusViewData.Concrete concrete = (StatusViewData.Concrete)dataSource.getItemAt(position);
|
StatusViewData.Concrete concrete = (StatusViewData.Concrete)dataSource.getItemAt(position);
|
||||||
if(concrete.isThreadMuted()) {
|
if(concrete.isMuted()) {
|
||||||
return VIEW_TYPE_STATUS_MUTED;
|
return VIEW_TYPE_STATUS_MUTED;
|
||||||
} else {
|
} else {
|
||||||
return VIEW_TYPE_STATUS;
|
return VIEW_TYPE_STATUS;
|
||||||
|
|
|
@ -126,10 +126,14 @@ data class Status(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isUserMuted(): Boolean {
|
fun isMuted(): Boolean {
|
||||||
return muted
|
return muted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isUserMuted(): Boolean {
|
||||||
|
return muted && !isThreadMuted()
|
||||||
|
}
|
||||||
|
|
||||||
fun isThreadMuted(): Boolean {
|
fun isThreadMuted(): Boolean {
|
||||||
return pleroma?.threadMuted ?: false
|
return pleroma?.threadMuted ?: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,7 +626,7 @@ public class NotificationsFragment extends SFragment implements
|
||||||
(NotificationViewData.Concrete) notifications.getPairedItem(position);
|
(NotificationViewData.Concrete) notifications.getPairedItem(position);
|
||||||
StatusViewData.Concrete statusViewData =
|
StatusViewData.Concrete statusViewData =
|
||||||
new StatusViewData.Builder(old.getStatusViewData())
|
new StatusViewData.Builder(old.getStatusViewData())
|
||||||
.setThreadMuted(isMuted)
|
.setMuted(isMuted)
|
||||||
.createStatusViewData();
|
.createStatusViewData();
|
||||||
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
|
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
|
||||||
old.getId(), old.getAccount(), statusViewData, old.isExpanded(), old.getEmoji());
|
old.getId(), old.getAccount(), statusViewData, old.isExpanded(), old.getEmoji());
|
||||||
|
@ -641,7 +641,7 @@ public class NotificationsFragment extends SFragment implements
|
||||||
|
|
||||||
StatusViewData.Builder viewDataBuilder = new StatusViewData.Builder(viewdata.getStatusViewData());
|
StatusViewData.Builder viewDataBuilder = new StatusViewData.Builder(viewdata.getStatusViewData());
|
||||||
viewDataBuilder.setThreadMuted(muted);
|
viewDataBuilder.setThreadMuted(muted);
|
||||||
viewDataBuilder.setThreadMutedOnBackend(muted);
|
viewDataBuilder.setMuted(muted);
|
||||||
|
|
||||||
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
|
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
|
||||||
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
|
viewdata.getType(), viewdata.getId(), viewdata.getAccount(),
|
||||||
|
|
|
@ -152,7 +152,6 @@ public class TimelineFragment extends SFragment implements
|
||||||
private EndlessOnScrollListener scrollListener;
|
private EndlessOnScrollListener scrollListener;
|
||||||
private boolean filterRemoveReplies;
|
private boolean filterRemoveReplies;
|
||||||
private boolean filterRemoveReblogs;
|
private boolean filterRemoveReblogs;
|
||||||
private boolean filterRemoveMutedUsers;
|
|
||||||
private boolean hideFab;
|
private boolean hideFab;
|
||||||
private boolean bottomLoading;
|
private boolean bottomLoading;
|
||||||
|
|
||||||
|
@ -353,11 +352,6 @@ public class TimelineFragment extends SFragment implements
|
||||||
|
|
||||||
filter = preferences.getBoolean("tabFilterHomeBoosts", true);
|
filter = preferences.getBoolean("tabFilterHomeBoosts", true);
|
||||||
filterRemoveReblogs = kind == Kind.HOME && !filter;
|
filterRemoveReblogs = kind == Kind.HOME && !filter;
|
||||||
|
|
||||||
filterRemoveMutedUsers = kind != Kind.USER &&
|
|
||||||
kind != Kind.USER_PINNED &&
|
|
||||||
kind != Kind.USER_WITH_REPLIES &&
|
|
||||||
kind != Kind.BOOKMARKS;
|
|
||||||
reloadFilters(false);
|
reloadFilters(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +675,7 @@ public class TimelineFragment extends SFragment implements
|
||||||
public void onMute(int position, boolean isMuted) {
|
public void onMute(int position, boolean isMuted) {
|
||||||
StatusViewData.Concrete statusViewData =
|
StatusViewData.Concrete statusViewData =
|
||||||
new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position))
|
new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position))
|
||||||
.setThreadMuted(isMuted)
|
.setMuted(isMuted)
|
||||||
.createStatusViewData();
|
.createStatusViewData();
|
||||||
statuses.setPairedItem(position, statusViewData);
|
statuses.setPairedItem(position, statusViewData);
|
||||||
updateAdapter();
|
updateAdapter();
|
||||||
|
@ -691,8 +685,8 @@ public class TimelineFragment extends SFragment implements
|
||||||
status.setThreadMuted(muted);
|
status.setThreadMuted(muted);
|
||||||
|
|
||||||
StatusViewData.Builder statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position));
|
StatusViewData.Builder statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position));
|
||||||
|
statusViewData.setMuted(muted);
|
||||||
statusViewData.setThreadMuted(muted);
|
statusViewData.setThreadMuted(muted);
|
||||||
statusViewData.setThreadMutedOnBackend(muted);
|
|
||||||
|
|
||||||
statuses.setPairedItem(position, statusViewData.createStatusViewData());
|
statuses.setPairedItem(position, statusViewData.createStatusViewData());
|
||||||
}
|
}
|
||||||
|
@ -999,7 +993,8 @@ public class TimelineFragment extends SFragment implements
|
||||||
private Call<List<Status>> getFetchCallByTimelineType(Kind kind, String tagOrId, String fromId,
|
private Call<List<Status>> getFetchCallByTimelineType(Kind kind, String tagOrId, String fromId,
|
||||||
String uptoId) {
|
String uptoId) {
|
||||||
MastodonApi api = mastodonApi;
|
MastodonApi api = mastodonApi;
|
||||||
boolean withMuted = true; // TODO: configurable
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||||
|
boolean withMuted = !preferences.getBoolean("hideMutedUsers", false);
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
default:
|
default:
|
||||||
case HOME:
|
case HOME:
|
||||||
|
@ -1175,9 +1170,8 @@ public class TimelineFragment extends SFragment implements
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Status status = it.next().asRightOrNull();
|
Status status = it.next().asRightOrNull();
|
||||||
if (status != null
|
if (status != null
|
||||||
&& ((filterRemoveReplies && status.getInReplyToId() != null)
|
&& ((status.getInReplyToId() != null && filterRemoveReplies)
|
||||||
|| (filterRemoveReblogs && status.getReblog() != null)
|
|| (status.getReblog() != null && filterRemoveReblogs)
|
||||||
|| (filterRemoveMutedUsers && status.isUserMuted())
|
|
||||||
|| shouldFilterStatus(status))) {
|
|| shouldFilterStatus(status))) {
|
||||||
it.remove();
|
it.remove();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import com.keylesspalace.tusky.entity.Filter
|
||||||
import com.keylesspalace.tusky.entity.Status
|
import com.keylesspalace.tusky.entity.Status
|
||||||
import com.keylesspalace.tusky.network.MastodonApi
|
import com.keylesspalace.tusky.network.MastodonApi
|
||||||
import com.keylesspalace.tusky.util.ThemeUtils
|
import com.keylesspalace.tusky.util.ThemeUtils
|
||||||
|
import com.keylesspalace.tusky.util.NotificationHelper
|
||||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
import com.mikepenz.google_material_typeface_library.GoogleMaterial
|
||||||
import com.mikepenz.iconics.IconicsDrawable
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
|
@ -171,7 +172,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
|
||||||
|
|
||||||
return when (preference) {
|
return when (preference) {
|
||||||
notificationPreference -> {
|
notificationPreference -> {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
|
||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
|
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
|
||||||
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)
|
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.keylesspalace.tusky.entity.NewStatus
|
||||||
import com.keylesspalace.tusky.entity.Status
|
import com.keylesspalace.tusky.entity.Status
|
||||||
import com.keylesspalace.tusky.network.MastodonApi
|
import com.keylesspalace.tusky.network.MastodonApi
|
||||||
import com.keylesspalace.tusky.util.SaveTootHelper
|
import com.keylesspalace.tusky.util.SaveTootHelper
|
||||||
|
import com.keylesspalace.tusky.util.NotificationHelper
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
|
@ -72,10 +73,9 @@ class SendTootService : Service(), Injectable {
|
||||||
val tootToSend = intent.getParcelableExtra<TootToSend>(KEY_TOOT)
|
val tootToSend = intent.getParcelableExtra<TootToSend>(KEY_TOOT)
|
||||||
?: throw IllegalStateException("SendTootService started without $KEY_TOOT extra")
|
?: throw IllegalStateException("SendTootService started without $KEY_TOOT extra")
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
|
||||||
val channel = NotificationChannel(CHANNEL_ID, getString(R.string.send_toot_notification_channel_name), NotificationManager.IMPORTANCE_LOW)
|
val channel = NotificationChannel(CHANNEL_ID, getString(R.string.send_toot_notification_channel_name), NotificationManager.IMPORTANCE_LOW)
|
||||||
notificationManager.createNotificationChannel(channel)
|
notificationManager.createNotificationChannel(channel)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var notificationText = tootToSend.warningText
|
var notificationText = tootToSend.warningText
|
||||||
|
|
|
@ -124,6 +124,12 @@ public class NotificationHelper {
|
||||||
*/
|
*/
|
||||||
private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15;
|
private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* by setting this as false, it's possible to test legacy notification channels on newer devices
|
||||||
|
*/
|
||||||
|
//public static final boolean NOTIFICATION_USE_CHANNELS = false;
|
||||||
|
public static final boolean NOTIFICATION_USE_CHANNELS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a given Mastodon notification and either creates a new Android notification or updates
|
* Takes a given Mastodon notification and either creates a new Android notification or updates
|
||||||
|
@ -353,7 +359,7 @@ public class NotificationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
|
public static void createNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
|
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
@ -411,7 +417,7 @@ public class NotificationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
|
public static void deleteNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
|
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
@ -422,7 +428,7 @@ public class NotificationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteLegacyNotificationChannels(@NonNull Context context, @NonNull AccountManager accountManager) {
|
public static void deleteLegacyNotificationChannels(@NonNull Context context, @NonNull AccountManager accountManager) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
|
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
@ -441,7 +447,7 @@ public class NotificationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean areNotificationsEnabled(@NonNull Context context, @NonNull AccountManager accountManager) {
|
public static boolean areNotificationsEnabled(@NonNull Context context, @NonNull AccountManager accountManager) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
|
|
||||||
// on Android >= O, notifications are enabled, if at least one channel is enabled
|
// on Android >= O, notifications are enabled, if at least one channel is enabled
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
@ -505,7 +511,7 @@ public class NotificationHelper {
|
||||||
private static boolean filterNotification(AccountEntity account, Notification notification,
|
private static boolean filterNotification(AccountEntity account, Notification notification,
|
||||||
Context context) {
|
Context context) {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
String channelId = getChannelId(account, notification);
|
String channelId = getChannelId(account, notification);
|
||||||
|
@ -559,7 +565,7 @@ public class NotificationHelper {
|
||||||
private static void setupPreferences(AccountEntity account,
|
private static void setupPreferences(AccountEntity account,
|
||||||
NotificationCompat.Builder builder) {
|
NotificationCompat.Builder builder) {
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (NOTIFICATION_USE_CHANNELS) {
|
||||||
return; //do nothing on Android O or newer, the system uses the channel settings anyway
|
return; //do nothing on Android O or newer, the system uses the channel settings anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,9 @@ public final class ViewDataUtils {
|
||||||
.setPoll(visibleStatus.getPoll())
|
.setPoll(visibleStatus.getPoll())
|
||||||
.setCard(visibleStatus.getCard())
|
.setCard(visibleStatus.getCard())
|
||||||
.setIsBot(visibleStatus.getAccount().getBot())
|
.setIsBot(visibleStatus.getAccount().getBot())
|
||||||
|
.setMuted(visibleStatus.isMuted())
|
||||||
.setUserMuted(visibleStatus.isUserMuted())
|
.setUserMuted(visibleStatus.isUserMuted())
|
||||||
.setThreadMuted(visibleStatus.isThreadMuted())
|
.setThreadMuted(visibleStatus.isThreadMuted())
|
||||||
.setThreadMutedOnBackend(visibleStatus.isThreadMuted())
|
|
||||||
.setConversationId(visibleStatus.getConversationId())
|
.setConversationId(visibleStatus.getConversationId())
|
||||||
.setEmojiReactions(visibleStatus.getEmojiReactions())
|
.setEmojiReactions(visibleStatus.getEmojiReactions())
|
||||||
.createStatusViewData();
|
.createStatusViewData();
|
||||||
|
|
|
@ -92,9 +92,9 @@ public abstract class StatusViewData {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final PollViewData poll;
|
private final PollViewData poll;
|
||||||
private final boolean isBot;
|
private final boolean isBot;
|
||||||
private final boolean isThreadMuted; /* toggle for showing thread */
|
private final boolean isMuted; /* user toggle */
|
||||||
private final boolean isUserMuted;
|
private final boolean isThreadMuted; /* thread_muted state got from backend */
|
||||||
private final boolean isThreadMutedOnBackend; /* thread_muted state got from backend */
|
private final boolean isUserMuted; /* muted state got from backend */
|
||||||
private final int conversationId;
|
private final int conversationId;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<EmojiReaction> emojiReactions;
|
private final List<EmojiReaction> emojiReactions;
|
||||||
|
@ -106,11 +106,11 @@ public abstract class StatusViewData {
|
||||||
Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId,
|
Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId,
|
||||||
@Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
|
@Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
|
||||||
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
|
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
|
||||||
boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isThreadMuted,
|
boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isMuted, boolean isThreadMuted,
|
||||||
boolean isUserMuted, boolean isThreadMutedOnBackend, int conversationId, @Nullable List<EmojiReaction> emojiReactions) {
|
boolean isUserMuted, int conversationId, @Nullable List<EmojiReaction> emojiReactions) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
if (Build.VERSION.SDK_INT == 23) {
|
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
|
||||||
// https://github.com/tuskyapp/Tusky/issues/563
|
// https://github.com/tuskyapp/Tusky/issues/563
|
||||||
this.content = replaceCrashingCharacters(content);
|
this.content = replaceCrashingCharacters(content);
|
||||||
this.spoilerText = spoilerText == null ? null : replaceCrashingCharacters(spoilerText).toString();
|
this.spoilerText = spoilerText == null ? null : replaceCrashingCharacters(spoilerText).toString();
|
||||||
|
@ -147,8 +147,8 @@ public abstract class StatusViewData {
|
||||||
this.isCollapsed = isCollapsed;
|
this.isCollapsed = isCollapsed;
|
||||||
this.poll = poll;
|
this.poll = poll;
|
||||||
this.isBot = isBot;
|
this.isBot = isBot;
|
||||||
|
this.isMuted = isMuted;
|
||||||
this.isThreadMuted = isThreadMuted;
|
this.isThreadMuted = isThreadMuted;
|
||||||
this.isThreadMutedOnBackend = isThreadMutedOnBackend;
|
|
||||||
this.isUserMuted = isUserMuted;
|
this.isUserMuted = isUserMuted;
|
||||||
this.conversationId = conversationId;
|
this.conversationId = conversationId;
|
||||||
this.emojiReactions = emojiReactions;
|
this.emojiReactions = emojiReactions;
|
||||||
|
@ -304,12 +304,12 @@ public abstract class StatusViewData {
|
||||||
return isThreadMuted;
|
return isThreadMuted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isThreadMutedOnBackend() {
|
public boolean isMuted() {
|
||||||
return isThreadMutedOnBackend;
|
return isMuted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUserMuted() {
|
public boolean isUserMuted() {
|
||||||
return isUserMuted;
|
return isUserMuted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -351,9 +351,9 @@ public abstract class StatusViewData {
|
||||||
Objects.equals(card, concrete.card) &&
|
Objects.equals(card, concrete.card) &&
|
||||||
Objects.equals(poll, concrete.poll) &&
|
Objects.equals(poll, concrete.poll) &&
|
||||||
isCollapsed == concrete.isCollapsed &&
|
isCollapsed == concrete.isCollapsed &&
|
||||||
|
isMuted == concrete.isMuted &&
|
||||||
isThreadMuted == concrete.isThreadMuted &&
|
isThreadMuted == concrete.isThreadMuted &&
|
||||||
isUserMuted == concrete.isUserMuted &&
|
isUserMuted == concrete.isUserMuted &&
|
||||||
isThreadMutedOnBackend == concrete.isThreadMutedOnBackend &&
|
|
||||||
conversationId == concrete.conversationId &&
|
conversationId == concrete.conversationId &&
|
||||||
Objects.equals(emojiReactions, concrete.emojiReactions);
|
Objects.equals(emojiReactions, concrete.emojiReactions);
|
||||||
}
|
}
|
||||||
|
@ -462,8 +462,8 @@ public abstract class StatusViewData {
|
||||||
private boolean isCollapsed; /** Whether the status is shown partially or fully */
|
private boolean isCollapsed; /** Whether the status is shown partially or fully */
|
||||||
private PollViewData poll;
|
private PollViewData poll;
|
||||||
private boolean isBot;
|
private boolean isBot;
|
||||||
|
private boolean isMuted;
|
||||||
private boolean isThreadMuted;
|
private boolean isThreadMuted;
|
||||||
private boolean isThreadMutedOnBackend;
|
|
||||||
private boolean isUserMuted;
|
private boolean isUserMuted;
|
||||||
private int conversationId;
|
private int conversationId;
|
||||||
private List<EmojiReaction> emojiReactions;
|
private List<EmojiReaction> emojiReactions;
|
||||||
|
@ -503,9 +503,9 @@ public abstract class StatusViewData {
|
||||||
isCollapsed = viewData.isCollapsed();
|
isCollapsed = viewData.isCollapsed();
|
||||||
poll = viewData.poll;
|
poll = viewData.poll;
|
||||||
isBot = viewData.isBot();
|
isBot = viewData.isBot();
|
||||||
|
isMuted = viewData.isMuted;
|
||||||
isThreadMuted = viewData.isThreadMuted;
|
isThreadMuted = viewData.isThreadMuted;
|
||||||
isUserMuted = viewData.isUserMuted;
|
isUserMuted = viewData.isUserMuted;
|
||||||
isThreadMutedOnBackend = viewData.isThreadMutedOnBackend;
|
|
||||||
emojiReactions = viewData.emojiReactions;
|
emojiReactions = viewData.emojiReactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,27 +677,27 @@ public abstract class StatusViewData {
|
||||||
this.poll = PollViewDataKt.toViewData(poll);
|
this.poll = PollViewDataKt.toViewData(poll);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setMuted(Boolean isMuted) {
|
||||||
|
this.isMuted = isMuted;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder setUserMuted(Boolean isUserMuted) {
|
public Builder setUserMuted(Boolean isUserMuted) {
|
||||||
this.isUserMuted = isUserMuted;
|
this.isUserMuted = isUserMuted;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setThreadMuted(Boolean isThreadMuted) {
|
public Builder setThreadMuted(Boolean isThreadMuted) {
|
||||||
this.isThreadMuted = isThreadMuted;
|
this.isThreadMuted = isThreadMuted;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setThreadMutedOnBackend(Boolean isThreadMutedOnBackend) {
|
|
||||||
this.isThreadMutedOnBackend = isThreadMutedOnBackend;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setConversationId(int conversationId) {
|
public Builder setConversationId(int conversationId) {
|
||||||
this.conversationId = conversationId;
|
this.conversationId = conversationId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setEmojiReactions(List<EmojiReaction> emojiReactions) {
|
public Builder setEmojiReactions(List<EmojiReaction> emojiReactions) {
|
||||||
this.emojiReactions = emojiReactions;
|
this.emojiReactions = emojiReactions;
|
||||||
return this;
|
return this;
|
||||||
|
@ -712,8 +712,8 @@ public abstract class StatusViewData {
|
||||||
visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded,
|
visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded,
|
||||||
isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount,
|
isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount,
|
||||||
favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application,
|
favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application,
|
||||||
statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isThreadMuted,
|
statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isMuted, isThreadMuted,
|
||||||
isUserMuted, isThreadMutedOnBackend, conversationId, emojiReactions);
|
isUserMuted, conversationId, emojiReactions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:contentDescription="@null"
|
android:contentDescription="@null"
|
||||||
|
|
|
@ -23,5 +23,6 @@
|
||||||
<string name="notification_emoji_description">Notifications about new emoji reactions</string>
|
<string name="notification_emoji_description">Notifications about new emoji reactions</string>
|
||||||
|
|
||||||
<string name="pref_title_notification_filter_emoji">my posts are reacted with emojis</string>
|
<string name="pref_title_notification_filter_emoji">my posts are reacted with emojis</string>
|
||||||
|
<string name="pref_title_hide_muted_users">Hide muted users</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="notificationFilterPolls"
|
android:key="notificationFilterEmojis"
|
||||||
android:title="@string/pref_title_notification_filter_poll"
|
android:title="@string/pref_title_notification_filter_emoji"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="notificationFilterEmojiReactons"
|
android:key="notificationFilterPolls"
|
||||||
android:title="@string/pref_title_notification_filter_emoji"
|
android:title="@string/pref_title_notification_filter_poll"
|
||||||
app:iconSpaceReserved="false" />
|
app:iconSpaceReserved="false" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,12 @@
|
||||||
android:title="@string/pref_title_confirm_reblogs"
|
android:title="@string/pref_title_confirm_reblogs"
|
||||||
app:singleLineTitle="false" />
|
app:singleLineTitle="false" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="hideMutedUsers"
|
||||||
|
android:title="@string/pref_title_hide_muted_users"
|
||||||
|
app:singleLineTitle="false" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/pref_title_browser_settings">
|
<PreferenceCategory android:title="@string/pref_title_browser_settings">
|
||||||
|
|
Loading…
Reference in New Issue