Replace enhancement dialog with a nice page
BIN
app/assets/color-pop0.jpg
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
app/assets/color-pop1.jpg
Normal file
After Width: | Height: | Size: 73 KiB |
BIN
app/assets/low-light0.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
app/assets/low-light1.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
app/assets/portrait-blur0.jpg
Normal file
After Width: | Height: | Size: 105 KiB |
BIN
app/assets/portrait-blur1.jpg
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
app/assets/retouch0.jpg
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
app/assets/retouch1.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
app/assets/style-transfer0.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
app/assets/style-transfer1.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
app/assets/super-resolution0.jpg
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
app/assets/super-resolution1.jpg
Normal file
After Width: | Height: | Size: 91 KiB |
|
@ -1234,6 +1234,7 @@
|
|||
"@enhanceLowLightTitle": {
|
||||
"description": "Enhance a photo taken in low-light environment"
|
||||
},
|
||||
"enhanceLowLightDescription": "Brighten your photos taken in low-light environments",
|
||||
"enhanceLowLightParamBrightnessLabel": "Brightness",
|
||||
"@enhanceLowLightParamBrightnessLabel": {
|
||||
"description": "This parameter sets how much brighter the output will be"
|
||||
|
@ -1250,6 +1251,7 @@
|
|||
"@enhancePortraitBlurTitle": {
|
||||
"description": "Blur the background of a photo"
|
||||
},
|
||||
"enhancePortraitBlurDescription": "Blur the background of your photos, work best with portraits",
|
||||
"enhancePortraitBlurParamBlurLabel": "Blurriness",
|
||||
"@enhancePortraitBlurParamBlurLabel": {
|
||||
"description": "This parameter sets the radius of the blur filter"
|
||||
|
@ -1258,6 +1260,7 @@
|
|||
"@enhanceSuperResolution4xTitle": {
|
||||
"description": "Upscale an image. The algorithm implemented in the app will upscale to 4x the original resolution (eg, 100x100 to 400x400)"
|
||||
},
|
||||
"enhanceSuperResolution4xDescription": "Enlarge your photos to 4x of its original resolution (see Help for details on how max resolution applies here)",
|
||||
"enhanceStyleTransferTitle": "Style transfer",
|
||||
"@enhanceStyleTransferTitle": {
|
||||
"description": "Transfer the image style from a reference image to a photo"
|
||||
|
@ -1266,10 +1269,16 @@
|
|||
"@enhanceStyleTransferStyleDialogTitle": {
|
||||
"description": "Pick a reference image for the style transfer algorithm"
|
||||
},
|
||||
"enhanceStyleTransferStyleDialogDescription": "Transfer image style from a reference image to your photos",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification": "Please pick a style",
|
||||
"@enhanceStyleTransferNoStyleSelectedNotification": {
|
||||
"description": "Show this error if users did not pick a reference image"
|
||||
},
|
||||
"enhanceColorPopTitle": "Color pop",
|
||||
"@enhanceColorPopTitle": {
|
||||
"description": "Desaturate the background of a photo"
|
||||
},
|
||||
"enhanceColorPopDescription": "Desaturate the background of your photos, work best with portraits",
|
||||
"enhanceGenericParamWeightLabel": "Weight",
|
||||
"@enhanceGenericParamWeightLabel": {
|
||||
"description": "This generic parameter sets the weight of the applied effect. The effect will be more obvious when the weight is high."
|
||||
|
@ -1278,6 +1287,7 @@
|
|||
"@enhanceRetouchTitle": {
|
||||
"description": "Automatically improve your photo"
|
||||
},
|
||||
"enhanceRetouchDescription": "Automatically retouch your photos, improve overall color and vibrance",
|
||||
"doubleTapExitNotification": "Tap again to exit",
|
||||
"@doubleTapExitNotification": {
|
||||
"description": "If double tap to exit is enabled in settings, shown when users tap the back button"
|
||||
|
|
|
@ -110,17 +110,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -292,17 +299,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -371,11 +385,18 @@
|
|||
"shareMethodPreviewDescription",
|
||||
"shareMethodOriginalFileTitle",
|
||||
"shareMethodOriginalFileDescription",
|
||||
"enhanceLowLightDescription",
|
||||
"collectionEditedPhotosLabel",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -439,10 +460,17 @@
|
|||
"shareMethodPreviewDescription",
|
||||
"shareMethodOriginalFileTitle",
|
||||
"shareMethodOriginalFileDescription",
|
||||
"enhanceLowLightDescription",
|
||||
"collectionEditedPhotosLabel",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"imageEditToolbarColorLabel",
|
||||
"imageEditToolbarTransformLabel",
|
||||
"imageEditTransformOrientation",
|
||||
|
@ -474,10 +502,17 @@
|
|||
"shareMethodPreviewDescription",
|
||||
"shareMethodOriginalFileTitle",
|
||||
"shareMethodOriginalFileDescription",
|
||||
"enhanceLowLightDescription",
|
||||
"collectionEditedPhotosLabel",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"imageEditToolbarColorLabel",
|
||||
"imageEditToolbarTransformLabel",
|
||||
"imageEditTransformOrientation",
|
||||
|
@ -528,17 +563,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -637,17 +679,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -725,17 +774,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -813,17 +869,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -901,17 +964,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
@ -989,17 +1059,24 @@
|
|||
"enhanceIntroDialogTitle",
|
||||
"enhanceIntroDialogDescription",
|
||||
"enhanceLowLightTitle",
|
||||
"enhanceLowLightDescription",
|
||||
"enhanceLowLightParamBrightnessLabel",
|
||||
"collectionEditedPhotosLabel",
|
||||
"deletePermanentlyLocalConfirmationDialogContent",
|
||||
"enhancePortraitBlurTitle",
|
||||
"enhancePortraitBlurDescription",
|
||||
"enhancePortraitBlurParamBlurLabel",
|
||||
"enhanceSuperResolution4xTitle",
|
||||
"enhanceSuperResolution4xDescription",
|
||||
"enhanceStyleTransferTitle",
|
||||
"enhanceStyleTransferStyleDialogTitle",
|
||||
"enhanceStyleTransferStyleDialogDescription",
|
||||
"enhanceStyleTransferNoStyleSelectedNotification",
|
||||
"enhanceColorPopTitle",
|
||||
"enhanceColorPopDescription",
|
||||
"enhanceGenericParamWeightLabel",
|
||||
"enhanceRetouchTitle",
|
||||
"enhanceRetouchDescription",
|
||||
"doubleTapExitNotification",
|
||||
"imageEditDiscardDialogTitle",
|
||||
"imageEditDiscardDialogContent",
|
||||
|
|
|
@ -2,12 +2,15 @@ import 'dart:async';
|
|||
import 'dart:math' as math;
|
||||
|
||||
import 'package:android_intent_plus/android_intent.dart';
|
||||
import 'package:circular_reveal_animation/circular_reveal_animation.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/api/api.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/file.dart';
|
||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||
import 'package:nc_photos/help_utils.dart';
|
||||
|
@ -17,7 +20,6 @@ import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
|||
import 'package:nc_photos/mobile/android/k.dart' as android;
|
||||
import 'package:nc_photos/object_extension.dart';
|
||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/url_launcher_util.dart';
|
||||
|
@ -28,125 +30,268 @@ import 'package:nc_photos/widget/settings.dart';
|
|||
import 'package:nc_photos/widget/stateful_slider.dart';
|
||||
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
|
||||
|
||||
class EnhanceHandler {
|
||||
const EnhanceHandler({
|
||||
class ImageEnhancerArguments {
|
||||
const ImageEnhancerArguments(this.account, this.file, this.isSaveToServer);
|
||||
|
||||
final Account account;
|
||||
final File file;
|
||||
final bool isSaveToServer;
|
||||
}
|
||||
|
||||
class ImageEnhancer extends StatefulWidget {
|
||||
static const routeName = "/image-enhancer";
|
||||
|
||||
static Route buildRoute(ImageEnhancerArguments args) => MaterialPageRoute(
|
||||
builder: (context) => ImageEnhancer.fromArgs(args),
|
||||
);
|
||||
|
||||
static bool isSupportedFormat(File file) =>
|
||||
file_util.isSupportedImageFormat(file) && file.contentType != "image/gif";
|
||||
|
||||
const ImageEnhancer({
|
||||
super.key,
|
||||
required this.account,
|
||||
required this.file,
|
||||
required this.isSaveToServer,
|
||||
});
|
||||
|
||||
static bool isSupportedFormat(File file) =>
|
||||
file_util.isSupportedImageFormat(file) && file.contentType != "image/gif";
|
||||
ImageEnhancer.fromArgs(ImageEnhancerArguments args, {Key? key})
|
||||
: this(
|
||||
key: key,
|
||||
account: args.account,
|
||||
file: args.file,
|
||||
isSaveToServer: args.isSaveToServer,
|
||||
);
|
||||
|
||||
Future<void> call(BuildContext context) async {
|
||||
if (!Pref().hasShownEnhanceInfoOr()) {
|
||||
await _showInfo(context);
|
||||
}
|
||||
if (!Pref().hasShownSaveEditResultDialogOr()) {
|
||||
await _showSaveEditResultDialog(context);
|
||||
}
|
||||
@override
|
||||
createState() => _ImageEnhancerState();
|
||||
|
||||
if (!await const PermissionHandler().ensureStorageWritePermission()) {
|
||||
return;
|
||||
}
|
||||
final Account account;
|
||||
final File file;
|
||||
final bool isSaveToServer;
|
||||
}
|
||||
|
||||
final selected = await _pickAlgorithm(context);
|
||||
if (selected == null) {
|
||||
// user canceled
|
||||
return;
|
||||
}
|
||||
_log.info("[call] Selected: ${selected.name}");
|
||||
final args = await _getArgs(context, selected);
|
||||
class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_c = KiwiContainer().resolve<DiContainer>();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_showInitialDialogs();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) => AppTheme(
|
||||
child: Scaffold(
|
||||
body: Builder(
|
||||
builder: _buildContent,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
return ColoredBox(
|
||||
color: Colors.black,
|
||||
child: Column(
|
||||
children: [
|
||||
_buildAppBar(context),
|
||||
Expanded(
|
||||
child: PageView.builder(
|
||||
controller: _pageController,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: _options.length,
|
||||
itemBuilder: (context, i) => Padding(
|
||||
padding: const EdgeInsets.all(48),
|
||||
child: _options[i].showcaseBuilder(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 36,
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: MediaQuery.of(context).size.width / 2 - 80),
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: _options.length,
|
||||
itemBuilder: _buildItem,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
height: 72,
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
child: Text(_selectedOption.description),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAppBar(BuildContext context) => AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
shadowColor: Colors.transparent,
|
||||
foregroundColor: Colors.white.withOpacity(.87),
|
||||
title: Text(L10n.global().enhanceTooltip),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(
|
||||
L10n.global().applyButtonLabel,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
onPressed: () => _onSavePressed(context),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.help_outline),
|
||||
tooltip: L10n.global().helpTooltip,
|
||||
onPressed: () {
|
||||
launch(_selectedOption.link);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Widget _buildItem(BuildContext context, int index) {
|
||||
final opt = _options[index];
|
||||
return _ListChild(
|
||||
title: opt.title,
|
||||
isSelected: identical(_selectedOption, opt),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedOption = opt;
|
||||
_pageController.animateToPage(
|
||||
index,
|
||||
duration: k.animationDurationNormal,
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onSavePressed(BuildContext context) async {
|
||||
final args = await _getArgs(context, _selectedOption.algorithm);
|
||||
if (args == null) {
|
||||
// user canceled
|
||||
return;
|
||||
}
|
||||
switch (selected) {
|
||||
switch (_selectedOption.algorithm) {
|
||||
case _Algorithm.zeroDce:
|
||||
await ImageProcessor.zeroDce(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
_c.pref.getEnhanceMaxWidthOr(),
|
||||
_c.pref.getEnhanceMaxHeightOr(),
|
||||
args["iteration"] ?? 8,
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
|
||||
case _Algorithm.deepLab3Portrait:
|
||||
await ImageProcessor.deepLab3Portrait(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
_c.pref.getEnhanceMaxWidthOr(),
|
||||
_c.pref.getEnhanceMaxHeightOr(),
|
||||
args["radius"] ?? 16,
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
|
||||
case _Algorithm.esrgan:
|
||||
await ImageProcessor.esrgan(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
_c.pref.getEnhanceMaxWidthOr(),
|
||||
_c.pref.getEnhanceMaxHeightOr(),
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
|
||||
case _Algorithm.arbitraryStyleTransfer:
|
||||
await ImageProcessor.arbitraryStyleTransfer(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
math.min(
|
||||
Pref().getEnhanceMaxWidthOr(), isAtLeast5GbRam() ? 1600 : 1280),
|
||||
_c.pref.getEnhanceMaxWidthOr(), _isAtLeast5GbRam() ? 1600 : 1280),
|
||||
math.min(
|
||||
Pref().getEnhanceMaxHeightOr(), isAtLeast5GbRam() ? 1200 : 960),
|
||||
_c.pref.getEnhanceMaxHeightOr(), _isAtLeast5GbRam() ? 1200 : 960),
|
||||
args["styleUri"],
|
||||
args["weight"],
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
|
||||
case _Algorithm.deepLab3ColorPop:
|
||||
await ImageProcessor.deepLab3ColorPop(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
_c.pref.getEnhanceMaxWidthOr(),
|
||||
_c.pref.getEnhanceMaxHeightOr(),
|
||||
args["weight"],
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
|
||||
case _Algorithm.neurOp:
|
||||
await ImageProcessor.neurOp(
|
||||
"${account.url}/${file.path}",
|
||||
file.filename,
|
||||
Pref().getEnhanceMaxWidthOr(),
|
||||
Pref().getEnhanceMaxHeightOr(),
|
||||
"${widget.account.url}/${widget.file.path}",
|
||||
widget.file.filename,
|
||||
_c.pref.getEnhanceMaxWidthOr(),
|
||||
_c.pref.getEnhanceMaxHeightOr(),
|
||||
headers: {
|
||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
||||
},
|
||||
isSaveToServer: isSaveToServer,
|
||||
isSaveToServer: widget.isSaveToServer,
|
||||
);
|
||||
break;
|
||||
}
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
Future<void> _showInitialDialogs() async {
|
||||
if (!_c.pref.hasShownEnhanceInfoOr()) {
|
||||
await _showInfo(context);
|
||||
}
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
final value = await _ensurePermission();
|
||||
if (!mounted || !value) {
|
||||
return;
|
||||
}
|
||||
if (!_c.pref.hasShownSaveEditResultDialogOr()) {
|
||||
await _showSaveEditResultDialog(context);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> _ensurePermission() async {
|
||||
if (!await const PermissionHandler().ensureStorageWritePermission()) {
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showInfo(BuildContext context) async {
|
||||
|
@ -177,7 +322,7 @@ class EnhanceHandler {
|
|||
],
|
||||
),
|
||||
);
|
||||
unawaited(Pref().setHasShownEnhanceInfo(true));
|
||||
unawaited(_c.pref.setHasShownEnhanceInfo(true));
|
||||
}
|
||||
|
||||
Future<void> _showSaveEditResultDialog(BuildContext context) async {
|
||||
|
@ -189,79 +334,6 @@ class EnhanceHandler {
|
|||
);
|
||||
}
|
||||
|
||||
Future<_Algorithm?> _pickAlgorithm(BuildContext context) =>
|
||||
showDialog<_Algorithm>(
|
||||
context: context,
|
||||
builder: (context) => SimpleDialog(
|
||||
children: _getOptions()
|
||||
.map((o) => SimpleDialogOption(
|
||||
padding: const EdgeInsets.all(0),
|
||||
child: ListTile(
|
||||
title: Text(o.title),
|
||||
subtitle: o.subtitle?.run((t) => Text(t)),
|
||||
trailing: o.link != null
|
||||
? SizedBox(
|
||||
height: double.maxFinite,
|
||||
child: TextButton(
|
||||
child: Text(L10n.global().detailsTooltip),
|
||||
onPressed: () {
|
||||
launch(o.link!);
|
||||
},
|
||||
),
|
||||
)
|
||||
: null,
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(o.algorithm);
|
||||
},
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
|
||||
List<_Option> _getOptions() => [
|
||||
if (platform_k.isAndroid)
|
||||
_Option(
|
||||
title: L10n.global().enhanceRetouchTitle,
|
||||
link: enhanceRetouchUrl,
|
||||
algorithm: _Algorithm.neurOp,
|
||||
),
|
||||
if (platform_k.isAndroid)
|
||||
_Option(
|
||||
title: L10n.global().enhanceColorPopTitle,
|
||||
subtitle: "DeepLap v3",
|
||||
link: enhanceDeepLabColorPopUrl,
|
||||
algorithm: _Algorithm.deepLab3ColorPop,
|
||||
),
|
||||
if (platform_k.isAndroid)
|
||||
_Option(
|
||||
title: L10n.global().enhanceLowLightTitle,
|
||||
subtitle: "Zero-DCE",
|
||||
link: enhanceZeroDceUrl,
|
||||
algorithm: _Algorithm.zeroDce,
|
||||
),
|
||||
if (platform_k.isAndroid)
|
||||
_Option(
|
||||
title: L10n.global().enhancePortraitBlurTitle,
|
||||
subtitle: "DeepLap v3",
|
||||
link: enhanceDeepLabPortraitBlurUrl,
|
||||
algorithm: _Algorithm.deepLab3Portrait,
|
||||
),
|
||||
if (platform_k.isAndroid)
|
||||
_Option(
|
||||
title: L10n.global().enhanceSuperResolution4xTitle,
|
||||
subtitle: "ESRGAN",
|
||||
link: enhanceEsrganUrl,
|
||||
algorithm: _Algorithm.esrgan,
|
||||
),
|
||||
if (platform_k.isAndroid && isAtLeast4GbRam())
|
||||
_Option(
|
||||
title: L10n.global().enhanceStyleTransferTitle,
|
||||
link: enhanceStyleTransferUrl,
|
||||
algorithm: _Algorithm.arbitraryStyleTransfer,
|
||||
),
|
||||
];
|
||||
|
||||
Future<Map<String, dynamic>?> _getArgs(
|
||||
BuildContext context, _Algorithm selected) async {
|
||||
switch (selected) {
|
||||
|
@ -458,20 +530,68 @@ class EnhanceHandler {
|
|||
return weight?.run((it) => {"weight": it});
|
||||
}
|
||||
|
||||
bool isAtLeast4GbRam() {
|
||||
bool _isAtLeast4GbRam() {
|
||||
// We can't compare with 4096 directly as some RAM are preserved
|
||||
return AndroidInfo().totalMemMb > 3584;
|
||||
}
|
||||
|
||||
bool isAtLeast5GbRam() {
|
||||
bool _isAtLeast5GbRam() {
|
||||
return AndroidInfo().totalMemMb > 4608;
|
||||
}
|
||||
|
||||
final Account account;
|
||||
final File file;
|
||||
final bool isSaveToServer;
|
||||
late final _options = [
|
||||
if (platform_k.isAndroid) ...[
|
||||
_Option(
|
||||
title: L10n.global().enhanceRetouchTitle,
|
||||
description: L10n.global().enhanceRetouchDescription,
|
||||
link: enhanceRetouchUrl,
|
||||
showcaseBuilder: (_) => const _RetouchShowcase(),
|
||||
algorithm: _Algorithm.neurOp,
|
||||
),
|
||||
_Option(
|
||||
title: L10n.global().enhanceColorPopTitle,
|
||||
description: L10n.global().enhanceColorPopDescription,
|
||||
link: enhanceDeepLabColorPopUrl,
|
||||
showcaseBuilder: (_) => const _ColorPopShowcase(),
|
||||
algorithm: _Algorithm.deepLab3ColorPop,
|
||||
),
|
||||
_Option(
|
||||
title: L10n.global().enhanceLowLightTitle,
|
||||
description: L10n.global().enhanceLowLightDescription,
|
||||
link: enhanceZeroDceUrl,
|
||||
showcaseBuilder: (_) => const _LowLightShowcase(),
|
||||
algorithm: _Algorithm.zeroDce,
|
||||
),
|
||||
_Option(
|
||||
title: L10n.global().enhancePortraitBlurTitle,
|
||||
description: L10n.global().enhancePortraitBlurDescription,
|
||||
link: enhanceDeepLabPortraitBlurUrl,
|
||||
showcaseBuilder: (_) => const _PortraitBlurShowcase(),
|
||||
algorithm: _Algorithm.deepLab3Portrait,
|
||||
),
|
||||
_Option(
|
||||
title: L10n.global().enhanceSuperResolution4xTitle,
|
||||
description: L10n.global().enhanceSuperResolution4xDescription,
|
||||
link: enhanceEsrganUrl,
|
||||
showcaseBuilder: (_) => const _SuperResolutionShowcase(),
|
||||
algorithm: _Algorithm.esrgan,
|
||||
),
|
||||
if (_isAtLeast4GbRam())
|
||||
_Option(
|
||||
title: L10n.global().enhanceStyleTransferTitle,
|
||||
description: L10n.global().enhanceStyleTransferStyleDialogDescription,
|
||||
link: enhanceStyleTransferUrl,
|
||||
showcaseBuilder: (_) => const _StyleTransferShowcase(),
|
||||
algorithm: _Algorithm.arbitraryStyleTransfer,
|
||||
),
|
||||
],
|
||||
];
|
||||
|
||||
static final _log = Logger("widget.handler.enhance_handler.EnhanceHandler");
|
||||
late final DiContainer _c;
|
||||
late var _selectedOption = _options[0];
|
||||
late final _pageController = PageController(keepPage: false);
|
||||
|
||||
static final _log = Logger("widget.image_enhancer._ImageEnhancerState");
|
||||
}
|
||||
|
||||
enum _Algorithm {
|
||||
|
@ -486,17 +606,270 @@ enum _Algorithm {
|
|||
class _Option {
|
||||
const _Option({
|
||||
required this.title,
|
||||
this.subtitle,
|
||||
this.link,
|
||||
required this.description,
|
||||
required this.link,
|
||||
required this.showcaseBuilder,
|
||||
required this.algorithm,
|
||||
});
|
||||
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final String? link;
|
||||
final String description;
|
||||
final String link;
|
||||
final Widget Function(BuildContext context) showcaseBuilder;
|
||||
final _Algorithm algorithm;
|
||||
}
|
||||
|
||||
class _ListChild extends StatelessWidget {
|
||||
const _ListChild({
|
||||
required this.title,
|
||||
required this.isSelected,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(24)),
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
color: isSelected ? Colors.white24 : null,
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color:
|
||||
isSelected ? Colors.white : AppTheme.unfocusedIconColorDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final String title;
|
||||
final bool isSelected;
|
||||
final VoidCallback? onTap;
|
||||
}
|
||||
|
||||
mixin _ShowcaseStateMixin<T extends StatefulWidget>
|
||||
on State<T>, TickerProviderStateMixin<T> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
Future.delayed(const Duration(milliseconds: 250)).then((_) {
|
||||
if (mounted) {
|
||||
animController.forward();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
dispose() {
|
||||
animController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
late final animController = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(seconds: 1),
|
||||
);
|
||||
late final Animation<double> anim = CurvedAnimation(
|
||||
parent: animController,
|
||||
curve: Curves.easeIn,
|
||||
);
|
||||
}
|
||||
|
||||
class _RetouchShowcase extends StatefulWidget {
|
||||
const _RetouchShowcase();
|
||||
|
||||
@override
|
||||
createState() => _RetouchShowcaseState();
|
||||
}
|
||||
|
||||
class _RetouchShowcaseState extends State<_RetouchShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/retouch0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/retouch1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _ColorPopShowcase extends StatefulWidget {
|
||||
const _ColorPopShowcase();
|
||||
|
||||
@override
|
||||
createState() => _ColorPopShowcaseState();
|
||||
}
|
||||
|
||||
class _ColorPopShowcaseState extends State<_ColorPopShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/color-pop0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/color-pop1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _LowLightShowcase extends StatefulWidget {
|
||||
const _LowLightShowcase();
|
||||
|
||||
@override
|
||||
createState() => _LowLightShowcaseState();
|
||||
}
|
||||
|
||||
class _LowLightShowcaseState extends State<_LowLightShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/low-light0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/low-light1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _PortraitBlurShowcase extends StatefulWidget {
|
||||
const _PortraitBlurShowcase();
|
||||
|
||||
@override
|
||||
createState() => _PortraitBlurShowcaseState();
|
||||
}
|
||||
|
||||
class _PortraitBlurShowcaseState extends State<_PortraitBlurShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/portrait-blur0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/portrait-blur1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _SuperResolutionShowcase extends StatefulWidget {
|
||||
const _SuperResolutionShowcase();
|
||||
|
||||
@override
|
||||
createState() => _SuperResolutionShowcaseState();
|
||||
}
|
||||
|
||||
class _SuperResolutionShowcaseState extends State<_SuperResolutionShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/super-resolution0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/super-resolution1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _StyleTransferShowcase extends StatefulWidget {
|
||||
const _StyleTransferShowcase();
|
||||
|
||||
@override
|
||||
createState() => _StyleTransferShowcaseState();
|
||||
}
|
||||
|
||||
class _StyleTransferShowcaseState extends State<_StyleTransferShowcase>
|
||||
with TickerProviderStateMixin, _ShowcaseStateMixin {
|
||||
@override
|
||||
build(BuildContext context) => Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/style-transfer0.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
CircularRevealAnimation(
|
||||
animation: anim,
|
||||
centerAlignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
"assets/style-transfer1.jpg",
|
||||
fit: BoxFit.contain,
|
||||
gaplessPlayback: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
class _StylePickerResult {
|
||||
const _StylePickerResult(this.styleUri, this.weight);
|
||||
|
||||
|
@ -602,8 +975,9 @@ class _StylePickerState extends State<_StylePicker> {
|
|||
TextButton(
|
||||
onPressed: () {
|
||||
if (_selected == null) {
|
||||
SnackBarManager().showSnackBar(const SnackBar(
|
||||
content: Text("Please pick a style"),
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global()
|
||||
.enhanceStyleTransferNoStyleSelectedNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
} else {
|
||||
|
@ -676,6 +1050,5 @@ class _StylePickerState extends State<_StylePicker> {
|
|||
"file:///android_asset/tf/arbitrary-style-transfer/6.jpg",
|
||||
];
|
||||
|
||||
static final _log =
|
||||
Logger("widget.handler.enhance_handler._StylePickerState");
|
||||
static final _log = Logger("widget.image_enhancer._StylePickerState");
|
||||
}
|
|
@ -20,6 +20,7 @@ import 'package:nc_photos/widget/dynamic_album_browser.dart';
|
|||
import 'package:nc_photos/widget/enhanced_photo_browser.dart';
|
||||
import 'package:nc_photos/widget/home.dart';
|
||||
import 'package:nc_photos/widget/image_editor.dart';
|
||||
import 'package:nc_photos/widget/image_enhancer.dart';
|
||||
import 'package:nc_photos/widget/local_file_viewer.dart';
|
||||
import 'package:nc_photos/widget/people_browser.dart';
|
||||
import 'package:nc_photos/widget/person_browser.dart';
|
||||
|
@ -173,6 +174,7 @@ class _MyAppState extends State<MyApp>
|
|||
route ??= _handlePlaceBrowserRoute(settings);
|
||||
route ??= _handlePlacesBrowserRoute(settings);
|
||||
route ??= _handleResultViewerRoute(settings);
|
||||
route ??= _handleImageEnhancerRoute(settings);
|
||||
return route;
|
||||
}
|
||||
|
||||
|
@ -621,6 +623,19 @@ class _MyAppState extends State<MyApp>
|
|||
return null;
|
||||
}
|
||||
|
||||
Route<dynamic>? _handleImageEnhancerRoute(RouteSettings settings) {
|
||||
try {
|
||||
if (settings.name == ImageEnhancer.routeName &&
|
||||
settings.arguments != null) {
|
||||
final args = settings.arguments as ImageEnhancerArguments;
|
||||
return ImageEnhancer.buildRoute(args);
|
||||
}
|
||||
} catch (e) {
|
||||
_log.severe("[_handleImageEnhancerRoute] Failed while handling route", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final _scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
|
||||
final _navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
|
|
|
@ -24,10 +24,10 @@ import 'package:nc_photos/theme.dart';
|
|||
import 'package:nc_photos/use_case/update_property.dart';
|
||||
import 'package:nc_photos/widget/animated_visibility.dart';
|
||||
import 'package:nc_photos/widget/disposable.dart';
|
||||
import 'package:nc_photos/widget/handler/enhance_handler.dart';
|
||||
import 'package:nc_photos/widget/handler/remove_selection_handler.dart';
|
||||
import 'package:nc_photos/widget/horizontal_page_viewer.dart';
|
||||
import 'package:nc_photos/widget/image_editor.dart';
|
||||
import 'package:nc_photos/widget/image_enhancer.dart';
|
||||
import 'package:nc_photos/widget/image_viewer.dart';
|
||||
import 'package:nc_photos/widget/slideshow_dialog.dart';
|
||||
import 'package:nc_photos/widget/slideshow_viewer.dart';
|
||||
|
@ -217,7 +217,7 @@ class _ViewerState extends State<Viewer>
|
|||
onPressed: () => _onSharePressed(context),
|
||||
),
|
||||
if (features.isSupportEnhancement &&
|
||||
EnhanceHandler.isSupportedFormat(file)) ...[
|
||||
ImageEnhancer.isSupportedFormat(file)) ...[
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.tune_outlined,
|
||||
|
@ -605,11 +605,9 @@ class _ViewerState extends State<Viewer>
|
|||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
|
||||
_log.info("[_onEnhancePressed] Enhance file: ${file.path}");
|
||||
EnhanceHandler(
|
||||
account: widget.account,
|
||||
file: file,
|
||||
isSaveToServer: c.pref.isSaveEditResultToServerOr(),
|
||||
)(context);
|
||||
Navigator.of(context).pushNamed(ImageEnhancer.routeName,
|
||||
arguments: ImageEnhancerArguments(
|
||||
widget.account, file, c.pref.isSaveEditResultToServerOr()));
|
||||
}
|
||||
|
||||
void _onDownloadPressed() {
|
||||
|
|
|
@ -213,6 +213,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
circular_reveal_animation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: circular_reveal_animation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -37,6 +37,7 @@ dependencies:
|
|||
bloc: ^8.0.0
|
||||
bloc_concurrency: ^0.2.0
|
||||
cached_network_image: ^3.2.1
|
||||
circular_reveal_animation: ^2.0.1
|
||||
collection: ^1.15.0
|
||||
connectivity_plus: ^2.0.2
|
||||
devicelocale: ^0.5.0
|
||||
|
|