Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions android/app/src/main/kotlin/com/zulip/flutter/DownloadManager.g.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Autogenerated from Pigeon (v26.0.2), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

package com.zulip.flutter

import android.util.Log
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MessageCodec
import io.flutter.plugin.common.StandardMethodCodec
import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer
private object DownloadManagerPigeonUtils {

fun wrapResult(result: Any?): List<Any?> {
return listOf(result)
}

fun wrapError(exception: Throwable): List<Any?> {
return if (exception is DownloadManagerError) {
listOf(
exception.code,
exception.message,
exception.details
)
} else {
listOf(
exception.javaClass.simpleName,
exception.toString(),
"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)
)
}
}
}

/**
* Error class for passing custom error details to Flutter via a thrown PlatformException.
* @property code The error code.
* @property message The error message.
* @property details The error details. Must be a datatype supported by the api codec.
*/
class DownloadManagerError (
val code: String,
override val message: String? = null,
val details: Any? = null
) : Throwable()
private open class DownloadManagerPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return super.readValueOfType(type, buffer)
}
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
super.writeValue(stream, value)
}
}


/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface DownloadManagerHostApi {
/**
* Downloads a file using the given URL and saves it with the specified file name in the Downloads directory.
* Returns a success message or an error message.
*/
fun downloadFile(fileUrl: String, fileName: String, callback: (Result<String>) -> Unit)

companion object {
/** The codec used by DownloadManagerHostApi. */
val codec: MessageCodec<Any?> by lazy {
DownloadManagerPigeonCodec()
}
/** Sets up an instance of `DownloadManagerHostApi` to handle messages through the `binaryMessenger`. */
@JvmOverloads
fun setUp(binaryMessenger: BinaryMessenger, api: DownloadManagerHostApi?, messageChannelSuffix: String = "") {
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.zulip.DownloadManagerHostApi.downloadFile$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val fileUrlArg = args[0] as String
val fileNameArg = args[1] as String
api.downloadFile(fileUrlArg, fileNameArg) { result: Result<String> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(DownloadManagerPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(DownloadManagerPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
32 changes: 31 additions & 1 deletion android/app/src/main/kotlin/com/zulip/flutter/ZulipPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.zulip.flutter

import android.annotation.SuppressLint
import android.app.DownloadManager
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
Expand All @@ -19,6 +20,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.graphics.drawable.IconCompat
import io.flutter.embedding.engine.plugins.FlutterPlugin
import org.json.JSONObject
import androidx.core.net.toUri

private const val TAG = "ZulipPlugin"
Expand Down Expand Up @@ -284,17 +286,42 @@ private class AndroidNotificationHost(val context: Context)
}
}

/** Host class for handling downloads via DownloadManager */
class DownloadHost(private val context: Context) : DownloadManagerHostApi {

/** Downloads a file from the given URL and saves it to the specified filename in the Downloads folder. */
override fun downloadFile(fileUrl: String, fileName: String, callback: (Result<String>) -> Unit) {
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager

val uri = fileUrl.toUri()

val request = DownloadManager.Request(uri).apply {
setTitle("Downloading $fileName")
setDescription("File is being downloaded...")
setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
}
// Queue the download
downloadManager.enqueue(request)
callback(Result.success("Download started successfully for: $fileName"))
}
}

/** A Flutter plugin for the Zulip app's ad-hoc needs. */
// @Keep is needed because this class is used only
// from ZulipShimPlugin, via reflection.
@Keep
class ZulipPlugin : FlutterPlugin { // TODO ActivityAware too?
private var notificationHost: AndroidNotificationHost? = null
private var downloadHost: DownloadHost? = null

override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
Log.d(TAG, "Attaching to Flutter engine.")
notificationHost = AndroidNotificationHost(binding.applicationContext)
downloadHost = DownloadHost(binding.applicationContext)

AndroidNotificationHostApi.setUp(binding.binaryMessenger, notificationHost)
DownloadManagerHostApi.setUp(binding.binaryMessenger, downloadHost)
}

override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
Expand All @@ -303,6 +330,9 @@ class ZulipPlugin : FlutterPlugin { // TODO ActivityAware too?
return
}
AndroidNotificationHostApi.setUp(binding.binaryMessenger, null)
DownloadManagerHostApi.setUp(binding.binaryMessenger, null)

notificationHost = null
downloadHost = null
}
}
}
16 changes: 16 additions & 0 deletions assets/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,22 @@
"@lightboxVideoDuration": {
"description": "The total duration of the video playing in the lightbox."
},
"lightboxDownloadImageTooltip": "Download image",
"@lightboxDownloadImageTooltip": {
"description": "Tooltip in lightbox for the download image action."
},
"lightboxDownloadImageStarted": "Starting download...",
"@lightboxDownloadImageStarted": {
"description": "Message shown when the image download has started."
},
"lightboxDownloadImageFailed": "Failed to download the image.",
"@lightboxDownloadImageFailed": {
"description": "Message shown when the image download fails."
},
"lightboxDownloadImageError": "An error occurred while downloading the image.",
"@lightboxDownloadImageError": {
"description": "Message shown when an unexpected error occurs during image download."
},
"loginPageTitle": "Log in",
"@loginPageTitle": {
"description": "Title for login page."
Expand Down
24 changes: 24 additions & 0 deletions lib/generated/l10n/zulip_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,30 @@ abstract class ZulipLocalizations {
/// **'Video duration'**
String get lightboxVideoDuration;

/// Tooltip in lightbox for the download image action.
///
/// In en, this message translates to:
/// **'Download image'**
String get lightboxDownloadImageTooltip;

/// Message shown when the image download has started.
///
/// In en, this message translates to:
/// **'Starting download...'**
String get lightboxDownloadImageStarted;

/// Message shown when the image download fails.
///
/// In en, this message translates to:
/// **'Failed to download the image.'**
String get lightboxDownloadImageFailed;

/// Message shown when an unexpected error occurs during image download.
///
/// In en, this message translates to:
/// **'An error occurred while downloading the image.'**
String get lightboxDownloadImageError;

/// Title for login page.
///
/// In en, this message translates to:
Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsAr extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_de.dart
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,19 @@ class ZulipLocalizationsDe extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Videolänge';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Anmelden';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_el.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsEl extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsEn extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_es.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsEs extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,19 @@ class ZulipLocalizationsFr extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_he.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsHe extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
13 changes: 13 additions & 0 deletions lib/generated/l10n/zulip_localizations_hu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,19 @@ class ZulipLocalizationsHu extends ZulipLocalizations {
@override
String get lightboxVideoDuration => 'Video duration';

@override
String get lightboxDownloadImageTooltip => 'Download image';

@override
String get lightboxDownloadImageStarted => 'Starting download...';

@override
String get lightboxDownloadImageFailed => 'Failed to download the image.';

@override
String get lightboxDownloadImageError =>
'An error occurred while downloading the image.';

@override
String get loginPageTitle => 'Log in';

Expand Down
Loading