Skip to content

Commit

Permalink
properly localize notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
newhinton committed Jan 20, 2024
1 parent dc1e122 commit 6a0c915
Show file tree
Hide file tree
Showing 11 changed files with 308 additions and 187 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.annotation.StringRes
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.WorkManager
import ca.pkay.rcloneexplorer.BroadcastReceivers.SyncRestartAction
import ca.pkay.rcloneexplorer.Items.FileItem
import ca.pkay.rcloneexplorer.R
import ca.pkay.rcloneexplorer.notifications.GenericSyncNotification
import ca.pkay.rcloneexplorer.notifications.support.StatusObject
import ca.pkay.rcloneexplorer.util.FLog
import ca.pkay.rcloneexplorer.util.NotificationUtils
import ca.pkay.rcloneexplorer.workmanager.SyncWorker
Expand All @@ -23,20 +26,19 @@ abstract class WorkerNotification(var mContext: Context) {
abstract val CHANNEL_ID: String


val CHANNEL_SUCCESS_ID = this.CHANNEL_ID +"_success"
open val CHANNEL_FAIL_ID = this.CHANNEL_ID+"_fail"
open val CHANNEL_SUCCESS_ID = this.CHANNEL_ID + "_success"
open val CHANNEL_FAIL_ID = this.CHANNEL_ID + "_fail"

val GROUP_ID = "de.felixnuesse.extract.taskworker.group"
val GROUP_DESCRIPTION = mContext.getString(R.string.workernotification_group_description)



// Todo: Either make all resources, or all strings. Not both.
abstract val titleStartingSync: Int
abstract val serviceOngoingTitle: Int
abstract val serviceFailed: Int
abstract val serviceCancelled: Int
abstract val serviceSuccess: Int
abstract val initialTitle: String
abstract val serviceOngoingTitle: String
abstract val serviceFailed: String
abstract val serviceCancelled: String
abstract val serviceSuccess: String


abstract val channel_ongoing_title: String
Expand All @@ -49,13 +51,18 @@ abstract class WorkerNotification(var mContext: Context) {

abstract val PERSISTENT_NOTIFICATION_ID: Int

// Check if those can stay the same when channels are muted
val SUMMARY_GROUP = this.CHANNEL_ID + "_summary"
abstract val SUMMARY_ID: Int


private val OPERATION_FAILED_GROUP = "ca.pkay.rcexplorer.OPERATION_FAILED_GROUP"
private val OPERATION_SUCCESS_GROUP = "ca.pkay.rcexplorer.OPERATION_SUCCESS_GROUP"

companion object {
const val CANCEL_ID_NOTSET = "CANCEL_ID_NOTSET"
}

// Check if those can stay the same when channels are muted
private val OPERATION_FAILED_GROUP = "ca.pkay.rcexplorer.OPERATION_FAILED_GROUP"
private val OPERATION_SUCCESS_GROUP = "ca.pkay.rcexplorer.OPERATION_SUCCESS_GROUP"


private var mCancelUnsetId: UUID = UUID.randomUUID()
Expand Down Expand Up @@ -93,111 +100,113 @@ abstract class WorkerNotification(var mContext: Context) {
}

fun showFailedNotification(
title: String,
content: String,
notificationId: Int,
taskid: Long
title: String,
content: String,
notificationId: Int,
taskid: Long
) {
val i = Intent(mContext, SyncRestartAction::class.java)
i.putExtra(EXTRA_TASK_ID, taskid)

val retryPendingIntent = PendingIntent.getService(mContext, taskid.toInt(), i,
GenericSyncNotification.getFlags()
GenericSyncNotification.getFlags()
)
val builder = NotificationCompat.Builder(mContext, CHANNEL_FAIL_ID)
.setSmallIcon(R.drawable.ic_twotone_cloud_error_24)
.setContentTitle(mContext.getString(serviceFailed))
.setContentText(content)
.setStyle(
NotificationCompat.BigTextStyle().bigText(content)
)
.setGroup(OPERATION_FAILED_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
.addAction(
R.drawable.ic_refresh,
mContext.getString(R.string.retry_failed_sync),
retryPendingIntent
)
.setSmallIcon(R.drawable.ic_twotone_cloud_error_24)
.setContentTitle(serviceFailed)
.setContentText(content)
.setStyle(
NotificationCompat.BigTextStyle().bigText(content)
)
.setGroup(OPERATION_FAILED_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
.addAction(
R.drawable.ic_refresh,
mContext.getString(R.string.retry_failed_sync),
retryPendingIntent
)
NotificationUtils.createNotification(mContext, notificationId, builder.build())
}

fun showCancelledNotification(
title: String,
content: String,
notificationId: Int,
taskid: Long
title: String,
content: String,
notificationId: Int,
taskid: Long
) {
val i = Intent(mContext, SyncRestartAction::class.java)
i.putExtra(EXTRA_TASK_ID, taskid)

val retryPendingIntent = PendingIntent.getService(mContext, taskid.toInt(), i,
GenericSyncNotification.getFlags()
GenericSyncNotification.getFlags()
)
val builder = NotificationCompat.Builder(mContext, CHANNEL_FAIL_ID)
.setSmallIcon(R.drawable.ic_twotone_cloud_error_24)
.setContentTitle(mContext.getString(serviceCancelled))
.setContentText(content)
.setStyle(
NotificationCompat.BigTextStyle().bigText(content)
)
.setGroup(OPERATION_FAILED_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
.addAction(
R.drawable.ic_refresh,
mContext.getString(R.string.retry_failed_sync),
retryPendingIntent
)
.setSmallIcon(R.drawable.ic_twotone_cloud_error_24)
.setContentTitle(serviceCancelled)
.setContentText(content)
.setStyle(
NotificationCompat.BigTextStyle().bigText(content)
)
.setGroup(OPERATION_FAILED_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
.addAction(
R.drawable.ic_refresh,
mContext.getString(R.string.retry_failed_sync),
retryPendingIntent
)
NotificationUtils.createNotification(mContext, notificationId, builder.build())
}

fun showSuccessNotification(title: String, content: String, notificationId: Int) {
val builder = NotificationCompat.Builder(mContext, CHANNEL_SUCCESS_ID)
.setSmallIcon(R.drawable.ic_twotone_cloud_done_24)
.setContentTitle(mContext.getString(serviceSuccess, title))
.setContentText(content)
.setStyle(
NotificationCompat.BigTextStyle().bigText(
content
)
)
.setGroup(OPERATION_SUCCESS_GROUP)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setSmallIcon(R.drawable.ic_twotone_cloud_done_24)
.setContentTitle(String.format(serviceSuccess, title))
.setContentText(content)
.setGroup(SUMMARY_GROUP)
NotificationUtils.createNotification(mContext, notificationId, builder.build())


val summaryNotification = NotificationCompat.Builder(mContext, CHANNEL_SUCCESS_ID)
.setSmallIcon(R.drawable.ic_twotone_cloud_done_24)
.setContentTitle(String.format(serviceSuccess, title))
.setGroup(SUMMARY_GROUP)
.setGroupSummary(true)
NotificationUtils.createNotification(mContext, SUMMARY_ID, summaryNotification.build())
}

fun updateNotification(
title: String,
content: String,
bigTextArray: ArrayList<String>,
percent: Int,
notificationId: Int
title: String,
content: String,
bigTextArray: ArrayList<String>,
percent: Int,
notificationId: Int
): Notification? {
if(content.isBlank()){
if (content.isBlank()) {
FLog.e(tag(), "Missing notification content!")
return null
}

val builder = GenericSyncNotification(mContext).updateGenericNotification(
mContext.getString(serviceOngoingTitle, title),
content,
R.drawable.ic_twotone_rounded_cloud_sync_24,
bigTextArray,
percent,
SyncWorker::class.java,
null,
CHANNEL_ID
String.format(serviceOngoingTitle, title),
content,
R.drawable.ic_twotone_rounded_cloud_sync_24,
bigTextArray,
percent,
SyncWorker::class.java,
null,
CHANNEL_ID
)

if(mCancelId != mCancelUnsetId) {
if (mCancelId != mCancelUnsetId) {

val intent = WorkManager.getInstance(mContext)
.createCancelPendingIntent(mCancelId)
.createCancelPendingIntent(mCancelId)

builder.clearActions()
builder.addAction(
R.drawable.ic_cancel_download,
mContext.getString(R.string.cancel),
intent
R.drawable.ic_cancel_download,
mContext.getString(R.string.cancel),
intent
)
}

Expand All @@ -208,4 +217,10 @@ abstract class WorkerNotification(var mContext: Context) {
val notificationManagerCompat = NotificationManagerCompat.from(mContext)
notificationManagerCompat.cancel(notificationId)
}

fun string(@StringRes id: Int): String {
return mContext.getString(id)
}

abstract fun generateSuccessMessage(statusObject: StatusObject, fileItem: FileItem): String
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class EphemeralTaskManager(private var mContext: Context) {
addRemoteItemToData(EphemeralWorker.REMOTE, remote, data)

addFileItemToData(EphemeralWorker.DELETE_FILE, file, data)
data.putString(EphemeralWorker.DELETE_PATH, currentPath)
EphemeralTaskManager(context).work(data.build(), "")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import java.io.InputStreamReader
import java.io.InterruptedIOException
import kotlin.random.Random
import android.util.Log
import de.felixnuesse.extract.notifications.implementations.DeleteWorkerNotification
import de.felixnuesse.extract.notifications.implementations.MoveWorkerNotification
import de.felixnuesse.extract.notifications.implementations.UploadWorkerNotification


Expand All @@ -55,7 +57,6 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
const val MOVE_TARGETPATH = "MOVE_TARGETPATH"

const val DELETE_FILE = "DELETE_FILE"
const val DELETE_PATH = "DELETE_PATH"
}

internal enum class FAILURE_REASON {
Expand All @@ -82,7 +83,7 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
private val ongoingNotificationID = Random.nextInt()


private var mTitle: String = getString(mNotificationManager?.titleStartingSync)
private var mTitle: String = mNotificationManager?.initialTitle ?: ""

override fun doWork(): Result {

Expand Down Expand Up @@ -148,7 +149,6 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
)
}
Type.DELETE -> {
val d = inputData.getString(DELETE_PATH)
val fileItem = getFileitemFromParcel(DELETE_FILE)

if(fileItem == null){
Expand Down Expand Up @@ -197,7 +197,8 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
return when(type){
Type.DOWNLOAD -> DownloadWorkerNotification(mContext)
Type.UPLOAD -> UploadWorkerNotification(mContext)
else -> DownloadWorkerNotification(mContext)
Type.DELETE -> DeleteWorkerNotification(mContext)
Type.MOVE -> MoveWorkerNotification(mContext)
}
}

Expand Down Expand Up @@ -303,27 +304,10 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame

private fun showSuccessNotification(notificationId: Int) {
//Todo: Show sync-errors in notification. Also see line 169
var message = mContext.resources.getQuantityString(
R.plurals.operation_success_description,
statusObject.getTotalTransfers(),
mTitle,
statusObject.getTotalSize(),
statusObject.getTotalTransfers()
)
if (statusObject.getTotalTransfers() == 0) {
message = mContext.resources.getString(R.string.operation_success_description_zero)
}
if (statusObject.getDeletions() > 0) {
message += """
${
mContext.getString(
R.string.operation_success_description_deletions_prefix,
statusObject.getDeletions()
)
}
""".trimIndent()
}
//Todo: This should be context dependend on the type. It is currently not!


var message = mNotificationManager?.generateSuccessMessage(statusObject, getCurrentFile())?: "error"

mNotificationManager?.showSuccessNotification(
mTitle,
Expand Down Expand Up @@ -426,12 +410,12 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
}
}

private fun getFileitemFromParcel(key: String): FileItem? {
private fun getFileitemFromParcel(key: String): FileItem {

val sourceParcelByteArray = inputData.getByteArray(key)
if(sourceParcelByteArray == null){
log("No valid target was passed!")
return null
throw NullPointerException("The passed FileItem was null. We cannot continue!")
}

val parcel = Parcel.obtain()
Expand All @@ -453,4 +437,33 @@ class EphemeralWorker (private var mContext: Context, workerParams: WorkerParame
parcel.setDataPosition(0)
return RemoteItem.CREATOR.createFromParcel(parcel)
}

private fun getCurrentFile(): FileItem {
return when(Type.valueOf(inputData.getString(EPHEMERAL_TYPE)?:Type.DOWNLOAD.name)){
Type.DOWNLOAD -> {
getFileitemFromParcel(DOWNLOAD_SOURCE)
}
Type.UPLOAD -> {
val pathAndName = inputData.getString(UPLOAD_FILE) ?: ""
val name = pathAndName.substring(pathAndName.lastIndexOf("/")+1, pathAndName.length)
val path = pathAndName.substring(0, pathAndName.lastIndexOf("/")+1)
// TODO: Make this work properly! All the params are guessed!
FileItem(
RemoteItem("", ""),
path,
name,
0L,
"modTime",
"mimeType",
false,
false)
}
Type.MOVE -> {
getFileitemFromParcel(MOVE_FILE)
}
Type.DELETE -> {
getFileitemFromParcel(DELETE_FILE)
}
}
}
}
Loading

0 comments on commit 6a0c915

Please sign in to comment.