Skip to content
Merged
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
4 changes: 4 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,9 @@
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>

<provider android:name=".WallpaperFileProvider" android:authorities="${applicationId}.wallpaper_provider" android:exported="false" android:grantUriPermissions="true" tools:replace="android:authorities,android:name">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/wallpaper_file_paths" />
</provider>
</application>
</manifest>
18 changes: 18 additions & 0 deletions android/app/src/main/kotlin/nl/jknaapen/fladder/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nl.jknaapen.fladder

import BatteryOptimizationPigeon
import FlutterError
import NativeVideoActivity
import PlayerSettingsPigeon
import StartResult
Expand All @@ -17,13 +18,20 @@ import android.provider.Settings
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.FileProvider
import com.ryanheise.audioservice.AudioServiceFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import nl.jknaapen.fladder.objects.PlayerSettingsObject
import nl.jknaapen.fladder.objects.TranslationsMessenger
import nl.jknaapen.fladder.objects.VideoPlayerObject
import nl.jknaapen.fladder.utility.leanBackEnabled
import androidx.core.net.toUri
import nl.jknaapen.fladder.wallpaper.WallpaperApi
import nl.jknaapen.fladder.wallpaper.WallpaperApiUtility
import java.io.File
import java.util.Objects

class WallpaperFileProvider : FileProvider()

class MainActivity : AudioServiceFragmentActivity(), NativeVideoActivity {
private lateinit var videoPlayerLauncher: ActivityResultLauncher<Intent>
Expand All @@ -37,6 +45,10 @@ class MainActivity : AudioServiceFragmentActivity(), NativeVideoActivity {
flutterEngine.dartExecutor.binaryMessenger,
this
)
WallpaperApi.setUp(
flutterEngine.dartExecutor.binaryMessenger,
WallpaperApiUtility(this, wallpaperLauncher)
)
VideoPlayerApi.setUp(
flutterEngine.dartExecutor.binaryMessenger,
videoPlayerHost.implementation
Expand Down Expand Up @@ -93,6 +105,12 @@ class MainActivity : AudioServiceFragmentActivity(), NativeVideoActivity {
setIntent(intent)
}

private val wallpaperLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
// Handle the result of the wallpaper intent if needed
}

override fun launchActivity(callback: (Result<StartResult>) -> Unit) {
try {
videoPlayerCallback = callback
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Autogenerated from Pigeon (v26.1.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

package nl.jknaapen.fladder.wallpaper

import FlutterError
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 WallpaperApiPigeonUtils {

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

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

private open class WallpaperApiPigeonCodec : 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 WallpaperApi {
fun openWallpaperPopup(filePath: String, callback: (Result<Boolean>) -> Unit)

companion object {
/** The codec used by WallpaperApi. */
val codec: MessageCodec<Any?> by lazy {
WallpaperApiPigeonCodec()
}

/** Sets up an instance of `WallpaperApi` to handle messages through the `binaryMessenger`. */
@JvmOverloads
fun setUp(
binaryMessenger: BinaryMessenger,
api: WallpaperApi?,
messageChannelSuffix: String = ""
) {
val separatedMessageChannelSuffix =
if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
run {
val channel = BasicMessageChannel<Any?>(
binaryMessenger,
"dev.flutter.pigeon.nl_jknaapen_fladder.wallpaper.WallpaperApi.openWallpaperPopup$separatedMessageChannelSuffix",
codec
)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val filePathArg = args[0] as String
api.openWallpaperPopup(filePathArg) { result: Result<Boolean> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(WallpaperApiPigeonUtils.wrapError(error))
} else {
val data = result.getOrNull()
reply.reply(WallpaperApiPigeonUtils.wrapResult(data))
}
}
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package nl.jknaapen.fladder.wallpaper

import FlutterError
import android.content.Intent
import androidx.core.content.FileProvider
import java.io.File

class WallpaperApiUtility(
val applicationContext: android.content.Context,
private val launcher: androidx.activity.result.ActivityResultLauncher<android.content.Intent>
) : WallpaperApi {
private var pendingCallback: ((Result<Boolean>) -> Unit)? = null

override fun openWallpaperPopup(filePath: String, callback: (Result<Boolean>) -> Unit) {
this.pendingCallback = callback

try {
val file = File(filePath)

val uri =
FileProvider.getUriForFile(
applicationContext,
"${applicationContext.packageName}.wallpaper_provider",
file
)

val intent = Intent(Intent.ACTION_ATTACH_DATA).apply {
addCategory(Intent.CATEGORY_DEFAULT)
setDataAndType(uri, "image/*")
putExtra("mimeType", "image/*")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}

launcher.launch(android.content.Intent.createChooser(intent, "Set wallpaper as:"))
} catch (e: Exception) {
// Pigeon handles exceptions gracefully and passes them back to Dart
throw FlutterError("INTENT_ERROR", "Failed to launch intent: ${e.message}", null)
}
}

fun onResult(success: Boolean) {
pendingCallback?.invoke(Result.success(success))
pendingCallback = null
}
}
4 changes: 4 additions & 0 deletions android/app/src/main/res/xml/wallpaper_file_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path name="cache_images" path="." />
</paths>
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2764,5 +2764,6 @@
"musicDashboard": "Music Dashboard",
"quiet": "Quiet",
"loud": "Loud",
"share": "Share"
"share": "Share",
"setAs": "Set as"
}
16 changes: 0 additions & 16 deletions lib/screens/photo_viewer/photo_viewer_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import 'package:extended_image/extended_image.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:iconsax_plus/iconsax_plus.dart';
import 'package:share_plus/share_plus.dart';

import 'package:fladder/models/item_base_model.dart';
import 'package:fladder/models/items/photos_model.dart';
Expand Down Expand Up @@ -484,11 +483,6 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
? IconsaxPlusLinear.filter_remove
: IconsaxPlusLinear.filter,
),
ElevatedIconButtonLabel(
label: context.localized.share,
onPressed: () => sharePhoto(currentPhoto),
icon: IconsaxPlusLinear.share,
),
].addInBetween(const SizedBox(width: 16)),
);
}),
Expand All @@ -512,16 +506,6 @@ class _PhotoViewerScreenState extends ConsumerState<PhotoViewerScreen> with Widg
},
);

