working push
This commit is contained in:
parent
2eb4c8d8f5
commit
3e4cc1cc7d
|
@ -177,7 +177,7 @@ dependencies {
|
|||
implementation "com.madgag.spongycastle:bctls-jdk15on:1.58.0.0"
|
||||
//implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
|
||||
|
||||
implementation 'com.github.UnifiedPush:android-connector:dev-SNAPSHOT'
|
||||
implementation 'com.github.UnifiedPush:android-connector:1.0.0'
|
||||
//Flavors
|
||||
|
||||
//Playstore
|
||||
|
|
|
@ -69,18 +69,7 @@
|
|||
android:name="app.fedilab.android.services.BackupNotificationInDataBaseService"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver android:name=".services.UpgradeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name="app.fedilab.android.services.RestartLiveNotificationReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="app.fedilab.android.services.PeertubeUploadReceiver"
|
||||
android:exported="false">
|
||||
|
@ -88,20 +77,7 @@
|
|||
<action android:name="app.fedilab.android.uploadservice.broadcast.status" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name="app.fedilab.android.services.StopLiveNotificationReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="StopLiveNotificationReceiver" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name="app.fedilab.android.services.StopDelayedNotificationReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="StopDelayedNotificationReceiver" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name="app.fedilab.android.services.StreamingHomeTimelineService"
|
||||
android:exported="false" />
|
||||
|
|
|
@ -76,7 +76,6 @@ import com.google.android.material.navigation.NavigationView;
|
|||
import com.google.android.material.tabs.TabLayout;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.unifiedpush.android.connector.Registration;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -96,7 +95,6 @@ import java.util.regex.Matcher;
|
|||
import app.fedilab.android.BuildConfig;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.asynctasks.ManageFiltersAsyncTask;
|
||||
import app.fedilab.android.asynctasks.PostSubscriptionAsyncTask;
|
||||
import app.fedilab.android.asynctasks.RetrieveAccountsAsyncTask;
|
||||
import app.fedilab.android.asynctasks.RetrieveFeedsAsyncTask;
|
||||
import app.fedilab.android.asynctasks.RetrieveInstanceAsyncTask;
|
||||
|
@ -158,7 +156,8 @@ import es.dmoral.toasty.Toasty;
|
|||
|
||||
import static app.fedilab.android.activities.WebviewActivity.trackingDomains;
|
||||
import static app.fedilab.android.asynctasks.ManageFiltersAsyncTask.action.GET_ALL_FILTER;
|
||||
import static app.fedilab.android.helper.BaseHelper.startStreaming;
|
||||
import static app.fedilab.android.helper.BaseHelper.NOTIF_NONE;
|
||||
import static app.fedilab.android.helper.BaseHelper.NOTIF_PUSH;
|
||||
import static app.fedilab.android.helper.Helper.changeDrawableColor;
|
||||
|
||||
|
||||
|
@ -422,9 +421,7 @@ public abstract class BaseMainActivity extends BaseActivity
|
|||
main_app_container = findViewById(R.id.main_app_container);
|
||||
|
||||
|
||||
if (social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
|
||||
new Registration().registerAppWithDialog(BaseMainActivity.this, account.getUsername() + "@" + account.getInstance());
|
||||
}
|
||||
|
||||
if (social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA || social == UpdateAccountInfoAsyncTask.SOCIAL.GNU || social == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
|
||||
new SyncTimelinesAsyncTask(BaseMainActivity.this, 0, Helper.canFetchList(BaseMainActivity.this, account), BaseMainActivity.this);
|
||||
|
||||
|
@ -1201,55 +1198,39 @@ public abstract class BaseMainActivity extends BaseActivity
|
|||
|
||||
//Live notification mode
|
||||
final Spinner set_live_type = dialogView.findViewById(R.id.set_live_type);
|
||||
String[] labels = {getString(R.string.live_notif), getString(R.string.live_delayed), getString(R.string.no_live_notif)};
|
||||
String[] labels = {getString(R.string.push_notif), getString(R.string.no_live_notif)};
|
||||
ArrayAdapter<String> adapterLive = new ArrayAdapter<>(BaseMainActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, labels);
|
||||
set_live_type.setAdapter(adapterLive);
|
||||
TextView set_live_type_indication = dialogView.findViewById(R.id.set_live_type_indication);
|
||||
switch (Helper.liveNotifType(BaseMainActivity.this)) {
|
||||
case Helper.NOTIF_LIVE:
|
||||
set_live_type_indication.setText(R.string.live_notif_indication);
|
||||
break;
|
||||
case Helper.NOTIF_DELAYED:
|
||||
set_live_type_indication.setText(R.string.set_live_type_indication);
|
||||
case Helper.NOTIF_PUSH:
|
||||
set_live_type_indication.setText(R.string.set_push_notifications);
|
||||
break;
|
||||
case Helper.NOTIF_NONE:
|
||||
set_live_type_indication.setText(R.string.no_live_indication);
|
||||
break;
|
||||
}
|
||||
set_live_type.setSelection(Helper.liveNotifType(BaseMainActivity.this), false);
|
||||
int livenotif = Helper.liveNotifType(BaseMainActivity.this);
|
||||
int selection = 0;
|
||||
if (livenotif == NOTIF_NONE)
|
||||
selection = 1;
|
||||
set_live_type.setSelection(selection, false);
|
||||
set_live_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
switch (position) {
|
||||
case Helper.NOTIF_LIVE:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, false);
|
||||
case 0:
|
||||
editor.putBoolean(Helper.SET_PUSH_NOTIFICATIONS, true);
|
||||
editor.apply();
|
||||
startStreaming(BaseMainActivity.this);
|
||||
Helper.startStreaming(BaseMainActivity.this);
|
||||
set_live_type_indication.setText(R.string.set_push_notifications);
|
||||
break;
|
||||
case Helper.NOTIF_DELAYED:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, false);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, true);
|
||||
editor.apply();
|
||||
startStreaming(BaseMainActivity.this);
|
||||
break;
|
||||
case Helper.NOTIF_NONE:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, false);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, false);
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
switch (Helper.liveNotifType(BaseMainActivity.this)) {
|
||||
case Helper.NOTIF_LIVE:
|
||||
set_live_type_indication.setText(R.string.live_notif_indication);
|
||||
break;
|
||||
case Helper.NOTIF_DELAYED:
|
||||
set_live_type_indication.setText(R.string.set_live_type_indication);
|
||||
break;
|
||||
case Helper.NOTIF_NONE:
|
||||
case 1:
|
||||
editor.putBoolean(Helper.SET_PUSH_NOTIFICATIONS, false);
|
||||
set_live_type_indication.setText(R.string.no_live_indication);
|
||||
editor.apply();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import android.os.Bundle;
|
|||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import android.content.SharedPreferences;
|
|||
import android.os.Build;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
|
@ -369,7 +368,6 @@ public class HttpsConnection {
|
|||
postData.append('=');
|
||||
postData.append(param.getValue());
|
||||
}
|
||||
Log.v(Helper.TAG, "postData: " + postData);
|
||||
byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
|
||||
if (proxy != null)
|
||||
httpURLConnection = (HttpsURLConnection) url.openConnection(proxy);
|
||||
|
|
|
@ -31,7 +31,6 @@ import java.util.List;
|
|||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.client.Entities.Account;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.services.LiveNotificationDelayedService;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
|
@ -72,12 +71,6 @@ public class AccountLiveAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_ALLOW_STREAM + accounts.get(i).getId() + accounts.get(i).getInstance(), holder.account_acct_live_notifications.isChecked());
|
||||
editor.apply();
|
||||
if (holder.account_acct_live_notifications.isChecked()) {
|
||||
LiveNotificationDelayedService.totalAccount++;
|
||||
} else {
|
||||
LiveNotificationDelayedService.totalAccount--;
|
||||
}
|
||||
Helper.startStreaming(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@ package app.fedilab.android.fragments;
|
|||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.TimePickerDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentUris;
|
||||
|
@ -29,7 +27,6 @@ import android.database.Cursor;
|
|||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
|
@ -74,7 +71,6 @@ import java.util.Set;
|
|||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.BaseMainActivity;
|
||||
import app.fedilab.android.activities.LiveNotificationSettingsAccountsActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.asynctasks.RetrieveRelationshipAsyncTask;
|
||||
import app.fedilab.android.asynctasks.RetrieveRemoteDataAsyncTask;
|
||||
|
@ -90,12 +86,7 @@ import app.fedilab.android.helper.ExpandableHeightListView;
|
|||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.interfaces.OnRetrieveRelationshipInterface;
|
||||
import app.fedilab.android.interfaces.OnRetrieveRemoteAccountInterface;
|
||||
import app.fedilab.android.jobs.ApplicationJob;
|
||||
import app.fedilab.android.jobs.NotificationsSyncJob;
|
||||
import app.fedilab.android.services.DownloadTrackingDBScriptsService;
|
||||
import app.fedilab.android.services.LiveNotificationDelayedService;
|
||||
import app.fedilab.android.services.StopDelayedNotificationReceiver;
|
||||
import app.fedilab.android.services.StopLiveNotificationReceiver;
|
||||
import app.fedilab.android.sqlite.AccountDAO;
|
||||
import app.fedilab.android.sqlite.MainMenuDAO;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
|
@ -637,23 +628,14 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot
|
|||
final Button sound_media = rootView.findViewById(R.id.sound_media);
|
||||
final Button sound_status = rootView.findViewById(R.id.sound_status);
|
||||
|
||||
final ImageButton set_hide_status_bar = rootView.findViewById(R.id.set_hide_status_bar);
|
||||
|
||||
Button set_notif_sound = rootView.findViewById(R.id.set_notif_sound);
|
||||
settings_time_from.setText(time_from);
|
||||
settings_time_to.setText(time_to);
|
||||
final LinearLayout set_hide_status_bar_container = rootView.findViewById(R.id.set_hide_status_bar_container);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
set_notif_sound.setVisibility(View.GONE);
|
||||
channels_container.setVisibility(View.VISIBLE);
|
||||
set_hide_status_bar_container.setVisibility(View.VISIBLE);
|
||||
set_hide_status_bar.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
|
||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
|
||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, LiveNotificationDelayedService.CHANNEL_ID);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
|
||||
sound_boost.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
|
||||
|
@ -923,36 +905,6 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot
|
|||
}
|
||||
}
|
||||
|
||||
boolean allow_live_notifications = sharedpreferences.getBoolean(Helper.SET_ALLOW_STREAM + userId + instance, true);
|
||||
TextView set_allow_live_notifications_title = rootView.findViewById(R.id.set_allow_live_notifications_title);
|
||||
if (account != null) {
|
||||
set_allow_live_notifications_title.setText(context.getString(R.string.set_allow_live_notifications, account.getAcct() + "@" + account.getInstance()));
|
||||
}
|
||||
final SwitchCompat set_allow_live_notifications = rootView.findViewById(R.id.set_allow_live_notifications);
|
||||
set_allow_live_notifications.setChecked(allow_live_notifications);
|
||||
set_allow_live_notifications.setOnClickListener(v -> {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putBoolean(Helper.SET_ALLOW_STREAM + userId + instance, set_allow_live_notifications.isChecked());
|
||||
editor.apply();
|
||||
if (set_allow_live_notifications.isChecked()) {
|
||||
LiveNotificationDelayedService.totalAccount++;
|
||||
} else {
|
||||
LiveNotificationDelayedService.totalAccount--;
|
||||
}
|
||||
if (set_allow_live_notifications.isChecked()) {
|
||||
LiveNotificationDelayedService.totalAccount++;
|
||||
} else {
|
||||
LiveNotificationDelayedService.totalAccount--;
|
||||
}
|
||||
Helper.startStreaming(context);
|
||||
|
||||
});
|
||||
|
||||
final ImageButton set_allow_live_notifications_others = rootView.findViewById(R.id.set_allow_live_notifications_others);
|
||||
set_allow_live_notifications_others.setOnClickListener(view -> {
|
||||
Intent intent = new Intent(context, LiveNotificationSettingsAccountsActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
|
||||
boolean notify = sharedpreferences.getBoolean(Helper.SET_NOTIFY, true);
|
||||
|
@ -971,35 +923,22 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot
|
|||
editor.apply();
|
||||
if (isChecked) {
|
||||
notification_container.setVisibility(View.VISIBLE);
|
||||
notification_container.setVisibility(View.VISIBLE);
|
||||
Helper.startStreaming(context);
|
||||
} else {
|
||||
context.sendBroadcast(new Intent(context, StopLiveNotificationReceiver.class));
|
||||
context.sendBroadcast(new Intent(context, StopDelayedNotificationReceiver.class));
|
||||
ApplicationJob.cancelAllJob(NotificationsSyncJob.NOTIFICATION_REFRESH);
|
||||
notification_container.setVisibility(View.GONE);
|
||||
}
|
||||
Helper.startStreaming(context);
|
||||
});
|
||||
|
||||
|
||||
//Live notification mode
|
||||
final Spinner set_live_type = rootView.findViewById(R.id.set_live_type);
|
||||
String[] labels = {context.getString(R.string.live_notif), context.getString(R.string.live_delayed), context.getString(R.string.no_live_notif)};
|
||||
ArrayAdapter<String> adapterLive = new ArrayAdapter<>(Objects.requireNonNull(getActivity()),
|
||||
android.R.layout.simple_spinner_dropdown_item, labels);
|
||||
String[] labels = {context.getString(R.string.push_notif), context.getString(R.string.no_live_notif)};
|
||||
|
||||
|
||||
LinearLayout live_notif_per_account = rootView.findViewById(R.id.live_notif_per_account);
|
||||
set_live_type.setAdapter(adapterLive);
|
||||
if (Helper.liveNotifType(context) == Helper.NOTIF_NONE) {
|
||||
live_notif_per_account.setVisibility(View.GONE);
|
||||
}
|
||||
TextView set_live_type_indication = rootView.findViewById(R.id.set_live_type_indication);
|
||||
switch (Helper.liveNotifType(context)) {
|
||||
case Helper.NOTIF_LIVE:
|
||||
set_live_type_indication.setText(R.string.live_notif_indication);
|
||||
break;
|
||||
case Helper.NOTIF_DELAYED:
|
||||
set_live_type_indication.setText(R.string.set_live_type_indication);
|
||||
case Helper.NOTIF_PUSH:
|
||||
set_live_type_indication.setText(R.string.set_push_notifications);
|
||||
break;
|
||||
case Helper.NOTIF_NONE:
|
||||
set_live_type_indication.setText(R.string.no_live_indication);
|
||||
|
@ -1008,40 +947,25 @@ public class ContentSettingsFragment extends Fragment implements OnRetrieveRemot
|
|||
set_live_type.setSelection(Helper.liveNotifType(context));
|
||||
liveNotificationCount = 0;
|
||||
set_live_type.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("ApplySharedPref")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (liveNotificationCount > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
|
||||
context.sendBroadcast(new Intent(context, StopLiveNotificationReceiver.class));
|
||||
context.sendBroadcast(new Intent(context, StopDelayedNotificationReceiver.class));
|
||||
ApplicationJob.cancelAllJob(NotificationsSyncJob.NOTIFICATION_REFRESH);
|
||||
switch (position) {
|
||||
case Helper.NOTIF_LIVE:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, false);
|
||||
live_notif_per_account.setVisibility(View.VISIBLE);
|
||||
case Helper.NOTIF_PUSH:
|
||||
editor.putBoolean(Helper.SET_PUSH_NOTIFICATIONS, true);
|
||||
editor.commit();
|
||||
set_live_type_indication.setText(R.string.live_notif_indication);
|
||||
Helper.startStreaming(context);
|
||||
break;
|
||||
case Helper.NOTIF_DELAYED:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, false);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, true);
|
||||
live_notif_per_account.setVisibility(View.VISIBLE);
|
||||
set_live_type_indication.setText(R.string.set_live_type_indication);
|
||||
editor.commit();
|
||||
Helper.startStreaming(context);
|
||||
set_live_type_indication.setText(R.string.set_push_notifications);
|
||||
|
||||
break;
|
||||
case Helper.NOTIF_NONE:
|
||||
editor.putBoolean(Helper.SET_LIVE_NOTIFICATIONS, false);
|
||||
editor.putBoolean(Helper.SET_DELAYED_NOTIFICATIONS, false);
|
||||
editor.putBoolean(Helper.SET_PUSH_NOTIFICATIONS, false);
|
||||
editor.commit();
|
||||
set_live_type_indication.setText(R.string.no_live_indication);
|
||||
live_notif_per_account.setVisibility(View.GONE);
|
||||
NotificationsSyncJob.schedule(false);
|
||||
break;
|
||||
}
|
||||
Helper.startStreaming(context);
|
||||
} else {
|
||||
liveNotificationCount++;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
@ -55,12 +54,10 @@ import app.fedilab.android.drawers.NotificationsListAdapter;
|
|||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.interfaces.OnRetrieveMissingNotificationsInterface;
|
||||
import app.fedilab.android.interfaces.OnRetrieveNotificationsInterface;
|
||||
import app.fedilab.android.services.LiveNotificationDelayedService;
|
||||
import app.fedilab.android.sqlite.AccountDAO;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
import static app.fedilab.android.activities.BaseMainActivity.countNewNotifications;
|
||||
|
||||
|
||||
|
@ -314,12 +311,6 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
if (type == Type.ALL) {
|
||||
if (lastReadNotifications != null && notifications.get(0).getId().compareTo(lastReadNotifications) > 0) {
|
||||
countNewNotifications++;
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(context));
|
||||
SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account accountdb = new AccountDAO(context, db).getUniqAccount(userId, instance);
|
||||
LiveNotificationDelayedService.since_ids.put(accountdb.getAcct() + "@" + accountdb.getInstance(), notifications.get(0).getId());
|
||||
}
|
||||
}
|
||||
for (Notification tmpNotification : notifications) {
|
||||
|
@ -446,14 +437,6 @@ public class DisplayNotificationsFragment extends Fragment implements OnRetrieve
|
|||
MainActivity.lastNotificationId = notifications.get(0).getId();
|
||||
updateNotificationLastId(notifications.get(0).getId());
|
||||
}
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(context));
|
||||
SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
Account account = new AccountDAO(context, db).getUniqAccount(userId, instance);
|
||||
if (MainActivity.lastNotificationId != null && notifications.get(0).getId().compareTo(MainActivity.lastNotificationId) > 0) {
|
||||
LiveNotificationDelayedService.since_ids.put(account.getAcct() + "@" + account.getInstance(), notifications.get(0).getId());
|
||||
}
|
||||
}
|
||||
if (textviewNoAction.getVisibility() == View.VISIBLE) {
|
||||
textviewNoAction.setVisibility(View.GONE);
|
||||
|
|
|
@ -96,6 +96,9 @@ import app.fedilab.android.sqlite.SearchDAO;
|
|||
import app.fedilab.android.sqlite.Sqlite;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
import static app.fedilab.android.helper.BaseHelper.NOTIF_PUSH;
|
||||
import static app.fedilab.android.helper.BaseHelper.liveNotifType;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Thomas on 24/04/2017.
|
||||
|
@ -756,7 +759,7 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
swipeRefreshLayout.setEnabled(true);
|
||||
boolean liveNotifications = sharedpreferences.getBoolean(Helper.SET_LIVE_NOTIFICATIONS, true);
|
||||
boolean liveNotifications = liveNotifType(context) == NOTIF_PUSH;
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME || type == RetrieveFeedsAsyncTask.Type.PF_HOME) {
|
||||
if (this.isVisible()) {
|
||||
if (statuses != null && statuses.size() > 0) {
|
||||
|
@ -861,7 +864,7 @@ public class DisplayStatusFragment extends Fragment implements OnPostActionInter
|
|||
super.setMenuVisibility(visible);
|
||||
if (context == null)
|
||||
return;
|
||||
int liveNotifications = Helper.liveNotifType(context);
|
||||
int liveNotifications = liveNotifType(context);
|
||||
//Store last toot id for home timeline to avoid to notify for those that have been already seen
|
||||
if (type == RetrieveFeedsAsyncTask.Type.HOME || type == RetrieveFeedsAsyncTask.Type.PF_HOME) {
|
||||
if (visible) {
|
||||
|
|
|
@ -137,6 +137,7 @@ import net.gotev.uploadservice.UploadService;
|
|||
import net.gotev.uploadservice.okhttp.OkHttpStack;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.unifiedpush.android.connector.Registration;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -211,8 +212,8 @@ import app.fedilab.android.client.Entities.Status;
|
|||
import app.fedilab.android.client.Entities.Tag;
|
||||
import app.fedilab.android.client.Entities.TagTimeline;
|
||||
import app.fedilab.android.client.Tls12SocketFactory;
|
||||
import app.fedilab.android.services.LiveNotificationDelayedService;
|
||||
import app.fedilab.android.services.LiveNotificationService;
|
||||
import app.fedilab.android.jobs.ApplicationJob;
|
||||
import app.fedilab.android.jobs.NotificationsSyncJob;
|
||||
import app.fedilab.android.sqlite.AccountDAO;
|
||||
import app.fedilab.android.sqlite.MainMenuDAO;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
|
@ -336,7 +337,7 @@ public class BaseHelper {
|
|||
public static final String SET_TIME_FROM = "set_time_from";
|
||||
public static final String SET_TIME_TO = "set_time_to";
|
||||
public static final String SET_AUTO_STORE = "set_auto_store";
|
||||
public static final String SET_POPUP_PUSH = "set_popup_push_new";
|
||||
public static final String SET_POPUP_PUSH = "set_popup_push_new_push";
|
||||
public static final String SET_POPUP_RELEASE_NOTES = "set_popup_push_release_notes";
|
||||
public static final String SET_NSFW_TIMEOUT = "set_nsfw_timeout";
|
||||
public static final String SET_MED_DESC_TIMEOUT = "set_med_desc_timeout";
|
||||
|
@ -348,8 +349,7 @@ public class BaseHelper {
|
|||
public static final String SET_SHOW_BOOSTS = "set_show_boost";
|
||||
public static final String SET_SHOW_REPLIES = "set_show_replies";
|
||||
public static final String SET_VIDEO_NSFW = "set_video_nsfw";
|
||||
public static final String SET_LIVE_NOTIFICATIONS = "set_live_notifications";
|
||||
public static final String SET_DELAYED_NOTIFICATIONS = "set_delayed_notifications";
|
||||
public static final String SET_PUSH_NOTIFICATIONS = "set_push_notifications";
|
||||
public static final String SET_DISABLE_GIF = "set_disable_gif";
|
||||
public static final String SET_DISABLE_ANIMATED_EMOJI = "set_disable_animated_emoji";
|
||||
public static final String SET_CAPITALIZE = "set_capitalize";
|
||||
|
@ -406,8 +406,7 @@ public class BaseHelper {
|
|||
public static final int THEME_DARK = 2;
|
||||
public static final int THEME_BLACK = 3;
|
||||
|
||||
public static final int NOTIF_LIVE = 0;
|
||||
public static final int NOTIF_DELAYED = 1;
|
||||
public static final int NOTIF_PUSH = 3;
|
||||
public static final int NOTIF_NONE = 2;
|
||||
|
||||
public static final int LED_COLOUR = 0;
|
||||
|
@ -589,17 +588,32 @@ public class BaseHelper {
|
|||
|
||||
public static int liveNotifType(Context context) {
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean live = sharedpreferences.getBoolean(SET_LIVE_NOTIFICATIONS, false);
|
||||
boolean delayed = sharedpreferences.getBoolean(SET_DELAYED_NOTIFICATIONS, true);
|
||||
if (delayed) {
|
||||
return NOTIF_DELAYED;
|
||||
} else if (live) {
|
||||
return NOTIF_LIVE;
|
||||
boolean push = sharedpreferences.getBoolean(SET_PUSH_NOTIFICATIONS, false);
|
||||
if (push) {
|
||||
return NOTIF_PUSH;
|
||||
} else {
|
||||
return NOTIF_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public static void startStreaming(Context context) {
|
||||
int liveNotifications = liveNotifType(context);
|
||||
switch (liveNotifications) {
|
||||
case NOTIF_PUSH:
|
||||
if (social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
|
||||
new Registration().registerAppWithDialog(context);
|
||||
ApplicationJob.cancelAllJob(NotificationsSyncJob.NOTIFICATION_REFRESH);
|
||||
} else {
|
||||
new Registration().unregisterApp(context);
|
||||
NotificationsSyncJob.schedule(false);
|
||||
}
|
||||
break;
|
||||
case NOTIF_NONE:
|
||||
new Registration().unregisterApp(context);
|
||||
NotificationsSyncJob.schedule(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Check if the user is connected to Internet
|
||||
|
@ -4331,29 +4345,6 @@ public class BaseHelper {
|
|||
|
||||
}
|
||||
|
||||
public static void startStreaming(Context context) {
|
||||
int liveNotifications = liveNotifType(context);
|
||||
Intent streamingIntent = null;
|
||||
switch (liveNotifications) {
|
||||
case NOTIF_LIVE:
|
||||
streamingIntent = new Intent(context, LiveNotificationService.class);
|
||||
break;
|
||||
case NOTIF_DELAYED:
|
||||
streamingIntent = new Intent(context, LiveNotificationDelayedService.class);
|
||||
break;
|
||||
}
|
||||
if (streamingIntent != null) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
context.startForegroundService(streamingIntent);
|
||||
} else {
|
||||
context.startService(streamingIntent);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
context.startService(streamingIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean canFetchList(Context context, Account account) {
|
||||
SharedPreferences sharedpreferences = context.getSharedPreferences(APP_PREFS, Context.MODE_PRIVATE);
|
||||
|
|
|
@ -18,7 +18,6 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
|
@ -115,11 +114,6 @@ public class ECDH {
|
|||
|
||||
private static byte[] generateSecret(PrivateKey myPrivKey, PublicKey otherPubKey) throws Exception {
|
||||
ECPublicKey ecPubKey = (ECPublicKey) otherPubKey;
|
||||
Log.d(TAG, "public key Wx: "
|
||||
+ ecPubKey.getW().getAffineX().toString(16));
|
||||
Log.d(TAG, "public key Wy: "
|
||||
+ ecPubKey.getW().getAffineY().toString(16));
|
||||
|
||||
KeyAgreement keyAgreement = KeyAgreement.getInstance(KEGEN_ALG, PROVIDER);
|
||||
keyAgreement.init(myPrivKey);
|
||||
keyAgreement.doPhase(otherPubKey, true);
|
||||
|
|
|
@ -1,4 +1,298 @@
|
|||
package app.fedilab.android.helper;
|
||||
/* Copyright 2021 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
class NotificationsHelper {
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.client.API;
|
||||
import app.fedilab.android.client.APIResponse;
|
||||
import app.fedilab.android.client.Entities.Account;
|
||||
import app.fedilab.android.client.Entities.Notification;
|
||||
import app.fedilab.android.client.GNUAPI;
|
||||
import app.fedilab.android.fragments.DisplayNotificationsFragment;
|
||||
|
||||
import static app.fedilab.android.helper.BaseHelper.INTENT_ACTION;
|
||||
import static app.fedilab.android.helper.BaseHelper.INTENT_TARGETED_ACCOUNT;
|
||||
import static app.fedilab.android.helper.BaseHelper.NOTIFICATION_INTENT;
|
||||
import static app.fedilab.android.helper.BaseHelper.PREF_INSTANCE;
|
||||
import static app.fedilab.android.helper.BaseHelper.PREF_KEY_ID;
|
||||
import static app.fedilab.android.helper.BaseHelper.getMainLogo;
|
||||
|
||||
import static app.fedilab.android.helper.BaseHelper.notify_user;
|
||||
|
||||
|
||||
public class NotificationsHelper {
|
||||
|
||||
|
||||
public static void task(Context context, Account account) {
|
||||
APIResponse apiResponse;
|
||||
|
||||
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
//Check which notifications the user wants to see
|
||||
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
|
||||
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
|
||||
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
|
||||
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
|
||||
boolean notif_poll = sharedpreferences.getBoolean(Helper.SET_NOTIF_POLL, true);
|
||||
//User disagree with all notifications
|
||||
if (!notif_follow && !notif_add && !notif_mention && !notif_share && !notif_poll)
|
||||
return; //Nothing is done
|
||||
//No account connected, the service is stopped
|
||||
if (!Helper.isLoggedIn(context))
|
||||
return;
|
||||
//If WIFI only and on WIFI OR user defined any connections to use the service.
|
||||
if (!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(context)) {
|
||||
if (account.getSocial().compareTo("FRIENDICA") != 0 && account.getSocial().compareTo("GNU") != 0) {
|
||||
API api = new API(context, account.getInstance(), account.getToken());
|
||||
apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null, false);
|
||||
} else {
|
||||
GNUAPI gnuApi = new GNUAPI(context, account.getInstance(), account.getToken());
|
||||
apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null);
|
||||
}
|
||||
onRetrieveNotifications(context, apiResponse, account);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void onRetrieveNotifications(Context context, APIResponse apiResponse, final Account account) {
|
||||
List<Notification> notificationsReceived = apiResponse.getNotifications();
|
||||
|
||||
if (apiResponse.getError() != null || notificationsReceived == null || notificationsReceived.size() == 0 || account == null)
|
||||
return;
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
|
||||
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
|
||||
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
|
||||
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
|
||||
boolean notif_poll = sharedpreferences.getBoolean(Helper.SET_NOTIF_POLL, true);
|
||||
boolean notif_status = sharedpreferences.getBoolean(Helper.SET_NOTIF_STATUS, true);
|
||||
final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
final List<Notification> notifications = new ArrayList<>();
|
||||
int pos = 0;
|
||||
for (Notification notif : notificationsReceived) {
|
||||
if (max_id == null || notif.getId().compareTo(max_id) > 0) {
|
||||
notifications.add(pos, notif);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (notifications.size() == 0)
|
||||
return;
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
int newFollows = 0;
|
||||
int newAdds = 0;
|
||||
int newMentions = 0;
|
||||
int newShare = 0;
|
||||
int newPolls = 0;
|
||||
int newStatus = 0;
|
||||
String notificationUrl = null;
|
||||
String title = null;
|
||||
final String message;
|
||||
String targeted_account = null;
|
||||
Helper.NotifType notifType = Helper.NotifType.MENTION;
|
||||
|
||||
for (Notification notification : notifications) {
|
||||
switch (notification.getType()) {
|
||||
case "mention":
|
||||
notifType = Helper.NotifType.MENTION;
|
||||
if (notif_mention) {
|
||||
newMentions++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_mention));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_mention));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "status":
|
||||
notifType = Helper.NotifType.STATUS;
|
||||
if (notif_status) {
|
||||
newStatus++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_status));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_status));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "reblog":
|
||||
notifType = Helper.NotifType.BOOST;
|
||||
if (notif_share) {
|
||||
newShare++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_reblog));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_reblog));
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "favourite":
|
||||
notifType = Helper.NotifType.FAV;
|
||||
if (notif_add) {
|
||||
newAdds++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_favourite));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_favourite));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "follow_request":
|
||||
notifType = Helper.NotifType.FOLLLOW;
|
||||
if (notif_follow) {
|
||||
newFollows++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_follow_request));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_follow_request));
|
||||
targeted_account = notification.getAccount().getId();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "follow":
|
||||
notifType = Helper.NotifType.FOLLLOW;
|
||||
if (notif_follow) {
|
||||
newFollows++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), context.getString(R.string.notif_follow));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), context.getString(R.string.notif_follow));
|
||||
targeted_account = notification.getAccount().getId();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "poll":
|
||||
notifType = Helper.NotifType.POLL;
|
||||
if (notif_poll) {
|
||||
newPolls++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
if (notification.getAccount().getId() != null && notification.getAccount().getId().equals(userId))
|
||||
title = context.getString(R.string.notif_poll_self);
|
||||
else
|
||||
title = context.getString(R.string.notif_poll);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
int allNotifCount = newFollows + newAdds + newMentions + newShare + newPolls + newStatus;
|
||||
if (allNotifCount > 0) {
|
||||
//Some others notification
|
||||
int other = allNotifCount - 1;
|
||||
if (other > 0)
|
||||
message = context.getResources().getQuantityString(R.plurals.other_notifications, other, other);
|
||||
else
|
||||
message = "";
|
||||
final Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
|
||||
intent.putExtra(PREF_KEY_ID, account.getId());
|
||||
if (targeted_account != null && notifType == Helper.NotifType.FOLLLOW)
|
||||
intent.putExtra(INTENT_TARGETED_ACCOUNT, targeted_account);
|
||||
intent.putExtra(PREF_INSTANCE, account.getInstance());
|
||||
if (notificationUrl != null) {
|
||||
final String finalTitle = title;
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
final String finalNotificationUrl = notificationUrl;
|
||||
Helper.NotifType finalNotifType = notifType;
|
||||
Runnable myRunnable = () -> Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(finalNotificationUrl)
|
||||
.listener(new RequestListener<Bitmap>() {
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
|
||||
notify_user(context, account, intent, BitmapFactory.decodeResource(context.getResources(),
|
||||
getMainLogo(context)), finalNotifType, finalTitle, message);
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if (lastNotif == null || notifications.get(0).getId().compareTo(lastNotif) > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
notify_user(context, account, intent, resource, finalNotifType, finalTitle, message);
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if (lastNotif == null || notifications.get(0).getId().compareTo(lastNotif) > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import app.fedilab.android.client.Entities.Notification;
|
|||
import app.fedilab.android.client.GNUAPI;
|
||||
import app.fedilab.android.fragments.DisplayNotificationsFragment;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.NotificationsHelper;
|
||||
import app.fedilab.android.sqlite.AccountDAO;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
|
||||
|
@ -145,215 +146,8 @@ public class BaseNotificationsSyncJob extends Job {
|
|||
GNUAPI gnuApi = new GNUAPI(getContext(), account.getInstance(), account.getToken());
|
||||
apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null);
|
||||
}
|
||||
onRetrieveNotifications(apiResponse, account);
|
||||
NotificationsHelper.onRetrieveNotifications(getContext(), apiResponse, account);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onRetrieveNotifications(APIResponse apiResponse, final Account account) {
|
||||
List<Notification> notificationsReceived = apiResponse.getNotifications();
|
||||
if (apiResponse.getError() != null || notificationsReceived == null || notificationsReceived.size() == 0 || account == null)
|
||||
return;
|
||||
final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true);
|
||||
boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true);
|
||||
boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true);
|
||||
boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true);
|
||||
boolean notif_poll = sharedpreferences.getBoolean(Helper.SET_NOTIF_POLL, true);
|
||||
boolean notif_status = sharedpreferences.getBoolean(Helper.SET_NOTIF_STATUS, true);
|
||||
final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
final List<Notification> notifications = new ArrayList<>();
|
||||
int pos = 0;
|
||||
for (Notification notif : notificationsReceived) {
|
||||
if (max_id == null || notif.getId().compareTo(max_id) > 0) {
|
||||
notifications.add(pos, notif);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (notifications.size() == 0)
|
||||
return;
|
||||
//No previous notifications in cache, so no notification will be sent
|
||||
int newFollows = 0;
|
||||
int newAdds = 0;
|
||||
int newMentions = 0;
|
||||
int newShare = 0;
|
||||
int newPolls = 0;
|
||||
int newStatus = 0;
|
||||
String notificationUrl = null;
|
||||
String title = null;
|
||||
final String message;
|
||||
String targeted_account = null;
|
||||
Helper.NotifType notifType = Helper.NotifType.MENTION;
|
||||
|
||||
for (Notification notification : notifications) {
|
||||
switch (notification.getType()) {
|
||||
case "mention":
|
||||
notifType = Helper.NotifType.MENTION;
|
||||
if (notif_mention) {
|
||||
newMentions++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_mention));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_mention));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "status":
|
||||
notifType = Helper.NotifType.STATUS;
|
||||
if (notif_status) {
|
||||
newStatus++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_status));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_status));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "reblog":
|
||||
notifType = Helper.NotifType.BOOST;
|
||||
if (notif_share) {
|
||||
newShare++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_reblog));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_reblog));
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "favourite":
|
||||
notifType = Helper.NotifType.FAV;
|
||||
if (notif_add) {
|
||||
newAdds++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_favourite));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_favourite));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "follow_request":
|
||||
notifType = Helper.NotifType.FOLLLOW;
|
||||
if (notif_follow) {
|
||||
newFollows++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_follow_request));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_follow_request));
|
||||
targeted_account = notification.getAccount().getId();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "follow":
|
||||
notifType = Helper.NotifType.FOLLLOW;
|
||||
if (notif_follow) {
|
||||
newFollows++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
if (notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0)
|
||||
title = String.format("%s %s", notification.getAccount().getDisplay_name(), getContext().getString(R.string.notif_follow));
|
||||
else
|
||||
title = String.format("@%s %s", notification.getAccount().getAcct(), getContext().getString(R.string.notif_follow));
|
||||
targeted_account = notification.getAccount().getId();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "poll":
|
||||
notifType = Helper.NotifType.POLL;
|
||||
if (notif_poll) {
|
||||
newPolls++;
|
||||
if (notificationUrl == null) {
|
||||
notificationUrl = notification.getAccount().getAvatar();
|
||||
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
|
||||
if (notification.getAccount().getId() != null && notification.getAccount().getId().equals(userId))
|
||||
title = getContext().getString(R.string.notif_poll_self);
|
||||
else
|
||||
title = getContext().getString(R.string.notif_poll);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
int allNotifCount = newFollows + newAdds + newMentions + newShare + newPolls + newStatus;
|
||||
if (allNotifCount > 0) {
|
||||
//Some others notification
|
||||
int other = allNotifCount - 1;
|
||||
if (other > 0)
|
||||
message = getContext().getResources().getQuantityString(R.plurals.other_notifications, other, other);
|
||||
else
|
||||
message = "";
|
||||
final Intent intent = new Intent(getContext(), MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT);
|
||||
intent.putExtra(PREF_KEY_ID, account.getId());
|
||||
if (targeted_account != null && notifType == Helper.NotifType.FOLLLOW)
|
||||
intent.putExtra(INTENT_TARGETED_ACCOUNT, targeted_account);
|
||||
intent.putExtra(PREF_INSTANCE, account.getInstance());
|
||||
if (notificationUrl != null) {
|
||||
final String finalTitle = title;
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
final String finalNotificationUrl = notificationUrl;
|
||||
Helper.NotifType finalNotifType = notifType;
|
||||
Runnable myRunnable = () -> Glide.with(getContext())
|
||||
.asBitmap()
|
||||
.load(finalNotificationUrl)
|
||||
.listener(new RequestListener<Bitmap>() {
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
|
||||
|
||||
notify_user(getContext(), account, intent, BitmapFactory.decodeResource(getContext().getResources(),
|
||||
getMainLogo(getContext())), finalNotifType, finalTitle, message);
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if (lastNotif == null || notifications.get(0).getId().compareTo(lastNotif) > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(new CustomTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||
notify_user(getContext(), account, intent, resource, finalNotifType, finalTitle, message);
|
||||
String lastNotif = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), null);
|
||||
if (lastNotif == null || notifications.get(0).getId().compareTo(lastNotif) > 0) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId() + account.getInstance(), notifications.get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,12 +15,25 @@ package app.fedilab.android.services;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.unifiedpush.android.connector.MessagingReceiver;
|
||||
import org.unifiedpush.android.connector.MessagingReceiverHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.client.API;
|
||||
import app.fedilab.android.client.APIResponse;
|
||||
import app.fedilab.android.client.Entities.Account;
|
||||
import app.fedilab.android.client.GNUAPI;
|
||||
import app.fedilab.android.fragments.DisplayNotificationsFragment;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.NotificationsHelper;
|
||||
import app.fedilab.android.helper.PushNotifications;
|
||||
import app.fedilab.android.sqlite.AccountDAO;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
|
@ -28,13 +41,27 @@ class handler implements MessagingReceiverHandler {
|
|||
|
||||
|
||||
@Override
|
||||
public void onMessage(@Nullable Context context, @NotNull String s, @NotNull String s1) {
|
||||
new PushNotifications()
|
||||
.displayNotification(context, s);
|
||||
public void onMessage(@Nullable Context context, @NotNull String s) {
|
||||
SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
final List<Account> accounts = new AccountDAO(context, db).getPushNotificationAccounts();
|
||||
new Thread(() -> {
|
||||
for (Account account : accounts) {
|
||||
APIResponse apiResponse;
|
||||
if (account.getSocial().compareTo("FRIENDICA") != 0 && account.getSocial().compareTo("GNU") != 0) {
|
||||
API api = new API(context, account.getInstance(), account.getToken());
|
||||
apiResponse = api.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null, false);
|
||||
} else {
|
||||
GNUAPI gnuApi = new GNUAPI(context, account.getInstance(), account.getToken());
|
||||
apiResponse = gnuApi.getNotificationsSince(DisplayNotificationsFragment.Type.ALL, null);
|
||||
}
|
||||
NotificationsHelper.onRetrieveNotifications(context, apiResponse, account);
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewEndpoint(@Nullable Context context, @NotNull String endpoint, @NotNull String s1) {
|
||||
public void onNewEndpoint(@Nullable Context context, @NotNull String endpoint) {
|
||||
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putString(Helper.SERVER_ENDPOINT, endpoint);
|
||||
|
@ -45,17 +72,17 @@ class handler implements MessagingReceiverHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onRegistrationFailed(@Nullable Context context, @NotNull String s) {
|
||||
public void onRegistrationFailed(@Nullable Context context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegistrationRefused(@Nullable Context context, @NotNull String s) {
|
||||
public void onRegistrationRefused(@Nullable Context context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnregistered(@Nullable Context context, @NotNull String s) {
|
||||
public void onUnregistered(@Nullable Context context) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,102 +89,6 @@
|
|||
android:layout_marginBottom="10dp"
|
||||
android:textColor="@color/mastodonC2" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/live_notif_per_account"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/settings_option_margin"
|
||||
android:layout_marginBottom="@dimen/settings_option_margin"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/set_allow_live_notifications_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_allow_live_notifications"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_allow_live_notifications_indication"
|
||||
android:textColor="@color/mastodonC2"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/set_allow_live_notifications"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/set_allow_live_notifications_others"
|
||||
style="@style/colored_button"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="end"
|
||||
android:contentDescription="@string/live_notif"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/ic_account_circle_acct" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/set_hide_status_bar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/settings_option_margin"
|
||||
android:layout_marginBottom="@dimen/settings_option_margin"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_hide_status_bar"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/set_hide_status_bar_indication"
|
||||
android:textColor="@color/mastodonC2"
|
||||
android:textSize="12sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/set_hide_status_bar"
|
||||
style="@style/colored_button"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:contentDescription="@string/bookmark_add"
|
||||
android:padding="5dp"
|
||||
android:src="@drawable/ic_hide_status_bar" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/notification_settings"
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
<string name="disclaimer_full">Information below may reflect the user\'s profile incompletely.</string>
|
||||
<string name="insert_emoji">Insert emoji</string>
|
||||
<string name="no_emoji">The app did not collect custom emojis for the moment.</string>
|
||||
<string name="live_notif">Live notifications</string>
|
||||
<string name="push_notif">Push notifications</string>
|
||||
<string name="logout_confirmation">Are you sure you want to logout?</string>
|
||||
<string name="logout_account_confirmation">Are you sure you want to logout @%1$s@%2$s?</string>
|
||||
<!-- Status -->
|
||||
|
@ -984,7 +984,6 @@
|
|||
<string name="set_blur_sensitive_indication">If disabled, sensitive media will be hidden with a button</string>
|
||||
<string name="set_long_press_media_indication">Store media in full size with a long press on previews</string>
|
||||
<string name="set_display_timeline_in_list_indication">Add an ellipse button at the top right for listing all tags/instances/lists</string>
|
||||
<string name="live_notif_indication">Keep an open connection to the streaming API for live notifications.</string>
|
||||
<string name="set_enable_time_slot_indication">During the time slot, the app will send notifications. You can reverse (ie: silent) this time slot with the right spinner.</string>
|
||||
<string name="set_display_fedilab_features_button_indication">Display a Fedilab button below profile picture. It is a shortcut for accessing in-app features.</string>
|
||||
<string name="set_quick_reply_indication">Allow to reply directly in timelines below statuses</string>
|
||||
|
@ -1121,8 +1120,7 @@
|
|||
|
||||
<string name="set_hide_status_bar">Hide Fedilab notification bar</string>
|
||||
<string name="set_hide_status_bar_indication">For hiding the remaining notification in the status bar, tap on the eye icon button then uncheck: \"Display in status bar\"</string>
|
||||
<string name="set_live_type_indication">Notifications will be delayed every 30 seconds. That will allow to drain less battery.</string>
|
||||
<string name="live_delayed">Live notifications delayed</string>
|
||||
<string name="set_push_notifications">Use a push notifications system for getting notifications in real time.</string>
|
||||
<string name="no_live_notif">No live notifications</string>
|
||||
<string name="no_live_indication">Notifications will be fetched every 15 minutes.</string>
|
||||
<string name="action_add_notes">Add notes</string>
|
||||
|
|
Loading…
Reference in New Issue