diff --git a/.gitignore b/.gitignore index 24476c5..8cac985 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ .history .svn/ migrate_working_dir/ +.vscode/ # IntelliJ related *.iml diff --git a/README.md b/README.md index e9e9339..c7c5dfa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -![Retro Logo](https://user-images.githubusercontent.com/60364512/228030301-f2139d22-48da-412b-9862-8f72e471e89c.png#gh-dark-mode-only) +![Retro Logo](https://user-images.githubusercontent.com/60364512/228030301-f2139d22-48da-412b-9862-8f72e471e89c.png#gh-dark-mode-only) ![Retro Logo](https://user-images.githubusercontent.com/60364512/228030177-6b7a51f2-fe24-4ce4-8235-8d35f2526250.png#gh-light-mode-only) -An OTR generation tool. +An OTR / O2R generation tool. ## Getting Started diff --git a/lib/arc/arc.dart b/lib/arc/arc.dart new file mode 100644 index 0000000..e31e8b6 --- /dev/null +++ b/lib/arc/arc.dart @@ -0,0 +1,165 @@ +// ignore_for_file: sort_constructors_first, cascade_invocations + +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:archive/archive.dart'; +import 'package:flutter_storm/flutter_storm.dart'; +import 'package:flutter_storm/flutter_storm_defines.dart'; +import 'package:retro/utils/log.dart'; + +enum ArcMode { + otr, o2r +} + +class Arc { + static ZipDecoder zdec = ZipDecoder(); + static ZipEncoder zenc = ZipEncoder(); + + dynamic handle; + String path; + + Arc(this.path) { + final mode = path.endsWith('.otr') ? ArcMode.otr : ArcMode.o2r; + final file = File(path); + + switch (mode) { + case ArcMode.otr: + if(file.existsSync()) { + handle = MPQArchive.open(path, 0, 0); + } else { + handle = MPQArchive.create(path, MPQ_CREATE_SIGNATURE | MPQ_CREATE_ARCHIVE_V2, 65535); + } + break; + case ArcMode.o2r: + if(file.existsSync()) { + handle = zdec.decodeBytes(file.readAsBytesSync()); + } else { + handle = Archive(); + } + break; + } + } + + Future?> _listMPQFiles({ FutureOr Function(String, Uint8List)? onFile }) async { + final files = []; + try { + var fileFound = false; + + final mpqArchive = handle as MPQArchive; + final hFind = FileFindResource(); + mpqArchive.findFirstFile('*', hFind, null); + + final fileName = hFind.fileName(); + if (fileName != null && fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') { + files.add(fileName); + if(onFile != null) { + final file = mpqArchive.openFileEx(fileName, 0); + await onFile(fileName, file.read(file.size())); + } + } + + do { + try { + mpqArchive.findNextFile(hFind); + fileFound = true; + + final fileName = hFind.fileName(); + if (fileName == null || + fileName == SIGNATURE_NAME || + fileName == LISTFILE_NAME || + fileName == ATTRIBUTES_NAME) { + continue; + } + + log('File name: $fileName'); + if (fileName != null && fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') { + files.add(fileName); + if(onFile != null) { + final file = mpqArchive.openFileEx(fileName, 0); + await onFile(fileName, file.read(file.size())); + } + } + } on StormLibException catch (e) { + log('Failed to find next file: ${e.message}'); + fileFound = false; + break; + } on Exception catch (e) { + log('Got an error: $e'); + fileFound = false; + } + } while (fileFound); + + hFind.close(); + return files; + } on StormLibException catch (e) { + log('Failed to set locale: ${e.message}'); + return null; + } + } + + Future?> _listZipFiles({ FutureOr Function(String, Uint8List)? onFile }) async { + final files = []; + final archive = handle as Archive; + for (final file in archive) { + files.add(file.name); + if(onFile != null) { + await onFile(file.name, file.content as Uint8List); + } + } + return files; + } + + void _addMPQFile(String path, Uint8List data) { + final mpqArchive = handle as MPQArchive; + final timestamp = DateTime.now().millisecondsSinceEpoch ~/ 1000; + mpqArchive.createFile(path, timestamp, data.length, 0, 0) + ..write(data, data.length, MPQ_COMPRESSION_ZLIB) + ..finish(); + } + + void _addZipFile(String path, Uint8List data) { + final archive = handle as Archive; + archive.addFile(ArchiveFile(path, data.length, data)); + } + + void _closeMPQ() { + final mpqArchive = handle as MPQArchive; + mpqArchive.close(); + } + + void _closeZip() { + final archive = handle as Archive; + final file = File(path); + final fileBytes = zenc.encode(archive); + if(fileBytes == null) { + throw Exception('Failed to encode archive'); + } + file.writeAsBytesSync(fileBytes); + } + + Future?> listItems({ FutureOr Function(String, Uint8List)? onFile }) { + if(handle is MPQArchive) { + return _listMPQFiles(onFile: onFile); + } else { + return _listZipFiles(onFile: onFile); + } + } + + void addFile(String path, Uint8List data) { + if(handle is MPQArchive) { + return _addMPQFile(path, data); + } else { + return _addZipFile(path, data); + } + } + + void close() { + if(handle is MPQArchive) { + return _closeMPQ(); + } else { + return _closeZip(); + } + } +} diff --git a/lib/features/create/create_finish/create_finish_screen.dart b/lib/features/create/create_finish/create_finish_screen.dart index da6d4ab..1c16ea9 100644 --- a/lib/features/create/create_finish/create_finish_screen.dart +++ b/lib/features/create/create_finish/create_finish_screen.dart @@ -128,7 +128,7 @@ class _CreateFinishBottomBarModalState ) ], ) - : Text(i18n.createFinishScreen_generateOtr), + : Text(i18n.createFinishScreen_generateOtr, style: TextStyle(color: Colors.white)), ), ), ], diff --git a/lib/features/create/create_finish/create_finish_viewmodel.dart b/lib/features/create/create_finish/create_finish_viewmodel.dart index 83d6ae4..50075d9 100644 --- a/lib/features/create/create_finish/create_finish_viewmodel.dart +++ b/lib/features/create/create_finish/create_finish_viewmodel.dart @@ -10,6 +10,7 @@ import 'package:flutter_storm/flutter_storm.dart'; import 'package:flutter_storm/flutter_storm_defines.dart'; import 'package:image/image.dart'; import 'package:path/path.dart' as dartp; +import 'package:retro/arc/arc.dart'; import 'package:retro/models/app_state.dart'; import 'package:retro/models/stage_entry.dart'; import 'package:retro/models/texture_manifest_entry.dart'; @@ -40,7 +41,7 @@ class CreateFinishViewModel with ChangeNotifier { notifyListeners(); } - onTogglePrependAlt(newPrependAltValue) async { + Future onTogglePrependAlt(bool newPrependAltValue) async { prependAlt = newPrependAltValue; notifyListeners(); } @@ -149,7 +150,9 @@ class CreateFinishViewModel with ChangeNotifier { Future onGenerateOTR(Function onCompletion) async { final outputFile = await FilePicker.platform.saveFile( dialogTitle: 'Please select an output file:', - fileName: 'generated.otr', + fileName: 'generated.o2r', + type: FileType.custom, + allowedExtensions: ['otr', 'o2r'], ); if (outputFile == null) { @@ -209,27 +212,17 @@ class CreateFinishViewModel with ChangeNotifier { } } -Future generateOTR( - Tuple4, String, SendPort, bool> params) async { +Future generateOTR(Tuple4, String, SendPort, bool> params) async { try { - MPQArchive? mpqArchive = MPQArchive.create( - params.item2, MPQ_CREATE_SIGNATURE | MPQ_CREATE_ARCHIVE_V2, 12288); + final arcFile = Arc(params.item2); + for (final entry in params.item1.entries) { if (entry.value is CustomStageEntry) { for (final file in (entry.value as CustomStageEntry).files) { - final fileLength = await file.length(); final fileData = await file.readAsBytes(); final fileName = "${entry.key}/${p.normalize(file.path).split("/").last}"; - - final mpqFile = mpqArchive.createFile( - fileName, - DateTime.now().millisecondsSinceEpoch ~/ 1000, - fileLength, - 0, - MPQ_FILE_COMPRESS); - mpqFile.write(fileData, fileLength, MPQ_COMPRESSION_ZLIB); - mpqFile.finish(); + arcFile.addFile(fileName, fileData); params.item3.send(1); } } else if (entry.value is CustomSequencesEntry) { @@ -237,14 +230,7 @@ Future generateOTR( final sequence = await compute(Sequence.fromSeqFile, pair); final fileName = '${entry.key}/${sequence.path}'; final data = sequence.build(); - final mpqFile = mpqArchive.createFile( - fileName, - DateTime.now().millisecondsSinceEpoch ~/ 1000, - data.length, - 0, - MPQ_FILE_COMPRESS); - mpqFile.write(data, data.length, MPQ_COMPRESSION_ZLIB); - mpqFile.finish(); + arcFile.addFile(fileName, data); params.item3.send(1); } } else if (entry.value is CustomTexturesEntry) { @@ -262,21 +248,13 @@ Future generateOTR( continue; } - final mpqFile = mpqArchive.createFile( - texture.item1, - DateTime.now().millisecondsSinceEpoch ~/ 1000, - texture.item2!.length, - 0, - MPQ_FILE_COMPRESS); - mpqFile.write( - texture.item2!, texture.item2!.length, MPQ_COMPRESSION_ZLIB); - mpqFile.finish(); + arcFile.addFile(texture.item1, texture.item2!); } } } params.item3.send(true); - mpqArchive.close(); + arcFile.close(); } on StormLibException catch (e) { log(e.message); } @@ -296,8 +274,8 @@ Future> processTextureEntry( return Tuple2((params.item3 ? 'alt/' : '') + fileName, data); } -Future processJPEG(pair, String textureName) async { - final Uint8List imageData = await pair.item1.readAsBytes(); +Future processJPEG(Tuple2 pair, String textureName) async { + final imageData = await pair.item1.readAsBytes(); final image = decodeJpg(imageData); if (image == null) { @@ -330,8 +308,8 @@ Future processPNG( return null; } - texture.textureType = pair.item2.textureType; - texture.isPalette = image.hasPalette && + texture..textureType = pair.item2.textureType + ..isPalette = image.hasPalette && (texture.textureType == TextureType.Palette4bpp || texture.textureType == TextureType.Palette8bpp); diff --git a/lib/features/create/create_replace_textures/components/folder_content_view.dart b/lib/features/create/create_replace_textures/components/folder_content_view.dart index bfc1aa9..8bb91c9 100644 --- a/lib/features/create/create_replace_textures/components/folder_content_view.dart +++ b/lib/features/create/create_replace_textures/components/folder_content_view.dart @@ -1,8 +1,12 @@ +import 'dart:collection'; +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:retro/features/create/create_finish/create_finish_viewmodel.dart'; import 'package:retro/features/create/create_replace_textures/create_replace_textures_viewmodel.dart'; -import 'package:retro/utils/language_ext.dart'; +import 'package:retro/models/texture_manifest_entry.dart'; +import 'package:tuple/tuple.dart'; // ignore: non_constant_identifier_names Widget FolderContent( @@ -51,13 +55,14 @@ Widget FolderContent( prototypeItem: const SizedBox(width: 0, height: 20), itemBuilder: (context, index) { final key = viewModel.processedFiles.keys.elementAt(index); + // ignore: avoid_dynamic_calls return Text("${finishViewModel.prependAlt ? 'alt/' : ''}$key (${viewModel.processedFiles[key]?.length ?? 0} tex)"); },),),), Padding( padding: const EdgeInsets.only(top: 20), child: ElevatedButton( onPressed: viewModel.processedFiles.isNotEmpty ? () { - finishViewModel.onAddCustomTextureEntry(cast(viewModel.processedFiles)); + finishViewModel.onAddCustomTextureEntry(viewModel.processedFiles as HashMap>>); viewModel.reset(); Navigator.of(context).popUntil(ModalRoute.withName('/create_selection')); } : null, diff --git a/lib/features/create/create_replace_textures/create_replace_textures_viewmodel.dart b/lib/features/create/create_replace_textures/create_replace_textures_viewmodel.dart index 62fe358..2f9cf34 100644 --- a/lib/features/create/create_replace_textures/create_replace_textures_viewmodel.dart +++ b/lib/features/create/create_replace_textures/create_replace_textures_viewmodel.dart @@ -10,6 +10,7 @@ import 'package:flutter_storm/flutter_storm.dart'; import 'package:flutter_storm/flutter_storm_defines.dart'; import 'package:image/image.dart'; import 'package:path/path.dart' as path; +import 'package:retro/arc/arc.dart'; import 'package:retro/models/texture_manifest_entry.dart'; import 'package:retro/otr/resource.dart'; import 'package:retro/otr/resource_type.dart'; @@ -72,7 +73,7 @@ class CreateReplaceTexturesViewModel extends ChangeNotifier { Future onSelectOTR() async { final result = await FilePicker.platform.pickFiles( - allowMultiple: true, type: FileType.custom, allowedExtensions: ['otr']); + allowMultiple: true, type: FileType.custom, allowedExtensions: ['otr', 'o2r']); if (result != null && result.files.isNotEmpty) { // save paths filtering out nulls selectedOTRPaths = result.paths.whereType().toList(); @@ -169,8 +170,8 @@ Future?> processFolder( return null; } - final manifestContents = await manifestFile.readAsString(); - Map manifest = jsonDecode(manifestContents); + String manifestContents = await manifestFile.readAsString(); + Map manifest = json.decode(manifestContents) as Map; // find all images in folder final supportedExtensions = ['.png', '.jpeg', '.jpg']; @@ -234,53 +235,14 @@ Future?> processOTR( for (final otrPath in params.item1) { log('Processing OTR: $otrPath'); - MPQArchive? mpqArchive = MPQArchive.open(otrPath, 0, MPQ_OPEN_READ_ONLY); - - final hFind = FileFindResource(); - mpqArchive.findFirstFile('*', hFind, null); - - // process first file - final fileName = hFind.fileName(); - await processFile(fileName!, mpqArchive, - '${params.item2}/$otrNameForOutputDirectory/$fileName', - (TextureManifestEntry entry) { - processedFiles[fileName] = entry; - }); - - do { - try { - mpqArchive.findNextFile(hFind); - fileFound = true; - - final fileName = hFind.fileName(); - if (fileName == null || - fileName == SIGNATURE_NAME || - fileName == LISTFILE_NAME || - fileName == ATTRIBUTES_NAME) { - continue; - } - - log('Processing file: $fileName'); - final processed = await processFile(fileName, mpqArchive, - '${params.item2}/$otrNameForOutputDirectory/$fileName', - (TextureManifestEntry entry) { - processedFiles[fileName] = entry; - }); - - if (!processed) { - continue; - } - } on StormLibException catch (e) { - log('Got a StormLib error: ${e.message}'); - fileFound = false; - } on Exception catch (e) { - log('Got an error: $e'); - fileFound = false; - } - } while (fileFound); - - hFind.close(); - mpqArchive.close(); + final arcFile = Arc(otrPath); + + await arcFile.listItems(onFile: (String fileName, Uint8List data) async { + await processFile(fileName, data, '${params.item2}/$otrNameForOutputDirectory/$fileName', (TextureManifestEntry entry) { + processedFiles[fileName] = entry; + }); + },); + arcFile.close(); } return processedFiles; @@ -290,62 +252,48 @@ Future?> processOTR( } } -Future processFile(String fileName, MPQArchive mpqArchive, - String outputPath, Function onProcessed) async { - try { - final file = mpqArchive.openFileEx(fileName, 0); - final fileSize = file.size(); - final fileData = file.read(fileSize); +Future processFile(String fileName, Uint8List data, String outputPath, Function onProcessed) async { + final resource = Resource.empty() + ..rawLoad = true + ..open(data); - final resource = Resource.empty(); - resource.rawLoad = true; - resource.open(fileData); + if (![ResourceType.texture, ResourceType.sohBackground] + .contains(resource.resourceType)) { + return false; + } - if (![ResourceType.texture, ResourceType.sohBackground] - .contains(resource.resourceType)) { + String? hash; + + switch (resource.resourceType) { + case ResourceType.texture: + final texture = Texture.empty(); + texture.open(data); + + final pngBytes = texture.toPNGBytes(); + final textureFile = File('$outputPath.png'); + await textureFile.create(recursive: true); + await textureFile.writeAsBytes(pngBytes); + final textureBytes = await textureFile.readAsBytes(); + hash = sha256.convert(textureBytes).toString(); + onProcessed(TextureManifestEntry( + hash, texture.textureType, texture.width, texture.height)); + break; + case ResourceType.sohBackground: + final background = Background.empty(); + background.open(data); + + log('Found JPEG background: $fileName!'); + final textureFile = File('$outputPath.jpg'); + final image = decodeJpg(background.texData)!; + await textureFile.create(recursive: true); + await textureFile.writeAsBytes(background.texData); + hash = sha256.convert(background.texData).toString(); + onProcessed(TextureManifestEntry( + hash, TextureType.JPEG32bpp, image.width, image.height)); + break; + default: return false; - } - - String? hash; - - switch (resource.resourceType) { - case ResourceType.texture: - final texture = Texture.empty(); - texture.open(fileData); - - final pngBytes = texture.toPNGBytes(); - final textureFile = File('$outputPath.png'); - await textureFile.create(recursive: true); - await textureFile.writeAsBytes(pngBytes); - final textureBytes = await textureFile.readAsBytes(); - hash = sha256.convert(textureBytes).toString(); - onProcessed(TextureManifestEntry( - hash, texture.textureType, texture.width, texture.height)); - break; - case ResourceType.sohBackground: - final background = Background.empty(); - background.open(fileData); - - log('Found JPEG background: $fileName!'); - final textureFile = File('$outputPath.jpg'); - final image = decodeJpg(background.texData)!; - await textureFile.create(recursive: true); - await textureFile.writeAsBytes(background.texData); - hash = sha256.convert(background.texData).toString(); - onProcessed(TextureManifestEntry( - hash, TextureType.JPEG32bpp, image.width, image.height)); - break; - default: - return false; - } - - return true; - } on StormLibException catch (e) { - log('Failed to find next file: ${e.message}'); - return false; - } catch (e) { - // Not a texture - print(e); - return false; } + + return true; } diff --git a/lib/features/home/home_screen.dart b/lib/features/home/home_screen.dart index adcf0c5..7158256 100644 --- a/lib/features/home/home_screen.dart +++ b/lib/features/home/home_screen.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_gradient_animation_text/flutter_gradient_animation_text.dart'; import 'package:provider/provider.dart'; import 'package:retro/features/home/home_viewmodel.dart'; import 'package:retro/ui/components/option_card.dart'; @@ -25,6 +27,28 @@ class _HomeScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text(i18n.appTitle, style: textTheme.displaySmall), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Brought to you by', style: textTheme.titleSmall), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 4), + child: GradientAnimationText( + text: Text('HM64'), + colors: [ + Colors.indigo, + Colors.blue, + Colors.green, + Colors.yellow, + Colors.orange, + Colors.red, + ], + duration: const Duration(seconds: 2), + ), + ), + const Icon(Icons.favorite, color: Colors.red), + ], + ), const SizedBox(height: 40), Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/features/inspect_otr/inspect_otr_viewmodel.dart b/lib/features/inspect_otr/inspect_otr_viewmodel.dart index 4434095..c30f23f 100644 --- a/lib/features/inspect_otr/inspect_otr_viewmodel.dart +++ b/lib/features/inspect_otr/inspect_otr_viewmodel.dart @@ -1,8 +1,6 @@ import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; -import 'package:flutter_storm/flutter_storm.dart'; -import 'package:flutter_storm/flutter_storm_bindings_generated.dart'; -import 'package:retro/utils/log.dart'; +import 'package:retro/arc/arc.dart'; class InspectOTRViewModel extends ChangeNotifier { String? selectedOTRPath; @@ -10,7 +8,7 @@ class InspectOTRViewModel extends ChangeNotifier { List filteredFilesInOTR = []; bool isProcessing = false; - reset() { + void reset() { selectedOTRPath = null; filesInOTR = []; filteredFilesInOTR = []; @@ -18,7 +16,7 @@ class InspectOTRViewModel extends ChangeNotifier { } Future onSelectOTR() async { - final result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['otr']); + final result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['otr', 'o2r']); if (result != null && result.files.isNotEmpty) { selectedOTRPath = result.paths.first; if (selectedOTRPath == null) { @@ -28,7 +26,7 @@ class InspectOTRViewModel extends ChangeNotifier { isProcessing = true; notifyListeners(); - final list = await compute(listOTRItems, selectedOTRPath!); + final list = await compute(listFileItems, selectedOTRPath!); if (list != null) { filesInOTR = list; filteredFilesInOTR = list; @@ -47,40 +45,9 @@ class InspectOTRViewModel extends ChangeNotifier { } } -Future?> listOTRItems(String path) async { - try { - var fileFound = false; - final files = []; - - final mpqArchive = MPQArchive.open(path, 0, MPQ_OPEN_READ_ONLY); - final hFind = FileFindResource(); - mpqArchive.findFirstFile('*', hFind, null); - - final fileName = hFind.fileName(); - if (fileName != null && fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') { - files.add(fileName); - } - - do { - try { - mpqArchive.findNextFile(hFind); - fileFound = true; - final fileName = hFind.fileName(); - log('File name: $fileName'); - if (fileName != null && fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') { - files.add(fileName); - } - } on StormLibException catch (e) { - log('Failed to find next file: ${e.message}'); - fileFound = false; - } - } while (fileFound); - - hFind.close(); - mpqArchive.close(); - return files; - } on StormLibException catch (e) { - log('Failed to set locale: ${e.message}'); - return null; - } +Future?> listFileItems(String path) async { + final arcFile = Arc(path); + final files = arcFile.listItems(); + arcFile.close(); + return files; } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 83bb00f..a559875 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1,28 +1,28 @@ { "appTitle": "Retro", - "home_createOption": "Erstelle OTR", - "home_createOptionSubtitle": "Erstelle eine OTR für SoH", - "home_inspectOption": "Überprüfe OTR", - "home_inspectOptionSubtitle": "Überprüfe die Inhalte einer OTR", + "home_createOption": "Erstelle OTR / O2R", + "home_createOptionSubtitle": "Erstelle eine OTR / O2R für SoH", + "home_inspectOption": "Überprüfe OTR / O2R", + "home_inspectOptionSubtitle": "Überprüfe die Inhalte einer OTR / O2R", "createSelectionScreen_title": "Erstelle eine Auswahl", "createSelectionScreen_subtitle": "Wähle die Kategorie, von der du etwas erstellen willst", "createSelectionScreen_nonHdTex": "Tausche Texturen aus", "createSelectionScreen_customSequences": "Benutzidentifizierte Sequenzen", "createSelectionScreen_custom": "Benutzeridentifiziert", "createReplaceTexturesScreen_Option": "Tausche Texturen aus", - "createReplaceTexturesScreen_OptionDescription": "Tausche Texturen einer OTR durch andere Texturen aus", + "createReplaceTexturesScreen_OptionDescription": "Tausche Texturen einer OTR / O2R durch andere Texturen aus", "questionContentView_mainQuestion": "Hast du bereits einen Austausch-Texturen Ordner?", "questionContentView_mainText": "Falls du einen von diesem Tool generierten Ordner für Austausch-Texturen hast, wähle Ja.\nFalls du keinen hast, wähle Nein und wir werden sofort mit dem Erstellen von Austuasch-Texturen starten.", "questionContentView_yes": "Ja", "questionContentView_no": "Nein", - "otrContentView_otrPath": "OTR Pfad", + "otrContentView_otrPath": "OTR / O2R Pfad", "otrContentView_otrSelect": "Wähle", "otrContentView_details": "Details", - "otrContentView_step1": "1. Wähle OTR dessen Texturen du austauschen möchtest", + "otrContentView_step1": "1. Wähle OTR / O2R dessen Texturen du austauschen möchtest", "otrContentView_step2": "2. Wir extrahieren Texturen Assets als PNG mit korrekter Ordner Struktur", "otrContentView_step3": "3. Ersetze die Texturen in dem Ordner mit den extrahierten Texturen", "otrContentView_step4": "4. Führe diesen Flow erneut aus und wähle deinen Extrahier-Ordner", - "otrContentView_step5": "5. Wir generieren eine OTR mit anderen Texturen! 🚀", + "otrContentView_step5": "5. Wir generieren eine OTR / O2R mit anderen Texturen! 🚀", "otrContentView_processing": "Verarbeite...", "folderContentView_customTexturePath": "Benutzeridentifizierter Austausch-Texturen Ordner", "folderContentView_prependAltToggle": "Füge einen `alt/` Dies ermöglicht es den Spielern, Assets im Spiel zu aktivieren oder zu deaktivieren.", @@ -34,18 +34,18 @@ "createCustomSequences_selectButton": "Wähle", "createCustomSequences_stageFiles": "Dateien indexieren", "createFinishScreen_finish": "Beenden", - "createFinishScreen_finishSubtitle": "Übersicht über deine OTR Details", - "createFinishScreen_generateOtr": "Generiere OTR", - "components_ephemeralBar_finalizeOtr": "Vollende OTR ⚡️", + "createFinishScreen_finishSubtitle": "Übersicht über deine OTR / O2R Details", + "createFinishScreen_generateOtr": "Generiere OTR / O2R", + "components_ephemeralBar_finalizeOtr": "Vollende OTR / O2R ⚡️", "createCustomScreen_title": "Via Pfad", "createCustomScreen_subtitle": "Wähle Dateien, die im Pfad platziert werden sollen", "createCustomScreen_labelPath": "Pfad", "createCustomScreen_selectButton": "Wähle Dateien", "createCustomScreen_fileToInsert": "Dateien zum Einfügen: ", "createCustomScreen_stageFiles": "Stage Files", - "inspectOtrScreen_inspectOtr": "Überprüfe OTR", - "inspectOtrScreen_inspectOtrSubtitle": "Überprüfe die Inhalte einer OTR", - "inspectOtrScreen_noOtrSelected": "Keine OTR ausgewählt", + "inspectOtrScreen_inspectOtr": "Überprüfe OTR / O2R", + "inspectOtrScreen_inspectOtrSubtitle": "Überprüfe die Inhalte einer OTR / O2R", + "inspectOtrScreen_noOtrSelected": "Keine OTR / O2R ausgewählt", "inspectOtrScreen_selectButton": "Wähle", "inspectOtrScreen_search": "Suchen" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index bed5ae9..04141c7 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,28 +1,28 @@ { "appTitle": "Retro", - "home_createOption": "Create OTR", - "home_createOptionSubtitle": "Create an OTR for SoH", - "home_inspectOption": "Inspect OTR", - "home_inspectOptionSubtitle": "Inspect the contents of an OTR", + "home_createOption": "Create OTR / O2R", + "home_createOptionSubtitle": "Create an OTR / O2R for SoH", + "home_inspectOption": "Inspect OTR / O2R", + "home_inspectOptionSubtitle": "Inspect the contents of an OTR / O2R", "createSelectionScreen_title": "Create Selection", "createSelectionScreen_subtitle": "Select the type of selection you want to create", "createSelectionScreen_nonHdTex": "Replace Textures", "createSelectionScreen_customSequences": "Custom Sequences", "createSelectionScreen_custom": "Custom", "createReplaceTexturesScreen_Option": "Replace Textures", - "createReplaceTexturesScreen_OptionDescription": "Replace textures from an OTR with custom ones", + "createReplaceTexturesScreen_OptionDescription": "Replace textures from an OTR / O2R with custom ones", "questionContentView_mainQuestion": "Do you already have a texture replacement folder?", "questionContentView_mainText": "If you have a folder generated by this tool with replacements, select Yes.\nIf you don't have one, select No and we'll get you started with creating replacements.", "questionContentView_yes": "Yes", "questionContentView_no": "No", - "otrContentView_otrPath": "OTR Path", + "otrContentView_otrPath": "OTR / O2R Path", "otrContentView_otrSelect": "Select", "otrContentView_details": "Details", - "otrContentView_step1": "1. Select OTR that you want to replace textures from", + "otrContentView_step1": "1. Select OTR / O2R that you want to replace textures from", "otrContentView_step2": "2. We extract texture assets as PNG with correct folder structure", "otrContentView_step3": "3. You replace the textures in that extraction folder", "otrContentView_step4": "4. Run this flow again and present your extraction folder", - "otrContentView_step5": "5. We generate an OTR with the changed textures! 🚀", + "otrContentView_step5": "5. We generate an OTR / O2R with the changed textures! 🚀", "otrContentView_processing": "Processing...", "folderContentView_customTexturePath": "Custom Texture Replacements Folder", "folderContentView_prependAltToggle": "Prepend `alt/`. This will allow players to toggle these assets on-the-fly in game.", @@ -34,18 +34,18 @@ "createCustomSequences_selectButton": "Select", "createCustomSequences_stageFiles": "Stage Files", "createFinishScreen_finish": "Finish", - "createFinishScreen_finishSubtitle": "Review your OTR details", - "createFinishScreen_generateOtr": "Generate OTR", - "components_ephemeralBar_finalizeOtr": "Finalize OTR ⚡️", + "createFinishScreen_finishSubtitle": "Review your OTR / O2R details", + "createFinishScreen_generateOtr": "Generate OTR / O2R", + "components_ephemeralBar_finalizeOtr": "Finalize OTR / O2R ⚡️", "createCustomScreen_title": "Custom Directory", "createCustomScreen_subtitle": "Select directory to pack as .otr", "createCustomScreen_labelPath": "Path", "createCustomScreen_selectButton": "Select Directory", "createCustomScreen_fileToInsert": "Files to insert: ", "createCustomScreen_stageFiles": "Stage Files", - "inspectOtrScreen_inspectOtr": "Inspect OTR", - "inspectOtrScreen_inspectOtrSubtitle": "Inspect the contents of an OTR", - "inspectOtrScreen_noOtrSelected": "No OTR Selected", + "inspectOtrScreen_inspectOtr": "Inspect OTR / O2R", + "inspectOtrScreen_inspectOtrSubtitle": "Inspect the contents of an OTR / O2R", + "inspectOtrScreen_noOtrSelected": "No OTR / O2R Selected", "inspectOtrScreen_selectButton": "Select", "inspectOtrScreen_search": "Search" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index cbbde49..cc66f5a 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1,28 +1,28 @@ { "appTitle": "Retro", - "home_createOption": "Crear OTR", - "home_createOptionSubtitle": "Crear un OTR para SoH", - "home_inspectOption": "Inspeccionar OTR", - "home_inspectOptionSubtitle": "Inspeccionar el contenido de un OTR", + "home_createOption": "Crear OTR / O2R", + "home_createOptionSubtitle": "Crear un OTR / O2R para SoH", + "home_inspectOption": "Inspeccionar OTR / O2R", + "home_inspectOptionSubtitle": "Inspeccionar el contenido de un OTR / O2R", "createSelectionScreen_title": "Crear selección", "createSelectionScreen_subtitle": "Seleccione el tipo de selección que desea crear", "createSelectionScreen_nonHdTex": "Reemplazar texturas", "createSelectionScreen_customSequences": "Secuencias personalizadas", "createSelectionScreen_custom": "Personalizada", "createReplaceTexturesScreen_Option": "Reemplazar texturas", - "createReplaceTexturesScreen_OptionDescription": "Reemplace texturas de un OTR con otras personalizadas", + "createReplaceTexturesScreen_OptionDescription": "Reemplace texturas de un OTR / O2R con otras personalizadas", "questionContentView_mainQuestion": "¿Ya tiene una carpeta de reemplazo de texturas?", "questionContentView_mainText": "Si tiene una carpeta generada por esta herramienta con reemplazos, seleccione Sí.\nDe lo contrario, seleccione No y le ayudaremos con la creación de reemplazos.", "questionContentView_yes": "Sí", "questionContentView_no": "No", - "otrContentView_otrPath": "Ruta del OTR", + "otrContentView_otrPath": "Ruta del OTR / O2R", "otrContentView_otrSelect": "Seleccionar", "otrContentView_details": "Detalles", - "otrContentView_step1": "1. Seleccione un OTR del que desee reemplazar texturas", + "otrContentView_step1": "1. Seleccione un OTR / O2R del que desee reemplazar texturas", "otrContentView_step2": "2. Extraemos las texturas como PNG con la estructura de carpetas correcta", "otrContentView_step3": "3. Reemplace las texturas de la carpeta de extracción", "otrContentView_step4": "4. Ejecute este procedimiento de nuevo y seleccione la carpeta de extracción", - "otrContentView_step5": "5. ¡Generamos un OTR con las texturas modificadas! 🚀", + "otrContentView_step5": "5. ¡Generamos un OTR / O2R con las texturas modificadas! 🚀", "otrContentView_processing": "Procesando...", "folderContentView_customTexturePath": "Carpeta de reemplazos de texturas personalizadas", "folderContentView_prependAltToggle": "Agregar en `alt/`. Esto permitirá a los jugadores cambiar los recursos durante el juego.", @@ -34,18 +34,18 @@ "createCustomSequences_selectButton": "Seleccionar", "createCustomSequences_stageFiles": "Agregar archivos", "createFinishScreen_finish": "Finalizar", - "createFinishScreen_finishSubtitle": "Compruebe los detalles de su OTR", - "createFinishScreen_generateOtr": "Generar OTR", - "components_ephemeralBar_finalizeOtr": "Finalizar OTR ⚡️", + "createFinishScreen_finishSubtitle": "Compruebe los detalles de su OTR / O2R", + "createFinishScreen_generateOtr": "Generar OTR / O2R", + "components_ephemeralBar_finalizeOtr": "Finalizar OTR / O2R ⚡️", "createCustomScreen_title": "Por ruta", "createCustomScreen_subtitle": "Seleccione archivos que desee colocar en la ruta", "createCustomScreen_labelPath": "Ruta", "createCustomScreen_selectButton": "Seleccionar archivos", "createCustomScreen_fileToInsert": "Archivos para insertar: ", "createCustomScreen_stageFiles": "Agregar archivos", - "inspectOtrScreen_inspectOtr": "Inspeccionar OTR", - "inspectOtrScreen_inspectOtrSubtitle": "Inspeccione el contenido de un OTR", - "inspectOtrScreen_noOtrSelected": "No se ha seleccionado un OTR", + "inspectOtrScreen_inspectOtr": "Inspeccionar OTR / O2R", + "inspectOtrScreen_inspectOtrSubtitle": "Inspeccione el contenido de un OTR / O2R", + "inspectOtrScreen_noOtrSelected": "No se ha seleccionado un OTR / O2R", "inspectOtrScreen_selectButton": "Seleccionar", "inspectOtrScreen_search": "Buscar" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index e984800..54d52e1 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1,31 +1,31 @@ { "appTitle": "Retro", - "home_createOption": "Créer un OTR", - "home_createOptionSubtitle": "Créer un OTR pour SoH", - "home_inspectOption": "Inspecter un OTR", - "home_inspectOptionSubtitle": "Inspecter le contenu d'un OTR", - "createSelectionScreen_title": "Création d'un OTR", - "createSelectionScreen_subtitle": "Sélectionnez le type d'OTR que vous souhaitez créer", + "home_createOption": "Créer un OTR / O2R", + "home_createOptionSubtitle": "Créer un OTR / O2R pour SoH", + "home_inspectOption": "Inspecter un OTR / O2R", + "home_inspectOptionSubtitle": "Inspecter le contenu d'un OTR / O2R", + "createSelectionScreen_title": "Création d'un OTR / O2R", + "createSelectionScreen_subtitle": "Sélectionnez le type d'OTR / O2R que vous souhaitez créer", "createSelectionScreen_nonHdTex": "Remplacer les textures", "createSelectionScreen_customSequences": "Séquences personnalisées", "createSelectionScreen_custom": "Personnalisé", "createReplaceTexturesScreen_Option": "Remplacer les textures", - "createReplaceTexturesScreen_OptionDescription": "Remplacer les textures d'un OTR par des textures personnalisées", + "createReplaceTexturesScreen_OptionDescription": "Remplacer les textures d'un OTR / O2R par des textures personnalisées", "questionContentView_mainQuestion": "Avez-vous déjà un dossier de remplacement de texture?", "questionContentView_mainText": "Si vous avez déjà un dossier de remplacement généré par cet outil, sélectionnez Oui.\nSi vous n'en avez pas, sélectionnez Non et nous vous aiderons à générer un dossier.", "questionContentView_yes": "Oui", "questionContentView_no": "Non", - "otrContentView_otrPath": "Chemin de l'OTR", + "otrContentView_otrPath": "Chemin de l'OTR / O2R", "otrContentView_otrSelect": "Sélectionner", "otrContentView_details": "Details", - "otrContentView_step1": "1. Sélectionnez l'OTR à partir duquel vous souhaitez remplacer les textures.", + "otrContentView_step1": "1. Sélectionnez l'OTR / O2R à partir duquel vous souhaitez remplacer les textures.", "otrContentView_step2": "2. Nous extrayons les assets de texture en PNG avec une structure de dossier correcte.", "otrContentView_step3": "3. Vous remplacez les textures dans ce dossier d'extraction", "otrContentView_step4": "4. Exécutez à nouveau l'opération et choisissez votre dossier d'extraction", - "otrContentView_step5": "5. Nous générons un OTR avec les textures modifiées! 🚀", + "otrContentView_step5": "5. Nous générons un OTR / O2R avec les textures modifiées! 🚀", "otrContentView_processing": "Traitement en cours...", "folderContentView_customTexturePath": "Dossier de remplacements de textures personnalisées", - "folderContentView_prependAltToggle": "Ajouter un dossier `alt/` à votre OTR. Permet aux joueurs d'activer ou désactiver les assets en jeu.", + "folderContentView_prependAltToggle": "Ajouter un dossier `alt/` à votre OTR / O2R. Permet aux joueurs d'activer ou désactiver les assets en jeu.", "folderContentView_selectButton": "Sélectionner", "folderContentView_stageTextures": "Indexer les textures", "createCustomSequences_addCustomSequences": "Ajouter des séquences personnalisées", @@ -34,18 +34,18 @@ "createCustomSequences_selectButton": "Sélectionner", "createCustomSequences_stageFiles": "Indexer les fichiers", "createFinishScreen_finish": "Terminer", - "createFinishScreen_finishSubtitle": "Vérifiez les détails de votre OTR", - "createFinishScreen_generateOtr": "Générer l'OTR", - "components_ephemeralBar_finalizeOtr": "Finaliser l'OTR ⚡️", - "createCustomScreen_title": "OTR Personnalisé par le chemin", + "createFinishScreen_finishSubtitle": "Vérifiez les détails de votre OTR / O2R", + "createFinishScreen_generateOtr": "Générer l'OTR / O2R", + "components_ephemeralBar_finalizeOtr": "Finaliser l'OTR / O2R ⚡️", + "createCustomScreen_title": "OTR / O2R Personnalisé par le chemin", "createCustomScreen_subtitle": "Sélectionnez les fichiers à placer dans le chemin", "createCustomScreen_labelPath": "Chemin", "createCustomScreen_selectButton": "Sélectionnez les fichiers", "createCustomScreen_fileToInsert": "Fichiers à ajouter: ", "createCustomScreen_stageFiles": "Indexer les fichiers", - "inspectOtrScreen_inspectOtr": "Inspecter un OTR", - "inspectOtrScreen_inspectOtrSubtitle": "Inspecter le contenu d'un OTR", - "inspectOtrScreen_noOtrSelected": "Aucun OTR sélectionné", + "inspectOtrScreen_inspectOtr": "Inspecter un OTR / O2R", + "inspectOtrScreen_inspectOtrSubtitle": "Inspecter le contenu d'un OTR / O2R", + "inspectOtrScreen_noOtrSelected": "Aucun OTR / O2R sélectionné", "inspectOtrScreen_selectButton": "Sélectionner", "inspectOtrScreen_search": "Rechercher" } \ No newline at end of file diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index 7feb8b4..e404ba8 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1,28 +1,28 @@ { "appTitle": "Retro", - "home_createOption": "Maak een OTR", - "home_createOptionSubtitle": "Maak OTR voor SoH", - "home_inspectOption": "Inspecteer een OTR", - "home_inspectOptionSubtitle": "Inspecteer de inhoud van een OTR", + "home_createOption": "Maak een OTR / O2R", + "home_createOptionSubtitle": "Maak OTR / O2R voor SoH", + "home_inspectOption": "Inspecteer een OTR / O2R", + "home_inspectOptionSubtitle": "Inspecteer de inhoud van een OTR / O2R", "createSelectionScreen_title": "Selectie maken", "createSelectionScreen_subtitle": "Selecteer het type selectie dat je wilt maken", "createSelectionScreen_nonHdTex": "Vervang textures (niet-HD)", "createSelectionScreen_customSequences": "Aangepaste composities", "createSelectionScreen_custom": "Aangepast", "createReplaceTexturesScreen_Option": "Vervang textures", - "createReplaceTexturesScreen_OptionDescription": "Vervang textures van een OTR door aangepaste (niet-hd) textures", + "createReplaceTexturesScreen_OptionDescription": "Vervang textures van een OTR / O2R door aangepaste (niet-hd) textures", "questionContentView_mainQuestion": "Heb je al een map met vervangende textures?", "questionContentView_mainText": "Als je een map heeft die door deze tool is gegenereerd met vervangingen, selecteer Ja.\nals je er nog geen hebt, selecteer Nee en dan gaan we een map maken.", "questionContentView_yes": "Ja", "questionContentView_no": "Nee", - "otrContentView_otrPath": "OTR Pad", + "otrContentView_otrPath": "OTR / O2R Pad", "otrContentView_otrSelect": "Selecteer", "otrContentView_details": "Details", - "otrContentView_step1": "1. Selecteer OTR waar in je textures wilt vervangen", + "otrContentView_step1": "1. Selecteer OTR / O2R waar in je textures wilt vervangen", "otrContentView_step2": "2. We extracten texture assets als PNG met de juiste mapstructuur", "otrContentView_step3": "3. Je vervangd textures in die aangemaakte map", "otrContentView_step4": "4. Voer dit process opnieuw uit en voer je extractiemap in", - "otrContentView_step5": "5. We genereren een OTR met de gewijzigde textures! 🚀", + "otrContentView_step5": "5. We genereren een OTR / O2R met de gewijzigde textures! 🚀", "otrContentView_processing": "Verwerken...", "folderContentView_customTexturePath": "Vervangende Texture Map", "folderContentView_prependAltToggle": "Prepend `alt/`. This will allow players to toggle these assets on-the-fly in game.", @@ -34,18 +34,18 @@ "createCustomSequences_selectButton": "Selecteer", "createCustomSequences_stageFiles": "Stage-bestanden", "createFinishScreen_finish": "Klaar", - "createFinishScreen_finishSubtitle": "Controleer jouw OTR-gegevens", - "createFinishScreen_generateOtr": "Generate OTR", - "components_ephemeralBar_finalizeOtr": "Proces afgerond OTR ⚡️", + "createFinishScreen_finishSubtitle": "Controleer jouw OTR / O2R-gegevens", + "createFinishScreen_generateOtr": "Generate OTR / O2R", + "components_ephemeralBar_finalizeOtr": "Proces afgerond OTR / O2R ⚡️", "createCustomScreen_title": "Via Pad", "createCustomScreen_subtitle": "Selecteer bestanden om op pad te plaatsen", "createCustomScreen_labelPath": "Pad", "createCustomScreen_selectButton": "Selecteer bestanden", "createCustomScreen_fileToInsert": "Bestanden om in te voegen: ", "createCustomScreen_stageFiles": "Stage-bestanden", - "inspectOtrScreen_inspectOtr": "Inspecteer OTR", - "inspectOtrScreen_inspectOtrSubtitle": "Inspecteer de inhoud van een OTR", - "inspectOtrScreen_noOtrSelected": "Geen OTR geselecteerd", + "inspectOtrScreen_inspectOtr": "Inspecteer OTR / O2R", + "inspectOtrScreen_inspectOtrSubtitle": "Inspecteer de inhoud van een OTR / O2R", + "inspectOtrScreen_noOtrSelected": "Geen OTR / O2R geselecteerd", "inspectOtrScreen_selectButton": "Selecteer", "inspectOtrScreen_search": "Zoek" } \ No newline at end of file diff --git a/lib/models/texture_manifest_entry.dart b/lib/models/texture_manifest_entry.dart index 6ae323d..107d20d 100644 --- a/lib/models/texture_manifest_entry.dart +++ b/lib/models/texture_manifest_entry.dart @@ -4,14 +4,19 @@ class TextureManifestEntry { TextureManifestEntry(this.hash, this.textureType, this.textureWidth, this.textureHeight); - TextureManifestEntry.fromJson(Map json): - hash = json['hash'], - textureType = TextureType.fromValue(json['textureType']), - textureWidth = json['textureWidth'], - textureHeight = json['textureHeight']; + factory TextureManifestEntry.fromJson(dynamic json) { + return TextureManifestEntry( + json['hash'] as String, + TextureType.values[json['textureType'] as int], + json['textureWidth'] as int, + json['textureHeight'] as int, + ); + } + String hash; TextureType textureType; - int textureWidth, textureHeight; + int textureWidth; + int textureHeight; Map toJson() => { 'hash': hash, diff --git a/lib/otr/resource.dart b/lib/otr/resource.dart index bd07b70..a9fc91b 100644 --- a/lib/otr/resource.dart +++ b/lib/otr/resource.dart @@ -32,7 +32,7 @@ class Resource { writeInt8(isCustom ? 1 : 0); // 0x14 writeInt8(0); // 0x15 writeInt8(0); // 0x16 - writeInt8(0); // 0x17 + writeInt8(0); // 0x17 writeInt32(0); // 0x18 writeInt32(0); // 0x1C diff --git a/lib/otr/version.dart b/lib/otr/version.dart index 133f538..605ca0a 100644 --- a/lib/otr/version.dart +++ b/lib/otr/version.dart @@ -18,6 +18,6 @@ enum Version { static Version fromValue(int value) { return Version.values - .firstWhere((Version version) => version.value == value); + .firstWhere((Version version) => version.value == value, orElse: () => Version.unknown); } } diff --git a/lib/ui/components/ephemeral_bar.dart b/lib/ui/components/ephemeral_bar.dart index 2142dc4..ddd677b 100644 --- a/lib/ui/components/ephemeral_bar.dart +++ b/lib/ui/components/ephemeral_bar.dart @@ -95,7 +95,7 @@ class _EphemeralBarState extends State child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Text('Retro: 0.0.5', style: textTheme.bodyMedium!.copyWith( + Text('Retro: 0.1.0', style: textTheme.bodyMedium!.copyWith( color: colorScheme.onSurface,), ), if (!isExpanded) @@ -127,7 +127,7 @@ class _EphemeralBarState extends State return SizedBox.fromSize( size: Size(size.width, max(size.height * animation.value, 24)), child: CreateFinishBottomBarModal( - bottomBar: bottomBar, dismissCallback: () { + bottomBar: bottomBar, dismissCallback: () { expandController.reverse(); viewModel.toggleEphemeralBar(); },),); diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 94d9863..9a12841 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -26,9 +26,9 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: flutter_storm: 9d6bb8ed36b51e877d7a3aef59328b696766d5d9 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451 + url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399 window_size: 339dafa0b27a95a62a843042038fa6c3c48de195 PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index c66fb96..57211ef 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -203,7 +203,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 50346df..48cbd85 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ =3.0.0-417 <4.0.0" - flutter: ">=3.3.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 869df14..7500e75 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: retro -description: An OTR generation tool. +description: An OTR / O2R generation tool. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. @@ -47,12 +47,14 @@ dependencies: flutter_storm: git: url: https://github.com/HarbourMasters/flutter_storm.git - ref: e42354c946c603f7ce86090d599158bb4306cd19 + ref: 7cfb8ef3560f3ff3bdda64f1a283fc06f4325dfc tuple: ^2.0.1 crypto: ^3.0.2 image: ^4.0.7 - intl: ^0.18.0 + intl: ^0.18.1 path: ^1.8.2 + archive: ^3.6.0 + flutter_gradient_animation_text: ^1.0.2 flutter_icons: windows: @@ -78,6 +80,9 @@ dev_dependencies: flutter_lints: ^2.0.0 very_good_analysis: ^3.1.0 +dependency_overrides: + intl: ^0.18.1 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/test/widget_test.dart b/test/widget_test.dart index 01ac5d8..31069c2 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -5,25 +5,4 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(const MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +void main() { }