Future<void> sharePhoto(PhotoModel photo) async {
final file = await CustomCacheManager.instance.getSingleFile(photo.downloadPath(ref));
await SharePlus.instance.share(ShareParams(files: [
XFile(
file.path,
),
]));
await file.delete();
}

Future<void> markAsFavourite(PhotoModel photo, {bool? value}) async {
await ref.read(userProvider.notifier).setAsFavorite(value ?? !photo.userData.isFavourite, photo.id);

Expand Down
80 changes: 80 additions & 0 deletions lib/src/wallpaper_api.g.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Autogenerated from Pigeon (v26.1.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers

import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;

import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
import 'package:flutter/services.dart';

PlatformException _createConnectionError(String channelName) {
return PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel: "$channelName".',
);
}


class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
void writeValue(WriteBuffer buffer, Object? value) {
if (value is int) {
buffer.putUint8(4);
buffer.putInt64(value);
} else {
super.writeValue(buffer, value);
}
}

@override
Object? readValueOfType(int type, ReadBuffer buffer) {
switch (type) {
default:
return super.readValueOfType(type, buffer);
}
}
}

class WallpaperApi {
/// Constructor for [WallpaperApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
WallpaperApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
: pigeonVar_binaryMessenger = binaryMessenger,
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
final BinaryMessenger? pigeonVar_binaryMessenger;

static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();

final String pigeonVar_messageChannelSuffix;

Future<bool> openWallpaperPopup(String filePath) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.nl_jknaapen_fladder.wallpaper.WallpaperApi.openWallpaperPopup$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[filePath]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else if (pigeonVar_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (pigeonVar_replyList[0] as bool?)!;
}
}
}
Loading
Loading