import icon pack

This commit is contained in:
Adam Velebil 2023-02-17 17:35:29 +01:00
parent b8580c0612
commit 494e99b36f
No known key found for this signature in database
GPG Key ID: C9B1E4A3CBBD2E10
4 changed files with 143 additions and 1 deletions

View File

@ -17,6 +17,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -29,6 +30,7 @@ import 'app/message.dart';
import 'app/state.dart';
import 'core/state.dart';
import 'desktop/state.dart';
import 'oath/state.dart';
import 'version.dart';
import 'widgets/choice_filter_chip.dart';
import 'widgets/responsive_dialog.dart';
@ -191,6 +193,36 @@ class AboutPage extends ConsumerWidget {
},
),
],
... [
const SizedBox(height: 12.0,),
FilterChip(
label: const Text('Import icon pack'),
onSelected: (value) async {
final result = await FilePicker.platform.pickFiles(
allowedExtensions: ['zip'],
type: FileType.custom,
allowMultiple: false,
lockParentWindow: true,
dialogTitle: 'Choose icon pack');
if (result != null && result.files.isNotEmpty) {
final importStatus = await ref
.read(issuerIconProvider)
.importPack(result.paths.first!);
await ref.read(withContextProvider)(
(context) async {
if (importStatus) {
showMessage(context, 'Icon pack imported');
} else {
showMessage(context, 'Error importing icon pack');
}
},
);
}
},
),
]
],
),
),

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:archive/archive.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
@ -128,6 +129,12 @@ class IssuerIconProvider {
if (!await packFile.exists()) {
_log.debug('Failed to find icons pack ${packFile.path}');
_issuerIconPack = IssuerIconPack(
uuid: '',
name: '',
version: 0,
directory: Directory(''),
icons: []);
return;
}
@ -149,6 +156,91 @@ class IssuerIconProvider {
'Parsed ${_issuerIconPack.name} with ${_issuerIconPack.icons.length} icons');
}
Future<bool> _cleanTempDirectory(Directory tempDirectory) async {
if (await tempDirectory.exists()) {
await tempDirectory.delete(recursive: true);
}
if (await tempDirectory.exists()) {
_log.error('Failed to remove temp directory');
return false;
}
return true;
}
Future<bool> importPack(String filePath) async {
final packFile = File(filePath);
if (!await packFile.exists()) {
_log.error('Input file does not exist');
return false;
}
// copy input file to temporary folder
final documentsDirectory = await getApplicationDocumentsDirectory();
final tempDirectory = Directory('${documentsDirectory.path}${Platform.pathSeparator}temp${Platform.pathSeparator}');
if (!await _cleanTempDirectory(tempDirectory)) {
_log.error('Failed to cleanup temp directory');
return false;
}
await tempDirectory.create(recursive: true);
final tempCopy = await packFile.copy('${tempDirectory.path}${basename(packFile.path)}');
final bytes = await File(tempCopy.path).readAsBytes();
final destination = Directory('${tempDirectory.path}ex${Platform.pathSeparator}');
final archive = ZipDecoder().decodeBytes(bytes);
for (final file in archive) {
final filename = file.name;
if (file.isFile) {
final data = file.content as List<int>;
_log.debug('Writing file: ${destination.path}$filename');
final extractedFile = File('${destination.path}$filename');
final createdFile = await extractedFile.create(recursive: true);
await createdFile.writeAsBytes(data);
} else {
_log.debug('Writing directory: ${destination.path}$filename');
Directory('${destination.path}$filename')
.createSync(recursive: true);
}
}
// check that there is pack.json
final packJsonFile = File('${destination.path}pack.json');
if (!await packJsonFile.exists()) {
_log.error('File is not a icon pack.');
//await _cleanTempDirectory(tempDirectory);
return false;
}
// remove old icons pack and icon pack cache
final packDirectory = Directory(
'${documentsDirectory.path}${Platform.pathSeparator}issuer_icons${Platform.pathSeparator}');
if (!await _cleanTempDirectory(packDirectory)) {
_log.error('Could not remove old pack directory');
await _cleanTempDirectory(tempDirectory);
return false;
}
final packCacheDirectory = Directory(
'${documentsDirectory.path}${Platform.pathSeparator}issuer_icons_cache${Platform.pathSeparator}');
if (!await _cleanTempDirectory(packCacheDirectory)) {
_log.error('Could not remove old cache directory');
await _cleanTempDirectory(tempDirectory);
return false;
}
await destination.rename(packDirectory.path);
readPack('issuer_icons');
await _cleanTempDirectory(tempDirectory);
return true;
}
VectorGraphic? issuerVectorGraphic(String issuer, Widget placeHolder) {
final matching = _issuerIconPack.icons
.where((element) => element.issuer.any((element) => element == issuer));

View File

@ -18,7 +18,7 @@ packages:
source: hosted
version: "5.5.0"
archive:
dependency: transitive
dependency: "direct main"
description:
name: archive
sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb"
@ -217,6 +217,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.1.4"
file_picker:
dependency: "direct main"
description:
name: file_picker
sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9
url: "https://pub.dev"
source: hosted
version: "5.2.5"
fixnum:
dependency: transitive
description:
@ -248,6 +256,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
flutter_riverpod:
dependency: "direct main"
description:

View File

@ -57,6 +57,8 @@ dependencies:
vector_graphics: ^1.0.1
vector_graphics_compiler: ^1.0.1
path: ^1.8.2
file_picker: ^5.2.5
archive: ^3.3.2
dev_dependencies:
integration_test: