GitNex-Android-App/app/src/main/java/org/mian/gitnex/notifications/NotificationsWorker.java

236 lines
7.7 KiB
Java

package org.mian.gitnex.notifications;
import android.Manifest;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.app.TaskStackBuilder;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gitnex.tea4j.v2.models.NotificationThread;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.database.api.BaseApi;
import org.mian.gitnex.database.api.UserAccountsApi;
import org.mian.gitnex.database.models.UserAccount;
import org.mian.gitnex.helpers.Constants;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import retrofit2.Call;
import retrofit2.Response;
/**
* @author opyale
*/
public class NotificationsWorker extends Worker {
private final Context context;
private final Map<UserAccount, Map<String, String>> userAccounts;
public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
UserAccountsApi userAccountsApi = BaseApi.getInstance(context, UserAccountsApi.class);
this.context = context;
TinyDB tinyDB = TinyDB.getInstance(context);
assert userAccountsApi != null;
this.userAccounts = new HashMap<>(userAccountsApi.getCount());
int delay;
if (tinyDB.getInt("notificationsPollingDelayId") == 0) {
delay = 15;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 1) {
delay = 30;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 2) {
delay = 45;
} else if (tinyDB.getInt("notificationsPollingDelayId") == 3) {
delay = 60;
} else {
delay = Constants.defaultPollingDelay;
}
ZonedDateTime zdt = ZonedDateTime.now();
zdt = zdt.minusMinutes(delay);
String previousTimestamp = String.valueOf(zdt.toOffsetDateTime());
for (UserAccount userAccount : userAccountsApi.loggedInUserAccounts()) {
// We do also accept empty values, since the server version was not saved properly in
// the beginning.
if (userAccount.getServerVersion() == null
|| userAccount.getServerVersion().isEmpty()
|| new Version(userAccount.getServerVersion()).higherOrEqual("1.12.3")) {
Map<String, String> userAccountParameters = new HashMap<>();
userAccountParameters.put("previousTimestamp", previousTimestamp);
userAccounts.put(userAccount, userAccountParameters);
}
}
}
@NonNull @Override
public Result doWork() {
startPolling();
return Result.success();
}
private void startPolling() {
for (UserAccount userAccount : userAccounts.keySet()) {
Map<String, String> userAccountParameters = userAccounts.get(userAccount);
assert userAccountParameters != null;
try {
Call<List<NotificationThread>> call =
RetrofitClient.getApiInterface(
context,
userAccount.getInstanceUrl(),
"token " + userAccount.getToken(),
null)
.notifyGetList2(
false,
List.of("unread"),
null,
userAccountParameters.get("previousTimestamp"),
null,
1,
25);
Response<List<NotificationThread>> response = call.execute();
if (response.code() == 200 && response.body() != null) {
List<NotificationThread> notificationThreads = response.body();
if (!notificationThreads.isEmpty()) {
sendNotifications(userAccount, notificationThreads);
}
}
} catch (Exception ignored) {
}
}
}
private void sendNotifications(
@NonNull UserAccount userAccount,
@NonNull List<NotificationThread> notificationThreads) {
PendingIntent pendingIntent = getPendingIntent(userAccount);
NotificationManagerCompat notificationManagerCompat =
NotificationManagerCompat.from(context);
Notification summaryNotification =
new NotificationCompat.Builder(context, Constants.mainNotificationChannelId)
.setContentTitle(
context.getString(R.string.newMessages, userAccount.getUserName()))
.setContentText(
String.format(
context.getString(R.string.youHaveGotNewNotifications),
notificationThreads.size()))
.setSmallIcon(R.drawable.gitnex_transparent)
.setGroup(userAccount.getUserName())
.setGroupSummary(true)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
if (ActivityCompat.checkSelfPermission(
getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
MaterialAlertDialogBuilder materialAlertDialogBuilder =
new MaterialAlertDialogBuilder(context)
.setTitle(R.string.pageTitleNotifications)
.setMessage(context.getString(R.string.openAppSettings))
.setNeutralButton(
R.string.cancelButton, (dialog, which) -> dialog.dismiss())
.setPositiveButton(
R.string.isOpen,
(dialog, which) -> {
Intent intent =
new Intent(
Settings
.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri =
Uri.fromParts(
"package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
});
materialAlertDialogBuilder.create().show();
return;
}
notificationManagerCompat.notify(userAccount.getAccountId(), summaryNotification);
for (NotificationThread notificationThread : notificationThreads) {
String subjectUrl = notificationThread.getSubject().getUrl();
String issueId =
context.getResources().getString(R.string.hash)
+ subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1);
String notificationHeader =
issueId
+ " "
+ notificationThread.getSubject().getTitle()
+ " "
+ String.format(
context.getResources()
.getString(R.string.notificationExtraInfo),
notificationThread.getRepository().getFullName(),
notificationThread.getSubject().getType());
NotificationCompat.Builder builder1 =
getBaseNotificationBuilder()
.setContentTitle(notificationHeader)
.setGroup(userAccount.getUserName())
.setContentIntent(pendingIntent);
notificationManagerCompat.notify(
Notifications.uniqueNotificationId(context), builder1.build());
}
}
private NotificationCompat.Builder getBaseNotificationBuilder() {
return new NotificationCompat.Builder(context, Constants.mainNotificationChannelId)
.setSmallIcon(R.drawable.gitnex_transparent)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true);
}
private PendingIntent getPendingIntent(@NonNull UserAccount userAccount) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("launchFragment", "notifications");
intent.putExtra("switchAccountId", userAccount.getAccountId());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntentWithParentStack(intent);
return stackBuilder.getPendingIntent(
1, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}
}