[mobile] Fix Image editor (#6819)
## Description - Fix bottom navigation bar color in light theme - Fix initial color in paint editor - Tap to reset tune adjustment value (brightness, exposure, etc..) and add haptics when crossing zero
This commit is contained in:
@@ -224,17 +224,17 @@ extension CustomColorScheme on ColorScheme {
|
||||
Color get videoPlayerPrimaryColor => brightness == Brightness.light
|
||||
? const Color.fromRGBO(0, 179, 60, 1)
|
||||
: const Color.fromRGBO(1, 222, 77, 1);
|
||||
|
||||
Color get videoPlayerBackgroundColor => brightness == Brightness.light
|
||||
? const Color(0xFFF5F5F5)
|
||||
: const Color(0xFF252525);
|
||||
|
||||
|
||||
Color get videoPlayerBorderColor => brightness == Brightness.light
|
||||
? const Color(0xFF424242)
|
||||
: const Color(0xFFFFFFFF);
|
||||
|
||||
Color get imageEditorPrimaryColor => const Color.fromRGBO(8, 194, 37, 1);
|
||||
|
||||
Color get editorBackgroundColor => brightness == Brightness.light
|
||||
? const Color(0xFFF5F5F5)
|
||||
: const Color(0xFF252525);
|
||||
|
||||
Color get defaultBackgroundColor =>
|
||||
brightness == Brightness.light ? backgroundBaseLight : backgroundBaseDark;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import "package:flutter_svg/svg.dart";
|
||||
import "package:photos/ente_theme_data.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
|
||||
class CircularIconButton extends StatelessWidget {
|
||||
class CircularIconButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback onTap;
|
||||
final String? svgPath;
|
||||
@@ -11,7 +11,7 @@ class CircularIconButton extends StatelessWidget {
|
||||
final bool isSelected;
|
||||
|
||||
const CircularIconButton({
|
||||
super.key,
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.onTap,
|
||||
this.svgPath,
|
||||
@@ -40,12 +40,12 @@ class CircularIconButton extends StatelessWidget {
|
||||
.colorScheme
|
||||
.imageEditorPrimaryColor
|
||||
.withOpacity(0.24)
|
||||
: colorScheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
? Theme.of(context).colorScheme.imageEditorPrimaryColor
|
||||
: colorScheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ente_theme_data.dart";
|
||||
|
||||
class ImageEditorColorPicker extends StatefulWidget {
|
||||
final double value;
|
||||
@@ -23,7 +23,6 @@ class ColorSliderState extends State<ImageEditorColorPicker> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: SizedBox(
|
||||
@@ -55,7 +54,7 @@ class ColorSliderState extends State<ImageEditorColorPicker> {
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
border: Border.all(
|
||||
color: colorScheme.backgroundElevated2,
|
||||
color: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
width: 6,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter_svg/svg.dart";
|
||||
import "package:photos/ente_theme_data.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/tools/editor/image_editor/circular_icon_button.dart";
|
||||
@@ -191,7 +192,7 @@ class CropAspectChip extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? colorScheme.fillBasePressed
|
||||
: colorScheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import "dart:async";
|
||||
import "dart:io";
|
||||
import "dart:math";
|
||||
import "dart:typed_data";
|
||||
import 'dart:ui' as ui show Image;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter/services.dart";
|
||||
import "package:flutter_image_compress/flutter_image_compress.dart";
|
||||
import "package:flutter_svg/svg.dart";
|
||||
import "package:logging/logging.dart";
|
||||
@@ -176,17 +176,18 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
|
||||
final isLightMode = Theme.of(context).brightness == Brightness.light;
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
final textTheme = getEnteTextTheme(context);
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: colorScheme.backgroundBase,
|
||||
body: PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (didPop) return;
|
||||
editorKey.currentState?.disablePopScope = true;
|
||||
_showExitConfirmationDialog(context);
|
||||
},
|
||||
child: ProImageEditor.file(
|
||||
return PopScope(
|
||||
canPop: false,
|
||||
onPopInvoked: (didPop) {
|
||||
if (didPop) return;
|
||||
editorKey.currentState?.disablePopScope = true;
|
||||
_showExitConfirmationDialog(context);
|
||||
},
|
||||
child: Scaffold(
|
||||
extendBodyBehindAppBar: true,
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: colorScheme.backgroundBase,
|
||||
body: ProImageEditor.file(
|
||||
key: editorKey,
|
||||
widget.file,
|
||||
callbacks: ProImageEditorCallbacks(
|
||||
@@ -205,6 +206,14 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
|
||||
),
|
||||
configs: ProImageEditorConfigs(
|
||||
imageEditorTheme: ImageEditorTheme(
|
||||
uiOverlayStyle: SystemUiOverlayStyle(
|
||||
systemNavigationBarContrastEnforced: true,
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
statusBarBrightness:
|
||||
isLightMode ? Brightness.dark : Brightness.light,
|
||||
statusBarIconBrightness:
|
||||
isLightMode ? Brightness.dark : Brightness.light,
|
||||
),
|
||||
appBarBackgroundColor: colorScheme.backgroundBase,
|
||||
background: colorScheme.backgroundBase,
|
||||
bottomBarBackgroundColor: colorScheme.backgroundBase,
|
||||
@@ -212,6 +221,7 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
|
||||
background: colorScheme.backgroundBase,
|
||||
),
|
||||
paintingEditor: PaintingEditorTheme(
|
||||
initialColor: const Color(0xFF00FFFF),
|
||||
background: colorScheme.backgroundBase,
|
||||
),
|
||||
textEditor: const TextEditorTheme(
|
||||
@@ -227,6 +237,12 @@ class _ImageEditorPageState extends State<ImageEditorPage> {
|
||||
background: colorScheme.backgroundBase,
|
||||
),
|
||||
emojiEditor: EmojiEditorTheme(
|
||||
bottomActionBarConfig: BottomActionBarConfig(
|
||||
showSearchViewButton: true,
|
||||
buttonColor: colorScheme.backgroundBase,
|
||||
buttonIconColor: colorScheme.tabIcon,
|
||||
backgroundColor: colorScheme.backgroundBase,
|
||||
),
|
||||
backgroundColor: colorScheme.backgroundBase,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter_svg/svg.dart";
|
||||
import "package:photos/ente_theme_data.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/tools/editor/image_editor/circular_icon_button.dart";
|
||||
@@ -174,7 +175,7 @@ class _FontPickerWidget extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? colorScheme.fillBasePressed
|
||||
: colorScheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
),
|
||||
child: Center(
|
||||
@@ -209,7 +210,7 @@ class _BackgroundPickerWidget extends StatelessWidget {
|
||||
'text': 'Aa',
|
||||
'selectedBackgroundColor':
|
||||
isLightMode ? colorScheme.fillFaint : Colors.white,
|
||||
'backgroundColor': colorScheme.backgroundElevated2,
|
||||
'backgroundColor': Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
'border': null,
|
||||
'textColor': Colors.white,
|
||||
'selectedInnerBackgroundColor': Colors.black,
|
||||
@@ -219,7 +220,7 @@ class _BackgroundPickerWidget extends StatelessWidget {
|
||||
'text': 'Aa',
|
||||
'selectedBackgroundColor':
|
||||
isLightMode ? colorScheme.fillFaint : Colors.white,
|
||||
'backgroundColor': colorScheme.backgroundElevated2,
|
||||
'backgroundColor': Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
'border': null,
|
||||
'textColor': Colors.black,
|
||||
'selectedInnerBackgroundColor': Colors.transparent,
|
||||
@@ -229,7 +230,7 @@ class _BackgroundPickerWidget extends StatelessWidget {
|
||||
'text': 'Aa',
|
||||
'selectedBackgroundColor':
|
||||
isLightMode ? colorScheme.fillFaint : Colors.white,
|
||||
'backgroundColor': colorScheme.backgroundElevated2,
|
||||
'backgroundColor': Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
'border': null,
|
||||
'textColor': Colors.black,
|
||||
'selectedInnerBackgroundColor': Colors.black.withOpacity(0.11),
|
||||
@@ -241,7 +242,7 @@ class _BackgroundPickerWidget extends StatelessWidget {
|
||||
'text': 'Aa',
|
||||
'selectedBackgroundColor':
|
||||
isLightMode ? colorScheme.fillFaint : Colors.black,
|
||||
'backgroundColor': colorScheme.backgroundElevated2,
|
||||
'backgroundColor': Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
'border':
|
||||
isLightMode ? null : Border.all(color: Colors.white, width: 2),
|
||||
'textColor': Colors.black,
|
||||
@@ -354,7 +355,7 @@ class _AlignPickerWidget extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? colorScheme.fillBasePressed
|
||||
: colorScheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
border: isSelected
|
||||
? Border.all(color: Colors.black, width: 2)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:flutter/services.dart";
|
||||
import "package:flutter_svg/svg.dart";
|
||||
import "package:photos/ente_theme_data.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
@@ -36,6 +37,24 @@ class _ImageEditorTuneBarState extends State<ImageEditorTuneBar>
|
||||
with ImageEditorConvertedConfigs, SimpleConfigsAccessState {
|
||||
TuneEditorState get tuneEditor => widget.editor;
|
||||
|
||||
final Map<int, double> _lastValues = {};
|
||||
|
||||
void _handleTuneItemTap(int index) {
|
||||
if (tuneEditor.selectedIndex == index) {
|
||||
final currentValue = tuneEditor.tuneAdjustmentMatrix[index].value;
|
||||
if (currentValue != 0) {
|
||||
_lastValues[index] = currentValue;
|
||||
tuneEditor.onChanged(0);
|
||||
} else if (_lastValues.containsKey(index)) {
|
||||
tuneEditor.onChanged(_lastValues[index]!);
|
||||
}
|
||||
} else {
|
||||
tuneEditor.setState(() {
|
||||
tuneEditor.selectedIndex = index;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(
|
||||
@@ -77,11 +96,7 @@ class _ImageEditorTuneBarState extends State<ImageEditorTuneBar>
|
||||
value: tuneEditor.tuneAdjustmentMatrix[index].value,
|
||||
max: item.max,
|
||||
min: item.min,
|
||||
onTap: () {
|
||||
tuneEditor.setState(() {
|
||||
tuneEditor.selectedIndex = index;
|
||||
});
|
||||
},
|
||||
onTap: () => _handleTuneItemTap(index),
|
||||
);
|
||||
}),
|
||||
),
|
||||
@@ -224,7 +239,10 @@ class _CircularProgressWithValueState extends State<CircularProgressWithValue>
|
||||
@override
|
||||
void didUpdateWidget(CircularProgressWithValue oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
if ((oldWidget.value < 0 && widget.value >= 0) ||
|
||||
(oldWidget.value > 0 && widget.value <= 0)) {
|
||||
HapticFeedback.vibrate();
|
||||
}
|
||||
if (oldWidget.value != widget.value) {
|
||||
_previousValue = oldWidget.value;
|
||||
_progressAnimation = Tween<double>(
|
||||
@@ -303,11 +321,11 @@ class _CircularProgressWithValueState extends State<CircularProgressWithValue>
|
||||
shape: BoxShape.circle,
|
||||
color: showValue || widget.isSelected
|
||||
? progressColor.withOpacity(0.2)
|
||||
: colorTheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
border: Border.all(
|
||||
color: widget.isSelected
|
||||
? progressColor.withOpacity(0.4)
|
||||
: colorTheme.backgroundElevated2,
|
||||
: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
@@ -395,7 +413,7 @@ class _TuneAdjustWidget extends StatelessWidget {
|
||||
margin: const EdgeInsets.symmetric(horizontal: 20),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(25),
|
||||
color: colorScheme.backgroundElevated2,
|
||||
color: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -410,7 +428,8 @@ class _TuneAdjustWidget extends StatelessWidget {
|
||||
overlayShape: const RoundSliderOverlayShape(overlayRadius: 0),
|
||||
activeTrackColor:
|
||||
Theme.of(context).colorScheme.imageEditorPrimaryColor,
|
||||
inactiveTrackColor: colorScheme.backgroundElevated2,
|
||||
inactiveTrackColor:
|
||||
Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
trackShape: const _CenterBasedTrackShape(),
|
||||
trackHeight: 24,
|
||||
),
|
||||
|
||||
@@ -31,7 +31,7 @@ class VideoEditorBottomAction extends StatelessWidget {
|
||||
height: 48,
|
||||
width: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.videoPlayerBackgroundColor,
|
||||
color: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: isSelected
|
||||
|
||||
@@ -43,7 +43,7 @@ class VideoEditorPlayerControl extends StatelessWidget {
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.videoPlayerBackgroundColor,
|
||||
color: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
borderRadius: BorderRadius.circular(56),
|
||||
),
|
||||
child: Row(
|
||||
|
||||
@@ -74,7 +74,7 @@ class _VideoEditorPageState extends State<VideoEditorPage> {
|
||||
trimStyle: TrimSliderStyle(
|
||||
onTrimmedColor: const ColorScheme.dark().videoPlayerPrimaryColor,
|
||||
onTrimmingColor: const ColorScheme.dark().videoPlayerPrimaryColor,
|
||||
background: Theme.of(context).colorScheme.videoPlayerBackgroundColor,
|
||||
background: Theme.of(context).colorScheme.editorBackgroundColor,
|
||||
positionLineColor:
|
||||
Theme.of(context).colorScheme.videoPlayerBorderColor,
|
||||
lineColor: Theme.of(context)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
- Aman: Fixed bottom nav bar color in light theme, resolved paint editor's initial color, and added tap-to-reset with haptics for tune adjustments (brightness/exposure)
|
||||
- Gracefully handle heic rendering on Android
|
||||
Reference in New Issue
Block a user