Notifications (#554)

Cleanup

Extending and improving notifications

Using new icons instead

Lowering polling delay to one minute and other improvements

Fixing minor issues

Simplifying progress layout

Fixing bugs and other improvements

Adding translations

Notifications

Co-authored-by: opyale <opyale@noreply.gitea.io>
Co-authored-by: 6543 <6543@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/554
Reviewed-by: 6543 <6543@noreply.codeberg.org>
Reviewed-by: M M Arif <mmarif@noreply.codeberg.org>
This commit is contained in:
opyale
2020-07-22 21:32:42 +02:00
committed by 6543
parent cd55f946f0
commit 39ac49b258
39 changed files with 1856 additions and 129 deletions

View File

@@ -0,0 +1,67 @@
package org.mian.gitnex.notifications;
import android.content.Context;
import android.os.Build;
import androidx.work.Constraints;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkManager;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.helpers.Version;
import java.util.concurrent.TimeUnit;
/**
* Author opyale
*/
public class NotificationsMaster {
private static int notificationsSupported = -1;
private static void checkVersion(TinyDB tinyDB) {
String currentVersion = tinyDB.getString("giteaVersion");
if(tinyDB.getBoolean("loggedInMode") && !currentVersion.isEmpty()) {
notificationsSupported = new Version(currentVersion).higherOrEqual("1.12.3") ? 1 : 0;
}
}
public static void fireWorker(Context context) {
WorkManager.getInstance(context).cancelAllWorkByTag(context.getPackageName());
}
public static void hireWorker(Context context) {
TinyDB tinyDB = new TinyDB(context);
if(notificationsSupported == -1) {
checkVersion(tinyDB);
}
if(notificationsSupported == 1) {
Constraints.Builder constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(false)
.setRequiresStorageNotLow(false)
.setRequiresCharging(false);
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
constraints.setRequiresDeviceIdle(false);
}
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, tinyDB.getInt("pollingDelayMinutes"), TimeUnit.MINUTES)
.setConstraints(constraints.build())
.addTag(context.getPackageName())
.build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork(context.getPackageName(), ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
}
}
}

View File

@@ -0,0 +1,160 @@
package org.mian.gitnex.notifications;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Build;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import org.mian.gitnex.R;
import org.mian.gitnex.activities.MainActivity;
import org.mian.gitnex.clients.RetrofitClient;
import org.mian.gitnex.helpers.AppUtil;
import org.mian.gitnex.helpers.TinyDB;
import org.mian.gitnex.models.NotificationThread;
import java.util.Date;
import java.util.List;
import retrofit2.Call;
import retrofit2.Response;
/**
* Author opyale
*/
public class NotificationsWorker extends Worker {
private static final int MAXIMUM_NOTIFICATIONS = 100;
private static final long[] VIBRATION_PATTERN = new long[]{ 1000, 1000 };
private Context context;
private TinyDB tinyDB;
public NotificationsWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.context = context;
this.tinyDB = new TinyDB(context);
}
@NonNull
@Override
public Result doWork() {
String instanceUrl = tinyDB.getString("instanceUrl");
String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
int notificationLoops = tinyDB.getInt("pollingDelayMinutes") >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10);
for(int i=0; i<notificationLoops; i++) {
long startPollingTime = System.currentTimeMillis();
try {
String previousRefreshTimestamp = tinyDB.getString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
Call<List<NotificationThread>> call = RetrofitClient.getInstance(instanceUrl, context)
.getApiInterface()
.getNotificationThreads(token, false, new String[]{"unread"}, previousRefreshTimestamp,
null, 1, MAXIMUM_NOTIFICATIONS);
Response<List<NotificationThread>> response = call.execute();
if(response.code() == 200) {
assert response.body() != null;
List<NotificationThread> notificationThreads = response.body();
Log.i("ReceivedNotifications", String.valueOf(notificationThreads.size()));
if(!notificationThreads.isEmpty()) {
for(NotificationThread notificationThread : notificationThreads) {
sendNotification(notificationThread);
}
}
tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
} else {
Log.e("onError", String.valueOf(response.code()));
}
} catch(Exception e) {
Log.e("onError", e.toString());
}
try {
if(notificationLoops > 1 && i < (notificationLoops - 1)) {
Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime));
}
} catch (InterruptedException ignored) {}
}
return Result.success();
}
private void sendNotification(NotificationThread notificationThread) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra("launchFragment", "notifications");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if(notificationManager != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name),
NotificationManager.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(VIBRATION_PATTERN);
notificationManager.createNotificationChannel(notificationChannel);
}
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 notificationBody = String.format(context.getResources().getString(R.string.notificationBody),
notificationThread.getSubject().getType());
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, context.getPackageName())
.setSmallIcon(R.drawable.gitnex_transparent).setContentTitle(notificationHeader)
.setContentText(notificationBody)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent).setVibrate(VIBRATION_PATTERN).setAutoCancel(true);
int previousNotificationId = tinyDB.getInt("previousNotificationId", 0);
int newPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1;
tinyDB.putInt("previousNotificationId", newPreviousNotificationId);
notificationManager.notify(previousNotificationId, builder.build());
}
}
}