mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-02-02 19:26:37 +00:00
install theme from zip archive functionality
This commit is contained in:
parent
848b1c3bbd
commit
604e4cfde7
3 changed files with 66 additions and 3 deletions
|
@ -1,9 +1,14 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:archive/archive_io.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:stackwallet/db/isar/main_db.dart';
|
||||
import 'package:stackwallet/models/isar/stack_theme.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/stack_file_system.dart';
|
||||
|
||||
final pThemeService = Provider<ThemeService>((ref) {
|
||||
return ThemeService.instance;
|
||||
|
@ -20,11 +25,68 @@ class ThemeService {
|
|||
void init(MainDB db) => _db ??= db;
|
||||
|
||||
Future<void> install({required ByteData themeArchive}) async {
|
||||
// todo unzip, install, and create theme object and add to db
|
||||
final themesDir = await StackFileSystem.applicationThemesDirectory();
|
||||
|
||||
final byteStream = InputStream(themeArchive);
|
||||
final archive = ZipDecoder().decodeBuffer(byteStream);
|
||||
|
||||
final themeJsonFiles = archive.files.where((e) => e.name == "theme.json");
|
||||
|
||||
if (themeJsonFiles.length != 1) {
|
||||
throw Exception("Invalid theme archive: Missing theme.json");
|
||||
}
|
||||
|
||||
final OutputStream os = OutputStream();
|
||||
themeJsonFiles.first.decompress(os);
|
||||
final String jsonString = utf8.decode(os.getBytes());
|
||||
final json = jsonDecode(jsonString) as Map;
|
||||
|
||||
final theme = StackTheme.fromJson(
|
||||
json: Map<String, dynamic>.from(json),
|
||||
applicationThemesDirectoryPath: themesDir.path,
|
||||
);
|
||||
|
||||
final String assetsPath = "${themesDir.path}/${theme.themeId}";
|
||||
|
||||
for (final file in archive.files) {
|
||||
if (file.isFile) {
|
||||
// TODO more sanitation?
|
||||
if (file.name.contains("..")) {
|
||||
Logging.instance.log(
|
||||
"Bad theme asset file path: ${file.name}",
|
||||
level: LogLevel.Error,
|
||||
);
|
||||
} else {
|
||||
final os = OutputFileStream("$assetsPath/${file.name}");
|
||||
file.writeContent(os);
|
||||
await os.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await db.isar.writeTxn(() async {
|
||||
await db.isar.stackThemes.put(theme);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> remove({required String themeId}) async {
|
||||
// todo delete local files and remove from db
|
||||
final themesDir = await StackFileSystem.applicationThemesDirectory();
|
||||
final isarId = await db.isar.stackThemes
|
||||
.where()
|
||||
.themeIdEqualTo(themeId)
|
||||
.idProperty()
|
||||
.findFirst();
|
||||
if (isarId != null) {
|
||||
await db.isar.writeTxn(() async {
|
||||
await db.isar.stackThemes.delete(isarId);
|
||||
});
|
||||
await Directory("${themesDir.path}/$themeId").delete(recursive: true);
|
||||
} else {
|
||||
Logging.instance.log(
|
||||
"Failed to delete theme $themeId",
|
||||
level: LogLevel.Warning,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> fetchThemeList() async {
|
||||
|
|
|
@ -42,7 +42,7 @@ packages:
|
|||
source: hosted
|
||||
version: "4.2.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb"
|
||||
|
|
|
@ -151,6 +151,7 @@ dependencies:
|
|||
dart_bs58check: ^3.0.2
|
||||
hex: ^0.2.0
|
||||
rational: ^2.2.2
|
||||
archive: ^3.3.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in a new issue