Skip to content

Commit e230f94

Browse files
committed
chore: Did some refactoring with jovial_svg.
1 parent be0cf0c commit e230f94

File tree

3 files changed

+86
-69
lines changed

3 files changed

+86
-69
lines changed

lib/model/totp/image_cache.dart

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
import 'dart:async';
22
import 'dart:convert';
33
import 'dart:io';
4-
import 'dart:typed_data';
54

65
import 'package:flutter/material.dart';
76
import 'package:flutter_riverpod/flutter_riverpod.dart';
87
import 'package:http/http.dart' as http;
9-
import 'package:jovial_misc/io_utils.dart';
10-
import 'package:jovial_svg/src/compact_noui.dart';
11-
import 'package:jovial_svg/src/svg_parser.dart';
128
import 'package:open_authenticator/model/settings/cache_totp_pictures.dart';
139
import 'package:open_authenticator/model/totp/decrypted.dart';
1410
import 'package:open_authenticator/model/totp/repository.dart';
1511
import 'package:open_authenticator/model/totp/totp.dart';
1612
import 'package:open_authenticator/utils/image_type.dart';
13+
import 'package:open_authenticator/utils/jovial_svg.dart';
1714
import 'package:open_authenticator/utils/utils.dart';
1815
import 'package:path/path.dart';
1916
import 'package:path_provider/path_provider.dart';
@@ -46,7 +43,7 @@ class TotpImageCacheManager extends AutoDisposeAsyncNotifier<Map<String, CacheOb
4643
CacheObject newCacheObject = entry.value.copyWith(legacy: false);
4744
if (entry.value.imageType == ImageType.svg) {
4845
File? cachedImage = (await cached.getCachedImage(entry.key, entry.value.url))?.$1;
49-
if (cachedImage != null && cachedImage.existsSync() && (await _svgToSi(cachedImage.readAsStringSync(), cachedImage))) {
46+
if (cachedImage != null && cachedImage.existsSync() && (await JovialSvgUtils.svgToSi(cachedImage.readAsStringSync(), cachedImage))) {
5047
newCacheObject = entry.value.copyWith(imageType: ImageType.si);
5148
}
5249
}
@@ -87,7 +84,7 @@ class TotpImageCacheManager extends AutoDisposeAsyncNotifier<Map<String, CacheOb
8784
ImageType imageType;
8885
if (imageUrl.endsWith('.svg')) {
8986
imageType = ImageType.svg;
90-
if (await _svgToSi(response.body, file)) {
87+
if (await JovialSvgUtils.svgToSi(response.body, file)) {
9188
imageType = ImageType.si;
9289
}
9390
} else {
@@ -107,23 +104,6 @@ class TotpImageCacheManager extends AutoDisposeAsyncNotifier<Map<String, CacheOb
107104
}
108105
}
109106

110-
/// Compiles a SVG string into an SI file.
111-
Future<bool> _svgToSi(String svg, File destinationFile) async {
112-
IOSink ioSink = destinationFile.openWrite();
113-
try {
114-
DataOutputSink outputSink = DataOutputSink(ioSink, Endian.big);
115-
SICompactBuilderNoUI siCompactBuilder = SICompactBuilderNoUI(bigFloats: false, warn: (_) {});
116-
StringSvgParser(svg, [], siCompactBuilder, warn: (_) {}).parse();
117-
siCompactBuilder.si.writeToFile(outputSink);
118-
return true;
119-
} catch (ex, stacktrace) {
120-
handleException(ex, stacktrace);
121-
} finally {
122-
await ioSink.close();
123-
}
124-
return false;
125-
}
126-
127107
/// Deletes the cached image, if possible.
128108
Future<void> deleteCachedImage(String uuid) async {
129109
Map<String, CacheObject> cached = Map.from(await future);

lib/utils/jovial_svg.dart

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import 'dart:io';
2+
import 'dart:typed_data';
3+
4+
import 'package:flutter/services.dart';
5+
import 'package:jovial_misc/io_utils.dart';
6+
import 'package:jovial_svg/jovial_svg.dart';
7+
import 'package:jovial_svg/src/compact.dart';
8+
import 'package:jovial_svg/src/compact_noui.dart';
9+
import 'package:jovial_svg/src/svg_parser.dart';
10+
import 'package:open_authenticator/utils/utils.dart';
11+
12+
/// Contains some useful methods to use with `jovial_svg`.
13+
class JovialSvgUtils {
14+
/// Compiles a SVG string into an SI file.
15+
static Future<bool> svgToSi(String svg, File destinationFile) async {
16+
IOSink ioSink = destinationFile.openWrite();
17+
try {
18+
DataOutputSink outputSink = DataOutputSink(ioSink, Endian.big);
19+
SICompactBuilderNoUI siCompactBuilder = SICompactBuilderNoUI(bigFloats: false, warn: (_) {});
20+
StringSvgParser(svg, [], siCompactBuilder, warn: (_) {}).parse();
21+
siCompactBuilder.si.writeToFile(outputSink);
22+
return true;
23+
} catch (ex, stacktrace) {
24+
handleException(ex, stacktrace);
25+
} finally {
26+
await ioSink.close();
27+
}
28+
return false;
29+
}
30+
31+
/// Loads an SI graphic from a file or from an asset.
32+
static ScalableImageSource siFromFileOrAsset(String source) {
33+
File file = File(source);
34+
return file.existsSync()
35+
? SIFileSource(file, null)
36+
: ScalableImageSource.fromSI(
37+
rootBundle,
38+
source,
39+
);
40+
}
41+
}
42+
43+
/// Allows to load a SI image from a file.
44+
class SIFileSource extends ScalableImageSource {
45+
/// File file.
46+
final File file;
47+
48+
/// The current color.
49+
final Color? currentColor;
50+
51+
/// Creates a new SI file source instance.
52+
SIFileSource(this.file, this.currentColor);
53+
54+
@override
55+
Future<ScalableImage> get si => createSI();
56+
57+
@override
58+
Future<ScalableImage> createSI({bool compact = false}) async {
59+
ScalableImageCompact scalableImageCompact = ScalableImageCompact.fromBytes(file.readAsBytesSync(), currentColor: currentColor);
60+
if (compact) {
61+
return scalableImageCompact;
62+
} else {
63+
return scalableImageCompact.toDag();
64+
}
65+
}
66+
67+
@override
68+
bool operator ==(final Object other) {
69+
if (other is SIFileSource) {
70+
return file == other.file && currentColor == other.currentColor;
71+
} else {
72+
return false;
73+
}
74+
}
75+
76+
@override
77+
int get hashCode => 0xf67cd716 ^ Object.hash(file, currentColor);
78+
79+
@override
80+
String toString() => '__SIFileSource($file $currentColor)';
81+
}

lib/widgets/sized_scalable_image.dart

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import 'dart:io';
2-
31
import 'package:flutter/material.dart';
4-
import 'package:flutter/services.dart';
52
import 'package:jovial_svg/jovial_svg.dart';
6-
import 'package:jovial_svg/src/compact.dart';
3+
import 'package:open_authenticator/utils/jovial_svg.dart';
74

85
/// A sized scalable image widget.
96
class SizedScalableImageWidget extends StatelessWidget {
@@ -42,14 +39,8 @@ class SizedScalableImageWidget extends StatelessWidget {
4239

4340
@override
4441
Widget build(BuildContext context) {
45-
File file = File(asset);
4642
Widget child = ScalableImageWidget.fromSISource(
47-
si: file.existsSync()
48-
? _SIFileSource(file, null)
49-
: ScalableImageSource.fromSI(
50-
rootBundle,
51-
asset,
52-
),
43+
si: JovialSvgUtils.siFromFileOrAsset(asset),
5344
fit: fit,
5445
alignment: alignment,
5546
);
@@ -80,38 +71,3 @@ class SizedScalableImageWidget extends StatelessWidget {
8071
return child;
8172
}
8273
}
83-
84-
class _SIFileSource extends ScalableImageSource {
85-
final File file;
86-
final Color? currentColor;
87-
88-
_SIFileSource(this.file, this.currentColor);
89-
90-
@override
91-
Future<ScalableImage> get si => createSI();
92-
93-
@override
94-
Future<ScalableImage> createSI({bool compact = false}) async {
95-
ScalableImageCompact scalableImageCompact = ScalableImageCompact.fromBytes(file.readAsBytesSync(), currentColor: currentColor);
96-
if (compact) {
97-
return scalableImageCompact;
98-
} else {
99-
return scalableImageCompact.toDag();
100-
}
101-
}
102-
103-
@override
104-
bool operator ==(final Object other) {
105-
if (other is _SIFileSource) {
106-
return file == other.file && currentColor == other.currentColor;
107-
} else {
108-
return false;
109-
}
110-
}
111-
112-
@override
113-
int get hashCode => 0xf67cd716 ^ Object.hash(file, currentColor);
114-
115-
@override
116-
String toString() => '__SIFileSource($file $currentColor)';
117-
}

0 commit comments

Comments
 (0)