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