Add pref to control whether to save to server/device

This commit is contained in:
Ming Ming 2022-09-10 15:12:30 +08:00
parent 3df8fbd7ca
commit eda68ff55c
7 changed files with 79 additions and 20 deletions

View file

@ -249,6 +249,15 @@ class Pref {
Future<bool> setMemoriesRange(int value) => _set<int>(PrefKey.memoriesRange,
value, (key, value) => provider.setInt(key, value));
bool? isSaveEditResultToServer() =>
provider.getBool(PrefKey.saveEditResultToServer);
bool isSaveEditResultToServerOr([bool def = true]) =>
isSaveEditResultToServer() ?? def;
Future<bool> setSaveEditResultToServer(bool value) => _set<bool>(
PrefKey.saveEditResultToServer,
value,
(key, value) => provider.setBool(key, value));
Future<bool> _set<T>(PrefKey key, T value,
Future<bool> Function(PrefKey key, T value) setFn) async {
if (await setFn(key, value)) {
@ -561,6 +570,7 @@ enum PrefKey {
shouldProcessExifWifiOnly,
doubleTapExit,
memoriesRange,
saveEditResultToServer,
// account pref
isEnableFaceRecognitionApp,
@ -632,6 +642,8 @@ extension on PrefKey {
return "doubleTapExit";
case PrefKey.memoriesRange:
return "memoriesRange";
case PrefKey.saveEditResultToServer:
return "saveEditResultToServer";
// account pref
case PrefKey.isEnableFaceRecognitionApp:

View file

@ -31,6 +31,7 @@ class EnhanceHandler {
const EnhanceHandler({
required this.account,
required this.file,
required this.isSaveToServer,
});
static bool isSupportedFormat(File file) =>
@ -67,6 +68,7 @@ class EnhanceHandler {
headers: {
"Authorization": Api.getAuthorizationHeaderValue(account),
},
isSaveToServer: isSaveToServer,
);
break;
@ -80,6 +82,7 @@ class EnhanceHandler {
headers: {
"Authorization": Api.getAuthorizationHeaderValue(account),
},
isSaveToServer: isSaveToServer,
);
break;
@ -92,6 +95,7 @@ class EnhanceHandler {
headers: {
"Authorization": Api.getAuthorizationHeaderValue(account),
},
isSaveToServer: isSaveToServer,
);
break;
@ -108,6 +112,7 @@ class EnhanceHandler {
headers: {
"Authorization": Api.getAuthorizationHeaderValue(account),
},
isSaveToServer: isSaveToServer,
);
break;
}
@ -353,6 +358,7 @@ class EnhanceHandler {
final Account account;
final File file;
final bool isSaveToServer;
static final _log = Logger("widget.handler.enhance_handler.EnhanceHandler");
}

View file

@ -2,11 +2,13 @@ import 'dart:async';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:kiwi/kiwi.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/api/api.dart';
import 'package:nc_photos/api/api_util.dart' as api_util;
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/cache_manager_util.dart';
import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/help_utils.dart' as help_util;
import 'package:nc_photos/k.dart' as k;
@ -258,6 +260,7 @@ class _ImageEditorState extends State<ImageEditor> {
}
Future<void> _onSavePressed(BuildContext context) async {
final c = KiwiContainer().resolve<DiContainer>();
await ImageProcessor.filter(
"${widget.account.url}/${widget.file.path}",
widget.file.filename,
@ -267,6 +270,7 @@ class _ImageEditorState extends State<ImageEditor> {
headers: {
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
},
isSaveToServer: c.pref.isSaveEditResultToServerOr(),
);
Navigator.of(context).pop();
}

View file

@ -602,11 +602,13 @@ class _ViewerState extends State<Viewer>
_log.shout("[_onEnhancePressed] Video file not supported");
return;
}
final c = KiwiContainer().resolve<DiContainer>();
_log.info("[_onEnhancePressed] Enhance file: ${file.path}");
EnhanceHandler(
account: widget.account,
file: file,
isSaveToServer: c.pref.isSaveEditResultToServerOr(),
)(context);
}

View file

@ -28,6 +28,7 @@ class ImageProcessorChannelHandler(context: Context) :
call.argument("filename")!!,
call.argument("maxWidth")!!,
call.argument("maxHeight")!!,
call.argument<Boolean>("isSaveToServer")!!,
call.argument("iteration")!!,
result
)
@ -45,6 +46,7 @@ class ImageProcessorChannelHandler(context: Context) :
call.argument("filename")!!,
call.argument("maxWidth")!!,
call.argument("maxHeight")!!,
call.argument<Boolean>("isSaveToServer")!!,
call.argument("radius")!!,
result
)
@ -62,6 +64,7 @@ class ImageProcessorChannelHandler(context: Context) :
call.argument("filename")!!,
call.argument("maxWidth")!!,
call.argument("maxHeight")!!,
call.argument<Boolean>("isSaveToServer")!!,
result
)
} catch (e: Throwable) {
@ -78,6 +81,7 @@ class ImageProcessorChannelHandler(context: Context) :
call.argument("filename")!!,
call.argument("maxWidth")!!,
call.argument("maxHeight")!!,
call.argument<Boolean>("isSaveToServer")!!,
call.argument("styleUri")!!,
call.argument("weight")!!,
result
@ -96,6 +100,7 @@ class ImageProcessorChannelHandler(context: Context) :
call.argument("filename")!!,
call.argument("maxWidth")!!,
call.argument("maxHeight")!!,
call.argument<Boolean>("isSaveToServer")!!,
call.argument("filters")!!,
result
)
@ -132,10 +137,10 @@ class ImageProcessorChannelHandler(context: Context) :
private fun zeroDce(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, iteration: Int,
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean, iteration: Int,
result: MethodChannel.Result
) = method(
fileUrl, headers, filename, maxWidth, maxHeight,
fileUrl, headers, filename, maxWidth, maxHeight, isSaveToServer,
ImageProcessorService.METHOD_ZERO_DCE, result, onIntent = {
it.putExtra(ImageProcessorService.EXTRA_ITERATION, iteration)
}
@ -143,9 +148,10 @@ class ImageProcessorChannelHandler(context: Context) :
private fun deepLab3Portrait(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, radius: Int, result: MethodChannel.Result
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean, radius: Int,
result: MethodChannel.Result
) = method(
fileUrl, headers, filename, maxWidth, maxHeight,
fileUrl, headers, filename, maxWidth, maxHeight, isSaveToServer,
ImageProcessorService.METHOD_DEEP_LAP_PORTRAIT, result, onIntent = {
it.putExtra(ImageProcessorService.EXTRA_RADIUS, radius)
}
@ -153,18 +159,19 @@ class ImageProcessorChannelHandler(context: Context) :
private fun esrgan(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, result: MethodChannel.Result
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean,
result: MethodChannel.Result
) = method(
fileUrl, headers, filename, maxWidth, maxHeight,
fileUrl, headers, filename, maxWidth, maxHeight, isSaveToServer,
ImageProcessorService.METHOD_ESRGAN, result
)
private fun arbitraryStyleTransfer(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, styleUri: String, weight: Float,
result: MethodChannel.Result
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean,
styleUri: String, weight: Float, result: MethodChannel.Result
) = method(
fileUrl, headers, filename, maxWidth, maxHeight,
fileUrl, headers, filename, maxWidth, maxHeight, isSaveToServer,
ImageProcessorService.METHOD_ARBITRARY_STYLE_TRANSFER, result,
onIntent = {
it.putExtra(
@ -176,14 +183,14 @@ class ImageProcessorChannelHandler(context: Context) :
private fun filter(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, filters: List<Map<String, Any>>,
result: MethodChannel.Result
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean,
filters: List<Map<String, Any>>, result: MethodChannel.Result
) {
// convert to serializable
val l = arrayListOf<Serializable>()
filters.mapTo(l, { HashMap(it) })
method(
fileUrl, headers, filename, maxWidth, maxHeight,
fileUrl, headers, filename, maxWidth, maxHeight, isSaveToServer,
ImageProcessorService.METHOD_FILTER, result,
onIntent = {
it.putExtra(ImageProcessorService.EXTRA_FILTERS, l)
@ -204,7 +211,7 @@ class ImageProcessorChannelHandler(context: Context) :
private fun method(
fileUrl: String, headers: Map<String, String>?, filename: String,
maxWidth: Int, maxHeight: Int, method: String,
maxWidth: Int, maxHeight: Int, isSaveToServer: Boolean, method: String,
result: MethodChannel.Result, onIntent: ((Intent) -> Unit)? = null
) {
val intent = Intent(context, ImageProcessorService::class.java).apply {
@ -216,6 +223,9 @@ class ImageProcessorChannelHandler(context: Context) :
putExtra(ImageProcessorService.EXTRA_FILENAME, filename)
putExtra(ImageProcessorService.EXTRA_MAX_WIDTH, maxWidth)
putExtra(ImageProcessorService.EXTRA_MAX_HEIGHT, maxHeight)
putExtra(
ImageProcessorService.EXTRA_IS_SAVE_TO_SERVER, isSaveToServer
)
onIntent?.invoke(this)
}
ContextCompat.startForegroundService(context, intent)

View file

@ -37,6 +37,7 @@ class ImageProcessorService : Service() {
const val EXTRA_FILENAME = "filename"
const val EXTRA_MAX_WIDTH = "maxWidth"
const val EXTRA_MAX_HEIGHT = "maxHeight"
const val EXTRA_IS_SAVE_TO_SERVER = "isSaveToServer"
const val EXTRA_RADIUS = "radius"
const val EXTRA_ITERATION = "iteration"
const val EXTRA_STYLE_URI = "styleUri"
@ -134,7 +135,7 @@ class ImageProcessorService : Service() {
// there are commands running in the bg
addCommand(
ImageProcessorEnhanceCommand(
startId, "null", "", null, "", 0, 0
startId, "null", "", null, "", 0, 0, false
)
)
}
@ -184,10 +185,11 @@ class ImageProcessorService : Service() {
val filename = extras.getString(EXTRA_FILENAME)!!
val maxWidth = extras.getInt(EXTRA_MAX_WIDTH)
val maxHeight = extras.getInt(EXTRA_MAX_HEIGHT)
val isSaveToServer = extras.getBoolean(EXTRA_IS_SAVE_TO_SERVER)
addCommand(
ImageProcessorFilterCommand(
startId, fileUrl, headers, filename, maxWidth,
maxHeight, filters
maxHeight, isSaveToServer, filters
)
)
}
@ -211,10 +213,11 @@ class ImageProcessorService : Service() {
val filename = extras.getString(EXTRA_FILENAME)!!
val maxWidth = extras.getInt(EXTRA_MAX_WIDTH)
val maxHeight = extras.getInt(EXTRA_MAX_HEIGHT)
val isSaveToServer = extras.getBoolean(EXTRA_IS_SAVE_TO_SERVER)
addCommand(
ImageProcessorEnhanceCommand(
startId, method, fileUrl, headers, filename, maxWidth,
maxHeight, args = args
maxHeight, isSaveToServer, args = args
)
)
}
@ -421,6 +424,7 @@ private abstract class ImageProcessorImageCommand(
val filename: String,
val maxWidth: Int,
val maxHeight: Int,
val isSaveToServer: Boolean,
) : ImageProcessorCommand {
abstract fun apply(context: Context, fileUri: Uri): Bitmap
}
@ -433,9 +437,11 @@ private class ImageProcessorEnhanceCommand(
filename: String,
maxWidth: Int,
maxHeight: Int,
isSaveToServer: Boolean,
val args: Map<String, Any?> = mapOf(),
) : ImageProcessorImageCommand(
startId, method, fileUrl, headers, filename, maxWidth, maxHeight
startId, method, fileUrl, headers, filename, maxWidth, maxHeight,
isSaveToServer
) {
override fun apply(context: Context, fileUri: Uri): Bitmap {
return when (method) {
@ -471,10 +477,11 @@ private class ImageProcessorFilterCommand(
filename: String,
maxWidth: Int,
maxHeight: Int,
isSaveToServer: Boolean,
val filters: List<ImageFilter>,
) : ImageProcessorImageCommand(
startId, ImageProcessorService.METHOD_FILTER, fileUrl, headers, filename,
maxWidth, maxHeight
maxWidth, maxHeight, isSaveToServer
) {
override fun apply(context: Context, fileUri: Uri): Bitmap {
return ImageFilterProcessor(
@ -687,7 +694,7 @@ private open class ImageProcessorCommandTask(context: Context) :
oExif.saveAttributes()
handleCancel()
val persister = EnhancedFileServerPersisterWithFallback(context)
val persister = getPersister(cmd.isSaveToServer)
return persister.persist(cmd, outFile)
} finally {
outFile.delete()
@ -748,7 +755,7 @@ private open class ImageProcessorCommandTask(context: Context) :
logE(TAG, "[copyExif] Failed while saving EXIF", e)
}
val persister = EnhancedFileServerPersisterWithFallback(context)
val persister = getPersister(cmd.isSaveToServer)
return persister.persist(cmd, outFile)
} finally {
outFile.delete()
@ -773,6 +780,14 @@ private open class ImageProcessorCommandTask(context: Context) :
}
}
private fun getPersister(isSaveToServer: Boolean): EnhancedFilePersister {
return if (isSaveToServer) {
EnhancedFileServerPersisterWithFallback(context)
} else {
EnhancedFileDevicePersister(context)
}
}
@SuppressLint("StaticFieldLeak")
private val context = context
}

View file

@ -82,6 +82,7 @@ class ImageProcessor {
int maxHeight,
int iteration, {
Map<String, String>? headers,
required bool isSaveToServer,
}) =>
_methodChannel.invokeMethod("zeroDce", <String, dynamic>{
"fileUrl": fileUrl,
@ -90,6 +91,7 @@ class ImageProcessor {
"maxWidth": maxWidth,
"maxHeight": maxHeight,
"iteration": iteration,
"isSaveToServer": isSaveToServer,
});
static Future<void> deepLab3Portrait(
@ -99,6 +101,7 @@ class ImageProcessor {
int maxHeight,
int radius, {
Map<String, String>? headers,
required bool isSaveToServer,
}) =>
_methodChannel.invokeMethod("deepLab3Portrait", <String, dynamic>{
"fileUrl": fileUrl,
@ -107,6 +110,7 @@ class ImageProcessor {
"maxWidth": maxWidth,
"maxHeight": maxHeight,
"radius": radius,
"isSaveToServer": isSaveToServer,
});
static Future<void> esrgan(
@ -115,6 +119,7 @@ class ImageProcessor {
int maxWidth,
int maxHeight, {
Map<String, String>? headers,
required bool isSaveToServer,
}) =>
_methodChannel.invokeMethod("esrgan", <String, dynamic>{
"fileUrl": fileUrl,
@ -122,6 +127,7 @@ class ImageProcessor {
"filename": filename,
"maxWidth": maxWidth,
"maxHeight": maxHeight,
"isSaveToServer": isSaveToServer,
});
static Future<void> arbitraryStyleTransfer(
@ -132,6 +138,7 @@ class ImageProcessor {
String styleUri,
double weight, {
Map<String, String>? headers,
required bool isSaveToServer,
}) =>
_methodChannel.invokeMethod("arbitraryStyleTransfer", <String, dynamic>{
"fileUrl": fileUrl,
@ -141,6 +148,7 @@ class ImageProcessor {
"maxHeight": maxHeight,
"styleUri": styleUri,
"weight": weight,
"isSaveToServer": isSaveToServer,
});
static Future<void> filter(
@ -150,6 +158,7 @@ class ImageProcessor {
int maxHeight,
List<ImageFilter> filters, {
Map<String, String>? headers,
required bool isSaveToServer,
}) =>
_methodChannel.invokeMethod("filter", <String, dynamic>{
"fileUrl": fileUrl,
@ -158,6 +167,7 @@ class ImageProcessor {
"maxWidth": maxWidth,
"maxHeight": maxHeight,
"filters": filters.map((f) => f.toJson()).toList(),
"isSaveToServer": isSaveToServer,
});
static Future<Rgba8Image> filterPreview(