mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-06-26 16:46:51 +08:00
Images: null safety++
This commit is contained in:
@ -1,5 +1,3 @@
|
|||||||
// @dart=2.9
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
||||||
|
|
||||||
@ -38,7 +36,10 @@ class SettingsDisplayImagesCaptionScreenState
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var settings = Provider.of<Settings>(context);
|
var settings = Provider.of<Settings>(context);
|
||||||
var saveDoNotCaptionTag = (String doNotCaptionTags) {
|
var saveDoNotCaptionTag = (String? doNotCaptionTags) {
|
||||||
|
if (doNotCaptionTags == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
settings.doNotCaptionTags = parseTags(doNotCaptionTags);
|
settings.doNotCaptionTags = parseTags(doNotCaptionTags);
|
||||||
settings.save();
|
settings.save();
|
||||||
};
|
};
|
||||||
@ -52,8 +53,8 @@ class SettingsDisplayImagesCaptionScreenState
|
|||||||
labelText:
|
labelText:
|
||||||
tr('settings.display.images.captions.doNotCaptionTags.label'),
|
tr('settings.display.images.captions.doNotCaptionTags.label'),
|
||||||
),
|
),
|
||||||
validator: (String value) {
|
validator: (String? value) {
|
||||||
value = value.trim();
|
value = value!.trim();
|
||||||
if (parseTags(value).isEmpty) {
|
if (parseTags(value).isEmpty) {
|
||||||
return tr(
|
return tr(
|
||||||
'settings.display.images.captions.doNotCaptionTags.validator.empty');
|
'settings.display.images.captions.doNotCaptionTags.validator.empty');
|
||||||
@ -74,12 +75,15 @@ class SettingsDisplayImagesCaptionScreenState
|
|||||||
initialValue: csvTags(settings.doNotCaptionTags),
|
initialValue: csvTags(settings.doNotCaptionTags),
|
||||||
),
|
),
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
if (!doNotCaptionTagsKey.currentState.validate()) return;
|
if (!doNotCaptionTagsKey.currentState!.validate()) return;
|
||||||
saveDoNotCaptionTag(doNotCaptionTagsKey.currentState.value);
|
saveDoNotCaptionTag(doNotCaptionTagsKey.currentState!.value);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
var saveDoThemeTag = (String doCaptionTags) {
|
var saveDoThemeTag = (String? doCaptionTags) {
|
||||||
|
if (doCaptionTags == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
settings.doCaptionTags = parseTags(doCaptionTags);
|
settings.doCaptionTags = parseTags(doCaptionTags);
|
||||||
settings.save();
|
settings.save();
|
||||||
doNotCaptionTagsForm.createState();
|
doNotCaptionTagsForm.createState();
|
||||||
@ -92,8 +96,8 @@ class SettingsDisplayImagesCaptionScreenState
|
|||||||
hintText: tr('settings.display.images.captions.doCaptionTags.hint'),
|
hintText: tr('settings.display.images.captions.doCaptionTags.hint'),
|
||||||
labelText: tr('settings.display.images.captions.doCaptionTags.label'),
|
labelText: tr('settings.display.images.captions.doCaptionTags.label'),
|
||||||
),
|
),
|
||||||
validator: (String value) {
|
validator: (String? value) {
|
||||||
if (parseTags(value).isEmpty) {
|
if (parseTags(value!).isEmpty) {
|
||||||
return tr(
|
return tr(
|
||||||
'settings.display.images.captions.doCaptionTags.validator.empty');
|
'settings.display.images.captions.doCaptionTags.validator.empty');
|
||||||
}
|
}
|
||||||
@ -113,8 +117,8 @@ class SettingsDisplayImagesCaptionScreenState
|
|||||||
initialValue: csvTags(settings.doCaptionTags),
|
initialValue: csvTags(settings.doCaptionTags),
|
||||||
),
|
),
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
if (!doCaptionTagsKey.currentState.validate()) return;
|
if (!doCaptionTagsKey.currentState!.validate()) return;
|
||||||
saveDoThemeTag(doCaptionTagsKey.currentState.value);
|
saveDoThemeTag(doCaptionTagsKey.currentState!.value);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// @dart=2.9
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
||||||
@ -40,8 +40,8 @@ class SettingsDisplayImagesThemingScreenState
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var settings = Provider.of<Settings>(context);
|
var settings = Provider.of<Settings>(context);
|
||||||
|
|
||||||
var saveDoNotThemeTag = (String doNotThemeTags) {
|
var saveDoNotThemeTag = (String? doNotThemeTags) {
|
||||||
settings.doNotThemeTags = parseTags(doNotThemeTags);
|
settings.doNotThemeTags = parseTags(doNotThemeTags!);
|
||||||
settings.save();
|
settings.save();
|
||||||
};
|
};
|
||||||
var doNotThemeTagsForm = Form(
|
var doNotThemeTagsForm = Form(
|
||||||
@ -52,8 +52,8 @@ class SettingsDisplayImagesThemingScreenState
|
|||||||
hintText: tr('settings.display.images.theming.doNotThemeTags.hint'),
|
hintText: tr('settings.display.images.theming.doNotThemeTags.hint'),
|
||||||
labelText: tr('settings.display.images.theming.doNotThemeTags.label'),
|
labelText: tr('settings.display.images.theming.doNotThemeTags.label'),
|
||||||
),
|
),
|
||||||
validator: (String value) {
|
validator: (String? value) {
|
||||||
value = value.trim();
|
value = value!.trim();
|
||||||
if (parseTags(value).isEmpty) {
|
if (parseTags(value).isEmpty) {
|
||||||
return tr(
|
return tr(
|
||||||
'settings.display.images.theming.doNotThemeTags.validator.empty');
|
'settings.display.images.theming.doNotThemeTags.validator.empty');
|
||||||
@ -72,13 +72,13 @@ class SettingsDisplayImagesThemingScreenState
|
|||||||
initialValue: csvTags(settings.doNotThemeTags),
|
initialValue: csvTags(settings.doNotThemeTags),
|
||||||
),
|
),
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
if (!doNotThemeTagsKey.currentState.validate()) return;
|
if (!doNotThemeTagsKey.currentState!.validate()) return;
|
||||||
saveDoNotThemeTag(doNotThemeTagsKey.currentState.value);
|
saveDoNotThemeTag(doNotThemeTagsKey.currentState!.value);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
var saveDoThemeTag = (String doThemeTags) {
|
var saveDoThemeTag = (String? doThemeTags) {
|
||||||
settings.doThemeTags = parseTags(doThemeTags);
|
settings.doThemeTags = parseTags(doThemeTags!);
|
||||||
settings.save();
|
settings.save();
|
||||||
};
|
};
|
||||||
var doThemeTagsForm = Form(
|
var doThemeTagsForm = Form(
|
||||||
@ -89,8 +89,8 @@ class SettingsDisplayImagesThemingScreenState
|
|||||||
hintText: tr('settings.display.images.theming.doThemeTags.hint'),
|
hintText: tr('settings.display.images.theming.doThemeTags.hint'),
|
||||||
labelText: tr('settings.display.images.theming.doThemeTags.label'),
|
labelText: tr('settings.display.images.theming.doThemeTags.label'),
|
||||||
),
|
),
|
||||||
validator: (String value) {
|
validator: (String? value) {
|
||||||
if (parseTags(value).isEmpty) {
|
if (parseTags(value!).isEmpty) {
|
||||||
return tr(
|
return tr(
|
||||||
'settings.display.images.theming.doThemeTags.validator.empty');
|
'settings.display.images.theming.doThemeTags.validator.empty');
|
||||||
}
|
}
|
||||||
@ -110,8 +110,8 @@ class SettingsDisplayImagesThemingScreenState
|
|||||||
initialValue: csvTags(settings.doThemeTags),
|
initialValue: csvTags(settings.doThemeTags),
|
||||||
),
|
),
|
||||||
onChanged: () {
|
onChanged: () {
|
||||||
if (!doThemeTagsKey.currentState.validate()) return;
|
if (!doThemeTagsKey.currentState!.validate()) return;
|
||||||
saveDoThemeTag(doThemeTagsKey.currentState.value);
|
saveDoThemeTag(doThemeTagsKey.currentState!.value);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
var body = ListView(children: <Widget>[
|
var body = ListView(children: <Widget>[
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// @dart=2.9
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
||||||
|
|
||||||
@ -35,19 +33,21 @@ import 'package:gitjournal/widgets/images/image_details.dart';
|
|||||||
import 'package:gitjournal/widgets/images/themable_image.dart';
|
import 'package:gitjournal/widgets/images/themable_image.dart';
|
||||||
|
|
||||||
class MarkdownImage extends StatelessWidget {
|
class MarkdownImage extends StatelessWidget {
|
||||||
final double width;
|
final double? width;
|
||||||
final double height;
|
final double? height;
|
||||||
final String altText;
|
final String altText;
|
||||||
final String tooltip;
|
final String tooltip;
|
||||||
|
|
||||||
|
// FIXME: Avoid using dynamic!
|
||||||
final Future<dynamic> data;
|
final Future<dynamic> data;
|
||||||
|
|
||||||
MarkdownImage._(
|
MarkdownImage._(
|
||||||
this.data, this.width, this.height, String altText, String tooltip)
|
this.data, this.width, this.height, String? altText, String? tooltip)
|
||||||
: altText = altText ?? "",
|
: altText = altText ?? "",
|
||||||
tooltip = tooltip ?? "";
|
tooltip = tooltip ?? "";
|
||||||
|
|
||||||
factory MarkdownImage(Uri uri, String imageDirectory,
|
factory MarkdownImage(Uri uri, String imageDirectory,
|
||||||
{double width, double height, String altText, String titel}) {
|
{double? width, double? height, String? altText, String? titel}) {
|
||||||
final file = ((uri.isScheme("http") || uri.isScheme("https"))
|
final file = ((uri.isScheme("http") || uri.isScheme("https"))
|
||||||
? DefaultCacheManager().getSingleFile(uri.toString())
|
? DefaultCacheManager().getSingleFile(uri.toString())
|
||||||
: Future.sync(
|
: Future.sync(
|
||||||
@ -118,7 +118,7 @@ class MarkdownImage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
errorMessage,
|
errorMessage,
|
||||||
style: theme.textTheme.bodyText1
|
style: theme.textTheme.bodyText1!
|
||||||
.copyWith(color: theme.errorColor),
|
.copyWith(color: theme.errorColor),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
@ -134,7 +134,7 @@ class MarkdownImage extends StatelessWidget {
|
|||||||
Widget im;
|
Widget im;
|
||||||
if (snapshot.data is String) {
|
if (snapshot.data is String) {
|
||||||
im = ThemableImage.svg(
|
im = ThemableImage.svg(
|
||||||
snapshot.data,
|
snapshot.data as String,
|
||||||
width: width ?? MediaQuery.of(context).size.width,
|
width: width ?? MediaQuery.of(context).size.width,
|
||||||
height: height,
|
height: height,
|
||||||
themingMethod: override == ThemeOverride.No ||
|
themingMethod: override == ThemeOverride.No ||
|
||||||
@ -167,7 +167,7 @@ class MarkdownImage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
im = ThemableImage.image(
|
im = ThemableImage.image(
|
||||||
snapshot.data,
|
snapshot.data as File,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
doTheme: (settings.themeRasterGraphics ||
|
doTheme: (settings.themeRasterGraphics ||
|
||||||
@ -185,7 +185,8 @@ class MarkdownImage extends StatelessWidget {
|
|||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ImageDetails(
|
builder: (context) => ImageDetails(
|
||||||
im, captionText(context, altText, tooltip))));
|
im as ThemableImage,
|
||||||
|
captionText(context, altText, tooltip))));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -215,7 +216,7 @@ class MarkdownImage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Color getOverlayBackgroundColor(BuildContext context,
|
Color getOverlayBackgroundColor(BuildContext context,
|
||||||
{Color light, Color dark}) {
|
{Color? light, Color? dark}) {
|
||||||
final settings = Provider.of<Settings>(context);
|
final settings = Provider.of<Settings>(context);
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
return theme.brightness == Brightness.dark
|
return theme.brightness == Brightness.dark
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// @dart=2.9
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
Copyright 2020-2021 Roland Fredenhagen <important@van-fredenhagen.de>
|
||||||
|
|
||||||
@ -25,9 +23,9 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
|
||||||
class ThemableImage extends StatelessWidget {
|
class ThemableImage extends StatelessWidget {
|
||||||
final double width;
|
final double? width;
|
||||||
final double height;
|
final double? height;
|
||||||
final File file;
|
final File? file;
|
||||||
final String string;
|
final String string;
|
||||||
final ThemingMethod themingMethod;
|
final ThemingMethod themingMethod;
|
||||||
final ThemingCondition themingCondition;
|
final ThemingCondition themingCondition;
|
||||||
@ -57,12 +55,12 @@ class ThemableImage extends StatelessWidget {
|
|||||||
|
|
||||||
ThemableImage.from(
|
ThemableImage.from(
|
||||||
ThemableImage ti, {
|
ThemableImage ti, {
|
||||||
double width,
|
double? width,
|
||||||
double height,
|
double? height,
|
||||||
ThemingMethod themingMethod,
|
ThemingMethod? themingMethod,
|
||||||
ThemingCondition themingCondition,
|
ThemingCondition? themingCondition,
|
||||||
ColorCondition colorCondition,
|
ColorCondition? colorCondition,
|
||||||
Color bg,
|
Color? bg,
|
||||||
}) : file = ti.file,
|
}) : file = ti.file,
|
||||||
string = ti.string,
|
string = ti.string,
|
||||||
width = width ?? ti.width,
|
width = width ?? ti.width,
|
||||||
@ -76,7 +74,7 @@ class ThemableImage extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget image;
|
Widget image;
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
image = Image.file(file, width: width, height: height);
|
image = Image.file(file!, width: width, height: height);
|
||||||
} else if (string.isNotEmpty) {
|
} else if (string.isNotEmpty) {
|
||||||
image = SvgPicture(
|
image = SvgPicture(
|
||||||
StringPicture(
|
StringPicture(
|
||||||
@ -104,7 +102,7 @@ class ThemableImage extends StatelessWidget {
|
|||||||
!_hasBackground(svgRoot, svgRoot.viewport.viewBox.width,
|
!_hasBackground(svgRoot, svgRoot.viewport.viewBox.width,
|
||||||
svgRoot.viewport.viewBox.height) ||
|
svgRoot.viewport.viewBox.height) ||
|
||||||
themingMethod == ThemingMethod.wToBg) {
|
themingMethod == ThemingMethod.wToBg) {
|
||||||
svgRoot = _themeDrawable(svgRoot, (Color color) {
|
svgRoot = _themeDrawable(svgRoot, (Color? color) {
|
||||||
switch (themingMethod) {
|
switch (themingMethod) {
|
||||||
case ThemingMethod.wToBg:
|
case ThemingMethod.wToBg:
|
||||||
return color == Colors.white ? bg : color;
|
return color == Colors.white ? bg : color;
|
||||||
@ -114,7 +112,7 @@ class ThemableImage extends StatelessWidget {
|
|||||||
return color;
|
return color;
|
||||||
|
|
||||||
case ThemingMethod.invertBrightness:
|
case ThemingMethod.invertBrightness:
|
||||||
final hslColor = HSLColor.fromColor(color);
|
final hslColor = HSLColor.fromColor(color!);
|
||||||
final backGroundLightness = HSLColor.fromColor(bg).lightness;
|
final backGroundLightness = HSLColor.fromColor(bg).lightness;
|
||||||
switch (colorCondition) {
|
switch (colorCondition) {
|
||||||
case ColorCondition.all:
|
case ColorCondition.all:
|
||||||
@ -142,8 +140,7 @@ class ThemableImage extends StatelessWidget {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return color;
|
}) as DrawableRoot;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Picture pic = svgRoot.toPicture(
|
final Picture pic = svgRoot.toPicture(
|
||||||
@ -178,7 +175,7 @@ bool _hasBackground(Drawable draw, double width, double height,
|
|||||||
if (draw is DrawableShape) {
|
if (draw is DrawableShape) {
|
||||||
final drawShape = draw;
|
final drawShape = draw;
|
||||||
return drawShape.style.fill != null &&
|
return drawShape.style.fill != null &&
|
||||||
drawShape.style.fill.color.alpha > minAlpha &&
|
drawShape.style.fill!.color!.alpha > minAlpha &&
|
||||||
[
|
[
|
||||||
Offset(width * maxBorder, height * maxBorder),
|
Offset(width * maxBorder, height * maxBorder),
|
||||||
Offset(width - width * maxBorder, height * maxBorder),
|
Offset(width - width * maxBorder, height * maxBorder),
|
||||||
@ -189,7 +186,7 @@ bool _hasBackground(Drawable draw, double width, double height,
|
|||||||
// TODO Allow for two shapes to be the background together
|
// TODO Allow for two shapes to be the background together
|
||||||
if (draw is DrawableParent) {
|
if (draw is DrawableParent) {
|
||||||
final drawParent = draw;
|
final drawParent = draw;
|
||||||
return drawParent.children.any((element) => _hasBackground(
|
return drawParent.children!.any((element) => _hasBackground(
|
||||||
element, width, height,
|
element, width, height,
|
||||||
minAlpha: minAlpha, maxBorder: maxBorder, maxDepth: maxDepth - 1));
|
minAlpha: minAlpha, maxBorder: maxBorder, maxDepth: maxDepth - 1));
|
||||||
}
|
}
|
||||||
@ -198,28 +195,28 @@ bool _hasBackground(Drawable draw, double width, double height,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Drawable _themeDrawable(
|
Drawable _themeDrawable(
|
||||||
Drawable draw, Color Function(Color color) transformColor) {
|
Drawable draw, Color? Function(Color? color) transformColor) {
|
||||||
if (draw is DrawableStyleable && !(draw is DrawableGroup)) {
|
if (draw is DrawableStyleable && !(draw is DrawableGroup)) {
|
||||||
final DrawableStyleable drawStylable = draw;
|
final DrawableStyleable drawStylable = draw;
|
||||||
draw = drawStylable.mergeStyle(DrawableStyle(
|
draw = drawStylable.mergeStyle(DrawableStyle(
|
||||||
stroke: drawStylable.style.stroke != null &&
|
stroke: drawStylable.style!.stroke != null &&
|
||||||
drawStylable.style.stroke.color != null
|
drawStylable.style!.stroke!.color != null
|
||||||
? DrawablePaint.merge(
|
? DrawablePaint.merge(
|
||||||
DrawablePaint(drawStylable.style.stroke.style,
|
DrawablePaint(drawStylable.style!.stroke!.style,
|
||||||
color: transformColor(drawStylable.style.stroke.color)),
|
color: transformColor(drawStylable.style!.stroke!.color)),
|
||||||
drawStylable.style.stroke)
|
drawStylable.style!.stroke)
|
||||||
: null,
|
: null,
|
||||||
fill: drawStylable.style.fill != null &&
|
fill: drawStylable.style!.fill != null &&
|
||||||
drawStylable.style.fill.color != null
|
drawStylable.style!.fill!.color != null
|
||||||
? DrawablePaint.merge(
|
? DrawablePaint.merge(
|
||||||
DrawablePaint(drawStylable.style.fill.style,
|
DrawablePaint(drawStylable.style!.fill!.style,
|
||||||
color: transformColor(drawStylable.style.fill.color)),
|
color: transformColor(drawStylable.style!.fill!.color)),
|
||||||
drawStylable.style.fill)
|
drawStylable.style!.fill)
|
||||||
: null));
|
: null));
|
||||||
}
|
}
|
||||||
if (draw is DrawableParent) {
|
if (draw is DrawableParent) {
|
||||||
final DrawableParent drawParent = draw;
|
final DrawableParent drawParent = draw;
|
||||||
final children = drawParent.children
|
final children = drawParent.children!
|
||||||
.map((e) => _themeDrawable(e, transformColor))
|
.map((e) => _themeDrawable(e, transformColor))
|
||||||
.toList(growable: false);
|
.toList(growable: false);
|
||||||
if (draw is DrawableRoot) {
|
if (draw is DrawableRoot) {
|
||||||
|
Reference in New Issue
Block a user