From 7d6772d8ea0f3168459e9dd147d0ce8a9070ec6c Mon Sep 17 00:00:00 2001 From: KizKizz Date: Fri, 2 Aug 2024 23:40:20 -0700 Subject: [PATCH 1/4] prep --- .../items_swapper_acc_homepage.dart | 67 ++++++--------- .../items_swapper_data_loader.dart | 12 ++- lib/itemsSwapper/items_swapper_homepage.dart | 21 ++--- .../items_swapper_la_homepage.dart | 85 ++++++++++--------- lib/modsAdder/mods_adder_homepage.dart | 4 +- .../mods_swapper_acc_homepage.dart | 13 +-- .../mods_swapper_acc_swappage.dart | 41 ++++++++- lib/modsSwapper/mods_swapper_data_loader.dart | 8 +- lib/modsSwapper/mods_swapper_homepage.dart | 53 ++++++------ lib/modsSwapper/mods_swapper_la_homepage.dart | 16 ++-- lib/modsSwapper/mods_swapper_la_swappage.dart | 78 ++++++++++++++--- lib/modsSwapper/mods_swapper_popup.dart | 5 +- lib/modsSwapper/mods_swapper_swappage.dart | 55 ++++++++++-- lib/pages/home_page.dart | 18 ++-- lib/swapAll/swap_all_apply_homepage.dart | 48 ++++++----- lib/ui_translation_helper.dart | 21 +++-- 16 files changed, 339 insertions(+), 206 deletions(-) diff --git a/lib/itemsSwapper/items_swapper_acc_homepage.dart b/lib/itemsSwapper/items_swapper_acc_homepage.dart index 698c1ef..c1d85a6 100644 --- a/lib/itemsSwapper/items_swapper_acc_homepage.dart +++ b/lib/itemsSwapper/items_swapper_acc_homepage.dart @@ -211,7 +211,7 @@ class _ItemsSwapperAccHomePageState extends State { borderRadius: BorderRadius.circular(3), border: Border.all(color: Theme.of(context).hintColor, width: 1), ), - child: swapperSearchTextController.text.isEmpty + child: swapperFromItemsSearchTextController.text.isEmpty ? Image.network( '$modManMAIconDatabaseLink${fromItemCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', errorBuilder: (context, error, stackTrace) => Image.asset( @@ -234,13 +234,9 @@ class _ItemsSwapperAccHomePageState extends State { )), ), //name - modManCurActiveItemNameLanguage == 'JP' - ? swapperFromItemsSearchTextController.text.isEmpty - ? Text(fromItemCsvData[i].jpName) - : Text(fromItemSearchResults[i].jpName) - : swapperFromItemsSearchTextController.text.isEmpty - ? Text(fromItemCsvData[i].enName) - : Text(fromItemSearchResults[i].enName), + swapperFromItemsSearchTextController.text.isEmpty + ? Text(modManCurActiveItemNameLanguage == 'JP' ? fromItemCsvData[i].jpName : fromItemCsvData[i].enName) + : Text(modManCurActiveItemNameLanguage == 'JP' ? fromItemSearchResults[i].jpName : fromItemSearchResults[i].enName), ]), subtitle: swapperFromItemsSearchTextController.text.isEmpty ? selectedFromAccCsvFile == fromItemCsvData[i] @@ -284,8 +280,7 @@ class _ItemsSwapperAccHomePageState extends State { } } //confirm icon set - fromItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + fromItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -484,36 +479,23 @@ class _ItemsSwapperAccHomePageState extends State { borderRadius: BorderRadius.circular(3), border: Border.all(color: Theme.of(context).hintColor, width: 1), ), - child: swapperSearchTextController.text.isEmpty - ? Image.network( - '$modManMAIconDatabaseLink${availableAccCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', - errorBuilder: (context, error, stackTrace) => Image.asset( - 'assets/img/placeholdersquare.png', - filterQuality: FilterQuality.none, - fit: BoxFit.fitWidth, - ), - filterQuality: FilterQuality.none, - fit: BoxFit.fitWidth, - ) - : Image.network( - '$modManMAIconDatabaseLink${toAccSearchResults[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', - errorBuilder: (context, error, stackTrace) => Image.asset( - 'assets/img/placeholdersquare.png', - filterQuality: FilterQuality.none, - fit: BoxFit.fitWidth, - ), - filterQuality: FilterQuality.none, - fit: BoxFit.fitWidth, - )), + child: Image.network( + swapperSearchTextController.text.isEmpty + ? '$modManMAIconDatabaseLink${availableAccCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}' + : '$modManMAIconDatabaseLink${toAccSearchResults[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', + errorBuilder: (context, error, stackTrace) => Image.asset( + 'assets/img/placeholdersquare.png', + filterQuality: FilterQuality.none, + fit: BoxFit.fitWidth, + ), + filterQuality: FilterQuality.none, + fit: BoxFit.fitWidth, + )), ), //name - modManCurActiveItemNameLanguage == 'JP' - ? swapperSearchTextController.text.isEmpty - ? Text(availableAccCsvData[i].jpName) - : Text(toAccSearchResults[i].jpName) - : swapperSearchTextController.text.isEmpty - ? Text(availableAccCsvData[i].enName) - : Text(toAccSearchResults[i].enName), + swapperSearchTextController.text.isEmpty + ? Text(modManCurActiveItemNameLanguage == 'JP' ? availableAccCsvData[i].jpName : availableAccCsvData[i].enName) + : Text(modManCurActiveItemNameLanguage == 'JP' ? toAccSearchResults[i].jpName : toAccSearchResults[i].enName) ]), onChanged: (CsvAccessoryIceFile? currentItem) { //print("Current ${moddedItemsList[i].groupName}"); @@ -534,8 +516,7 @@ class _ItemsSwapperAccHomePageState extends State { } } //confirm icon set - toItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + toItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -549,7 +530,7 @@ class _ItemsSwapperAccHomePageState extends State { ), ), ], - )) + )), ], ), ), @@ -718,7 +699,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, String fromAccItem ), ), ), - ) + ), ], ), ], @@ -732,7 +713,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, String fromAccItem ElevatedButton( onPressed: () { Navigator.pop(context); - msas.swapperAccSwappingDialog(context, true, fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName); + msas.swapperAccSwappingDialog(context, true, fromItemModGet(), fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName); }, child: Text(curLangText!.uiSwap)) ]); diff --git a/lib/itemsSwapper/items_swapper_data_loader.dart b/lib/itemsSwapper/items_swapper_data_loader.dart index 0f05223..acd10e4 100644 --- a/lib/itemsSwapper/items_swapper_data_loader.dart +++ b/lib/itemsSwapper/items_swapper_data_loader.dart @@ -1,7 +1,7 @@ - import 'package:flutter/material.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/mod_file_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; @@ -34,7 +34,8 @@ SubMod fromItemSubmodGet(List iceFileNames) { orElse: () => '', ); if (p.basename(icePathFromOgData) == iceName) { - modFileList.add(ModFile(iceName, fromItemNameSwap, fromItemNameSwap, fromItemNameSwap, selectedCategoryF!, '', [], icePathFromOgData, false, DateTime(0), 0, false, false, false, [], [], [], [], [], [])); + modFileList.add( + ModFile(iceName, fromItemNameSwap, fromItemNameSwap, fromItemNameSwap, selectedCategoryF!, '', [], icePathFromOgData, false, DateTime(0), 0, false, false, false, [], [], [], [], [], [])); } } //} @@ -43,6 +44,10 @@ SubMod fromItemSubmodGet(List iceFileNames) { return SubMod(fromItemNameSwap, fromItemNameSwap, fromItemName, selectedCategoryF!, '', false, DateTime(0), 0, false, false, false, false, false, -1, -1, '', [], [], [], [], [], modFileList); } +Mod fromItemModGet() { + return Mod('', '', '', '', false, DateTime(0), 0, false, false, false, [], [], [], [], []); +} + Future> getAccSwapToCsvList(List cvsAccDataInput, String category) async { return cvsAccDataInput.where((element) => element.category == category && element.enName.isNotEmpty && element.jpName.isNotEmpty).toList(); } @@ -248,8 +253,7 @@ class _ItemsSwapperDataLoaderState extends State { // (a, b) => a.enName.compareTo(b.enName), // ); // } - return const ItemsSwapperWeaponHomePage( - ); + return const ItemsSwapperWeaponHomePage(); } else { availableItemsCsvData = snapshot.data; if (modManCurActiveItemNameLanguage == 'JP') { diff --git a/lib/itemsSwapper/items_swapper_homepage.dart b/lib/itemsSwapper/items_swapper_homepage.dart index 50b6fa7..7d85253 100644 --- a/lib/itemsSwapper/items_swapper_homepage.dart +++ b/lib/itemsSwapper/items_swapper_homepage.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; import 'package:pso2_mod_manager/itemsSwapper/items_swapper_data_loader.dart'; @@ -252,7 +253,7 @@ class _ItemsSwapperHomePageState extends State { borderRadius: BorderRadius.circular(3), border: Border.all(color: Theme.of(context).hintColor, width: 1), ), - child: swapperSearchTextController.text.isEmpty + child: swapperFromItemsSearchTextController.text.isEmpty ? Image.network( '$modManMAIconDatabaseLink${fromItemCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', errorBuilder: (context, error, stackTrace) => Image.asset( @@ -336,8 +337,7 @@ class _ItemsSwapperHomePageState extends State { } //confirm icon set - fromItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + fromItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -587,8 +587,7 @@ class _ItemsSwapperHomePageState extends State { } //confirm icon set - toItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + toItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -602,7 +601,7 @@ class _ItemsSwapperHomePageState extends State { ), ), ], - )) + )), ], ), ), @@ -640,7 +639,8 @@ class _ItemsSwapperHomePageState extends State { ? null : () { if (selectedFromCsvFile != null && selectedToCsvFile != null) { - swapperConfirmDialog(context, fromItemSubmodGet(fromItemAvailableIces), fromItemIds, fromItemAvailableIces, toItemIds, toItemAvailableIces); + swapperConfirmDialog( + context, fromItemModGet(), fromItemSubmodGet(fromItemAvailableIces), fromItemIds, fromItemAvailableIces, toItemIds, toItemAvailableIces); } }, child: Text(curLangText!.uiNext)) @@ -658,7 +658,8 @@ class _ItemsSwapperHomePageState extends State { } } -Future swapperConfirmDialog(context, SubMod fromSubmod, List fromItemIds, List fromItemAvailableIces, List toItemIds, List toItemAvailableIces) async { +Future swapperConfirmDialog( + context, Mod fromMod, SubMod fromSubmod, List fromItemIds, List fromItemAvailableIces, List toItemIds, List toItemAvailableIces) async { await showDialog( barrierDismissible: false, context: context, @@ -779,7 +780,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, List fromI ), ), ), - ) + ), ], ), ], @@ -793,7 +794,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, List fromI ElevatedButton( onPressed: () { Navigator.pop(context); - mss.swapperSwappingDialog(context, true, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemIds[0], toItemIds[0]); + mss.swapperSwappingDialog(context, true, fromMod, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemIds[0], toItemIds[0]); }, child: Text(curLangText!.uiSwap)) ]); diff --git a/lib/itemsSwapper/items_swapper_la_homepage.dart b/lib/itemsSwapper/items_swapper_la_homepage.dart index 1498d2e..1454aa0 100644 --- a/lib/itemsSwapper/items_swapper_la_homepage.dart +++ b/lib/itemsSwapper/items_swapper_la_homepage.dart @@ -39,17 +39,6 @@ List> queueFromEmotesAvailableIces = []; List> queueToEmotesAvailableIces = []; List queueSwappedLaPaths = []; List queueToItemNames = []; -List motionTypes = [ - curLangText!.uiAll, - curLangText!.uiGlideMotion, - curLangText!.uiJumpMotion, - curLangText!.uiLandingMotion, - curLangText!.uiDashMotion, - curLangText!.uiRunMotion, - curLangText!.uiStandbyMotion, - curLangText!.uiSwimMotion -]; -String dropDownSelectedMotionType = motionTypes.first; class ItemsSwapperEmotesHomePage extends StatefulWidget { const ItemsSwapperEmotesHomePage({super.key}); @@ -82,6 +71,22 @@ class _ItemsSwapperEmotesHomePageState extends State //create Directory(modManSwapperOutputDirPath).createSync(recursive: true); + if (isEmotesToStandbyMotions) { + availableEmotesCsvData = availableEmotesCsvData.where((element) => element.subCategory == 'Standby Motion').toList(); + } + List motionTypeNames = [ + curLangText!.uiAll, + curLangText!.uiGlideMotion, + curLangText!.uiJumpMotion, + curLangText!.uiLandingMotion, + curLangText!.uiDashMotion, + curLangText!.uiRunMotion, + curLangText!.uiStandbyMotion, + curLangText!.uiSwimMotion + ]; + List motionTypes = ['All', 'Glide Motion', 'Jump Motion', 'Landing Motion', 'Dash Motion', 'Run Motion', 'Standby Motion', 'Swim Motion']; + String dropDownSelectedMotionType = motionTypeNames.first; + //fetch if (!isEmotesToStandbyMotions || fromItemCsvData.isEmpty) { // fromItemCsvData = csvEmotesData @@ -96,7 +101,7 @@ class _ItemsSwapperEmotesHomePageState extends State // element.rbHumanHashIceName.isNotEmpty || // element.rbVfxHashIceName.isNotEmpty)) // .toList(); - if (dropDownSelectedMotionType == motionTypes.first || selectedMotionType.isEmpty) { + if (motionTypes[motionTypeNames.indexOf(dropDownSelectedMotionType)] == motionTypes.first || selectedMotionType.isEmpty) { fromItemCsvData = csvEmotesData .where((element) => // element.jpName.isNotEmpty && @@ -114,7 +119,7 @@ class _ItemsSwapperEmotesHomePageState extends State .where((element) => // element.jpName.isNotEmpty && // element.enName.isNotEmpty && - element.subCategory == dropDownSelectedMotionType && + element.subCategory == motionTypes[motionTypeNames.indexOf(dropDownSelectedMotionType)] && (element.pso2HashIceName.isNotEmpty || element.pso2VfxHashIceName.isNotEmpty || element.rbCastFemaleHashIceName.isNotEmpty || @@ -170,10 +175,6 @@ class _ItemsSwapperEmotesHomePageState extends State // availableEmotesCsvData = availableEmotesCsvData.where((element) => element.pso2VfxHashIceName.isNotEmpty).toList(); // } - if (isEmotesToStandbyMotions) { - availableEmotesCsvData = availableEmotesCsvData.where((element) => element.subCategory == 'Standby Motion').toList(); - } - return Scaffold( backgroundColor: Colors.transparent, body: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { @@ -308,7 +309,7 @@ class _ItemsSwapperEmotesHomePageState extends State padding: EdgeInsets.symmetric(horizontal: 5), ), isDense: true, - items: motionTypes + items: motionTypeNames .map((item) => DropdownMenuItem( value: item, child: Row( @@ -336,10 +337,11 @@ class _ItemsSwapperEmotesHomePageState extends State dropDownSelectedMotionType = value.toString(); selectedFromEmotesCsvFile = null; fromItemCsvData.clear(); - if (dropDownSelectedMotionType == motionTypes.first) { + if (motionTypes[motionTypeNames.indexOf(dropDownSelectedMotionType)] == motionTypes.first) { availableEmotesCsvData = csvEmotesData.where((element) => element.jpName.isNotEmpty && element.enName.isNotEmpty).toList(); } else { - availableEmotesCsvData = csvEmotesData.where((element) => element.subCategory == dropDownSelectedMotionType).toList(); + availableEmotesCsvData = + csvEmotesData.where((element) => element.subCategory == motionTypes[motionTypeNames.indexOf(dropDownSelectedMotionType)]).toList(); } if (modManCurActiveItemNameLanguage == 'JP') { availableEmotesCsvData.sort((a, b) => a.jpName.compareTo(b.jpName)); @@ -502,10 +504,19 @@ class _ItemsSwapperEmotesHomePageState extends State title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text(modManCurActiveItemNameLanguage == 'JP' ? queueToEmoteCsvFiles[i].jpName : queueToEmoteCsvFiles[i].enName), + Text(queueToEmoteCsvFiles[i].gender, + style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)), + ], + ), + const Icon(Icons.arrow_forward_ios), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(queueFromEmoteCsvFiles[i].enName), + Text(modManCurActiveItemNameLanguage == 'JP' ? queueFromEmoteCsvFiles[i].jpName : queueFromEmoteCsvFiles[i].enName), Text(queueFromEmoteCsvFiles[i].gender, style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)), @@ -514,18 +525,9 @@ class _ItemsSwapperEmotesHomePageState extends State // line++) // Text(csvInfos.firstWhere((element) => queueFromEmoteCsvFiles[i].getDetailedList().contains(element.first))[line].split(': ').last, // style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)) - for (int line = 0; line < queueFromEmotesAvailableIces[i].length; line++) - Text(queueFromEmotesAvailableIces[i][line].split(': ').last, - style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)) - ], - ), - const Icon(Icons.arrow_forward_ios), - Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text(queueToEmoteCsvFiles[i].enName), - Text(queueToEmoteCsvFiles[i].gender, - style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)), + // for (int line = 0; line < queueFromEmotesAvailableIces[i].length; line++) + // Text(queueFromEmotesAvailableIces[i][line].split(': ').last, + // style: TextStyle(fontSize: Theme.of(context).textTheme.bodyMedium!.fontSize, color: Theme.of(context).hintColor)) ], ), ], @@ -779,7 +781,7 @@ class _ItemsSwapperEmotesHomePageState extends State ), ), ], - )) + )), ], ), ), @@ -809,7 +811,7 @@ class _ItemsSwapperEmotesHomePageState extends State queueFromEmoteCsvFiles.clear(); queueToEmoteCsvFiles.clear(); isEmotesToStandbyMotions = false; - dropDownSelectedMotionType = motionTypes.first; + dropDownSelectedMotionType = motionTypeNames.first; toIEmotesSearchResults.clear(); fromItemSearchResults.clear(); Navigator.pop(context); @@ -929,7 +931,7 @@ Future swapperLaConfirmDialog(context, SubMod fromSubmod, List fro ), ), ), - ) + ), ], ), ], @@ -943,7 +945,7 @@ Future swapperLaConfirmDialog(context, SubMod fromSubmod, List fro ElevatedButton( onPressed: () { Navigator.pop(context); - msls.swapperLaSwappingDialog(context, true, fromSubmod, toItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); + msls.swapperLaSwappingDialog(context, true, fromItemModGet(), fromSubmod, toItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); }, child: Text(curLangText!.uiSwap)) ]); @@ -987,7 +989,7 @@ Future swapperLaQueueConfirmDialog( Expanded( flex: 1, child: Text( - queueFromEmoteCsvFiles[i].enName, + modManCurActiveItemNameLanguage == 'JP' ? queueFromEmoteCsvFiles[i].jpName : queueFromEmoteCsvFiles[i].enName, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), )), const SizedBox( @@ -996,7 +998,7 @@ Future swapperLaQueueConfirmDialog( Expanded( flex: 1, child: Text( - queueToEmoteCsvFiles[i].enName, + modManCurActiveItemNameLanguage == 'JP' ? queueToEmoteCsvFiles[i].jpName : queueToEmoteCsvFiles[i].enName, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), )), ], @@ -1054,7 +1056,7 @@ Future swapperLaQueueConfirmDialog( ), ), ), - ) + ), ], ), ], @@ -1123,7 +1125,8 @@ Future swapperLaQueueConfirmDialog( for (int i = 0; i < queueFromEmotesAvailableIceList.length; i++) { fromEmotesAvailableIces = queueFromEmotesAvailableIceList[i].toList(); toEmotesAvailableIces = queueToEmotesAvailableIceList[i].toList(); - await msls.swapperLaQueueSwappingDialog(context, true, fromSubmod, queueToItemNameList[i], fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); + await msls.swapperLaQueueSwappingDialog( + context, true, fromItemModGet(), fromSubmod, queueToItemNameList[i], fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); setState( () {}, ); diff --git a/lib/modsAdder/mods_adder_homepage.dart b/lib/modsAdder/mods_adder_homepage.dart index 019d6ec..c919e8a 100644 --- a/lib/modsAdder/mods_adder_homepage.dart +++ b/lib/modsAdder/mods_adder_homepage.dart @@ -1869,8 +1869,8 @@ Future> modsAdderFilesProcess(context, List xFilePath // List pathsWithNoIceInRoot = []; //copy files to temp for (var xFile in xFilePaths) { - String tempModDirName = p.basenameWithoutExtension(xFile.path); - if (Directory(modManAddModsTempDirPath).existsSync() && Directory(modManAddModsTempDirPath).listSync().where((element) => p.basenameWithoutExtension(element.path) == tempModDirName).isNotEmpty) { + String tempModDirName = p.basename(xFile.path); + if (Directory(modManAddModsTempDirPath).existsSync() && Directory(modManAddModsTempDirPath).listSync().where((element) => p.basename(element.path) == tempModDirName).isNotEmpty) { DateTime now = DateTime.now(); String formattedDate = DateFormat('MM-dd-yyyy-kk-mm-ss').format(now); tempModDirName += '_$formattedDate'; diff --git a/lib/modsSwapper/mods_swapper_acc_homepage.dart b/lib/modsSwapper/mods_swapper_acc_homepage.dart index 4d362a2..06d7b29 100644 --- a/lib/modsSwapper/mods_swapper_acc_homepage.dart +++ b/lib/modsSwapper/mods_swapper_acc_homepage.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; import 'package:pso2_mod_manager/loaders/language_loader.dart'; @@ -27,9 +28,10 @@ String fromItemIconLink = ''; String toItemIconLink = ''; class ModsSwapperAccHomePage extends StatefulWidget { - const ModsSwapperAccHomePage({super.key, required this.fromItem, required this.fromSubmod}); + const ModsSwapperAccHomePage({super.key, required this.fromItem, required this.fromMod, required this.fromSubmod}); final Item fromItem; + final Mod fromMod; final SubMod fromSubmod; @override @@ -238,8 +240,7 @@ class _ModsSwapperAccHomePageState extends State { } } //confirm icon set - fromItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + fromItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -538,7 +539,7 @@ class _ModsSwapperAccHomePageState extends State { ? null : () { if (selectedFromAccCsvFile != null && selectedToAccCsvFile != null) { - swapperConfirmDialog(context, widget.fromSubmod, fromAccItemId, fromAccItemAvailableIces, toAccItemId, toAccItemAvailableIces); + swapperConfirmDialog(context, widget.fromMod, widget.fromSubmod, fromAccItemId, fromAccItemAvailableIces, toAccItemId, toAccItemAvailableIces); } }, child: Text(curLangText!.uiNext)) @@ -556,7 +557,7 @@ class _ModsSwapperAccHomePageState extends State { } } -Future swapperConfirmDialog(context, SubMod fromSubmod, String fromAccItemId, List fromAccItemAvailableIces, String toAccItemId, List toAccItemAvailableIces) async { +Future swapperConfirmDialog(context, Mod fromMod, SubMod fromSubmod, String fromAccItemId, List fromAccItemAvailableIces, String toAccItemId, List toAccItemAvailableIces) async { await showDialog( barrierDismissible: false, context: context, @@ -683,7 +684,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, String fromAccItem ElevatedButton( onPressed: () { Navigator.pop(context); - swapperAccSwappingDialog(context, false, fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName); + swapperAccSwappingDialog(context, false, fromMod, fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName); }, child: Text(curLangText!.uiSwap)) ]); diff --git a/lib/modsSwapper/mods_swapper_acc_swappage.dart b/lib/modsSwapper/mods_swapper_acc_swappage.dart index da94d7d..66617b7 100644 --- a/lib/modsSwapper/mods_swapper_acc_swappage.dart +++ b/lib/modsSwapper/mods_swapper_acc_swappage.dart @@ -4,6 +4,7 @@ import 'package:cross_file/cross_file.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/filesDownloader/ice_files_download.dart'; import 'package:pso2_mod_manager/functions/og_ice_paths_fetcher.dart'; @@ -17,7 +18,7 @@ import 'package:path/path.dart' as p; import 'package:pso2_mod_manager/state_provider.dart'; import 'package:url_launcher/url_launcher.dart'; -Future modsSwapperAccIceFilesGet(context, bool isVanillaItemSwap, SubMod fromSubmod, List fromAccItemAvailableIces, List toAccItemAvailableIces, String toItemName) async { +Future modsSwapperAccIceFilesGet(context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, List fromAccItemAvailableIces, List toAccItemAvailableIces, String toItemName) async { //clean if (Directory(modManSwapperOutputDirPath).existsSync()) { Directory(modManSwapperOutputDirPath).deleteSync(recursive: true); @@ -324,6 +325,20 @@ Future modsSwapperAccIceFilesGet(context, bool isVanillaItemSwap, SubMod if (File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).existsSync()) { File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).renameSync(Uri.file('$packDirPath/$iceNameT').toFilePath()); } + //mod previews + //image + for (var imagePath in fromMod.previewImages) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { + File(imagePath).copySync(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(imagePath)}').toFilePath()); + } + } + //video + for (var videoPath in fromMod.previewVideos) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()).listSync().whereType().where((element) => p.basename(element.path) == p.basename(videoPath)).isEmpty) { + File(videoPath).copySync(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(videoPath)}').toFilePath()); + } + } + //submod previews //image for (var imagePath in fromSubmod.previewImages) { if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { @@ -336,12 +351,29 @@ Future modsSwapperAccIceFilesGet(context, bool isVanillaItemSwap, SubMod File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); } } + //modfile previews + //image + for (var imagePaths in fromSubmod.modFiles.map((e) => e.previewImages!).toList()) { + for (var imagePath in imagePaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { + File(imagePath).copySync(Uri.file('$packDirPath/${p.basename(imagePath)}').toFilePath()); + } + } + } + //video + for (var videoPaths in fromSubmod.modFiles.map((e) => e.previewVideos!).toList()) { + for (var videoPath in videoPaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(videoPath)).isEmpty) { + File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); + } + } + } } return Uri.file('$modManSwapperOutputDirPath/$toItemName').toFilePath(); } -Future swapperAccSwappingDialog(context, bool isVanillaItemSwap, SubMod fromSubmod, List fromAccItemAvailableIces, List toAccItemAvailableIces, String toItemName) async { +Future swapperAccSwappingDialog(context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, List fromAccItemAvailableIces, List toAccItemAvailableIces, String toItemName) async { String swappedModPath = ''; await showDialog( barrierDismissible: false, @@ -352,7 +384,7 @@ Future swapperAccSwappingDialog(context, bool isVanillaItemSwap, SubMod fr backgroundColor: Color(context.watch().uiBackgroundColorValue).withOpacity(0.8), contentPadding: const EdgeInsets.all(16), content: FutureBuilder( - future: swappedModPath.isEmpty ? modsSwapperAccIceFilesGet(context, isVanillaItemSwap, fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName) : null, + future: swappedModPath.isEmpty ? modsSwapperAccIceFilesGet(context, isVanillaItemSwap, fromMod, fromSubmod, fromAccItemAvailableIces, toAccItemAvailableIces, toItemName) : null, builder: ( BuildContext context, AsyncSnapshot snapshot, @@ -499,7 +531,8 @@ Future swapperAccSwappingDialog(context, bool isVanillaItemSwap, SubMod fr ), ), ), - ) + ), + ], ) : ScrollbarTheme( diff --git a/lib/modsSwapper/mods_swapper_data_loader.dart b/lib/modsSwapper/mods_swapper_data_loader.dart index 60c05f8..df97778 100644 --- a/lib/modsSwapper/mods_swapper_data_loader.dart +++ b/lib/modsSwapper/mods_swapper_data_loader.dart @@ -4,6 +4,7 @@ import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; import 'package:pso2_mod_manager/classes/csv_item_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/functions/player_item_data.dart'; import 'package:pso2_mod_manager/global_variables.dart'; @@ -121,9 +122,10 @@ Future> getWeaponsSwapToCsvList(List cv } class ModsSwapperDataLoader extends StatefulWidget { - const ModsSwapperDataLoader({super.key, required this.fromItem, required this.fromSubmod}); + const ModsSwapperDataLoader({super.key, required this.fromItem, required this.fromMod, required this.fromSubmod}); final Item fromItem; + final Mod fromMod; final SubMod fromSubmod; @override @@ -131,7 +133,6 @@ class ModsSwapperDataLoader extends StatefulWidget { } class _ModsSwapperDataLoaderState extends State { - @override Widget build(BuildContext context) { return FutureBuilder( @@ -292,6 +293,7 @@ class _ModsSwapperDataLoaderState extends State { } return ModsSwapperAccHomePage( fromItem: widget.fromItem, + fromMod: widget.fromMod, fromSubmod: widget.fromSubmod, ); } else if (csvEmotesData.isNotEmpty) { @@ -307,6 +309,7 @@ class _ModsSwapperDataLoaderState extends State { } return ModsSwapperEmotesHomePage( fromItem: widget.fromItem, + fromMod: widget.fromMod, fromSubmod: widget.fromSubmod, ); } else if (csvWeaponsData.isNotEmpty) { @@ -337,6 +340,7 @@ class _ModsSwapperDataLoaderState extends State { } return ModsSwapperHomePage( fromItem: widget.fromItem, + fromMod: widget.fromMod, fromSubmod: widget.fromSubmod, ); } diff --git a/lib/modsSwapper/mods_swapper_homepage.dart b/lib/modsSwapper/mods_swapper_homepage.dart index a9e5995..1594b16 100644 --- a/lib/modsSwapper/mods_swapper_homepage.dart +++ b/lib/modsSwapper/mods_swapper_homepage.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; import 'package:pso2_mod_manager/loaders/language_loader.dart'; @@ -29,9 +30,10 @@ String fromItemIconLink = ''; String toItemIconLink = ''; class ModsSwapperHomePage extends StatefulWidget { - const ModsSwapperHomePage({super.key, required this.fromItem, required this.fromSubmod}); + const ModsSwapperHomePage({super.key, required this.fromItem, required this.fromMod, required this.fromSubmod}); final Item fromItem; + final Mod fromMod; final SubMod fromSubmod; @override @@ -235,26 +237,26 @@ class _ModsSwapperHomePageState extends State { groupValue: selectedFromCsvFile, title: Row(children: [ if (fromItemCsvData.length > 1) - Padding( - padding: const EdgeInsets.only(top: 2, bottom: 2, right: 10), - child: Container( - width: 80, - height: 80, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - border: Border.all(color: Theme.of(context).hintColor, width: 1), - ), - child: Image.network( - '$modManMAIconDatabaseLink${fromItemCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', - errorBuilder: (context, error, stackTrace) => Image.asset( - 'assets/img/placeholdersquare.png', + Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2, right: 10), + child: Container( + width: 80, + height: 80, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + border: Border.all(color: Theme.of(context).hintColor, width: 1), + ), + child: Image.network( + '$modManMAIconDatabaseLink${fromItemCsvData[i].iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}', + errorBuilder: (context, error, stackTrace) => Image.asset( + 'assets/img/placeholdersquare.png', + filterQuality: FilterQuality.none, + fit: BoxFit.fitWidth, + ), filterQuality: FilterQuality.none, fit: BoxFit.fitWidth, - ), - filterQuality: FilterQuality.none, - fit: BoxFit.fitWidth, - )), - ), + )), + ), Text(modManCurActiveItemNameLanguage == 'JP' ? fromItemCsvData[i].jpName : fromItemCsvData[i].enName) ]), subtitle: Column( @@ -279,8 +281,7 @@ class _ModsSwapperHomePageState extends State { } //confirm icon set - fromItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + fromItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -538,8 +539,7 @@ class _ModsSwapperHomePageState extends State { } } //confirm icon set - toItemIconLink = - '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; + toItemIconLink = '$modManMAIconDatabaseLink${currentItem.iconImageWebPath.replaceAll('\\', '/').replaceAll(' ', '%20')}'; setState( () {}, @@ -595,7 +595,7 @@ class _ModsSwapperHomePageState extends State { selectedFromCsvFile!.category == 'Innerwears' && selectedToCsvFile!.category == 'Body Paints' ? isInnerwearToBodyPaint = true : isInnerwearToBodyPaint = false; - swapperConfirmDialog(context, widget.fromSubmod, fromItemIds, fromItemAvailableIces, toItemIds, toItemAvailableIces); + swapperConfirmDialog(context, widget.fromMod, widget.fromSubmod, fromItemIds, fromItemAvailableIces, toItemIds, toItemAvailableIces); } }, child: Text(curLangText!.uiNext)) @@ -613,7 +613,8 @@ class _ModsSwapperHomePageState extends State { } } -Future swapperConfirmDialog(context, SubMod fromSubmod, List fromItemIds, List fromItemAvailableIces, List toItemIds, List toItemAvailableIces) async { +Future swapperConfirmDialog( + context, Mod fromMod, SubMod fromSubmod, List fromItemIds, List fromItemAvailableIces, List toItemIds, List toItemAvailableIces) async { await showDialog( barrierDismissible: false, context: context, @@ -748,7 +749,7 @@ Future swapperConfirmDialog(context, SubMod fromSubmod, List fromI ElevatedButton( onPressed: () { Navigator.pop(context); - swapperSwappingDialog(context, false, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemIds[0], toItemIds[0]); + swapperSwappingDialog(context, false, fromMod, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemIds[0], toItemIds[0]); }, child: Text(curLangText!.uiSwap)) ]); diff --git a/lib/modsSwapper/mods_swapper_la_homepage.dart b/lib/modsSwapper/mods_swapper_la_homepage.dart index 9e1530c..b498cd1 100644 --- a/lib/modsSwapper/mods_swapper_la_homepage.dart +++ b/lib/modsSwapper/mods_swapper_la_homepage.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/csv_ice_file_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; import 'package:pso2_mod_manager/loaders/language_loader.dart'; @@ -37,9 +38,10 @@ List queueSwappedLaPaths = []; List queueToItemNames = []; class ModsSwapperEmotesHomePage extends StatefulWidget { - const ModsSwapperEmotesHomePage({super.key, required this.fromItem, required this.fromSubmod}); + const ModsSwapperEmotesHomePage({super.key, required this.fromItem, required this.fromMod, required this.fromSubmod}); final Item fromItem; + final Mod fromMod; final SubMod fromSubmod; @override @@ -666,10 +668,10 @@ class _ModsSwapperEmotesHomePageState extends State { : () async { if (queueFromEmoteCsvFiles.isEmpty) { if (selectedFromEmotesCsvFile != null && selectedToEmotesCsvFile != null) { - swapperLaConfirmDialog(context, widget.fromSubmod, fromEmotesAvailableIces, toEmotesAvailableIces, toItemName); + swapperLaConfirmDialog(context, widget.fromMod, widget.fromSubmod, fromEmotesAvailableIces, toEmotesAvailableIces, toItemName); } } else { - await swapperLaQueueConfirmDialog(context, widget.fromSubmod, queueFromEmotesAvailableIces, queueToEmotesAvailableIces, queueToItemNames); + await swapperLaQueueConfirmDialog(context, widget.fromMod, widget.fromSubmod, queueFromEmotesAvailableIces, queueToEmotesAvailableIces, queueToItemNames); setState(() {}); } }, @@ -688,7 +690,7 @@ class _ModsSwapperEmotesHomePageState extends State { } } -Future swapperLaConfirmDialog(context, SubMod fromSubmod, List fromEmotesAvailableIces, List toEmotesAvailableIces, String toSelectedItemName) async { +Future swapperLaConfirmDialog(context, Mod fromMod, SubMod fromSubmod, List fromEmotesAvailableIces, List toEmotesAvailableIces, String toSelectedItemName) async { await showDialog( barrierDismissible: false, context: context, @@ -768,7 +770,7 @@ Future swapperLaConfirmDialog(context, SubMod fromSubmod, List fro ElevatedButton( onPressed: () { Navigator.pop(context); - swapperLaSwappingDialog(context, false, fromSubmod, toItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); + swapperLaSwappingDialog(context, false, fromMod, fromSubmod, toItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); }, child: Text(curLangText!.uiSwap)) ]); @@ -776,7 +778,7 @@ Future swapperLaConfirmDialog(context, SubMod fromSubmod, List fro } Future swapperLaQueueConfirmDialog( - context, SubMod fromSubmod, List> queueFromEmotesAvailableIceList, List> queueToEmotesAvailableIceList, List queueToItemNameList) async { + context, Mod fromMod, SubMod fromSubmod, List> queueFromEmotesAvailableIceList, List> queueToEmotesAvailableIceList, List queueToItemNameList) async { await showDialog( barrierDismissible: false, context: context, @@ -948,7 +950,7 @@ Future swapperLaQueueConfirmDialog( for (int i = 0; i < queueFromEmotesAvailableIceList.length; i++) { fromEmotesAvailableIces = queueFromEmotesAvailableIceList[i].toList(); toEmotesAvailableIces = queueToEmotesAvailableIceList[i].toList(); - await swapperLaQueueSwappingDialog(context, false, fromSubmod, queueToItemNameList[i], fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); + await swapperLaQueueSwappingDialog(context, false, fromMod, fromSubmod, queueToItemNameList[i], fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths); setState( () {}, ); diff --git a/lib/modsSwapper/mods_swapper_la_swappage.dart b/lib/modsSwapper/mods_swapper_la_swappage.dart index 44cb556..b64091f 100644 --- a/lib/modsSwapper/mods_swapper_la_swappage.dart +++ b/lib/modsSwapper/mods_swapper_la_swappage.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/filesDownloader/ice_files_download.dart'; import 'package:pso2_mod_manager/functions/og_ice_paths_fetcher.dart'; @@ -18,8 +19,8 @@ import 'package:url_launcher/url_launcher.dart'; final validCharacters = RegExp(r'^[a-zA-Z0-9]+$'); -Future modsSwapperLaIceFilesGet( - context, bool isVanillaItemSwap, SubMod fromSubmod, String toSelectedItemName, List fromEmotesAvailableIces, List toEmotesAvailableIces, List queueSwappedLaPaths) async { +Future modsSwapperLaIceFilesGet(context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, String toSelectedItemName, List fromEmotesAvailableIces, + List toEmotesAvailableIces, List queueSwappedLaPaths) async { String newToSelectedItemName = toSelectedItemName; //clean if (Directory(modManSwapperOutputDirPath).existsSync() && queueSwappedLaPaths.isEmpty) { @@ -96,11 +97,19 @@ Future modsSwapperLaIceFilesGet( await Process.run('$modManZamboniExePath -outdir "$tempSubmodPathF"', [iceFileInTempF.path]); String extractedGroup1PathF = Uri.file('$tempSubmodPathF/${iceNameF}_ext/group1').toFilePath(); if (Directory(extractedGroup1PathF).existsSync()) { - extractedGroup1FilesF = Directory(extractedGroup1PathF).listSync(recursive: true).whereType().where((element) => validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)).toList(); + extractedGroup1FilesF = Directory(extractedGroup1PathF) + .listSync(recursive: true) + .whereType() + .where((element) => validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)) + .toList(); } String extractedGroup2PathF = Uri.file('$tempSubmodPathF/${iceNameF}_ext/group2').toFilePath(); if (Directory(extractedGroup2PathF).existsSync()) { - extractedGroup2FilesF = Directory(extractedGroup2PathF).listSync(recursive: true).whereType().where((element) => validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)).toList(); + extractedGroup2FilesF = Directory(extractedGroup2PathF) + .listSync(recursive: true) + .whereType() + .where((element) => validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)) + .toList(); } } @@ -210,7 +219,11 @@ Future modsSwapperLaIceFilesGet( //bti in group 1 human hash String rebootHumanHashGroup1PathF = Uri.file('$tempSubmodPathF/${rebootHumanHashIceNameF}_ext/group1').toFilePath(); if (Directory(rebootHumanHashGroup1PathF).existsSync()) { - List rebootHumanGroup1Bti = Directory(rebootHumanHashGroup1PathF).listSync().whereType().where((element) => p.extension(element.path) == '.bti' && validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)).toList(); + List rebootHumanGroup1Bti = Directory(rebootHumanHashGroup1PathF) + .listSync() + .whereType() + .where((element) => p.extension(element.path) == '.bti' && validCharacters.hasMatch(p.basenameWithoutExtension(element.path).split('_').first)) + .toList(); //get new name for bti from aqm String rebootHumanHashGroup2PathF = Uri.file('$tempSubmodPathF/${rebootHumanHashIceNameF}_ext/group2').toFilePath(); @@ -281,6 +294,28 @@ Future modsSwapperLaIceFilesGet( if (File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).existsSync()) { File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).renameSync(Uri.file('$packDirPath/$iceNameT').toFilePath()); } + //mod previews + //image + for (var imagePath in fromMod.previewImages) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$newToSelectedItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()) + .listSync() + .whereType() + .where((element) => p.basename(element.path) == p.basename(imagePath)) + .isEmpty) { + File(imagePath).copySync(Uri.file('$modManSwapperOutputDirPath/$newToSelectedItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(imagePath)}').toFilePath()); + } + } + //video + for (var videoPath in fromMod.previewVideos) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$newToSelectedItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()) + .listSync() + .whereType() + .where((element) => p.basename(element.path) == p.basename(videoPath)) + .isEmpty) { + File(videoPath).copySync(Uri.file('$modManSwapperOutputDirPath/$newToSelectedItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(videoPath)}').toFilePath()); + } + } + //submod previews //image for (var imagePath in fromSubmod.previewImages) { if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { @@ -293,12 +328,30 @@ Future modsSwapperLaIceFilesGet( File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); } } + //modfile previews + //image + for (var imagePaths in fromSubmod.modFiles.map((e) => e.previewImages!).toList()) { + for (var imagePath in imagePaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { + File(imagePath).copySync(Uri.file('$packDirPath/${p.basename(imagePath)}').toFilePath()); + } + } + } + //video + for (var videoPaths in fromSubmod.modFiles.map((e) => e.previewVideos!).toList()) { + for (var videoPath in videoPaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(videoPath)).isEmpty) { + File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); + } + } + } } return Uri.file('$modManSwapperOutputDirPath/$newToSelectedItemName').toFilePath(); } -Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fromSubmod, String toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) async { +Future swapperLaSwappingDialog( + context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, String toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) async { String swappedModPath = ''; await showDialog( barrierDismissible: false, @@ -310,7 +363,7 @@ Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fro contentPadding: const EdgeInsets.all(16), content: FutureBuilder( future: swappedModPath.isEmpty - ? modsSwapperLaIceFilesGet(context, isVanillaItemSwap, fromSubmod, toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) + ? modsSwapperLaIceFilesGet(context, isVanillaItemSwap, fromMod, fromSubmod, toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) : null, builder: ( BuildContext context, @@ -421,7 +474,7 @@ Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fro mainAxisSize: MainAxisSize.min, children: [ Text( - fromSubmod.itemName, + toSelectedItemName, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold), ), Text('${fromSubmod.modName} > ${fromSubmod.submodName}'), @@ -450,7 +503,7 @@ Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fro mainAxisSize: MainAxisSize.min, children: [ Text( - toSelectedItemName, + fromSubmod.itemName, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold), ), Text('${fromSubmod.modName} > ${fromSubmod.submodName}'), @@ -458,7 +511,7 @@ Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fro ), ), ), - ) + ), ], ) : ScrollbarTheme( @@ -544,7 +597,8 @@ Future swapperLaSwappingDialog(context, bool isVanillaItemSwap, SubMod fro })); } -Future swapperLaQueueSwappingDialog(context, bool isVanillaItemSwap, SubMod fromSubmod, String toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) async { +Future swapperLaQueueSwappingDialog( + context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, String toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths) async { //String swappedModPath = ''; await showDialog( barrierDismissible: false, @@ -555,7 +609,7 @@ Future swapperLaQueueSwappingDialog(context, bool isVanillaItemSwap, SubMo backgroundColor: Color(context.watch().uiBackgroundColorValue).withOpacity(0.8), contentPadding: const EdgeInsets.all(16), content: FutureBuilder( - future: modsSwapperLaIceFilesGet(context, isVanillaItemSwap, fromSubmod, toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths), + future: modsSwapperLaIceFilesGet(context, isVanillaItemSwap, fromMod, fromSubmod, toSelectedItemName, fromEmotesAvailableIces, toEmotesAvailableIces, queueSwappedLaPaths), builder: ( BuildContext context, AsyncSnapshot snapshot, diff --git a/lib/modsSwapper/mods_swapper_popup.dart b/lib/modsSwapper/mods_swapper_popup.dart index 693f46c..a44d67d 100644 --- a/lib/modsSwapper/mods_swapper_popup.dart +++ b/lib/modsSwapper/mods_swapper_popup.dart @@ -2,6 +2,7 @@ import 'package:card_banner/card_banner.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/global_variables.dart'; import 'package:pso2_mod_manager/loaders/language_loader.dart'; @@ -11,7 +12,7 @@ import 'package:pso2_mod_manager/state_provider.dart'; String toItemName = ''; String fromItemCategory = ''; -void modsSwapperDialog(context, Item fromItem, SubMod fromSubmod) { +void modsSwapperDialog(context, Item fromItem, Mod fromMod, SubMod fromSubmod) { availableAccCsvData.clear(); availableEmotesCsvData.clear(); availableItemsCsvData.clear(); @@ -36,7 +37,7 @@ void modsSwapperDialog(context, Item fromItem, SubMod fromSubmod) { position: CardBannerPosition.TOPRIGHT, padding: 2, edgeSize: 0, - child: SizedBox(width: MediaQuery.of(context).size.width * 0.8, height: MediaQuery.of(context).size.height, child: ModsSwapperDataLoader(fromItem: fromItem, fromSubmod: fromSubmod)), + child: SizedBox(width: MediaQuery.of(context).size.width * 0.8, height: MediaQuery.of(context).size.height, child: ModsSwapperDataLoader(fromItem: fromItem, fromMod: fromMod, fromSubmod: fromSubmod)), )); }); } diff --git a/lib/modsSwapper/mods_swapper_swappage.dart b/lib/modsSwapper/mods_swapper_swappage.dart index 0d19e02..c66f6f8 100644 --- a/lib/modsSwapper/mods_swapper_swappage.dart +++ b/lib/modsSwapper/mods_swapper_swappage.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:cross_file/cross_file.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:pso2_mod_manager/classes/mod_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/filesDownloader/ice_files_download.dart'; import 'package:pso2_mod_manager/functions/og_ice_paths_fetcher.dart'; @@ -17,8 +18,8 @@ import 'package:path/path.dart' as p; import 'package:pso2_mod_manager/state_provider.dart'; import 'package:url_launcher/url_launcher.dart'; -Future modsSwapperIceFilesGet( - context, bool isVanillaItemSwap, SubMod fromSubmod, List fromItemAvailableIces, List toItemAvailableIces, String toItemName, String fromItemId, String toItemId) async { +Future modsSwapperIceFilesGet(context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, List fromItemAvailableIces, List toItemAvailableIces, String toItemName, + String fromItemId, String toItemId) async { //clean if (Directory(modManSwapperOutputDirPath).existsSync()) { Directory(modManSwapperOutputDirPath).deleteSync(recursive: true); @@ -182,6 +183,28 @@ Future modsSwapperIceFilesGet( if (File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).existsSync()) { await File(Uri.file('$tempSubmodPathF/${iceNameF}_ext.ice').toFilePath()).rename(Uri.file('$packDirPath/$iceNameT').toFilePath()); } + //mod previews + //image + for (var imagePath in fromMod.previewImages) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()) + .listSync() + .whereType() + .where((element) => p.basename(element.path) == p.basename(imagePath)) + .isEmpty) { + File(imagePath).copySync(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(imagePath)}').toFilePath()); + } + } + //video + for (var videoPath in fromMod.previewVideos) { + if (Directory(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}').toFilePath()) + .listSync() + .whereType() + .where((element) => p.basename(element.path) == p.basename(videoPath)) + .isEmpty) { + File(videoPath).copySync(Uri.file('$modManSwapperOutputDirPath/$toItemName/${fromSubmod.modName.replaceAll(RegExp(charToReplace), '_')}/${p.basename(videoPath)}').toFilePath()); + } + } + //submod previews //image for (var imagePath in fromSubmod.previewImages) { if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { @@ -194,6 +217,23 @@ Future modsSwapperIceFilesGet( File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); } } + //modfile previews + //image + for (var imagePaths in fromSubmod.modFiles.map((e) => e.previewImages!).toList()) { + for (var imagePath in imagePaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(imagePath)).isEmpty) { + File(imagePath).copySync(Uri.file('$packDirPath/${p.basename(imagePath)}').toFilePath()); + } + } + } + //video + for (var videoPaths in fromSubmod.modFiles.map((e) => e.previewVideos!).toList()) { + for (var videoPath in videoPaths) { + if (Directory(packDirPath).listSync().whereType().where((element) => p.basename(element.path) == p.basename(videoPath)).isEmpty) { + File(videoPath).copySync(Uri.file('$packDirPath/${p.basename(videoPath)}').toFilePath()); + } + } + } //cmx if (fromSubmod.hasCmx! && fromSubmod.cmxFile!.isNotEmpty && File(fromSubmod.cmxFile!).existsSync()) { File cmxFileF = File(fromSubmod.cmxFile!); @@ -210,8 +250,8 @@ Future modsSwapperIceFilesGet( return Uri.file('$modManSwapperOutputDirPath/$toItemName').toFilePath(); } -Future swapperSwappingDialog( - context, bool isVanillaItemSwap, SubMod fromSubmod, List fromItemAvailableIces, List toItemAvailableIces, String toItemName, String fromItemId, String toItemId) async { +Future swapperSwappingDialog(context, bool isVanillaItemSwap, Mod fromMod, SubMod fromSubmod, List fromItemAvailableIces, List toItemAvailableIces, String toItemName, + String fromItemId, String toItemId) async { String swappedModPath = ''; await showDialog( barrierDismissible: false, @@ -222,8 +262,9 @@ Future swapperSwappingDialog( backgroundColor: Color(context.watch().uiBackgroundColorValue).withOpacity(0.8), contentPadding: const EdgeInsets.all(16), content: FutureBuilder( - future: - swappedModPath.isEmpty ? modsSwapperIceFilesGet(context, isVanillaItemSwap, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemId, toItemId) : null, + future: swappedModPath.isEmpty + ? modsSwapperIceFilesGet(context, isVanillaItemSwap, fromMod, fromSubmod, fromItemAvailableIces, toItemAvailableIces, toItemName, fromItemId, toItemId) + : null, builder: ( BuildContext context, AsyncSnapshot snapshot, @@ -371,7 +412,7 @@ Future swapperSwappingDialog( ), ), ), - ) + ), ], ) : ScrollbarTheme( diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 2645e19..5aa2e83 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -2453,7 +2453,7 @@ class _HomePageState extends State { return RoundedRectangleBorder( side: BorderSide(color: Theme.of(context).primaryColorLight), borderRadius: const BorderRadius.all(Radius.circular(2))); })), - menuChildren: quickApplyMenuButtons(context, curMod.submods.first)), + menuChildren: quickApplyMenuButtons(context, curMod, curMod.submods.first)), ), //More menu @@ -2697,7 +2697,7 @@ class _HomePageState extends State { if (!defaultCategoryDirs.contains(modViewItem!.category)) { fromItemCategory = await modsSwapperCategorySelect(context); } - modsSwapperDialog(context, modViewItem!, curMod.submods.first); + modsSwapperDialog(context, modViewItem!, curMod, curMod.submods.first); }, ), @@ -3058,7 +3058,7 @@ class _HomePageState extends State { return RoundedRectangleBorder( side: BorderSide(color: Theme.of(context).primaryColorLight), borderRadius: const BorderRadius.all(Radius.circular(2))); })), - menuChildren: quickApplyMenuButtons(context, curMod.submods[modViewModSetSubModIndex])), + menuChildren: quickApplyMenuButtons(context, curMod, curMod.submods[modViewModSetSubModIndex])), ), //More menu @@ -3287,7 +3287,7 @@ class _HomePageState extends State { if (!defaultCategoryDirs.contains(modViewItem!.category)) { fromItemCategory = await modsSwapperCategorySelect(context); } - modsSwapperDialog(context, modViewItem!, curMod.submods[modViewModSetSubModIndex]); + modsSwapperDialog(context, modViewItem!, curMod, curMod.submods[modViewModSetSubModIndex]); }, ), @@ -3762,7 +3762,7 @@ class _HomePageState extends State { return RoundedRectangleBorder( side: BorderSide(color: Theme.of(context).primaryColorLight), borderRadius: const BorderRadius.all(Radius.circular(2))); })), - menuChildren: quickApplyMenuButtons(context, curSubmod)), + menuChildren: quickApplyMenuButtons(context, curMod, curSubmod)), ), //More menu @@ -3996,7 +3996,7 @@ class _HomePageState extends State { if (!defaultCategoryDirs.contains(modViewItem!.category)) { fromItemCategory = await modsSwapperCategorySelect(context); } - modsSwapperDialog(context, modViewItem!, curSubmod); + modsSwapperDialog(context, modViewItem!, curMod, curSubmod); }, ), @@ -6240,7 +6240,7 @@ class _HomePageState extends State { } //WIDGETS============================================================================= - List quickApplyMenuButtons(context, SubMod submod) { + List quickApplyMenuButtons(context, Mod mod, SubMod submod) { List menuButtonList = []; List quickApplyItems = quickApplyItemList.where((e) => e.category == submod.category || (e.category == defaultCategoryDirs[1] && submod.category == defaultCategoryDirs[16])).toList(); //add popup @@ -6318,7 +6318,7 @@ class _HomePageState extends State { } String swappedPath = await modsSwapperAccIceFilesGet( - context, false, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName()); + context, false, mod, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName()); //adding var returnedVar = await modsAdderModFilesAdder( context, @@ -6351,7 +6351,7 @@ class _HomePageState extends State { String toItemId = toItem.id.toString(); String swappedPath = await modsSwapperIceFilesGet( - context, false, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName(), fromItemId, toItemId); + context, false, mod, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName(), fromItemId, toItemId); //adding var returnedVar = await modsAdderModFilesAdder( context, diff --git a/lib/swapAll/swap_all_apply_homepage.dart b/lib/swapAll/swap_all_apply_homepage.dart index e924dca..300ab9d 100644 --- a/lib/swapAll/swap_all_apply_homepage.dart +++ b/lib/swapAll/swap_all_apply_homepage.dart @@ -679,7 +679,7 @@ class _AqmInjectionHomePageState extends State { submodsToSwap.add(swapFromSubmods[i]); } } - await swapAllPopup(context, submodsToSwap, swapToItemList); + await swapAllPopup(context, widget.swapItem!.mods, submodsToSwap, swapToItemList); setState(() { isLoading = false; isAllButtonPressed = false; @@ -717,7 +717,7 @@ class _AqmInjectionHomePageState extends State { } } -Future swapAllPopup(context, List submods, List swapToItems) async { +Future swapAllPopup(context, List mods, List submods, List swapToItems) async { List totalSwapped = List.generate(swapToItems.length, (index) => 0); bool isSwapped = false; bool isSwapping = false; @@ -731,7 +731,7 @@ Future swapAllPopup(context, List submods, List swapToIte isSwapping = true; for (var item in swapToItems) { for (var submod in submods) { - SubMod? swappedSub = await swapAll(context, submod, item); + SubMod? swappedSub = await swapAll(context, mods.firstWhere((e) => e.modName == submod.modName && submod.location.contains(e.location)), submod, item); if (swappedSub != null) totalSwapped[swapToItems.indexOf(item)]++; swappedSub = null; setState( @@ -770,13 +770,15 @@ Future swapAllPopup(context, List submods, List swapToIte ), Visibility( visible: isSwapped, - child: const Padding( - padding: EdgeInsets.only(top: 20), - child: SizedBox(width: 25, height: 25) - ), + child: const Padding(padding: EdgeInsets.only(top: 20), child: SizedBox(width: 25, height: 25)), ), - Padding(padding: const EdgeInsets.symmetric(vertical: 10), child: Text(!isSwapped || isSwapping ? curLangText!.uiProcessing : isSwapped && !isSwapping ? curLangText!.uiAllDone : '')), - + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Text(!isSwapped || isSwapping + ? curLangText!.uiProcessing + : isSwapped && !isSwapping + ? curLangText!.uiAllDone + : '')), SizedBox( height: (50 * double.parse(swapToItems.length.toString())) + 8, width: 400, @@ -815,6 +817,7 @@ Future swapAllPopup(context, List submods, List swapToIte ? () { clearAllTempDirs(); isSwapped = false; + totalSwapped = []; Navigator.pop(context, true); } : null, @@ -839,7 +842,7 @@ Future> getAvailableItems(String category) async { .toList(); } -Future swapAll(context, SubMod submod, CsvItem swapToItem) async { +Future swapAll(context, Mod mod, SubMod submod, CsvItem swapToItem) async { bool found = false; Item? swapItem; Mod? swapMod; @@ -886,7 +889,8 @@ Future swapAll(context, SubMod submod, CsvItem swapToItem) async { } } - String swappedPath = await modsSwapperAccIceFilesGet(context, false, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName()); + String swappedPath = + await modsSwapperAccIceFilesGet(context, false, mod, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName()); //adding if (Directory(swappedPath).existsSync()) { var returnedVar = await modsAdderModFilesAdder( @@ -921,17 +925,21 @@ Future swapAll(context, SubMod submod, CsvItem swapToItem) async { String toItemId = toItem.id.toString(); String swappedPath = await modsSwapperIceFilesGet( - context, false, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName(), fromItemId, toItemId); + context, false, mod, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName(), fromItemId, toItemId); //adding if (Directory(swappedPath).existsSync()) { - var returnedVar = await modsAdderModFilesAdder( - context, - await modsAdderFilesProcess(context, [XFile(Uri.file('$swappedPath/${submod.modName.replaceAll(RegExp(charToReplaceWithoutSeparators), '_')}').toFilePath())], - modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName())); - List returnedItems = returnedVar.$2; - swapItem = returnedItems.first; - swapMod = swapItem.mods.firstWhere((e) => e.modName == submod.modName); - swapSubmod = swapMod.submods.firstWhere((e) => e.submodName == submod.submodName); + try { + var returnedVar = await modsAdderModFilesAdder( + context, + await modsAdderFilesProcess(context, [XFile(Uri.file('$swappedPath/${submod.modName.replaceAll(RegExp(charToReplaceWithoutSeparators), '_')}').toFilePath())], + modManCurActiveItemNameLanguage == 'JP' ? swapToItem.getJPName() : swapToItem.getENName())); + List returnedItems = returnedVar.$2; + swapItem = returnedItems.first; + swapMod = swapItem.mods.firstWhere((e) => e.modName == submod.modName); + swapSubmod = swapMod.submods.firstWhere((e) => e.submodName == submod.submodName); + } catch (e) { + return swapSubmod; + } } } } diff --git a/lib/ui_translation_helper.dart b/lib/ui_translation_helper.dart index cb8090e..285f2ce 100644 --- a/lib/ui_translation_helper.dart +++ b/lib/ui_translation_helper.dart @@ -1,5 +1,4 @@ import 'package:pso2_mod_manager/global_variables.dart'; -import 'package:pso2_mod_manager/itemsSwapper/items_swapper_la_homepage.dart'; import 'package:pso2_mod_manager/loaders/language_loader.dart'; import 'package:pso2_mod_manager/modsSwapper/mods_swapper_wp_homepage.dart'; @@ -64,16 +63,16 @@ void widgetsLanguageRefresh() { curLangText!.uiUnknownWeapons ]; - motionTypes = [ - curLangText!.uiAll, - curLangText!.uiGlideMotion, - curLangText!.uiJumpMotion, - curLangText!.uiLandingMotion, - curLangText!.uiDashMotion, - curLangText!.uiRunMotion, - curLangText!.uiStandbyMotion, - curLangText!.uiSwimMotion -]; +// motionTypes = [ +// curLangText!.uiAll, +// curLangText!.uiGlideMotion, +// curLangText!.uiJumpMotion, +// curLangText!.uiLandingMotion, +// curLangText!.uiDashMotion, +// curLangText!.uiRunMotion, +// curLangText!.uiStandbyMotion, +// curLangText!.uiSwimMotion +// ]; itemTypes = [curLangText!.uiAll, curLangText!.uiPSO2, curLangText!.uiNGS]; From c64a59c281fd73c70d4b1464c31740f1aca0a252 Mon Sep 17 00:00:00 2001 From: KizKizz Date: Sat, 3 Aug 2024 01:19:09 -0700 Subject: [PATCH 2/4] prep --- Language/LanguageSettings.json | 2 +- lib/pages/home_page.dart | 197 +- lib/pages/main_page.dart | 3293 +++++++++++----------- lib/sharing/mod_import_add_function.dart | 181 +- 4 files changed, 1900 insertions(+), 1773 deletions(-) diff --git a/Language/LanguageSettings.json b/Language/LanguageSettings.json index daf5aad..fc1cd15 100644 --- a/Language/LanguageSettings.json +++ b/Language/LanguageSettings.json @@ -17,4 +17,4 @@ "langFilePath": "E:\\Flutter project\\pso2_mod_manager\\Language\\JP.json", "selected": false } -] +] \ No newline at end of file diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 5aa2e83..519d44b 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -1767,18 +1767,55 @@ class _HomePageState extends State { ), //set if (modViewItem != null && context.watch().setsWindowVisible && !isFavListVisible && searchTextController.value.text.isEmpty && !isModViewFromApplied) - Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).primaryColorLight), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - ), - child: Text( - modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length < 2 - ? '${modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length} ${curLangText!.uiMod}' - : '${modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length} ${curLangText!.uiMods}', - style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), - ), + Wrap( + spacing: 2.5, + runSpacing: 2.5, + children: [ + Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + ), + child: Text( + modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length < 2 + ? '${modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length} ${curLangText!.uiMod}' + : '${modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName)).length} ${curLangText!.uiMods}', + style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), + ), + ), + // export + InkWell( + onTap: () async { + List submodsToExport = []; + for (var mod in modViewItem!.mods.where((element) => element.isSet && element.setNames.contains(selectedModSetName))) { + submodsToExport.addAll(mod.submods.where((element) => element.isSet && element.setNames.contains(selectedModSetName))); + } + await modExportHomePage(context, moddedItemsList, submodsToExport, false); + }, + child: Container( + height: 22, + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + ), + child: Row(mainAxisSize: MainAxisSize.min, children: [ + Padding( + padding: const EdgeInsets.only(right: 5), + child: Icon( + Icons.import_export, + color: Theme.of(context).buttonTheme.colorScheme!.primary, + size: 18, + ), + ), + Text( + curLangText!.uiExportAllMods, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).buttonTheme.colorScheme!.primary), + ) + ])), + ), + ], ), //Applied text @@ -5690,59 +5727,80 @@ class _HomePageState extends State { isModViewModsApplying = true; setState(() {}); Future.delayed(Duration(milliseconds: applyButtonsDelay), () async { - List allAppliedModFiles = []; - for (var item in curSet.setItems.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var mod in item.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var submod in mod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - allAppliedModFiles.addAll(submod.modFiles.where((element) => !element.applyStatus)); - } - } - } + // List allAppliedModFiles = []; + // for (var item in curSet.setItems.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var mod in item.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var submod in mod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // allAppliedModFiles.addAll(submod.modFiles.where((element) => !element.applyStatus)); + // } + // } + // } //apply mod files - if (await originalFilesCheck(context, allAppliedModFiles)) { - modFilesApply(context, allAppliedModFiles).then((value) async { - if (value.indexWhere((element) => element.applyStatus) != -1) { - for (var curItem in curSet.setItems) { - for (var curMod in curItem.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var curSubmod in curMod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - curSubmod.applyStatus = true; - curSubmod.isNew = false; - curSubmod.applyDate = DateTime.now(); - if (autoAqmInject) await aqmInjectionOnModsApply(context, curSubmod); - } - curMod.applyStatus = true; - curMod.isNew = false; - curMod.applyDate = DateTime.now(); - } - curItem.applyDate = DateTime.now(); - curItem.applyStatus = true; - if (curItem.mods.where((element) => element.isNew).isEmpty) { - curItem.isNew = false; - } - if (Provider.of(context, listen: false).markModdedItem) await applyOverlayedIcon(context, curItem); - Provider.of(context, listen: false).quickApplyStateSet('extra'); - } - List appliedModFiles = value; - String fileAppliedText = ''; + // if (await originalFilesCheck(context, allAppliedModFiles)) { + // modFilesApply(context, allAppliedModFiles).then((value) async { + // if (value.indexWhere((element) => element.applyStatus) != -1) { + // for (var curItem in curSet.setItems) { + // for (var curMod in curItem.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var curSubmod in curMod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // curSubmod.applyStatus = true; + // curSubmod.isNew = false; + // curSubmod.applyDate = DateTime.now(); + // if (autoAqmInject) await aqmInjectionOnModsApply(context, curSubmod); + // } + // curMod.applyStatus = true; + // curMod.isNew = false; + // curMod.applyDate = DateTime.now(); + // } + // curItem.applyDate = DateTime.now(); + // curItem.applyStatus = true; + // if (curItem.mods.where((element) => element.isNew).isEmpty) { + // curItem.isNew = false; + // } + // if (Provider.of(context, listen: false).markModdedItem) await applyOverlayedIcon(context, curItem); + // Provider.of(context, listen: false).quickApplyStateSet('extra'); + // } - for (var element in appliedModFiles.where((e) => e.applyStatus)) { - if (fileAppliedText.isEmpty) { - fileAppliedText = uiInTextArg(curLangText!.uiSuccessfullyAppliedX, curSet.setName); - } - if (!fileAppliedText.contains('${element.itemName} > ${element.modName} > ${element.submodName}\n')) { - fileAppliedText += '${element.itemName} > ${element.modName} > ${element.submodName}\n'; + for (var item in curSet.setItems) { + for (var mod in item.mods) { + for (var submod in mod.submods) { + //apply mod files + if (await originalFilesCheck(context, submod.modFiles)) { + //apply auto radius removal if on + if (removeBoundaryRadiusOnModsApply) await removeBoundaryOnModsApply(context, submod); + if (autoAqmInject) await aqmInjectionOnModsApply(context, submod); + + await applyModsToTheGame(context, item, mod, submod); + + if (Provider.of(context, listen: false).markModdedItem) { + await applyOverlayedIcon(context, item); } + Provider.of(context, listen: false).quickApplyStateSet('extra'); } - ScaffoldMessenger.of(context) - .showSnackBar(snackBarMessage(context, '${curLangText!.uiSuccess}!', fileAppliedText.trim(), appliedModFiles.length * 1000)); } - isModViewModsApplying = false; - saveModdedItemListToJson(); - setState(() {}); - }); + } } + + // List appliedModFiles = value; + // String fileAppliedText = ''; + + // for (var element in appliedModFiles.where((e) => e.applyStatus)) { + // if (fileAppliedText.isEmpty) { + // fileAppliedText = uiInTextArg(curLangText!.uiSuccessfullyAppliedX, curSet.setName); + // } + // if (!fileAppliedText.contains('${element.itemName} > ${element.modName} > ${element.submodName}\n')) { + // fileAppliedText += '${element.itemName} > ${element.modName} > ${element.submodName}\n'; + // } + // } + // ScaffoldMessenger.of(context) + // .showSnackBar(snackBarMessage(context, '${curLangText!.uiSuccess}!', fileAppliedText.trim(), appliedModFiles.length * 1000)); + // } + isModViewModsApplying = false; + saveModdedItemListToJson(); setState(() {}); + // }); + // } + // setState(() {}); }); }, child: const Icon( @@ -5754,6 +5812,27 @@ class _HomePageState extends State { ], ), + //Export All + ModManTooltip( + message: curLangText!.uiExportAllMods, + child: InkWell( + onTap: () async { + List submodsToExport = []; + for (var item in curSet.setItems) { + for (var mod in item.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + submodsToExport.addAll(mod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))); + } + } + await modExportHomePage(context, moddedItemsList, submodsToExport, false); + }, + child: const Icon( + Icons.import_export, + size: 26, + //color: curSet.setItems.where((element) => element.applyStatus).isNotEmpty ? Theme.of(context).disabledColor : null, + ), + ), + ), + //Rename ModManTooltip( message: curLangText!.uiRenameThisSet, @@ -6350,8 +6429,8 @@ class _HomePageState extends State { } String toItemId = toItem.id.toString(); - String swappedPath = await modsSwapperIceFilesGet( - context, false, mod, submod, fromItemIces, toItemIces, modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName(), fromItemId, toItemId); + String swappedPath = await modsSwapperIceFilesGet(context, false, mod, submod, fromItemIces, toItemIces, + modManCurActiveItemNameLanguage == 'JP' ? quickApplyItem.getJPName() : quickApplyItem.getENName(), fromItemId, toItemId); //adding var returnedVar = await modsAdderModFilesAdder( context, diff --git a/lib/pages/main_page.dart b/lib/pages/main_page.dart index 28ebe23..d95935a 100644 --- a/lib/pages/main_page.dart +++ b/lib/pages/main_page.dart @@ -88,1833 +88,1833 @@ class _MainPageState extends State { return Scaffold( key: mainPageScaffoldKey, endDrawer: Drawer( - width: 310, + width: 310, child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - //Title - Padding( - padding: const EdgeInsets.only(left: 5, top: 5, bottom: 5), - child: Text( - curLangText!.uiSettings, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, - ), - ), - ), - const Divider( - height: 1, - thickness: 1, - //color: Theme.of(context).textTheme.headlineMedium?.color, - ), - Expanded( - child: ScrollbarTheme( - data: ScrollbarThemeData( - thumbColor: WidgetStateProperty.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return Theme.of(context).textTheme.displaySmall?.color?.withOpacity(0.7); - } - return Theme.of(context).textTheme.displaySmall?.color?.withOpacity(0.5); - }), + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //Title + Padding( + padding: const EdgeInsets.only(left: 5, top: 5, bottom: 5), + child: Text( + curLangText!.uiSettings, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, + ), ), - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.all(5), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - //Language - InkWell( - onLongPress: () { - showDialog( - context: context, - builder: (ctx) => AlertDialog( - title: Text(curLangText!.uiAddANewLanguage), - content: SizedBox( - height: 110, - width: 300, - child: Column( - children: [ - Text(curLangText!.uiNewLanguageInititalInput), - Padding( - padding: const EdgeInsets.all(8.0), - child: SizedBox( - height: 50, - width: 60, - child: TextFormField( - inputFormatters: [UpperCaseTextFormatter()], - controller: newLangTextController, - maxLines: 1, - maxLength: 2, - style: const TextStyle(fontSize: 15), - decoration: const InputDecoration( - contentPadding: EdgeInsets.only(left: 10, top: 10), - //hintText: '', - border: OutlineInputBorder(), - //isDense: true, + ), + const Divider( + height: 1, + thickness: 1, + //color: Theme.of(context).textTheme.headlineMedium?.color, + ), + Expanded( + child: ScrollbarTheme( + data: ScrollbarThemeData( + thumbColor: WidgetStateProperty.resolveWith((states) { + if (states.contains(WidgetState.hovered)) { + return Theme.of(context).textTheme.displaySmall?.color?.withOpacity(0.7); + } + return Theme.of(context).textTheme.displaySmall?.color?.withOpacity(0.5); + }), + ), + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(5), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + //Language + InkWell( + onLongPress: () { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + title: Text(curLangText!.uiAddANewLanguage), + content: SizedBox( + height: 110, + width: 300, + child: Column( + children: [ + Text(curLangText!.uiNewLanguageInititalInput), + Padding( + padding: const EdgeInsets.all(8.0), + child: SizedBox( + height: 50, + width: 60, + child: TextFormField( + inputFormatters: [UpperCaseTextFormatter()], + controller: newLangTextController, + maxLines: 1, + maxLength: 2, + style: const TextStyle(fontSize: 15), + decoration: const InputDecoration( + contentPadding: EdgeInsets.only(left: 10, top: 10), + //hintText: '', + border: OutlineInputBorder(), + //isDense: true, + ), + validator: (value) { + if (value == null || value.isEmpty) { + return curLangText!.uiNewLanguageInitialEmptyError; + } + if (langDropDownList.indexWhere((e) => e == value) != -1) { + return curLangText!.uiNewLanguageInititalAlreadyExisted; + } + return null; + }, + onChanged: (text) { + setState(() { + setState( + () {}, + ); + }); + }, + ), ), - validator: (value) { - if (value == null || value.isEmpty) { - return curLangText!.uiNewLanguageInitialEmptyError; - } - if (langDropDownList.indexWhere((e) => e == value) != -1) { - return curLangText!.uiNewLanguageInititalAlreadyExisted; - } - return null; - }, - onChanged: (text) { - setState(() { - setState( - () {}, - ); - }); - }, ), - ), + ], + ), + ), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.of(ctx).pop(); + }, + child: Text(curLangText!.uiCancel), + ), + ElevatedButton( + onPressed: () async { + const JsonEncoder encoder = JsonEncoder.withIndent(' '); + String newLangPath = Uri.file('$modManLanguageDirPath/${newLangTextController.text.toUpperCase()}.json').toFilePath(); + TranslationText? newText = curLangText; + if (!File(newLangPath).existsSync()) { + await File(newLangPath).create(recursive: true); + } + TranslationLanguage newLang = TranslationLanguage(newLangTextController.text.toUpperCase(), 1, newLangPath, false); + languageList.add(newLang); + languageList.sort(((a, b) => a.langInitial.compareTo(b.langInitial))); + langDropDownList.add(newLangTextController.text.toUpperCase()); + newLangTextController.clear(); + //Json Write to language file + File(newLangPath).writeAsStringSync(encoder.convert(newText)); + //Json Write to settings + languageList.map((lang) => lang.toJson()).toList(); + File(modManLanguageSettingsJsonPath).writeAsStringSync(encoder.convert(languageList)); + setState(() {}); + Navigator.of(ctx).pop(); + }, + child: Text(curLangText!.uiAdd), ), ], ), + ); + }, + child: DropdownButtonHideUnderline( + child: DropdownButton2( + customButton: AbsorbPointer( + absorbing: true, + child: MaterialButton( + onPressed: (() {}), + child: Row( + children: [ + const Icon( + Icons.language, + size: 18, + ), + const SizedBox( + width: 10, + ), + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '${curLangText!.uiCurrentLanguage}: $langDropDownSelected', + style: const TextStyle(fontWeight: FontWeight.normal), + ), + const Icon(Icons.arrow_drop_down) + ], + ), + ), + ], + ), + ), ), - actions: [ - ElevatedButton( - onPressed: () { - Navigator.of(ctx).pop(); - }, - child: Text(curLangText!.uiCancel), + buttonStyleData: ButtonStyleData( + height: 40, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), ), - ElevatedButton( - onPressed: () async { - const JsonEncoder encoder = JsonEncoder.withIndent(' '); - String newLangPath = Uri.file('$modManLanguageDirPath/${newLangTextController.text.toUpperCase()}.json').toFilePath(); - TranslationText? newText = curLangText; - if (!File(newLangPath).existsSync()) { - await File(newLangPath).create(recursive: true); - } - TranslationLanguage newLang = TranslationLanguage(newLangTextController.text.toUpperCase(), 1, newLangPath, false); - languageList.add(newLang); - languageList.sort(((a, b) => a.langInitial.compareTo(b.langInitial))); - langDropDownList.add(newLangTextController.text.toUpperCase()); - newLangTextController.clear(); - //Json Write to language file - File(newLangPath).writeAsStringSync(encoder.convert(newText)); - //Json Write to settings - languageList.map((lang) => lang.toJson()).toList(); - File(modManLanguageSettingsJsonPath).writeAsStringSync(encoder.convert(languageList)); - setState(() {}); - Navigator.of(ctx).pop(); - }, - child: Text(curLangText!.uiAdd), + ), + dropdownStyleData: DropdownStyleData( + elevation: 3, + padding: const EdgeInsets.symmetric(vertical: 2), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).cardColor : Theme.of(context).primaryColor, + ), + ), + iconStyleData: const IconStyleData(iconSize: 15), + menuItemStyleData: const MenuItemStyleData( + height: 20, + padding: EdgeInsets.symmetric(horizontal: 5), + ), + isDense: true, + items: langDropDownList + .map((item) => DropdownMenuItem( + value: item, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + padding: const EdgeInsets.only(bottom: 3), + child: Text( + item, + style: const TextStyle( + //fontSize: 14, + //fontWeight: FontWeight.bold, + //color: Colors.white, + ), + overflow: TextOverflow.ellipsis, + ), + ) + ], + ))) + .toList(), + value: langDropDownSelected, + onChanged: (value) async { + langDropDownSelected = value.toString(); + for (var lang in languageList) { + if (lang.langInitial == value) { + lang.selected = true; + curActiveLang = lang.langInitial; + final prefs = await SharedPreferences.getInstance(); + prefs.setString('curActiveLanguage', curActiveLang); + var jsonData = jsonDecode(File(lang.langFilePath).readAsStringSync()); + curLangText = TranslationText.fromJson(jsonData); + //refresh widgets language + widgetsLanguageRefresh(); + } else { + lang.selected = false; + } + } + + //Json Write + const JsonEncoder encoder = JsonEncoder.withIndent(' '); + languageList.map((lang) => lang.toJson()).toList(); + File(modManLanguageSettingsJsonPath).writeAsStringSync(encoder.convert(languageList)); + Provider.of(context, listen: false).reloadSplashScreenTrue(); + Provider.of(context, listen: false).languageReloadTrue(); + setState(() {}); + await Future.delayed(const Duration(seconds: 2)); + Provider.of(context, listen: false).reloadSplashScreenFalse(); + Provider.of(context, listen: false).languageReloadFalse(); + setState(() {}); + }, + )), + ), + const SizedBox( + height: 5, + ), + + //Item Name Language + Padding( + padding: const EdgeInsets.only(top: 5, left: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon( + Icons.language, + size: 18, + ), + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiItemNameLanguage}:'), + ], ), + Padding( + padding: const EdgeInsets.only(top: 5, left: 22, bottom: 5), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiItemNameLanguageTooltip, + child: MaterialButton( + minWidth: 120, + height: 30, + //color: Theme.of(context).primaryColorDark, + onPressed: modManCurActiveItemNameLanguage == 'EN' + ? null + : () async { + final prefs = await SharedPreferences.getInstance(); + modManCurActiveItemNameLanguage = 'EN'; + prefs.setString('modManCurActiveItemNameLanguage', modManCurActiveItemNameLanguage); + setState(() {}); + }, + shape: RoundedRectangleBorder( + side: BorderSide( + color: modManCurActiveItemNameLanguage == 'EN' + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor), + borderRadius: const BorderRadius.all(Radius.circular(2))), + child: Text('EN', + style: TextStyle( + color: modManCurActiveItemNameLanguage == 'EN' + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor)), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 5, top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiItemNameLanguageTooltip, + child: MaterialButton( + minWidth: 120, + height: 30, + //color: Theme.of(context).primaryColorDark, + onPressed: modManCurActiveItemNameLanguage == 'JP' + ? null + : () async { + final prefs = await SharedPreferences.getInstance(); + modManCurActiveItemNameLanguage = 'JP'; + prefs.setString('modManCurActiveItemNameLanguage', modManCurActiveItemNameLanguage); + setState(() {}); + }, + shape: RoundedRectangleBorder( + side: BorderSide( + color: modManCurActiveItemNameLanguage == 'JP' + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor), + borderRadius: const BorderRadius.all(Radius.circular(2))), + child: Text('JP', + style: TextStyle( + color: modManCurActiveItemNameLanguage == 'JP' + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor)), + ), + ), + ), + ], + )), + ], + ), + ), + + //profiles select + Padding( + padding: const EdgeInsets.only(top: 5, left: 8), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon( + Icons.filter_1_rounded, + size: 18, + ), + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiProfiles}:'), + ], + ), + Padding( + padding: const EdgeInsets.only(top: 5, left: 22, bottom: 5), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiClickToChangeToThisProfileHoldToRename, + child: MaterialButton( + minWidth: 120, + height: 30, + //color: Theme.of(context).primaryColorDark, + onPressed: modManCurActiveProfile == 1 + ? null + : () async { + modSetList.clear(); + Navigator.pop(context); + final prefs = await SharedPreferences.getInstance(); + modManCurActiveProfile = 1; + prefs.setInt('modManCurActiveProfile', modManCurActiveProfile); + Provider.of(context, listen: false).reloadProfileTrue(); + modViewItem = null; + ogModFilesReset(); + Future.delayed(const Duration(milliseconds: 500), () { + setState(() {}); + // profileLoader(context).then((value) { + Provider.of(context, listen: false).setProfileName(modManProfile1Name); + Provider.of(context, listen: false).reloadProfileFalse(); + // }); + }); + + //setState(() {}); + }, + onLongPress: () async { + String newName = await newProfileNameDialog(context); + if (newName.isNotEmpty) { + final prefs = await SharedPreferences.getInstance(); + prefs.setString('modManProfile1Name', newName); + modManProfile1Name = newName; + Provider.of(context, listen: false).setProfileName(modManProfile1Name); + setState(() {}); + } + }, + shape: RoundedRectangleBorder( + side: BorderSide( + color: modManCurActiveProfile == 1 + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor), + borderRadius: const BorderRadius.all(Radius.circular(2))), + child: Text(modManProfile1Name, + style: TextStyle( + color: modManCurActiveProfile == 1 + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor)), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 5, top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiClickToChangeToThisProfileHoldToRename, + child: MaterialButton( + minWidth: 120, + height: 30, + //color: Theme.of(context).primaryColorDark, + onPressed: modManCurActiveProfile == 2 + ? null + : () async { + modSetList.clear(); + Navigator.pop(context); + final prefs = await SharedPreferences.getInstance(); + modManCurActiveProfile = 2; + prefs.setInt('modManCurActiveProfile', modManCurActiveProfile); + Provider.of(context, listen: false).reloadProfileTrue(); + modViewItem = null; + ogModFilesReset(); + Future.delayed(const Duration(milliseconds: 500), () { + setState(() {}); + // profileLoader(context).then((value) { + Provider.of(context, listen: false).setProfileName(modManProfile2Name); + Provider.of(context, listen: false).reloadProfileFalse(); + // }); + }); + + //setState(() {}); + }, + onLongPress: () async { + String newName = await newProfileNameDialog(context); + if (newName.isNotEmpty) { + final prefs = await SharedPreferences.getInstance(); + prefs.setString('modManProfile2Name', newName); + modManProfile2Name = newName; + Provider.of(context, listen: false).setProfileName(modManProfile2Name); + setState(() {}); + } + }, + shape: RoundedRectangleBorder( + side: BorderSide( + color: modManCurActiveProfile == 2 + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor), + borderRadius: const BorderRadius.all(Radius.circular(2))), + child: Text(modManProfile2Name, + style: TextStyle( + color: modManCurActiveProfile == 2 + ? MyApp.themeNotifier.value == ThemeMode.light + ? Color(lightModePrimarySwatch.value) + : Color(darkModePrimarySwatch.value) + : Theme.of(context).hintColor)), + ), + ), + ), + ], + )), ], ), - ); - }, - child: DropdownButtonHideUnderline( - child: DropdownButton2( - customButton: AbsorbPointer( - absorbing: true, + ), + + //JP start anticheat select + Visibility( + visible: context.watch().gameEdition == 'jp', child: MaterialButton( - onPressed: (() {}), + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (gameguardAnticheat) { + gameguardAnticheat = false; + prefs.setBool('gameguardAnticheat', false); + } else { + gameguardAnticheat = true; + prefs.setBool('gameguardAnticheat', true); + } + setState(() {}); + }), child: Row( children: [ const Icon( - Icons.language, + Icons.shield_outlined, size: 18, ), - const SizedBox( - width: 10, - ), - Expanded( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '${curLangText!.uiCurrentLanguage}: $langDropDownSelected', - style: const TextStyle(fontWeight: FontWeight.normal), - ), - const Icon(Icons.arrow_drop_down) - ], - ), + const SizedBox(width: 10), + Text( + gameguardAnticheat ? '${curLangText!.uiAntiCheatSelect}: ${curLangText!.uiGameguard}' : '${curLangText!.uiAntiCheatSelect}: ${curLangText!.uiWellbia}', + style: const TextStyle(fontWeight: FontWeight.normal), ), ], ), ), ), - buttonStyleData: ButtonStyleData( - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - ), + const SizedBox( + height: 5, ), - dropdownStyleData: DropdownStyleData( - elevation: 3, - padding: const EdgeInsets.symmetric(vertical: 2), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).cardColor : Theme.of(context).primaryColor, + + //backup mod settings + MaterialButton( + height: 40, + onPressed: (() async { + await jsonManualBackup(); + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.save, + size: 18, + ), + const SizedBox(width: 10), + Text( + '${curLangText!.uiBackupModSettings} - ${curLangText!.uiBackups}: ${Directory(modManJsonManualSaveDir).listSync().whereType().where((element) => p.extension(element.path) == '.zip').length}', + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), ), - iconStyleData: const IconStyleData(iconSize: 15), - menuItemStyleData: const MenuItemStyleData( - height: 20, - padding: EdgeInsets.symmetric(horizontal: 5), + const SizedBox( + height: 5, ), - isDense: true, - items: langDropDownList - .map((item) => DropdownMenuItem( - value: item, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: const EdgeInsets.only(bottom: 3), - child: Text( - item, - style: const TextStyle( - //fontSize: 14, - //fontWeight: FontWeight.bold, - //color: Colors.white, - ), - overflow: TextOverflow.ellipsis, - ), - ) - ], - ))) - .toList(), - value: langDropDownSelected, - onChanged: (value) async { - langDropDownSelected = value.toString(); - for (var lang in languageList) { - if (lang.langInitial == value) { - lang.selected = true; - curActiveLang = lang.langInitial; - final prefs = await SharedPreferences.getInstance(); - prefs.setString('curActiveLanguage', curActiveLang); - var jsonData = jsonDecode(File(lang.langFilePath).readAsStringSync()); - curLangText = TranslationText.fromJson(jsonData); - //refresh widgets language - widgetsLanguageRefresh(); - } else { - lang.selected = false; - } - } - - //Json Write - const JsonEncoder encoder = JsonEncoder.withIndent(' '); - languageList.map((lang) => lang.toJson()).toList(); - File(modManLanguageSettingsJsonPath).writeAsStringSync(encoder.convert(languageList)); - Provider.of(context, listen: false).reloadSplashScreenTrue(); - Provider.of(context, listen: false).languageReloadTrue(); - setState(() {}); - await Future.delayed(const Duration(seconds: 2)); - Provider.of(context, listen: false).reloadSplashScreenFalse(); - Provider.of(context, listen: false).languageReloadFalse(); - setState(() {}); - }, - )), - ), - const SizedBox( - height: 5, - ), - //Item Name Language - Padding( - padding: const EdgeInsets.only(top: 5, left: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + //Path reselect + MaterialButton( + height: 40, + onPressed: (() async { + await pso2PathsReloader(context); + }), + child: Row( children: [ const Icon( - Icons.language, + Icons.folder_copy_outlined, size: 18, ), - const SizedBox( - width: 10, + const SizedBox(width: 10), + Text( + curLangText!.uiReselectPso2binPath, + style: const TextStyle(fontWeight: FontWeight.normal), ), - Text('${curLangText!.uiItemNameLanguage}:'), ], ), - Padding( - padding: const EdgeInsets.only(top: 5, left: 22, bottom: 5), - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiItemNameLanguageTooltip, - child: MaterialButton( - minWidth: 120, - height: 30, - //color: Theme.of(context).primaryColorDark, - onPressed: modManCurActiveItemNameLanguage == 'EN' - ? null - : () async { - final prefs = await SharedPreferences.getInstance(); - modManCurActiveItemNameLanguage = 'EN'; - prefs.setString('modManCurActiveItemNameLanguage', modManCurActiveItemNameLanguage); - setState(() {}); - }, - shape: RoundedRectangleBorder( - side: BorderSide( - color: modManCurActiveItemNameLanguage == 'EN' - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor), - borderRadius: const BorderRadius.all(Radius.circular(2))), - child: Text('EN', - style: TextStyle( - color: modManCurActiveItemNameLanguage == 'EN' - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor)), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 5, top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiItemNameLanguageTooltip, - child: MaterialButton( - minWidth: 120, - height: 30, - //color: Theme.of(context).primaryColorDark, - onPressed: modManCurActiveItemNameLanguage == 'JP' - ? null - : () async { - final prefs = await SharedPreferences.getInstance(); - modManCurActiveItemNameLanguage = 'JP'; - prefs.setString('modManCurActiveItemNameLanguage', modManCurActiveItemNameLanguage); - setState(() {}); - }, - shape: RoundedRectangleBorder( - side: BorderSide( - color: modManCurActiveItemNameLanguage == 'JP' - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor), - borderRadius: const BorderRadius.all(Radius.circular(2))), - child: Text('JP', - style: TextStyle( - color: modManCurActiveItemNameLanguage == 'JP' - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor)), - ), - ), - ), - ], - )), - ], - ), - ), + ), + const SizedBox( + height: 5, + ), - //profiles select - Padding( - padding: const EdgeInsets.only(top: 5, left: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + //MM Path reselect + MaterialButton( + height: 40, + onPressed: (() async { + await modManPathReloader(context); + }), + child: Row( children: [ const Icon( - Icons.filter_1_rounded, + Icons.folder_copy_outlined, size: 18, ), - const SizedBox( - width: 10, - ), - Text('${curLangText!.uiProfiles}:'), + const SizedBox(width: 10), + Text(curLangText!.uiReselectModManFolderPath, style: const TextStyle(fontWeight: FontWeight.normal)), ], ), - Padding( - padding: const EdgeInsets.only(top: 5, left: 22, bottom: 5), - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiClickToChangeToThisProfileHoldToRename, - child: MaterialButton( - minWidth: 120, - height: 30, - //color: Theme.of(context).primaryColorDark, - onPressed: modManCurActiveProfile == 1 - ? null - : () async { - modSetList.clear(); - Navigator.pop(context); - final prefs = await SharedPreferences.getInstance(); - modManCurActiveProfile = 1; - prefs.setInt('modManCurActiveProfile', modManCurActiveProfile); - Provider.of(context, listen: false).reloadProfileTrue(); - modViewItem = null; - ogModFilesReset(); - Future.delayed(const Duration(milliseconds: 500), () { - setState(() {}); - // profileLoader(context).then((value) { - Provider.of(context, listen: false).setProfileName(modManProfile1Name); - Provider.of(context, listen: false).reloadProfileFalse(); - // }); - }); - - //setState(() {}); - }, - onLongPress: () async { - String newName = await newProfileNameDialog(context); - if (newName.isNotEmpty) { - final prefs = await SharedPreferences.getInstance(); - prefs.setString('modManProfile1Name', newName); - modManProfile1Name = newName; - Provider.of(context, listen: false).setProfileName(modManProfile1Name); - setState(() {}); - } - }, - shape: RoundedRectangleBorder( - side: BorderSide( - color: modManCurActiveProfile == 1 - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor), - borderRadius: const BorderRadius.all(Radius.circular(2))), - child: Text(modManProfile1Name, - style: TextStyle( - color: modManCurActiveProfile == 1 - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor)), - ), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 5, top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiClickToChangeToThisProfileHoldToRename, - child: MaterialButton( - minWidth: 120, - height: 30, - //color: Theme.of(context).primaryColorDark, - onPressed: modManCurActiveProfile == 2 - ? null - : () async { - modSetList.clear(); - Navigator.pop(context); - final prefs = await SharedPreferences.getInstance(); - modManCurActiveProfile = 2; - prefs.setInt('modManCurActiveProfile', modManCurActiveProfile); - Provider.of(context, listen: false).reloadProfileTrue(); - modViewItem = null; - ogModFilesReset(); - Future.delayed(const Duration(milliseconds: 500), () { - setState(() {}); - // profileLoader(context).then((value) { - Provider.of(context, listen: false).setProfileName(modManProfile2Name); - Provider.of(context, listen: false).reloadProfileFalse(); - // }); - }); - - //setState(() {}); - }, - onLongPress: () async { - String newName = await newProfileNameDialog(context); - if (newName.isNotEmpty) { - final prefs = await SharedPreferences.getInstance(); - prefs.setString('modManProfile2Name', newName); - modManProfile2Name = newName; - Provider.of(context, listen: false).setProfileName(modManProfile2Name); - setState(() {}); - } - }, - shape: RoundedRectangleBorder( - side: BorderSide( - color: modManCurActiveProfile == 2 - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor), - borderRadius: const BorderRadius.all(Radius.circular(2))), - child: Text(modManProfile2Name, - style: TextStyle( - color: modManCurActiveProfile == 2 - ? MyApp.themeNotifier.value == ThemeMode.light - ? Color(lightModePrimarySwatch.value) - : Color(darkModePrimarySwatch.value) - : Theme.of(context).hintColor)), - ), - ), - ), - ], - )), - ], - ), - ), - - //JP start anticheat select - Visibility( - visible: context.watch().gameEdition == 'jp', - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (gameguardAnticheat) { - gameguardAnticheat = false; - prefs.setBool('gameguardAnticheat', false); - } else { - gameguardAnticheat = true; - prefs.setBool('gameguardAnticheat', true); - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.shield_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - gameguardAnticheat ? '${curLangText!.uiAntiCheatSelect}: ${curLangText!.uiGameguard}' : '${curLangText!.uiAntiCheatSelect}: ${curLangText!.uiWellbia}', - style: const TextStyle(fontWeight: FontWeight.normal), - ), - ], ), - ), - ), - const SizedBox( - height: 5, - ), + const SizedBox( + height: 5, + ), - //backup mod settings - MaterialButton( - height: 40, - onPressed: (() async { - await jsonManualBackup(); - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.save, - size: 18, - ), - const SizedBox(width: 10), - Text( - '${curLangText!.uiBackupModSettings} - ${curLangText!.uiBackups}: ${Directory(modManJsonManualSaveDir).listSync().whereType().where((element) => p.extension(element.path) == '.zip').length}', - style: const TextStyle(fontWeight: FontWeight.normal), - ), - ], - ), - ), - const SizedBox( - height: 5, - ), + const Divider( + indent: 5, + endIndent: 5, + height: 1, + thickness: 1, + //color: Theme.of(context).textTheme.headlineMedium?.color, + ), - //Path reselect - MaterialButton( - height: 40, - onPressed: (() async { - await pso2PathsReloader(context); - }), - child: Row( - children: [ - const Icon( - Icons.folder_copy_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiReselectPso2binPath, - style: const TextStyle(fontWeight: FontWeight.normal), - ), - ], - ), - ), - const SizedBox( - height: 5, - ), + const SizedBox( + height: 5, + ), - //MM Path reselect - MaterialButton( - height: 40, - onPressed: (() async { - await modManPathReloader(context); - }), - child: Row( - children: [ - const Icon( - Icons.folder_copy_outlined, - size: 18, + //Open settings + Padding( + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), + child: Text( + '${curLangText!.uiLocations}:', + style: const TextStyle(fontWeight: FontWeight.w500), ), - const SizedBox(width: 10), - Text(curLangText!.uiReselectModManFolderPath, style: const TextStyle(fontWeight: FontWeight.normal)), - ], - ), - ), - const SizedBox( - height: 5, - ), - - const Divider( - indent: 5, - endIndent: 5, - height: 1, - thickness: 1, - //color: Theme.of(context).textTheme.headlineMedium?.color, - ), - - const SizedBox( - height: 5, - ), - - //Open settings - Padding( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), - child: Text( - '${curLangText!.uiLocations}:', - style: const TextStyle(fontWeight: FontWeight.w500), - ), - ), + ), - //Path open - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenMainModManFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenMainModManFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 5, - ), + ), + const SizedBox( + height: 5, + ), - //Path open - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManModsDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenModsFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManModsDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenModsFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 5, - ), + ), + const SizedBox( + height: 5, + ), - //Path open - //Open Backup - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManBackupsDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenBackupFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + //Open Backup + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManBackupsDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenBackupFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 5, - ), + ), + const SizedBox( + height: 5, + ), - //Path open json backup dir - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(Directory(modManJsonAutoSaveDir).parent.path)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenModSettingsBackupFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open json backup dir + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(Directory(modManJsonAutoSaveDir).parent.path)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenModSettingsBackupFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 5, - ), + ), + const SizedBox( + height: 5, + ), - //Path open - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManExportedDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenExportedModsFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManExportedDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenExportedModsFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), - const SizedBox( - height: 5, - ), + ), + const SizedBox( + height: 5, + ), - //Path open - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManDeletedItemsDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenDeletedItemsFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManDeletedItemsDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenDeletedItemsFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), + ), - const SizedBox( - height: 5, - ), + const SizedBox( + height: 5, + ), - //Path open - MaterialButton( - height: 40, - onPressed: (() async { - await launchUrl(Uri.file(modManOverlayedItemIconsDirPath)); - }), - child: Row( - children: [ - const Icon( - Icons.folder_open_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - curLangText!.uiOpenMarkedItemIconCacheFolder, - style: const TextStyle(fontWeight: FontWeight.normal), + //Path open + MaterialButton( + height: 40, + onPressed: (() async { + await launchUrl(Uri.file(modManOverlayedItemIconsDirPath)); + }), + child: Row( + children: [ + const Icon( + Icons.folder_open_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text( + curLangText!.uiOpenMarkedItemIconCacheFolder, + style: const TextStyle(fontWeight: FontWeight.normal), + ), + ], ), - ], - ), - ), + ), - const SizedBox( - height: 5, - ), + const SizedBox( + height: 5, + ), - const Divider( - indent: 5, - endIndent: 5, - height: 1, - thickness: 1, - //color: Theme.of(context).textTheme.headlineMedium?.color, - ), + const Divider( + indent: 5, + endIndent: 5, + height: 1, + thickness: 1, + //color: Theme.of(context).textTheme.headlineMedium?.color, + ), - const SizedBox( - height: 5, - ), + const SizedBox( + height: 5, + ), - //Other options - Padding( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), - child: Text( - '${curLangText!.uiOtherSettings}:', - style: const TextStyle(fontWeight: FontWeight.w500), - ), - ), + //Other options + Padding( + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), + child: Text( + '${curLangText!.uiOtherSettings}:', + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ), - //Backup Priority - ModManTooltip( - message: curLangText!.uiPrioritizeLocalBackupTooltip, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).prioritizeLocalBackup) { - prioritizeLocalBackup = false; - prefs.setBool('prioritizeLocalBackup', false); - Provider.of(context, listen: false).prioritizeLocalBackupFalse(); - } else { - prioritizeLocalBackup = true; - prefs.setBool('prioritizeLocalBackup', true); - Provider.of(context, listen: false).prioritizeLocalBackupTrue(); - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.backup, - size: 18, + //Backup Priority + ModManTooltip( + message: curLangText!.uiPrioritizeLocalBackupTooltip, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).prioritizeLocalBackup) { + prioritizeLocalBackup = false; + prefs.setBool('prioritizeLocalBackup', false); + Provider.of(context, listen: false).prioritizeLocalBackupFalse(); + } else { + prioritizeLocalBackup = true; + prefs.setBool('prioritizeLocalBackup', true); + Provider.of(context, listen: false).prioritizeLocalBackupTrue(); + } + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.backup, + size: 18, + ), + const SizedBox(width: 10), + Text(Provider.of(context, listen: false).prioritizeLocalBackup ? curLangText!.uiPrioritizeLocalBackups : curLangText!.uiPrioritizeSegaBackups, + style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(Provider.of(context, listen: false).prioritizeLocalBackup ? curLangText!.uiPrioritizeLocalBackups : curLangText!.uiPrioritizeSegaBackups, - style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //Items with recently added mods ontop - ModManTooltip( - message: curLangText!.uiPutItemsWithNewModsOnTopOfTheList, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (itemsWithNewModsOnTop) { - prefs.setBool('itemsWithNewModsOnTop', false); - itemsWithNewModsOnTop = false; - Provider.of(context, listen: false).itemListSortStateSet(ItemListSort.alphabeticalOrder); - for (var type in moddedItemsList) { - for (var cate in type.categories) { - cate.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); - } - } - } else { - prefs.setBool('itemsWithNewModsOnTop', true); - itemsWithNewModsOnTop = true; - Provider.of(context, listen: false).itemListSortStateSet(ItemListSort.recentModsAdded); - for (var type in moddedItemsList) { - for (var cate in type.categories) { - cate.items.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + //Items with recently added mods ontop + ModManTooltip( + message: curLangText!.uiPutItemsWithNewModsOnTopOfTheList, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (itemsWithNewModsOnTop) { + prefs.setBool('itemsWithNewModsOnTop', false); + itemsWithNewModsOnTop = false; + Provider.of(context, listen: false).itemListSortStateSet(ItemListSort.alphabeticalOrder); + for (var type in moddedItemsList) { + for (var cate in type.categories) { + cate.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); + } + } + } else { + prefs.setBool('itemsWithNewModsOnTop', true); + itemsWithNewModsOnTop = true; + Provider.of(context, listen: false).itemListSortStateSet(ItemListSort.recentModsAdded); + for (var type in moddedItemsList) { + for (var cate in type.categories) { + cate.items.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + } + } } - } - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.sort, - size: 18, + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.sort, + size: 18, + ), + const SizedBox(width: 10), + Text(itemsWithNewModsOnTop ? '${curLangText!.uiSortItemsByRecentlyAddedMods}: ON' : '${curLangText!.uiSortItemsByRecentlyAddedMods}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(itemsWithNewModsOnTop ? '${curLangText!.uiSortItemsByRecentlyAddedMods}: ON' : '${curLangText!.uiSortItemsByRecentlyAddedMods}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //Recently added mods ontop - ModManTooltip( - message: curLangText!.uiPutNewModsOnTopOfTheList, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (newModsOnTop) { - prefs.setBool('newModsOnTop', false); - newModsOnTop = false; - Provider.of(context, listen: false).modViewListSortStateSet(ModViewListSort.alphabeticalOrder); - for (var type in moddedItemsList) { - for (var cate in type.categories) { - for (var item in cate.items) { - item.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); - for (var mod in item.mods) { - mod.submods.sort((a, b) => a.submodName.toLowerCase().compareTo(b.submodName.toLowerCase())); + //Recently added mods ontop + ModManTooltip( + message: curLangText!.uiPutNewModsOnTopOfTheList, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (newModsOnTop) { + prefs.setBool('newModsOnTop', false); + newModsOnTop = false; + Provider.of(context, listen: false).modViewListSortStateSet(ModViewListSort.alphabeticalOrder); + for (var type in moddedItemsList) { + for (var cate in type.categories) { + for (var item in cate.items) { + item.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); + for (var mod in item.mods) { + mod.submods.sort((a, b) => a.submodName.toLowerCase().compareTo(b.submodName.toLowerCase())); + } + } } } - } - } - } else { - prefs.setBool('newModsOnTop', true); - newModsOnTop = true; - Provider.of(context, listen: false).modViewListSortStateSet(ModViewListSort.recentModsAdded); - for (var type in moddedItemsList) { - for (var cate in type.categories) { - for (var item in cate.items) { - item.mods.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); - for (var mod in item.mods) { - mod.submods.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + } else { + prefs.setBool('newModsOnTop', true); + newModsOnTop = true; + Provider.of(context, listen: false).modViewListSortStateSet(ModViewListSort.recentModsAdded); + for (var type in moddedItemsList) { + for (var cate in type.categories) { + for (var item in cate.items) { + item.mods.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + for (var mod in item.mods) { + mod.submods.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + } + } } } } - } - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.sort, - size: 18, + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.sort, + size: 18, + ), + const SizedBox(width: 10), + Text(newModsOnTop ? '${curLangText!.uiSortModsByRecentlyAdded}: ON' : '${curLangText!.uiSortModsByRecentlyAdded}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(newModsOnTop ? '${curLangText!.uiSortModsByRecentlyAdded}: ON' : '${curLangText!.uiSortModsByRecentlyAdded}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //cmx file refresh - ModManTooltip( - message: curLangText!.uiCmxRefreshToolTip, - child: MaterialButton( - height: 40, - onPressed: (() async { - cmxRefreshing = true; - setState(() {}); - await cmxRefresh(); - cmxRefreshing = false; - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.rotate_left, - size: 18, + //cmx file refresh + ModManTooltip( + message: curLangText!.uiCmxRefreshToolTip, + child: MaterialButton( + height: 40, + onPressed: (() async { + cmxRefreshing = true; + setState(() {}); + await cmxRefresh(); + cmxRefreshing = false; + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.rotate_left, + size: 18, + ), + const SizedBox(width: 10), + Text(cmxRefreshing ? curLangText!.uiRefreshingCmx : curLangText!.uiRefreshCmx, style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(cmxRefreshing ? curLangText!.uiRefreshingCmx : curLangText!.uiRefreshCmx, style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //overlay icons - ModManTooltip( - message: curLangText!.uiMarkModdedItemOnIconInGame, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).markModdedItem) { - prefs.setBool('markModdedItemIcon', false); - Provider.of(context, listen: false).markModdedItemSet(false); - } else { - prefs.setBool('markModdedItemIcon', true); - Provider.of(context, listen: false).markModdedItemSet(true); - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.image_aspect_ratio_outlined, - size: 18, + //overlay icons + ModManTooltip( + message: curLangText!.uiMarkModdedItemOnIconInGame, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).markModdedItem) { + prefs.setBool('markModdedItemIcon', false); + Provider.of(context, listen: false).markModdedItemSet(false); + } else { + prefs.setBool('markModdedItemIcon', true); + Provider.of(context, listen: false).markModdedItemSet(true); + } + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.image_aspect_ratio_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text(Provider.of(context, listen: false).markModdedItem ? '${curLangText!.uiMarkModdedItemInGame}: ON' : '${curLangText!.uiMarkModdedItemInGame}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(Provider.of(context, listen: false).markModdedItem ? '${curLangText!.uiMarkModdedItemInGame}: ON' : '${curLangText!.uiMarkModdedItemInGame}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //Sliding item icons - ModManTooltip( - message: Provider.of(context, listen: false).isSlidingItemIcons ? curLangText!.uiTurnOffSlidingItemIcons : curLangText!.uiTurnOnSlidingItemIcons, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).isSlidingItemIcons) { - isSlidingItemIcons = false; - prefs.setBool('isSlidingItemIcons', false); - Provider.of(context, listen: false).isSlidingItemIconsFalse(); - } else { - isSlidingItemIcons = true; - prefs.setBool('isSlidingItemIcons', true); - Provider.of(context, listen: false).isSlidingItemIconsTrue(); - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.slideshow_rounded, - size: 18, + //Sliding item icons + ModManTooltip( + message: Provider.of(context, listen: false).isSlidingItemIcons ? curLangText!.uiTurnOffSlidingItemIcons : curLangText!.uiTurnOnSlidingItemIcons, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).isSlidingItemIcons) { + isSlidingItemIcons = false; + prefs.setBool('isSlidingItemIcons', false); + Provider.of(context, listen: false).isSlidingItemIconsFalse(); + } else { + isSlidingItemIcons = true; + prefs.setBool('isSlidingItemIcons', true); + Provider.of(context, listen: false).isSlidingItemIconsTrue(); + } + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.slideshow_rounded, + size: 18, + ), + const SizedBox(width: 10), + Text(Provider.of(context, listen: false).isSlidingItemIcons ? '${curLangText!.uiSlidingItemIcons}: ON' : '${curLangText!.uiSlidingItemIcons}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - const SizedBox(width: 10), - Text(Provider.of(context, listen: false).isSlidingItemIcons ? '${curLangText!.uiSlidingItemIcons}: ON' : '${curLangText!.uiSlidingItemIcons}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], + ), ), - ), - ), - //Remove bounding radius on apply - ModManTooltip( - message: curLangText!.uiAutoRadiusRemovalTooltip, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).removeBoundaryRadiusOnModsApply) { - removeBoundaryRadiusOnModsApply = false; - prefs.setBool('removeBoundaryRadiusOnModsApply', false); - Provider.of(context, listen: false).removeBoundaryRadiusOnModsApplyFalse(); - } else { - removeBoundaryRadiusOnModsApply = true; - prefs.setBool('removeBoundaryRadiusOnModsApply', true); - Provider.of(context, listen: false).removeBoundaryRadiusOnModsApplyTrue(); - } - setState(() {}); - }), - child: Row( + //Remove bounding radius on apply + ModManTooltip( + message: curLangText!.uiAutoRadiusRemovalTooltip, + child: MaterialButton( + height: 40, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).removeBoundaryRadiusOnModsApply) { + removeBoundaryRadiusOnModsApply = false; + prefs.setBool('removeBoundaryRadiusOnModsApply', false); + Provider.of(context, listen: false).removeBoundaryRadiusOnModsApplyFalse(); + } else { + removeBoundaryRadiusOnModsApply = true; + prefs.setBool('removeBoundaryRadiusOnModsApply', true); + Provider.of(context, listen: false).removeBoundaryRadiusOnModsApplyTrue(); + } + setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.radio_button_checked, + size: 18, + ), + const SizedBox(width: 10), + Text( + Provider.of(context, listen: false).removeBoundaryRadiusOnModsApply + ? '${curLangText!.uiAutoBoundaryRadiusRemoval}: ON' + : '${curLangText!.uiAutoBoundaryRadiusRemoval}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], + ), + ), + ), + + //autoAqmInject + Column( + mainAxisSize: MainAxisSize.min, children: [ - const Icon( - Icons.radio_button_checked, - size: 18, + ModManTooltip( + message: curLangText!.uiAutoInjectCustomAqmFileIntoMods, + child: MaterialButton( + height: 40, + onPressed: File(modManCustomAqmFilePath).existsSync() + ? (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).autoAqmInject) { + autoAqmInject = false; + prefs.setBool('autoAqmInject', false); + Provider.of(context, listen: false).autoAqmInjectSet(false); + } else { + autoAqmInject = true; + prefs.setBool('autoAqmInject', true); + Provider.of(context, listen: false).autoAqmInjectSet(true); + } + setState(() {}); + }) + : null, + child: Row( + children: [ + const Icon( + Icons.auto_fix_normal, + size: 18, + ), + const SizedBox(width: 10), + Text( + Provider.of(context, listen: false).autoAqmInject + ? '${curLangText!.uiAutoCustomAqmInjection}: ON' + : '${curLangText!.uiAutoCustomAqmInjection}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) + ], + ), + ), ), - const SizedBox(width: 10), - Text( - Provider.of(context, listen: false).removeBoundaryRadiusOnModsApply - ? '${curLangText!.uiAutoBoundaryRadiusRemoval}: ON' - : '${curLangText!.uiAutoBoundaryRadiusRemoval}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) + ModManTooltip( + message: !File(modManCustomAqmFilePath).existsSync() ? curLangText!.uiSelectAqmFile : '${curLangText!.uiSelectAqmFile}: $modManCustomAqmFilePath', + child: MaterialButton( + minWidth: double.infinity, + height: 30, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + const XTypeGroup typeGroup = XTypeGroup( + label: '.aqm', + extensions: ['aqm'], + ); + final XFile? selectedFile = await openFile(acceptedTypeGroups: [typeGroup]); + if (selectedFile != null) { + modManCustomAqmFileName = selectedFile.name; + prefs.setString('modManCustomAqmFileName', modManCustomAqmFileName); + if (Directory(modManCustomAqmDir).existsSync() && modManCustomAqmFileName.isNotEmpty) { + modManCustomAqmFilePath = Uri.file('$modManCustomAqmDir/$modManCustomAqmFileName').toFilePath(); + File(selectedFile.path).copySync(modManCustomAqmFilePath); + } + } + setState(() {}); + }), + child: Row( + children: [ + const SizedBox(width: 28), + Text(!File(modManCustomAqmFilePath).existsSync() ? curLangText!.uiSelectAqmFile : curLangText!.uiReSelectAqmFile, + style: const TextStyle(fontWeight: FontWeight.w400)), + ], + ), + ), + ) ], ), - ), - ), - //autoAqmInject - Column( - mainAxisSize: MainAxisSize.min, - children: [ - ModManTooltip( - message: curLangText!.uiAutoInjectCustomAqmFileIntoMods, + //remove profanity Filter + Padding( + padding: const EdgeInsets.only(top: 5), child: MaterialButton( height: 40, - onPressed: File(modManCustomAqmFilePath).existsSync() - ? (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).autoAqmInject) { - autoAqmInject = false; - prefs.setBool('autoAqmInject', false); - Provider.of(context, listen: false).autoAqmInjectSet(false); - } else { - autoAqmInject = true; - prefs.setBool('autoAqmInject', true); - Provider.of(context, listen: false).autoAqmInjectSet(true); + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).profanityFilterRemove) { + bool downloadSuccessJP = false; + bool downloadSuccessNA = false; + if (!File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).existsSync()) { + await downloadProfanityFileJP().then((value) { + if (value) { + downloadSuccessJP = true; } - setState(() {}); - }) - : null, + }); + } + if (Directory(Uri.file('$modManPso2binPath/data/win32_na').toFilePath()).existsSync() && + !File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).existsSync()) { + await downloadProfanityFileNA().then((value) { + if (value) { + downloadSuccessNA = true; + } + }); + } else if (!Directory(Uri.file('$modManPso2binPath/data/win32_na').toFilePath()).existsSync()) { + downloadSuccessNA = true; + } + if (downloadSuccessJP && downloadSuccessNA) { + prefs.setBool('profanityFilterRemove', false); + Provider.of(context, listen: false).profanityFilterRemoveFalse(); + profanityFilterRemoval = false; + } + } else { + if (File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).existsSync()) { + await File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).delete(); + } + if (File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).existsSync()) { + await File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).delete(); + } + prefs.setBool('profanityFilterRemove', true); + Provider.of(context, listen: false).profanityFilterRemoveTrue(); + profanityFilterRemoval = true; + } + setState(() {}); + }), child: Row( children: [ const Icon( - Icons.auto_fix_normal, + Icons.abc_outlined, size: 18, ), const SizedBox(width: 10), Text( - Provider.of(context, listen: false).autoAqmInject - ? '${curLangText!.uiAutoCustomAqmInjection}: ON' - : '${curLangText!.uiAutoCustomAqmInjection}: OFF', + Provider.of(context, listen: false).profanityFilterRemove + ? '${curLangText!.uiRemoveProfanityFilter}: ON' + : '${curLangText!.uiRemoveProfanityFilter}: OFF', style: const TextStyle(fontWeight: FontWeight.w400)) ], ), ), ), + + //show hide preview panel ModManTooltip( - message: !File(modManCustomAqmFilePath).existsSync() ? curLangText!.uiSelectAqmFile : '${curLangText!.uiSelectAqmFile}: $modManCustomAqmFilePath', + message: curLangText!.uiPreviewShowHide, child: MaterialButton( - minWidth: double.infinity, - height: 30, + height: 40, onPressed: (() async { final prefs = await SharedPreferences.getInstance(); - const XTypeGroup typeGroup = XTypeGroup( - label: '.aqm', - extensions: ['aqm'], - ); - final XFile? selectedFile = await openFile(acceptedTypeGroups: [typeGroup]); - if (selectedFile != null) { - modManCustomAqmFileName = selectedFile.name; - prefs.setString('modManCustomAqmFileName', modManCustomAqmFileName); - if (Directory(modManCustomAqmDir).existsSync() && modManCustomAqmFileName.isNotEmpty) { - modManCustomAqmFilePath = Uri.file('$modManCustomAqmDir/$modManCustomAqmFileName').toFilePath(); - File(selectedFile.path).copySync(modManCustomAqmFilePath); - } + if (Provider.of(context, listen: false).showPreviewPanel) { + prefs.setBool('showPreviewPanel', false); + Provider.of(context, listen: false).showPreviewPanelSet(false); + showPreviewPanel = false; + } else { + prefs.setBool('showPreviewPanel', true); + Provider.of(context, listen: false).showPreviewPanelSet(true); + showPreviewPanel = true; } setState(() {}); }), child: Row( children: [ - const SizedBox(width: 28), - Text(!File(modManCustomAqmFilePath).existsSync() ? curLangText!.uiSelectAqmFile : curLangText!.uiReSelectAqmFile, - style: const TextStyle(fontWeight: FontWeight.w400)), + const Icon( + Icons.preview_outlined, + size: 18, + ), + const SizedBox(width: 10), + Text(Provider.of(context, listen: false).showPreviewPanel ? '${curLangText!.uiPreviewWindow}: ON' : '${curLangText!.uiPreviewWindow}: OFF', + style: const TextStyle(fontWeight: FontWeight.w400)) ], ), ), - ) - ], - ), - - //remove profanity Filter - Padding( - padding: const EdgeInsets.only(top: 5), - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).profanityFilterRemove) { - bool downloadSuccessJP = false; - bool downloadSuccessNA = false; - if (!File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).existsSync()) { - await downloadProfanityFileJP().then((value) { - if (value) { - downloadSuccessJP = true; - } - }); - } - if (Directory(Uri.file('$modManPso2binPath/data/win32_na').toFilePath()).existsSync() && - !File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).existsSync()) { - await downloadProfanityFileNA().then((value) { - if (value) { - downloadSuccessNA = true; - } - }); - } else if (!Directory(Uri.file('$modManPso2binPath/data/win32_na').toFilePath()).existsSync()) { - downloadSuccessNA = true; - } - if (downloadSuccessJP && downloadSuccessNA) { - prefs.setBool('profanityFilterRemove', false); - Provider.of(context, listen: false).profanityFilterRemoveFalse(); - profanityFilterRemoval = false; - } - } else { - if (File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).existsSync()) { - await File(Uri.file('$modManPso2binPath/data/win32/$profanityFilterIce').toFilePath()).delete(); - } - if (File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).existsSync()) { - await File(Uri.file('$modManPso2binPath/data/win32_na/$profanityFilterIce').toFilePath()).delete(); - } - prefs.setBool('profanityFilterRemove', true); - Provider.of(context, listen: false).profanityFilterRemoveTrue(); - profanityFilterRemoval = true; - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.abc_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text( - Provider.of(context, listen: false).profanityFilterRemove - ? '${curLangText!.uiRemoveProfanityFilter}: ON' - : '${curLangText!.uiRemoveProfanityFilter}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], - ), - ), - ), - - //show hide preview panel - ModManTooltip( - message: curLangText!.uiPreviewShowHide, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - if (Provider.of(context, listen: false).showPreviewPanel) { - prefs.setBool('showPreviewPanel', false); - Provider.of(context, listen: false).showPreviewPanelSet(false); - showPreviewPanel = false; - } else { - prefs.setBool('showPreviewPanel', true); - Provider.of(context, listen: false).showPreviewPanelSet(true); - showPreviewPanel = true; - } - setState(() {}); - }), - child: Row( - children: [ - const Icon( - Icons.preview_outlined, - size: 18, - ), - const SizedBox(width: 10), - Text(Provider.of(context, listen: false).showPreviewPanel ? '${curLangText!.uiPreviewWindow}: ON' : '${curLangText!.uiPreviewWindow}: OFF', - style: const TextStyle(fontWeight: FontWeight.w400)) - ], ), - ), - ), - //Auto fetching item icon on startup - Padding( - padding: const EdgeInsets.only(top: 5, left: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, + //Auto fetching item icon on startup + Padding( + padding: const EdgeInsets.only(top: 5, left: 8), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Icon( - Icons.auto_awesome_motion, - size: 18, + Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon( + Icons.auto_awesome_motion, + size: 18, + ), + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiStartupItemIconsFetching}:'), + ], ), - const SizedBox( - width: 10, + Padding( + padding: const EdgeInsets.only(top: 10, left: 25, bottom: 5), + child: ToggleButtons( + onPressed: (int index) async { + final prefs = await SharedPreferences.getInstance(); + prefs.setString('isAutoFetchingIconsOnStartup', saveValues[index]); + isAutoFetchingIconsOnStartup = saveValues[index]; + setState(() { + for (int i = 0; i < _selectedIconLoaderSwitches.length; i++) { + _selectedIconLoaderSwitches[i] = i == index; + } + }); + }, + borderRadius: const BorderRadius.all(Radius.circular(8)), + selectedBorderColor: Theme.of(context).colorScheme.primary, + constraints: const BoxConstraints( + minHeight: 25.0, + minWidth: 74.0, + ), + isSelected: _selectedIconLoaderSwitches, + children: iconLoaderSwitches, + ), + ), + ], + ), + ), + + const SizedBox( + height: 5, + ), + + const Divider( + indent: 5, + endIndent: 5, + height: 1, + thickness: 1, + //color: Theme.of(context).textTheme.headlineMedium?.color, + ), + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), + child: Text( + '${curLangText!.uiTheme}:', + style: const TextStyle(fontWeight: FontWeight.w500), + ), + ), + + //Dark theme + if (MyApp.themeNotifier.value == ThemeMode.dark) + ModManTooltip( + message: curLangText!.uiSwitchToLightTheme, + child: MaterialButton( + height: 40, + onPressed: (() async { + MyApp.themeNotifier.value = ThemeMode.light; + final prefs = await SharedPreferences.getInstance(); + Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); + prefs.setBool('isDarkModeOn', false); + //setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.dark_mode, + size: 18, + ), + const SizedBox(width: 10), + Text('${curLangText!.uiAppearance}: ${curLangText!.uiDarkTheme}', style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - Text('${curLangText!.uiStartupItemIconsFetching}:'), - ], + ), ), - Padding( - padding: const EdgeInsets.only(top: 10, left: 25, bottom: 5), - child: ToggleButtons( - onPressed: (int index) async { + if (MyApp.themeNotifier.value == ThemeMode.light) + ModManTooltip( + message: curLangText!.uiSwitchToDarkTheme, + child: MaterialButton( + height: 40, + onPressed: (() async { final prefs = await SharedPreferences.getInstance(); - prefs.setString('isAutoFetchingIconsOnStartup', saveValues[index]); - isAutoFetchingIconsOnStartup = saveValues[index]; - setState(() { - for (int i = 0; i < _selectedIconLoaderSwitches.length; i++) { - _selectedIconLoaderSwitches[i] = i == index; - } - }); - }, - borderRadius: const BorderRadius.all(Radius.circular(8)), - selectedBorderColor: Theme.of(context).colorScheme.primary, - constraints: const BoxConstraints( - minHeight: 25.0, - minWidth: 74.0, + MyApp.themeNotifier.value = ThemeMode.dark; + prefs.setBool('isDarkModeOn', true); + Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); + //setState(() {}); + }), + child: Row( + children: [ + const Icon( + Icons.light_mode, + size: 18, + ), + const SizedBox(width: 10), + Text('${curLangText!.uiAppearance}: ${curLangText!.uiLightTheme}', style: const TextStyle(fontWeight: FontWeight.w400)) + ], ), - isSelected: _selectedIconLoaderSwitches, - children: iconLoaderSwitches, ), ), - ], - ), - ), - - const SizedBox( - height: 5, - ), - - const Divider( - indent: 5, - endIndent: 5, - height: 1, - thickness: 1, - //color: Theme.of(context).textTheme.headlineMedium?.color, - ), - - Padding( - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5), - child: Text( - '${curLangText!.uiTheme}:', - style: const TextStyle(fontWeight: FontWeight.w500), - ), - ), + const SizedBox( + height: 5, + ), - //Dark theme - if (MyApp.themeNotifier.value == ThemeMode.dark) - ModManTooltip( - message: curLangText!.uiSwitchToLightTheme, - child: MaterialButton( - height: 40, - onPressed: (() async { - MyApp.themeNotifier.value = ThemeMode.light; - final prefs = await SharedPreferences.getInstance(); - Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); - prefs.setBool('isDarkModeOn', false); - //setState(() {}); - }), + //Opacity slider + Padding( + padding: const EdgeInsets.symmetric(horizontal: 7), child: Row( children: [ const Icon( - Icons.dark_mode, + Icons.opacity_outlined, size: 18, ), - const SizedBox(width: 10), - Text('${curLangText!.uiAppearance}: ${curLangText!.uiDarkTheme}', style: const TextStyle(fontWeight: FontWeight.w400)) + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiUIOpacity}:'), ], ), ), - ), - if (MyApp.themeNotifier.value == ThemeMode.light) - ModManTooltip( - message: curLangText!.uiSwitchToDarkTheme, - child: MaterialButton( - height: 40, - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - MyApp.themeNotifier.value = ThemeMode.dark; - prefs.setBool('isDarkModeOn', true); - Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); - //setState(() {}); - }), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 7), + child: Slider( + min: 0.0, + max: 1.0, + value: context.watch().uiOpacityValue, + onChanged: (value) async { + Provider.of(context, listen: false).uiOpacityValueSet(value); + final prefs = await SharedPreferences.getInstance(); + prefs.setDouble('uiOpacityValue', value); + }), + ), + //Theme color picker + Padding( + padding: const EdgeInsets.symmetric(horizontal: 7), child: Row( children: [ const Icon( - Icons.light_mode, + Icons.color_lens, size: 18, ), - const SizedBox(width: 10), - Text('${curLangText!.uiAppearance}: ${curLangText!.uiLightTheme}', style: const TextStyle(fontWeight: FontWeight.w400)) + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiUIColors}:'), ], ), ), - ), - const SizedBox( - height: 5, - ), - - //Opacity slider - Padding( - padding: const EdgeInsets.symmetric(horizontal: 7), - child: Row( - children: [ - const Icon( - Icons.opacity_outlined, - size: 18, - ), - const SizedBox( - width: 10, - ), - Text('${curLangText!.uiUIOpacity}:'), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 7), - child: Slider( - min: 0.0, - max: 1.0, - value: context.watch().uiOpacityValue, - onChanged: (value) async { - Provider.of(context, listen: false).uiOpacityValueSet(value); - final prefs = await SharedPreferences.getInstance(); - prefs.setDouble('uiOpacityValue', value); - }), - ), - //Theme color picker - Padding( - padding: const EdgeInsets.symmetric(horizontal: 7), - child: Row( - children: [ - const Icon( - Icons.color_lens, - size: 18, - ), - const SizedBox( - width: 10, - ), - Text('${curLangText!.uiUIColors}:'), - ], - ), - ), - SizedBox( - width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, + SizedBox( + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.only(top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiPrimarySwatch, - child: MaterialButton( - minWidth: 120, - height: 30, - color: MyApp.themeNotifier.value == ThemeMode.light ? Color(lightModePrimarySwatch.value) : Color(darkModePrimarySwatch.value), - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = Color(lightModePrimarySwatch.value); - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - CustomMaterialColor newMaterialColor = CustomMaterialColor(selectedColor!.red, selectedColor!.green, selectedColor!.blue); - lightModePrimarySwatch = newMaterialColor.materialColor; - prefs.setInt('lightModePrimarySwatch', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - } else { - currentColor = Color(darkModePrimarySwatch.value); - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - CustomMaterialColor newMaterialColor = CustomMaterialColor(selectedColor!.red, selectedColor!.green, selectedColor!.blue); - darkModePrimarySwatch = newMaterialColor.materialColor; - prefs.setInt('darkModePrimarySwatch', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiPrimarySwatch, + child: MaterialButton( + minWidth: 120, + height: 30, + color: MyApp.themeNotifier.value == ThemeMode.light ? Color(lightModePrimarySwatch.value) : Color(darkModePrimarySwatch.value), + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = Color(lightModePrimarySwatch.value); + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + CustomMaterialColor newMaterialColor = CustomMaterialColor(selectedColor!.red, selectedColor!.green, selectedColor!.blue); + lightModePrimarySwatch = newMaterialColor.materialColor; + prefs.setInt('lightModePrimarySwatch', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + } else { + currentColor = Color(darkModePrimarySwatch.value); + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + CustomMaterialColor newMaterialColor = CustomMaterialColor(selectedColor!.red, selectedColor!.green, selectedColor!.blue); + darkModePrimarySwatch = newMaterialColor.materialColor; + prefs.setInt('darkModePrimarySwatch', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); } - }); - } - setState(() {}); - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + setState(() {}); + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), ), - ), + Padding( + padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiMainUIBackground, + child: MaterialButton( + minWidth: 120, + height: 30, + color: MyApp.themeNotifier.value == ThemeMode.light ? Color(lightModeUIBackgroundColor.value) : Color(darkModeUIBackgroundColor.value), + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = lightModeUIBackgroundColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + lightModeUIBackgroundColor = selectedColor!; + prefs.setInt('lightModeUIBackgroundColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); + setState(() {}); + selectedColor = null; + } + }); + } else { + currentColor = darkModeUIBackgroundColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + darkModeUIBackgroundColor = selectedColor!; + prefs.setInt('darkModeUIBackgroundColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); + setState(() {}); + selectedColor = null; + } + }); + } + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), + ), + ], ), - Padding( - padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiMainUIBackground, - child: MaterialButton( - minWidth: 120, - height: 30, - color: MyApp.themeNotifier.value == ThemeMode.light ? Color(lightModeUIBackgroundColor.value) : Color(darkModeUIBackgroundColor.value), - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = lightModeUIBackgroundColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - lightModeUIBackgroundColor = selectedColor!; - prefs.setInt('lightModeUIBackgroundColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiPrimaryColor, + child: MaterialButton( + minWidth: 120, + height: 30, + color: Theme.of(context).primaryColor, + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = lightModePrimaryColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + lightModePrimaryColor = selectedColor!; + prefs.setInt('lightModePrimaryColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); setState(() {}); - selectedColor = null; - } - }); - } else { - currentColor = darkModeUIBackgroundColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - darkModeUIBackgroundColor = selectedColor!; - prefs.setInt('darkModeUIBackgroundColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); + } else { + currentColor = darkModePrimaryColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + darkModePrimaryColor = selectedColor!; + prefs.setInt('darkModePrimaryColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); setState(() {}); - selectedColor = null; } - }); - } - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiPrimaryColor, - child: MaterialButton( - minWidth: 120, - height: 30, - color: Theme.of(context).primaryColor, - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = lightModePrimaryColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - lightModePrimaryColor = selectedColor!; - prefs.setInt('lightModePrimaryColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - setState(() {}); - } else { - currentColor = darkModePrimaryColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - darkModePrimaryColor = selectedColor!; - prefs.setInt('darkModePrimaryColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; + Padding( + padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiPrimaryLight, + child: MaterialButton( + minWidth: 120, + height: 30, + color: Theme.of(context).primaryColorLight, + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = lightModePrimaryColorLight; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + lightModePrimaryColorLight = selectedColor!; + prefs.setInt('lightModePrimaryColorLight', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); + } else { + currentColor = darkModePrimaryColorLight; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + darkModePrimaryColorLight = selectedColor!; + prefs.setInt('darkModePrimaryColorLight', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); } - }); - setState(() {}); - } - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), ), - ), + ], ), - Padding( - padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiPrimaryLight, - child: MaterialButton( - minWidth: 120, - height: 30, - color: Theme.of(context).primaryColorLight, - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = lightModePrimaryColorLight; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - lightModePrimaryColorLight = selectedColor!; - prefs.setInt('lightModePrimaryColorLight', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - setState(() {}); - } else { - currentColor = darkModePrimaryColorLight; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - darkModePrimaryColorLight = selectedColor!; - prefs.setInt('darkModePrimaryColorLight', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiPrimaryDark, + child: MaterialButton( + minWidth: 120, + height: 30, + color: Theme.of(context).primaryColorDark, + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = lightModePrimaryColorDark; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + lightModePrimaryColorDark = selectedColor!; + prefs.setInt('lightModePrimaryColorDark', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); + } else { + currentColor = darkModePrimaryColorDark; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + darkModePrimaryColorDark = selectedColor!; + prefs.setInt('darkModePrimaryColorDark', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); } - }); - setState(() {}); - } - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only(top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiPrimaryDark, - child: MaterialButton( - minWidth: 120, - height: 30, - color: Theme.of(context).primaryColorDark, - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = lightModePrimaryColorDark; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - lightModePrimaryColorDark = selectedColor!; - prefs.setInt('lightModePrimaryColorDark', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - setState(() {}); - } else { - currentColor = darkModePrimaryColorDark; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - darkModePrimaryColorDark = selectedColor!; - prefs.setInt('darkModePrimaryColorDark', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; + Padding( + padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), + child: ModManTooltip( + message: curLangText!.uiMainCanvasBackground, + child: MaterialButton( + minWidth: 120, + height: 30, + color: Theme.of(context).canvasColor, + onPressed: () async { + final prefs = await SharedPreferences.getInstance(); + if (MyApp.themeNotifier.value == ThemeMode.light) { + currentColor = lightModeCanvasColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + lightModeCanvasColor = selectedColor!; + prefs.setInt('lightModeCanvasColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); + } else { + currentColor = darkModeCanvasColor; + pickerColor = currentColor; + getColor(context).then((_) { + if (selectedColor != null) { + darkModeCanvasColor = selectedColor!; + prefs.setInt('darkModeCanvasColor', selectedColor!.value); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + selectedColor = null; + } + }); + setState(() {}); } - }); - setState(() {}); - } - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + ), ), - ), + ], ), Padding( - padding: const EdgeInsets.only(left: 10, top: 5, bottom: 2.5), - child: ModManTooltip( - message: curLangText!.uiMainCanvasBackground, - child: MaterialButton( - minWidth: 120, - height: 30, - color: Theme.of(context).canvasColor, - onPressed: () async { - final prefs = await SharedPreferences.getInstance(); - if (MyApp.themeNotifier.value == ThemeMode.light) { - currentColor = lightModeCanvasColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - lightModeCanvasColor = selectedColor!; - prefs.setInt('lightModeCanvasColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - setState(() {}); - } else { - currentColor = darkModeCanvasColor; - pickerColor = currentColor; - getColor(context).then((_) { - if (selectedColor != null) { - darkModeCanvasColor = selectedColor!; - prefs.setInt('darkModeCanvasColor', selectedColor!.value); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - selectedColor = null; - } - }); - setState(() {}); - } - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), - ), + padding: const EdgeInsets.only(left: 0, top: 5, bottom: 2.5), + child: MaterialButton( + minWidth: 242, + height: 30, + //color: Theme.of(context).primaryColor, + onLongPress: () async { + final prefs = await SharedPreferences.getInstance(); + + if (MyApp.themeNotifier.value == ThemeMode.light) { + lightModePrimaryColor = const Color(0xffffffff); + lightModePrimaryColorLight = const Color(0xff3181ff); + lightModePrimaryColorDark = const Color(0xff000000); + lightModeCanvasColor = const Color(0xffffffff); + lightModeUIBackgroundColor = const Color(0xffffffff); + lightModePrimarySwatch = Colors.blue; + //Save to prefs + prefs.setInt('lightModePrimaryColor', lightModePrimaryColor.value); + prefs.setInt('lightModePrimaryColorLight', lightModePrimaryColorLight.value); + prefs.setInt('lightModePrimaryColorDark', lightModePrimaryColorDark.value); + prefs.setInt('lightModeCanvasColor', lightModeCanvasColor.value); + prefs.setInt('lightModeUIBackgroundColor', lightModeUIBackgroundColor.value); + prefs.setInt('lightModePrimarySwatch', Colors.blue.value); + Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); + } else { + darkModePrimaryColor = const Color(0xff000000); + darkModePrimaryColorLight = const Color(0xff706f6f); + darkModePrimaryColorDark = const Color(0xff000000); + darkModeCanvasColor = const Color(0xff2e2d2d); + darkModeUIBackgroundColor = const Color(0xff2e2d2d); + darkModePrimarySwatch = Colors.blue; + //Save to prefs + prefs.setInt('darkModePrimaryColor', darkModePrimaryColor.value); + prefs.setInt('darkModePrimaryColorLight', darkModePrimaryColorLight.value); + prefs.setInt('darkModePrimaryColorDark', darkModePrimaryColorDark.value); + prefs.setInt('darkModeCanvasColor', darkModeCanvasColor.value); + prefs.setInt('darkModeUIBackgroundColor', darkModeUIBackgroundColor.value); + prefs.setInt('darkModePrimarySwatch', Colors.blue.value); + Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); + } + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + setState(() {}); + }, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + onPressed: () {}, + child: Text(curLangText!.uiHoldToResetColors), ), ), - ], - ), - Padding( - padding: const EdgeInsets.only(left: 0, top: 5, bottom: 2.5), - child: MaterialButton( - minWidth: 242, - height: 30, - //color: Theme.of(context).primaryColor, - onLongPress: () async { - final prefs = await SharedPreferences.getInstance(); - - if (MyApp.themeNotifier.value == ThemeMode.light) { - lightModePrimaryColor = const Color(0xffffffff); - lightModePrimaryColorLight = const Color(0xff3181ff); - lightModePrimaryColorDark = const Color(0xff000000); - lightModeCanvasColor = const Color(0xffffffff); - lightModeUIBackgroundColor = const Color(0xffffffff); - lightModePrimarySwatch = Colors.blue; - //Save to prefs - prefs.setInt('lightModePrimaryColor', lightModePrimaryColor.value); - prefs.setInt('lightModePrimaryColorLight', lightModePrimaryColorLight.value); - prefs.setInt('lightModePrimaryColorDark', lightModePrimaryColorDark.value); - prefs.setInt('lightModeCanvasColor', lightModeCanvasColor.value); - prefs.setInt('lightModeUIBackgroundColor', lightModeUIBackgroundColor.value); - prefs.setInt('lightModePrimarySwatch', Colors.blue.value); - Provider.of(context, listen: false).uiBackgroundColorValueSet(lightModeUIBackgroundColor.value); - } else { - darkModePrimaryColor = const Color(0xff000000); - darkModePrimaryColorLight = const Color(0xff706f6f); - darkModePrimaryColorDark = const Color(0xff000000); - darkModeCanvasColor = const Color(0xff2e2d2d); - darkModeUIBackgroundColor = const Color(0xff2e2d2d); - darkModePrimarySwatch = Colors.blue; - //Save to prefs - prefs.setInt('darkModePrimaryColor', darkModePrimaryColor.value); - prefs.setInt('darkModePrimaryColorLight', darkModePrimaryColorLight.value); - prefs.setInt('darkModePrimaryColorDark', darkModePrimaryColorDark.value); - prefs.setInt('darkModeCanvasColor', darkModeCanvasColor.value); - prefs.setInt('darkModeUIBackgroundColor', darkModeUIBackgroundColor.value); - prefs.setInt('darkModePrimarySwatch', Colors.blue.value); - Provider.of(context, listen: false).uiBackgroundColorValueSet(darkModeUIBackgroundColor.value); - } - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - setState(() {}); - }, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), - onPressed: () {}, - child: Text(curLangText!.uiHoldToResetColors), - ), - ), - //Background Image - Padding( - padding: const EdgeInsets.only(left: 7, right: 7, top: 10), - child: Row( - children: [ - const Icon( - Icons.image, - size: 18, - ), - const SizedBox( - width: 10, + //Background Image + Padding( + padding: const EdgeInsets.only(left: 7, right: 7, top: 10), + child: Row( + children: [ + const Icon( + Icons.image, + size: 18, + ), + const SizedBox( + width: 10, + ), + Text('${curLangText!.uiBackgroundImage}:'), + ], ), - Text('${curLangText!.uiBackgroundImage}:'), - ], - ), - ), - Padding( - padding: const EdgeInsets.only(left: 7, right: 7, top: 5, bottom: 5), - child: Container( - constraints: const BoxConstraints(maxWidth: 232), - decoration: ShapeDecoration( - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), ), - child: Stack( - alignment: Alignment.topCenter, - children: [ - InkWell( - child: Container( - child: backgroundImage.path != '' - ? Stack( - alignment: Alignment.bottomCenter, - children: [ - Image.file( - backgroundImage, - fit: BoxFit.cover, - ), - Container( - width: double.infinity, - color: Theme.of(context).canvasColor.withOpacity(0.5), - child: Center(child: Text(curLangText!.uiClicktoChangeBackgroundImage))) - ], - ) - : Center(child: Text(curLangText!.uiNoBackgroundImageFound)), - ), - onTap: () async { - //await FilePicker.platform.pickFiles(dialogTitle: curLangText!.uiSelectBackgroundImage, lockParentWindow: true, type: FileType.image).then((value) async { - const XTypeGroup typeGroup = XTypeGroup( - label: 'images', - extensions: ['png', 'jpg'], - ); - await openFile(acceptedTypeGroups: [typeGroup]).then((value) async { - if (value != null) { - final prefs = await SharedPreferences.getInstance(); - //backgroundImage = File(value.paths.first!); - backgroundImage = File(value.path); - prefs.setString('backgroundImagePath', backgroundImage.path); - Provider.of(context, listen: false).backgroundImageTriggerTrue(); - } - }); - setState(() {}); - // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member - MyApp.themeNotifier.notifyListeners(); - }, + Padding( + padding: const EdgeInsets.only(left: 7, right: 7, top: 5, bottom: 5), + child: Container( + constraints: const BoxConstraints(maxWidth: 232), + decoration: ShapeDecoration( + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Stack( + alignment: Alignment.topCenter, children: [ - if (Provider.of(context, listen: false).backgroundImageTrigger || - (!showBackgroundImage && !Provider.of(context, listen: false).backgroundImageTrigger)) - ModManTooltip( - message: showBackgroundImage ? curLangText!.uiHideBackgroundImage : curLangText!.uiShowBackgroundImage, - child: InkWell( - child: Container( - decoration: ShapeDecoration( - color: Colors.blue, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), - ), - child: Icon( - showBackgroundImage ? Icons.hide_image_outlined : Icons.image_outlined, - color: Colors.white, - ), - ), - onTap: () async { - final prefs = await SharedPreferences.getInstance(); - if (showBackgroundImage) { - showBackgroundImage = false; - prefs.setBool('showBgImage', false); - Provider.of(context, listen: false).backgroundImageTriggerFalse(); - } else { - showBackgroundImage = true; - prefs.setBool('showBgImage', true); - Provider.of(context, listen: false).backgroundImageTriggerTrue(); - } - setState(() {}); - }, - ), + InkWell( + child: Container( + child: backgroundImage.path != '' + ? Stack( + alignment: Alignment.bottomCenter, + children: [ + Image.file( + backgroundImage, + fit: BoxFit.cover, + ), + Container( + width: double.infinity, + color: Theme.of(context).canvasColor.withOpacity(0.5), + child: Center(child: Text(curLangText!.uiClicktoChangeBackgroundImage))) + ], + ) + : Center(child: Text(curLangText!.uiNoBackgroundImageFound)), ), - if (Provider.of(context, listen: false).backgroundImageTrigger || - (!showBackgroundImage && !Provider.of(context, listen: false).backgroundImageTrigger)) - ModManTooltip( - message: curLangText!.uiHoldToRemoveBackgroundImage, - child: InkWell( - child: Container( - decoration: ShapeDecoration( - color: Colors.red, - shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + onTap: () async { + //await FilePicker.platform.pickFiles(dialogTitle: curLangText!.uiSelectBackgroundImage, lockParentWindow: true, type: FileType.image).then((value) async { + const XTypeGroup typeGroup = XTypeGroup( + label: 'images', + extensions: ['png', 'jpg'], + ); + await openFile(acceptedTypeGroups: [typeGroup]).then((value) async { + if (value != null) { + final prefs = await SharedPreferences.getInstance(); + //backgroundImage = File(value.paths.first!); + backgroundImage = File(value.path); + prefs.setString('backgroundImagePath', backgroundImage.path); + Provider.of(context, listen: false).backgroundImageTriggerTrue(); + } + }); + setState(() {}); + // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member + MyApp.themeNotifier.notifyListeners(); + }, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (Provider.of(context, listen: false).backgroundImageTrigger || + (!showBackgroundImage && !Provider.of(context, listen: false).backgroundImageTrigger)) + ModManTooltip( + message: showBackgroundImage ? curLangText!.uiHideBackgroundImage : curLangText!.uiShowBackgroundImage, + child: InkWell( + child: Container( + decoration: ShapeDecoration( + color: Colors.blue, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + child: Icon( + showBackgroundImage ? Icons.hide_image_outlined : Icons.image_outlined, + color: Colors.white, + ), + ), + onTap: () async { + final prefs = await SharedPreferences.getInstance(); + if (showBackgroundImage) { + showBackgroundImage = false; + prefs.setBool('showBgImage', false); + Provider.of(context, listen: false).backgroundImageTriggerFalse(); + } else { + showBackgroundImage = true; + prefs.setBool('showBgImage', true); + Provider.of(context, listen: false).backgroundImageTriggerTrue(); + } + setState(() {}); + }, ), - child: const Icon( - Icons.delete_forever_outlined, - color: Colors.white, + ), + if (Provider.of(context, listen: false).backgroundImageTrigger || + (!showBackgroundImage && !Provider.of(context, listen: false).backgroundImageTrigger)) + ModManTooltip( + message: curLangText!.uiHoldToRemoveBackgroundImage, + child: InkWell( + child: Container( + decoration: ShapeDecoration( + color: Colors.red, + shape: RoundedRectangleBorder(side: BorderSide(color: Theme.of(context).hintColor), borderRadius: const BorderRadius.all(Radius.circular(2))), + ), + child: const Icon( + Icons.delete_forever_outlined, + color: Colors.white, + ), + ), + onLongPress: () async { + final prefs = await SharedPreferences.getInstance(); + prefs.setString('backgroundImagePath', ''); + backgroundImage = File(''); + Provider.of(context, listen: false).backgroundImageTriggerFalse(); + setState(() {}); + }, ), ), - onLongPress: () async { - final prefs = await SharedPreferences.getInstance(); - prefs.setString('backgroundImagePath', ''); - backgroundImage = File(''); - Provider.of(context, listen: false).backgroundImageTriggerFalse(); - setState(() {}); - }, - ), - ), + ], + ), ], ), - ], + ), ), - ), - ), - ], - )), - ]), - ), - )), - ), - ], - )), + ], + )), + ]), + ), + )), + ), + ], + )), body: Column( children: [ WindowTitleBarBox( @@ -2293,8 +2293,9 @@ class _MainPageState extends State { saveSetListToJson(); } else { isModViewListHidden = false; - modSetList = await modSetLoader(); - saveSetListToJson(); + // modSetList = await modSetLoader(); + // saveSetListToJson(); + saveModdedItemListToJson(); Provider.of(context, listen: false).setsWindowVisibleSetTrue(); } }), diff --git a/lib/sharing/mod_import_add_function.dart b/lib/sharing/mod_import_add_function.dart index 42af4e3..3efc9a4 100644 --- a/lib/sharing/mod_import_add_function.dart +++ b/lib/sharing/mod_import_add_function.dart @@ -5,6 +5,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:pso2_mod_manager/aqmInjection/aqm_inject_functions.dart'; +import 'package:pso2_mod_manager/boundary/mods_boundary_functions.dart'; import 'package:pso2_mod_manager/classes/category_class.dart'; import 'package:pso2_mod_manager/classes/item_class.dart'; import 'package:pso2_mod_manager/classes/mod_class.dart'; @@ -13,6 +15,8 @@ import 'package:pso2_mod_manager/classes/mod_set_class.dart'; import 'package:pso2_mod_manager/classes/mods_adder_file_class.dart'; import 'package:pso2_mod_manager/classes/sub_mod_class.dart'; import 'package:pso2_mod_manager/functions/applied_list_builder.dart'; +import 'package:pso2_mod_manager/functions/apply_mods_functions.dart'; +import 'package:pso2_mod_manager/functions/icon_overlay.dart'; import 'package:pso2_mod_manager/functions/json_write.dart'; import 'package:pso2_mod_manager/functions/modfiles_apply.dart'; import 'package:pso2_mod_manager/functions/og_ice_paths_fetcher.dart'; @@ -111,12 +115,17 @@ Future modsImportFilesAdder(context, List itemsToAddList, S itemInList.mods.addAll(newModsFetcher(itemInList.location, cateInList.categoryName, foldersInNewItemPath, importedSetName)); } itemInList.isNew = true; + itemInList.setLatestCreationDate(); //Sort alpha - itemInList.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); + // itemInList.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); newSet.setItems.add(itemInList); } - //Sort alpha - cateInList.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); + //Sort + if (itemsWithNewModsOnTop) { + cateInList.items.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + } else { + cateInList.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); + } cateInList.visible = cateInList.items.isNotEmpty ? true : false; cateType.visible = cateType.categories.where((element) => element.items.isNotEmpty).isNotEmpty ? true : false; @@ -152,11 +161,15 @@ Future modsImportFilesAdder(context, List itemsToAddList, S } itemInList.isNew = true; //Sort alpha - itemInList.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); + // itemInList.mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); newSet.setItems.add(itemInList); } - //Sort alpha - newCate.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); + //Sort + if (itemsWithNewModsOnTop) { + newCate.items.sort((a, b) => b.creationDate!.compareTo(a.creationDate!)); + } else { + newCate.items.sort((a, b) => a.itemName.toLowerCase().compareTo(b.itemName.toLowerCase())); + } newCate.visible = newCate.items.isNotEmpty ? true : false; cateType.categories.add(newCate); cateType.visible = cateType.categories.where((element) => element.items.isNotEmpty).isNotEmpty ? true : false; @@ -204,8 +217,11 @@ Future newItemsFetcher(String catePath, String itemPath, String importedSe itemIcons = ['assets/img/placeholdersquare.png']; } - return Item(p.basename(itemPath), [], itemIcons, '', '', '', false, p.basename(catePath), Uri.file(itemPath).toFilePath(), false, DateTime(0), 0, false, true, true, [importedSetName], + Item newItem = Item(p.basename(itemPath), [], itemIcons, '', '', '', false, p.basename(catePath), Uri.file(itemPath).toFilePath(), false, DateTime(0), 0, false, true, true, [importedSetName], newModsFetcher(itemPath, p.basename(catePath), [], importedSetName)); + newItem.setLatestCreationDate(); + + return newItem; } List newModsFetcher(String itemPath, String cateName, List newModFolders, String importedSetName) { @@ -250,10 +266,13 @@ List newModsFetcher(String itemPath, String cateName, List newMo //add to submod SubMod subModInItemDir = SubMod(p.basename(itemPath), p.basename(itemPath), p.basename(itemPath), cateName, itemPath, false, DateTime(0), 0, false, false, true, false, false, -1, -1, '', [importedSetName], [], modPreviewImages, modPreviewVideos, [], modFilesInItemDir); + subModInItemDir.setLatestCreationDate(); //add to mod - mods.add( - Mod(p.basename(itemPath), p.basename(itemPath), cateName, itemPath, false, DateTime(0), 0, false, false, true, [importedSetName], modPreviewImages, modPreviewVideos, [], [subModInItemDir])); + Mod newMod = + Mod(p.basename(itemPath), p.basename(itemPath), cateName, itemPath, false, DateTime(0), 0, false, false, true, [importedSetName], modPreviewImages, modPreviewVideos, [], [subModInItemDir]); + newMod.setLatestCreationDate(); + mods.add(newMod); } // get submods in mod folders @@ -275,12 +294,14 @@ List newModsFetcher(String itemPath, String cateName, List newMo } } - mods.add(Mod(p.basename(dir.path), p.basename(itemPath), cateName, dir.path, false, DateTime(0), 0, true, false, true, [importedSetName], modPreviewImages, modPreviewVideos, [], - newSubModFetcher(dir.path, cateName, p.basename(itemPath), importedSetName))); + Mod newMod = Mod(p.basename(dir.path), p.basename(itemPath), cateName, dir.path, false, DateTime(0), 0, true, false, true, [importedSetName], modPreviewImages, modPreviewVideos, [], + newSubModFetcher(dir.path, cateName, p.basename(itemPath), importedSetName)); + newMod.setLatestCreationDate(); + mods.add(newMod); } //Sort alpha - mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); + // mods.sort((a, b) => a.modName.toLowerCase().compareTo(b.modName.toLowerCase())); return mods; } @@ -297,8 +318,8 @@ List newSubModFetcher(String modPath, String cateName, String itemName, // for (var element in ogFiles) { // ogFilePaths.add(element.path); // } - modFiles - .add(ModFile(p.basename(file.path), p.basename(modPath), p.basename(modPath), itemName, cateName, '', [], file.path, false, DateTime(0), 0, false, true, true, [importedSetName], [], [], [], [], [])); + modFiles.add(ModFile( + p.basename(file.path), p.basename(modPath), p.basename(modPath), itemName, cateName, '', [], file.path, false, DateTime(0), 0, false, true, true, [importedSetName], [], [], [], [], [])); //Sort alpha modFiles.sort((a, b) => a.modFileName.toLowerCase().compareTo(b.modFileName.toLowerCase())); } @@ -327,8 +348,10 @@ List newSubModFetcher(String modPath, String cateName, String itemName, hasCmx = true; } - submods.add(SubMod(p.basename(modPath), p.basename(modPath), itemName, cateName, modPath, false, DateTime(0), 0, true, false, true, hasCmx, false, -1, -1, cmxFile, [importedSetName], [], - modPreviewImages, modPreviewVideos, [], modFiles)); + SubMod newSubmod = SubMod(p.basename(modPath), p.basename(modPath), itemName, cateName, modPath, false, DateTime(0), 0, true, false, true, hasCmx, false, -1, -1, cmxFile, [importedSetName], [], + modPreviewImages, modPreviewVideos, [], modFiles); + newSubmod.setLatestCreationDate(); + submods.add(newSubmod); } //ices in sub dirs @@ -370,8 +393,8 @@ List newSubModFetcher(String modPath, String cateName, String itemName, List parentPaths = file.parent.path.split(modPath).last.trim().split(Uri.file('/').toFilePath()); parentPaths.removeWhere((element) => element.isEmpty); - modFiles.add( - ModFile(p.basename(file.path), parentPaths.join(' > '), p.basename(modPath), itemName, cateName, '', [], file.path, false, DateTime(0), 0, false, true, true, [importedSetName], [], [], [], [], [])); + modFiles.add(ModFile( + p.basename(file.path), parentPaths.join(' > '), p.basename(modPath), itemName, cateName, '', [], file.path, false, DateTime(0), 0, false, true, true, [importedSetName], [], [], [], [], [])); //Sort alpha modFiles.sort((a, b) => a.modFileName.toLowerCase().compareTo(b.modFileName.toLowerCase())); } @@ -379,15 +402,17 @@ List newSubModFetcher(String modPath, String cateName, String itemName, //Get submod name List parentPaths = dir.path.split(modPath).last.trim().split(Uri.file('/').toFilePath()); parentPaths.removeWhere((element) => element.isEmpty); - submods.add(SubMod(parentPaths.join(' > '), p.basename(modPath), itemName, cateName, dir.path, false, DateTime(0), 0, true, false, true, hasCmx, false, -1, -1, cmxFile, [importedSetName], [], - modPreviewImages, modPreviewVideos, [], modFiles)); + SubMod newSubmod = SubMod(parentPaths.join(' > '), p.basename(modPath), itemName, cateName, dir.path, false, DateTime(0), 0, true, false, true, hasCmx, false, -1, -1, cmxFile, [importedSetName], + [], modPreviewImages, modPreviewVideos, [], modFiles); + newSubmod.setLatestCreationDate(); + submods.add(newSubmod); } //remove empty submods submods.removeWhere((element) => element.modFiles.isEmpty); //Sort alpha - submods.sort((a, b) => a.submodName.toLowerCase().compareTo(b.submodName.toLowerCase())); + // submods.sort((a, b) => a.submodName.toLowerCase().compareTo(b.submodName.toLowerCase())); return submods; } @@ -478,56 +503,78 @@ Future<(String, bool)> newImportModSetDialog(context) async { Future applyImportedMods(context, ModSet curSet) async { isModViewModsApplying = true; - Future.delayed(const Duration(milliseconds: 200), () async { - List allAppliedModFiles = []; - for (var item in curSet.setItems.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var mod in item.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var submod in mod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - allAppliedModFiles.addAll(submod.modFiles.where((element) => !element.applyStatus)); + for (var item in curSet.setItems) { + for (var mod in item.mods) { + for (var submod in mod.submods) { + //apply mod files + if (await originalFilesCheck(context, submod.modFiles)) { + //apply auto radius removal if on + if (removeBoundaryRadiusOnModsApply) await removeBoundaryOnModsApply(context, submod); + if (autoAqmInject) await aqmInjectionOnModsApply(context, submod); + + await applyModsToTheGame(context, item, mod, submod); + + if (Provider.of(context, listen: false).markModdedItem) { + await applyOverlayedIcon(context, item); + } + Provider.of(context, listen: false).quickApplyStateSet('extra'); } } } + } + isModViewModsApplying = false; + saveModdedItemListToJson(); + Navigator.pop(context); + // Future.delayed(const Duration(milliseconds: 200), () async { + // List allAppliedModFiles = []; + // for (var item in curSet.setItems.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var mod in item.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var submod in mod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // allAppliedModFiles.addAll(submod.modFiles.where((element) => !element.applyStatus)); + // } + // } + // } - //apply mod files - if (await originalFilesCheck(context, allAppliedModFiles)) { - modFilesApply(context, allAppliedModFiles).then((value) async { - if (value.indexWhere((element) => element.applyStatus) != -1) { - for (var curItem in curSet.setItems) { - for (var curMod in curItem.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - for (var curSubmod in curMod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { - curSubmod.applyStatus = true; - curSubmod.isNew = false; - curSubmod.applyDate = DateTime.now(); - } - curMod.applyStatus = true; - curMod.isNew = false; - curMod.applyDate = DateTime.now(); - } - curItem.applyDate = DateTime.now(); - curItem.applyStatus = true; - if (curItem.mods.where((element) => element.isNew).isEmpty) { - curItem.isNew = false; - } - } - List appliedModFiles = value; - String fileAppliedText = ''; - - for (var element in appliedModFiles.where((e) => e.applyStatus)) { - if (fileAppliedText.isEmpty) { - fileAppliedText = uiInTextArg(curLangText!.uiSuccessfullyAppliedX, curSet.setName); - } - if (!fileAppliedText.contains('${element.itemName} > ${element.modName} > ${element.submodName}\n')) { - fileAppliedText += '${element.itemName} > ${element.modName} > ${element.submodName}\n'; - } - } - ScaffoldMessenger.of(context).showSnackBar(snackBarMessage(context, '${curLangText!.uiSuccess}!', fileAppliedText.trim(), appliedModFiles.length * 1000)); - } - isModViewModsApplying = false; - saveModdedItemListToJson(); - Navigator.pop(context); - }); - } - }); + //apply mod files + // if (await originalFilesCheck(context, allAppliedModFiles)) { + // modFilesApply(context, allAppliedModFiles).then((value) async { + // if (value.indexWhere((element) => element.applyStatus) != -1) { + // for (var curItem in curSet.setItems) { + // for (var curMod in curItem.mods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // for (var curSubmod in curMod.submods.where((element) => element.isSet && element.setNames.contains(curSet.setName))) { + // curSubmod.applyStatus = true; + // curSubmod.isNew = false; + // curSubmod.applyDate = DateTime.now(); + // } + // curMod.applyStatus = true; + // curMod.isNew = false; + // curMod.applyDate = DateTime.now(); + // } + // curItem.applyDate = DateTime.now(); + // curItem.applyStatus = true; + // if (curItem.mods.where((element) => element.isNew).isEmpty) { + // curItem.isNew = false; + // } + // } + // List appliedModFiles = value; + // String fileAppliedText = ''; + + // for (var element in appliedModFiles.where((e) => e.applyStatus)) { + // if (fileAppliedText.isEmpty) { + // fileAppliedText = uiInTextArg(curLangText!.uiSuccessfullyAppliedX, curSet.setName); + // } + // if (!fileAppliedText.contains('${element.itemName} > ${element.modName} > ${element.submodName}\n')) { + // fileAppliedText += '${element.itemName} > ${element.modName} > ${element.submodName}\n'; + // } + // } + // ScaffoldMessenger.of(context).showSnackBar(snackBarMessage(context, '${curLangText!.uiSuccess}!', fileAppliedText.trim(), appliedModFiles.length * 1000)); + // } + // isModViewModsApplying = false; + // saveModdedItemListToJson(); + // Navigator.pop(context); + // }); + // } + // }); } Future applyingImportedModLoader(context, ModSet curSet) async { From 8e998f8579d18dffeb8c7b6fb8d24c5184cac1e6 Mon Sep 17 00:00:00 2001 From: KizKizz Date: Sat, 3 Aug 2024 20:39:42 -0700 Subject: [PATCH 3/4] prep --- app_version_check/app_version.json | 8 ++- lib/sharing/mods_export.dart | 77 +++++++++++++++++------- lib/state_provider.dart | 19 ++++++ lib/swapAll/swap_all_apply_homepage.dart | 4 +- windows/runner/Runner.rc | 4 +- 5 files changed, 82 insertions(+), 30 deletions(-) diff --git a/app_version_check/app_version.json b/app_version_check/app_version.json index 38b2597..6c49ee2 100644 --- a/app_version_check/app_version.json +++ b/app_version_check/app_version.json @@ -1,10 +1,12 @@ { "name": "PSO2NGS Mod Manager", - "version": "2.8.8", + "version": "2.8.9", "description": [ - "Added Swap All function which allows swapping all mods in an item to multiple other items at once", + "Added Mod Set Export function", + "Fixed some bugs and improved Item/Mod swapping", "More bug fixes", - "アイテム内のすべてのMODを他の複数のアイテムに一度にスワップできるスワップ・オール機能を追加", + "MODセットエクスポート機能の追加", + "いくつかのバグを修正し、アイテム/Modの交換を改善しました", "その他のバグ修正" ], "windows_file": "", diff --git a/lib/sharing/mods_export.dart b/lib/sharing/mods_export.dart index 7e5015c..8e37ad9 100644 --- a/lib/sharing/mods_export.dart +++ b/lib/sharing/mods_export.dart @@ -15,8 +15,8 @@ import 'package:path/path.dart' as p; Future modExportHomePage(context, List baseList, List exportSubmods, appliedModsExport) async { File exportedZip = File(''); - bool isWaiting = true; List exportNames = exportSubmods.map((e) => '${e.itemName} > ${e.modName} > ${e.submodName}').toList(); + Provider.of(context, listen: false).createModExportProgressStatus(List.generate(exportNames.length, (index) => false)); return await showDialog( barrierDismissible: false, context: context, @@ -46,14 +46,34 @@ Future modExportHomePage(context, List baseList, List().modExportProgessZipping, + child: const Center( + child: Padding( + padding: EdgeInsets.only(bottom: 10), + child: Text('', style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),), + )), ), + Visibility( + visible: context.watch().modExportProgessZipping, + child: Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 10), + child: Text(curLangText!.uiPackingFiles, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold),), + )), + ), + for (int i = 0; i < exportNames.length; i++) + Text( + exportNames[i], + style: TextStyle(fontSize: 15, color: context.watch().modExportProgressStatus[i] ? Colors.green : null), + ), ], )), ), @@ -74,6 +94,7 @@ Future modExportHomePage(context, List baseList, List(context, listen: false).modExportProgessZippingStateSet(false); Navigator.pop(context, true); }, child: Text(curLangText!.uiClose)), @@ -83,8 +104,7 @@ Future modExportHomePage(context, List baseList, List modExportHomePage(context, List baseList, List(context, listen: false).modExportProgessZippingStateSet(false); await launchUrl(Uri.file(exportedZip.parent.path)); // ignore: use_build_context_synchronously Navigator.pop(context, true); @@ -116,7 +136,7 @@ Future modExportHomePage(context, List baseList, List modExport(List baseList, List exportSubmods, bool appliedModsExport) async { +Future modExport(context, List baseList, List exportSubmods, bool appliedModsExport) async { DateTime now = DateTime.now(); String formattedDate = DateFormat('MM-dd-yyyy-kk-mm-ss').format(now); String rootExportDir = '$modManExportedDirPath/PSO2NGSMMExportedMods_$formattedDate'; @@ -145,30 +165,39 @@ Future modExport(List baseList, List exportSubmods expModDir.createSync(recursive: true); Directory expSubmodDir = Directory(exportSubmod.location.replaceFirst(modManModsDirPath, rootExportDir)); expSubmodDir.createSync(recursive: true); + //previews file for mod + for (var filePath in mod.previewImages.where((element) => File(element).parent.path == mod.location)) { + await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); + } + for (var filePath in mod.previewVideos.where((element) => File(element).parent.path == mod.location)) { + await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); + } + //previews for submod + for (var filePath in exportSubmod.previewImages) { + await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); + } + for (var filePath in exportSubmod.previewVideos) { + await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); + } for (var modFile in exportSubmod.modFiles) { if (appliedModsExport) { if (modFile.applyStatus) await File(modFile.location).copy(modFile.location.replaceFirst(modManModsDirPath, rootExportDir)); } else { await File(modFile.location).copy(modFile.location.replaceFirst(modManModsDirPath, rootExportDir)); } - //previews for submod - for (var filePath in exportSubmod.previewImages) { - await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); - } - for (var filePath in exportSubmod.previewVideos) { - await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); - } - //previews file for mod - for (var filePath in mod.previewImages.where((element) => File(element).parent.path == mod.location)) { + //previews file for modFile + for (var filePath in modFile.previewImages!) { await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); } - for (var filePath in mod.previewVideos.where((element) => File(element).parent.path == mod.location)) { + for (var filePath in modFile.previewVideos!) { await File(filePath).copy(filePath.replaceFirst(modManModsDirPath, rootExportDir)); } - if (log.isNotEmpty) { + if (log.isNotEmpty && log.contains(exportSubmod.submodName)) { exportedLog.add(log); + Provider.of(context, listen: false).setModExportProgressStatus(exportSubmods.indexOf(exportSubmod), true); } log = ''; + await Future.delayed(const Duration(milliseconds: 10)); } } } @@ -176,9 +205,11 @@ Future modExport(List baseList, List exportSubmods } } } - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 50)); } } + Provider.of(context, listen: false).modExportProgessZippingStateSet(true); + await Future.delayed(const Duration(milliseconds: 50)); //Save logs File logFile = File(Uri.file('$rootExportDir/${curLangText!.uiExportedNote}.txt').toFilePath()); await logFile.create(recursive: true); diff --git a/lib/state_provider.dart b/lib/state_provider.dart index 0fe9051..fe4373f 100644 --- a/lib/state_provider.dart +++ b/lib/state_provider.dart @@ -49,6 +49,8 @@ class StateProvider with ChangeNotifier { String _aqmInjectionProgressStatus = ''; ItemListSort _itemListSortState = ItemListSort.alphabeticalOrder; ModViewListSort _modViewListSortState = ModViewListSort.alphabeticalOrder; + List _modExportProgressStatus = []; + bool _modExportProgessZipping = false; bool get isMainBinFound => _isMainBinFound; bool get isMainModManPathFound => _isMainModManPathFound; @@ -96,6 +98,23 @@ class StateProvider with ChangeNotifier { String get aqmInjectionProgressStatus => _aqmInjectionProgressStatus; ItemListSort get itemListSortState => _itemListSortState; ModViewListSort get modViewListSortState => _modViewListSortState; + List get modExportProgressStatus => _modExportProgressStatus; + bool get modExportProgessZipping => _modExportProgessZipping; + + void modExportProgessZippingStateSet(bool state) { + _modExportProgessZipping = state; + notifyListeners(); + } + + void setModExportProgressStatus(int index, bool status) { + _modExportProgressStatus[index] = status; + notifyListeners(); + } + + void createModExportProgressStatus(List list) { + _modExportProgressStatus = list; + notifyListeners(); + } void modViewListSortStateSet(ModViewListSort state) { _modViewListSortState = state; diff --git a/lib/swapAll/swap_all_apply_homepage.dart b/lib/swapAll/swap_all_apply_homepage.dart index 300ab9d..026b72c 100644 --- a/lib/swapAll/swap_all_apply_homepage.dart +++ b/lib/swapAll/swap_all_apply_homepage.dart @@ -764,13 +764,13 @@ Future swapAllPopup(context, List mods, List submods, List Date: Sat, 3 Aug 2024 20:53:40 -0700 Subject: [PATCH 4/4] prep --- lib/modsAdder/mods_adder_homepage.dart | 1979 ++++++++++++------------ 1 file changed, 986 insertions(+), 993 deletions(-) diff --git a/lib/modsAdder/mods_adder_homepage.dart b/lib/modsAdder/mods_adder_homepage.dart index c919e8a..194a565 100644 --- a/lib/modsAdder/mods_adder_homepage.dart +++ b/lib/modsAdder/mods_adder_homepage.dart @@ -154,7 +154,7 @@ void modsAdderHomePage(context) { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 0), child: SuperListView.builder( - physics: const RangeMaintainingScrollPhysics(), + physics: const RangeMaintainingScrollPhysics(), itemCount: modAdderDragDropFiles.length, itemBuilder: (BuildContext context, int index) { return ListTile( @@ -592,547 +592,261 @@ void modsAdderHomePage(context) { }), ), child: SuperListView.builder( - // shrinkWrap: true, - physics: const RangeMaintainingScrollPhysics(), - itemCount: processedFileList.length, - itemBuilder: (context, index) { - if (processedFileList.isNotEmpty) { - return Card( - margin: const EdgeInsets.only(top: 0, bottom: 2, left: 0, right: 0), - color: Color(context.watch().uiBackgroundColorValue).withOpacity(context.watch().uiOpacityValue), - shape: RoundedRectangleBorder( - side: BorderSide(color: Theme.of(context).primaryColorLight), borderRadius: const BorderRadius.all(Radius.circular(2))), - child: ExpansionTile( - initiallyExpanded: true, - maintainState: true, - //Edit Item's name - title: Row( - children: [ - Padding( - padding: const EdgeInsets.only(top: 2, bottom: 2, right: 10), - child: Container( - width: 80, - height: 80, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - border: Border.all(color: Theme.of(context).hintColor), - ), - child: processedFileList[index].itemIconPath.isEmpty - ? Image.asset( - 'assets/img/placeholdersquare.png', - fit: BoxFit.fitWidth, - ) - : Image.file( - File(processedFileList[index].itemIconPath), - fit: BoxFit.fitWidth, - ), - ), + // shrinkWrap: true, + physics: const RangeMaintainingScrollPhysics(), + itemCount: processedFileList.length, + itemBuilder: (context, index) { + if (processedFileList.isNotEmpty) { + return Card( + margin: const EdgeInsets.only(top: 0, bottom: 2, left: 0, right: 0), + color: Color(context.watch().uiBackgroundColorValue).withOpacity(context.watch().uiOpacityValue), + shape: RoundedRectangleBorder( + side: BorderSide(color: Theme.of(context).primaryColorLight), borderRadius: const BorderRadius.all(Radius.circular(2))), + child: ExpansionTile( + initiallyExpanded: true, + maintainState: true, + //Edit Item's name + title: Row( + children: [ + Padding( + padding: const EdgeInsets.only(top: 2, bottom: 2, right: 10), + child: Container( + width: 80, + height: 80, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + border: Border.all(color: Theme.of(context).hintColor), ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (processedFileList[index].isUnknown) - DropdownButton2( - hint: Text(curLangText!.uiSelectACategory), - underline: const SizedBox(), - buttonStyleData: ButtonStyleData( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3), - border: Border.all(color: Theme.of(context).hintColor), - ), - width: 200, - height: 35, - ), - dropdownStyleData: DropdownStyleData( - decoration: BoxDecoration( - color: Theme.of(context).primaryColorLight, - borderRadius: BorderRadius.circular(2), - ), - padding: const EdgeInsets.symmetric(vertical: 5), - elevation: 3, - maxHeight: constraints.maxHeight * 0.5, - ), - iconStyleData: const IconStyleData(icon: Icon(Icons.arrow_drop_down), iconSize: 30), - menuItemStyleData: const MenuItemStyleData( - height: 30, - ), - items: dropdownButtonCateList - .map((item) => DropdownMenuItem( - value: item, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - padding: const EdgeInsets.only(bottom: 3), - child: Text( - item, - style: const TextStyle( - //fontSize: 14, - //fontWeight: FontWeight.bold, - //color: Colors.white, - ), - overflow: TextOverflow.ellipsis, - ), - ) - ], - ))) - .toList(), - value: _selectedCategories[index], - onChanged: (value) async { - _selectedCategories[index] = value.toString(); - String newItemPath = processedFileList[index].itemDirPath.replaceFirst( - p.dirname(processedFileList[index].itemDirPath), - Uri.file('$modManModsAdderPath/${_selectedCategories[index]}').toFilePath()); - await io.copyPath(processedFileList[index].itemDirPath, newItemPath); - //delete item dir - Directory(processedFileList[index].itemDirPath).deleteSync(recursive: true); - //delete parent dir if empty - if (Directory(p.dirname(processedFileList[index].itemDirPath)).listSync().isEmpty) { - Directory(p.dirname(processedFileList[index].itemDirPath)).deleteSync(recursive: true); - } - processedFileList[index].setNewParentPathToChildren(newItemPath.trim()); - processedFileList[index].itemDirPath = newItemPath; - processedFileList[index].category = value.toString(); - debugPrint(processedFileList[index].itemDirPath); - setState( - () {}, - ); - }, + child: processedFileList[index].itemIconPath.isEmpty + ? Image.asset( + 'assets/img/placeholdersquare.png', + fit: BoxFit.fitWidth, + ) + : Image.file( + File(processedFileList[index].itemIconPath), + fit: BoxFit.fitWidth, + ), + ), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (processedFileList[index].isUnknown) + DropdownButton2( + hint: Text(curLangText!.uiSelectACategory), + underline: const SizedBox(), + buttonStyleData: ButtonStyleData( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3), + border: Border.all(color: Theme.of(context).hintColor), ), - if (!processedFileList[index].isUnknown) - SizedBox( - width: 150, - height: 40, - child: Padding( - padding: const EdgeInsets.only(top: 10), - child: Text( - defaultCategoryDirs.contains(processedFileList[index].category) - ? defaultCategoryNames[defaultCategoryDirs.indexOf(processedFileList[index].category)] - : processedFileList[index].category, - style: TextStyle( - fontWeight: FontWeight.w600, - color: !processedFileList[index].toBeAdded - ? Theme.of(context).disabledColor - : Theme.of(context).textTheme.bodyMedium!.color)), - ), + width: 200, + height: 35, + ), + dropdownStyleData: DropdownStyleData( + decoration: BoxDecoration( + color: Theme.of(context).primaryColorLight, + borderRadius: BorderRadius.circular(2), ), - SizedBox( - height: 40, - child: _itemNameRenameIndex[index] - ? Row( + padding: const EdgeInsets.symmetric(vertical: 5), + elevation: 3, + maxHeight: constraints.maxHeight * 0.5, + ), + iconStyleData: const IconStyleData(icon: Icon(Icons.arrow_drop_down), iconSize: 30), + menuItemStyleData: const MenuItemStyleData( + height: 30, + ), + items: dropdownButtonCateList + .map((item) => DropdownMenuItem( + value: item, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: SizedBox( - //width: constraints.maxWidth * 0.4, - height: 40, - child: Form( - key: _subItemFormValidate, - child: TextFormField( - autofocus: true, - controller: renameTextBoxController, - maxLines: 1, - maxLength: 50, - decoration: InputDecoration( - contentPadding: const EdgeInsets.only(left: 10, top: 10), - border: const OutlineInputBorder(), - hintText: processedFileList[index].itemName, - counterText: '', + Container( + padding: const EdgeInsets.only(bottom: 3), + child: Text( + item, + style: const TextStyle( + //fontSize: 14, + //fontWeight: FontWeight.bold, + //color: Colors.white, ), - inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]'))], - validator: (value) { - if (value == null || value.isEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameCannotBeEmpty; - } - - if (Directory(p.dirname(processedFileList[index].itemDirPath)) - .listSync() - .whereType() - .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) - .isNotEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameAlreadyExisted; - } - - return null; - }, - onChanged: (value) { - setState( - () {}, - ); - }, - onEditingComplete: () async { - if (renameTextBoxController.text != processedFileList[index].itemName && - _subItemFormValidate.currentState!.validate()) { - if (renameTextBoxController.text.isNotEmpty) { - //rename text - String newItemName = renameTextBoxController.text.trim(); - if (processedFileList[index].category == defaultCategoryDirs[1] && - !renameTextBoxController.text.contains('[Ba]')) { - newItemName += ' [Ba]'; - } else if (processedFileList[index].category == defaultCategoryDirs[11] && - !renameTextBoxController.text.contains('[In]')) { - newItemName += ' [In]'; - } else if (processedFileList[index].category == defaultCategoryDirs[15] && - !renameTextBoxController.text.contains('[Ou]')) { - newItemName += ' [Ou]'; - } else if (processedFileList[index].category == defaultCategoryDirs[16] && - !renameTextBoxController.text.contains('[Se]')) { - newItemName += ' [Se]'; - } else { - newItemName = renameTextBoxController.text; - } - //change dir name - processedFileList[index].itemName = newItemName; - var newItemDir = await Directory(processedFileList[index].itemDirPath).rename( - Uri.file('${p.dirname(processedFileList[index].itemDirPath)}/$newItemName').toFilePath()); - processedFileList[index].setNewParentPathToChildren(newItemDir.path.trim()); - processedFileList[index].itemIconPath = processedFileList[index] - .itemIconPath - .replaceFirst(processedFileList[index].itemDirPath, newItemDir.path); - processedFileList[index].itemDirPath = newItemDir.path; - } - - _itemNameRenameIndex[index] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - - setState( - () {}, - ); - } - }, - ), - ), - ), - ), - const SizedBox( - width: 5, - ), - SizedBox( - width: 40, - child: MaterialButton( - onPressed: renameTextBoxController.text == processedFileList[index].itemName - ? null - : () async { - if (_subItemFormValidate.currentState!.validate()) { - if (renameTextBoxController.text.isNotEmpty) { - //rename text - String newItemName = renameTextBoxController.text.trim(); - if (processedFileList[index].category == defaultCategoryDirs[1] && - !renameTextBoxController.text.contains('[Ba]')) { - newItemName += ' [Ba]'; - } else if (processedFileList[index].category == defaultCategoryDirs[11] && - !renameTextBoxController.text.contains('[In]')) { - newItemName += ' [In]'; - } else if (processedFileList[index].category == defaultCategoryDirs[15] && - !renameTextBoxController.text.contains('[Ou]')) { - newItemName += ' [Ou]'; - } else if (processedFileList[index].category == defaultCategoryDirs[16] && - !renameTextBoxController.text.contains('[Se]')) { - newItemName += ' [Se]'; - } else { - newItemName = renameTextBoxController.text; - } - //change dir name - processedFileList[index].itemName = newItemName; - var newItemDir = await Directory(processedFileList[index].itemDirPath).rename( - Uri.file('${p.dirname(processedFileList[index].itemDirPath)}/$newItemName').toFilePath()); - processedFileList[index].setNewParentPathToChildren(newItemDir.path.trim()); - processedFileList[index].itemIconPath = processedFileList[index] - .itemIconPath - .replaceFirst(processedFileList[index].itemDirPath, newItemDir.path); - processedFileList[index].itemDirPath = newItemDir.path; - } - - _itemNameRenameIndex[index] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - - setState( - () {}, - ); - } - }, - child: const Icon(Icons.check), + overflow: TextOverflow.ellipsis, ), - ), - const SizedBox( - width: 5, - ), - SizedBox( - width: 40, - child: MaterialButton( - onPressed: () { - _itemNameRenameIndex[index] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - + ) + ], + ))) + .toList(), + value: _selectedCategories[index], + onChanged: (value) async { + _selectedCategories[index] = value.toString(); + String newItemPath = processedFileList[index].itemDirPath.replaceFirst(p.dirname(processedFileList[index].itemDirPath), + Uri.file('$modManModsAdderPath/${_selectedCategories[index]}').toFilePath()); + await io.copyPath(processedFileList[index].itemDirPath, newItemPath); + //delete item dir + Directory(processedFileList[index].itemDirPath).deleteSync(recursive: true); + //delete parent dir if empty + if (Directory(p.dirname(processedFileList[index].itemDirPath)).listSync().isEmpty) { + Directory(p.dirname(processedFileList[index].itemDirPath)).deleteSync(recursive: true); + } + processedFileList[index].setNewParentPathToChildren(newItemPath.trim()); + processedFileList[index].itemDirPath = newItemPath; + processedFileList[index].category = value.toString(); + debugPrint(processedFileList[index].itemDirPath); + setState( + () {}, + ); + }, + ), + if (!processedFileList[index].isUnknown) + SizedBox( + width: 150, + height: 40, + child: Padding( + padding: const EdgeInsets.only(top: 10), + child: Text( + defaultCategoryDirs.contains(processedFileList[index].category) + ? defaultCategoryNames[defaultCategoryDirs.indexOf(processedFileList[index].category)] + : processedFileList[index].category, + style: TextStyle( + fontWeight: FontWeight.w600, + color: !processedFileList[index].toBeAdded + ? Theme.of(context).disabledColor + : Theme.of(context).textTheme.bodyMedium!.color)), + ), + ), + SizedBox( + height: 40, + child: _itemNameRenameIndex[index] + ? Row( + children: [ + Expanded( + child: SizedBox( + //width: constraints.maxWidth * 0.4, + height: 40, + child: Form( + key: _subItemFormValidate, + child: TextFormField( + autofocus: true, + controller: renameTextBoxController, + maxLines: 1, + maxLength: 50, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 10, top: 10), + border: const OutlineInputBorder(), + hintText: processedFileList[index].itemName, + counterText: '', + ), + inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]'))], + validator: (value) { + if (value == null || value.isEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameCannotBeEmpty; + } + + if (Directory(p.dirname(processedFileList[index].itemDirPath)) + .listSync() + .whereType() + .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) + .isNotEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameAlreadyExisted; + } + + return null; + }, + onChanged: (value) { setState( () {}, ); }, - child: const Icon(Icons.close), - ), - ), - ], - ) - : Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(bottom: 3), - child: Text( - processedFileList[index].category == defaultCategoryDirs[17] - ? processedFileList[index].itemName.split('_').isNotEmpty && - processedFileList[index].itemName.split('_').first == 'it' && - processedFileList[index].itemName.split('_')[1] == 'wp' - ? processedFileList[index].itemName - : processedFileList[index].itemName.replaceFirst('_', '*').replaceAll('_', '/') - : processedFileList[index].itemName.replaceAll('_', '/'), - style: TextStyle( - fontWeight: FontWeight.w600, - color: !processedFileList[index].toBeAdded - ? Theme.of(context).disabledColor - : Theme.of(context).textTheme.bodyMedium!.color)), - ), - ), - const SizedBox( - width: 5, - ), - if (processedFileList[index].isChildrenDuplicated) - Padding( - padding: const EdgeInsets.only(right: 5), - child: Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).primaryColorLight), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - ), - child: Text( - curLangText!.uiDuplicateModsInside, - style: TextStyle( - fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), - ), - ), - ), - Visibility( - visible: !defaultCategoryNames.contains(processedFileList[index].category) || - processedFileList[index].category == defaultCategoryNames[13], - child: SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiEditName, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: !_isNameEditing && processedFileList[index].toBeAdded - ? () { - renameTextBoxController.text = processedFileList[index].itemName; - renameTextBoxController.selection = TextSelection( - baseOffset: 0, - extentOffset: renameTextBoxController.text.length, - ); - _isNameEditing = true; - _itemNameRenameIndex[index] = true; - setState( - () {}, - ); - } - : null, - child: const Icon(Icons.edit), - ), - ), - ), - ), - const SizedBox( - width: 5, - ), - if (processedFileList[index].toBeAdded) - SizedBox( - width: 40, - child: ModManTooltip( - message: curLangText!.uiMarkThisNotToBeAdded, - child: MaterialButton( - onPressed: () { - processedFileList[index].toBeAdded = false; - for (var mod in processedFileList[index].modList) { - mod.toBeAdded = false; - for (var submod in mod.submodList) { - submod.toBeAdded = false; - } - } - setState( - () {}, - ); - }, - child: const Icon( - Icons.check_box_outlined, - color: Colors.green, - ), - ), - ), - ), - if (!processedFileList[index].toBeAdded) - SizedBox( - width: 40, - child: ModManTooltip( - message: curLangText!.uiMarkThisToBeAdded, - child: MaterialButton( - onPressed: () { - processedFileList[index].toBeAdded = true; - for (var mod in processedFileList[index].modList) { - mod.toBeAdded = true; - for (var submod in mod.submodList) { - submod.toBeAdded = true; - } + onEditingComplete: () async { + if (renameTextBoxController.text != processedFileList[index].itemName && + _subItemFormValidate.currentState!.validate()) { + if (renameTextBoxController.text.isNotEmpty) { + //rename text + String newItemName = renameTextBoxController.text.trim(); + if (processedFileList[index].category == defaultCategoryDirs[1] && + !renameTextBoxController.text.contains('[Ba]')) { + newItemName += ' [Ba]'; + } else if (processedFileList[index].category == defaultCategoryDirs[11] && + !renameTextBoxController.text.contains('[In]')) { + newItemName += ' [In]'; + } else if (processedFileList[index].category == defaultCategoryDirs[15] && + !renameTextBoxController.text.contains('[Ou]')) { + newItemName += ' [Ou]'; + } else if (processedFileList[index].category == defaultCategoryDirs[16] && + !renameTextBoxController.text.contains('[Se]')) { + newItemName += ' [Se]'; + } else { + newItemName = renameTextBoxController.text; } - setState( - () {}, - ); - }, - child: const Icon( - Icons.check_box_outline_blank_outlined, - color: Colors.red, - ), - ), - ), - ), - ], - ), - ) - ], - ), - ), - ], - ), - - textColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - iconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - collapsedTextColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - //childrenPadding: const EdgeInsets.only(left: 10), - children: [ - //mods list - SuperListView.builder( - shrinkWrap: true, - physics: const RangeMaintainingScrollPhysics(), - itemCount: processedFileList[index].modList.length, - itemBuilder: (context, mIndex) { - var curMod = processedFileList[index].modList[mIndex]; - // _isProcessingMoreFiles = false; - //rename trigger - // //List mainFolderRenameIndex = []; - // if (mainFolderRenameIndex.isEmpty || mainFolderRenameIndex.length != processedFileList[index].modList.length) { - // mainFolderRenameIndex = List.generate(processedFileList[index].modList.length, (index) => false); - // } - // if (pathCharLengthList[index].isNotEmpty) { - // pathCharLengthList[index].clear(); - // } - - int pathLength = 0; - for (var file in curMod.filesInMod) { - String tempPath = file.path.replaceFirst(modManModsAdderPath, modManModsDirPath); - if (tempPath.length > pathLength) { - pathLength = tempPath.length; - } - } - for (var sub in curMod.submodList) { - for (var modFile in sub.files) { - String tempPath = modFile.path.replaceFirst(modManModsAdderPath, modManModsDirPath); - if (tempPath.length > pathLength) { - pathLength = tempPath.length; - } - } - } - - pathCharLengthList[index].insert(mIndex, pathLength); - - return ExpansionTile( - initiallyExpanded: false, - childrenPadding: const EdgeInsets.only(left: 15), - textColor: - MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - iconColor: - MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - collapsedTextColor: - MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - //Edit Name - title: mainFolderRenameIndex[index][mIndex] - ? Row( - children: [ - Expanded( - child: SizedBox( - //width: constraints.maxWidth * 0.4, - height: 40, - child: Form( - key: _subItemFormValidate, - child: TextFormField( - autofocus: true, - controller: renameTextBoxController, - maxLines: 1, - maxLength: 50, - decoration: InputDecoration( - contentPadding: const EdgeInsets.only(left: 10, top: 10), - border: const OutlineInputBorder(), - hintText: curMod.modName, - counterText: '', - ), - inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]'))], - validator: (value) { - if (value == null || value.isEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameCannotBeEmpty; - } - - if (Directory(processedFileList[index].itemDirPath) - .listSync() - .whereType() - .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) - .isNotEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameAlreadyExisted; + //change dir name + processedFileList[index].itemName = newItemName; + var newItemDir = await Directory(processedFileList[index].itemDirPath) + .rename(Uri.file('${p.dirname(processedFileList[index].itemDirPath)}/$newItemName').toFilePath()); + processedFileList[index].setNewParentPathToChildren(newItemDir.path.trim()); + processedFileList[index].itemIconPath = processedFileList[index] + .itemIconPath + .replaceFirst(processedFileList[index].itemDirPath, newItemDir.path); + processedFileList[index].itemDirPath = newItemDir.path; } - return null; - }, - onChanged: (value) { - int pathLength = 0; - for (var file in curMod.filesInMod) { - String tempPath = file.path.replaceFirst(modManModsAdderPath, modManModsDirPath); - if (tempPath.length > pathLength) { - pathLength = tempPath.length; - } - } - for (var sub in curMod.submodList) { - for (var modFile in sub.files) { - String tempPath = modFile.path - .replaceFirst(modManModsAdderPath, modManModsDirPath) - .replaceFirst(curMod.modName, value); - if (tempPath.length > pathLength) { - pathLength = tempPath.length; - } - } - } + _itemNameRenameIndex[index] = false; + renameTextBoxController.clear(); + _isNameEditing = false; - _pathLengthInNameEdit = pathLength; setState( () {}, ); - }, - onEditingComplete: () async { - if (renameTextBoxController.text != curMod.modName && _subItemFormValidate.currentState!.validate()) { + } + }, + ), + ), + ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: renameTextBoxController.text == processedFileList[index].itemName + ? null + : () async { + if (_subItemFormValidate.currentState!.validate()) { if (renameTextBoxController.text.isNotEmpty) { - curMod.modName = renameTextBoxController.text; - var newModDir = await Directory(curMod.modDirPath).rename( - Uri.file('${p.dirname(curMod.modDirPath)}/${renameTextBoxController.text}').toFilePath()); - curMod.setNewParentPathToChildren(newModDir.path.trim()); - curMod.modDirPath = newModDir.path; + //rename text + String newItemName = renameTextBoxController.text.trim(); + if (processedFileList[index].category == defaultCategoryDirs[1] && + !renameTextBoxController.text.contains('[Ba]')) { + newItemName += ' [Ba]'; + } else if (processedFileList[index].category == defaultCategoryDirs[11] && + !renameTextBoxController.text.contains('[In]')) { + newItemName += ' [In]'; + } else if (processedFileList[index].category == defaultCategoryDirs[15] && + !renameTextBoxController.text.contains('[Ou]')) { + newItemName += ' [Ou]'; + } else if (processedFileList[index].category == defaultCategoryDirs[16] && + !renameTextBoxController.text.contains('[Se]')) { + newItemName += ' [Se]'; + } else { + newItemName = renameTextBoxController.text; + } + //change dir name + processedFileList[index].itemName = newItemName; + var newItemDir = await Directory(processedFileList[index].itemDirPath).rename( + Uri.file('${p.dirname(processedFileList[index].itemDirPath)}/$newItemName').toFilePath()); + processedFileList[index].setNewParentPathToChildren(newItemDir.path.trim()); + processedFileList[index].itemIconPath = processedFileList[index] + .itemIconPath + .replaceFirst(processedFileList[index].itemDirPath, newItemDir.path); + processedFileList[index].itemDirPath = newItemDir.path; } - mainFolderRenameIndex[index][mIndex] = false; + _itemNameRenameIndex[index] = false; renameTextBoxController.clear(); _isNameEditing = false; @@ -1141,139 +855,88 @@ void modsAdderHomePage(context) { ); } }, - ), - ), - ), - ), - const SizedBox( - width: 5, - ), - Text('$_pathLengthInNameEdit/259 ${curLangText!.uiCharacters}', - style: TextStyle( - color: pathCharLengthList[index][mIndex] > 259 - ? Colors.red - : Theme.of(context).textTheme.bodyMedium!.color)), - const SizedBox( - width: 5, - ), - SizedBox( - width: 40, - child: MaterialButton( - onPressed: renameTextBoxController.text == curMod.modName - ? null - : () async { - if (_subItemFormValidate.currentState!.validate()) { - if (renameTextBoxController.text.isNotEmpty) { - curMod.modName = renameTextBoxController.text; - var newModDir = await Directory(curMod.modDirPath).rename( - Uri.file('${p.dirname(curMod.modDirPath)}/${renameTextBoxController.text}').toFilePath()); - curMod.setNewParentPathToChildren(newModDir.path.trim()); - curMod.modDirPath = newModDir.path; - } - - mainFolderRenameIndex[index][mIndex] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - _pathLengthInNameEdit = 0; - - setState( - () {}, - ); - } - }, - child: const Icon(Icons.check), - ), - ), - const SizedBox( - width: 5, + child: const Icon(Icons.check), ), - SizedBox( - width: 40, - child: MaterialButton( - onPressed: () { - mainFolderRenameIndex[index][mIndex] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - _pathLengthInNameEdit = 0; - - setState( - () {}, - ); - }, - child: const Icon(Icons.close), - ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: () { + _itemNameRenameIndex[index] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + + setState( + () {}, + ); + }, + child: const Icon(Icons.close), ), - ], - ) - : Row( - children: [ - Expanded( - child: Text(curMod.modName, + ), + ], + ) + : Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(bottom: 3), + child: Text( + processedFileList[index].category == defaultCategoryDirs[17] + ? processedFileList[index].itemName.split('_').isNotEmpty && + processedFileList[index].itemName.split('_').first == 'it' && + processedFileList[index].itemName.split('_')[1] == 'wp' + ? processedFileList[index].itemName + : processedFileList[index].itemName.replaceFirst('_', '*').replaceAll('_', '/') + : processedFileList[index].itemName.replaceAll('_', '/'), style: TextStyle( - fontWeight: FontWeight.w500, - color: !curMod.toBeAdded + fontWeight: FontWeight.w600, + color: !processedFileList[index].toBeAdded ? Theme.of(context).disabledColor : Theme.of(context).textTheme.bodyMedium!.color)), ), - const SizedBox( - width: 5, - ), - Text( - '${pathCharLengthList[index][mIndex]}/259 ${curLangText!.uiCharacters}', - style: TextStyle( - color: - pathCharLengthList[index][mIndex] > 259 ? Colors.red : Theme.of(context).textTheme.bodyMedium!.color), - ), - const SizedBox( - width: 5, - ), - if (curMod.isChildrenDuplicated) - Padding( - padding: const EdgeInsets.only(right: 5), - child: Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).primaryColorLight), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - ), - child: Text( - curLangText!.uiDuplicateModsInside, - style: TextStyle( - fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), - ), + ), + const SizedBox( + width: 5, + ), + if (processedFileList[index].isChildrenDuplicated) + Padding( + padding: const EdgeInsets.only(right: 5), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), ), - ), - if (curMod.isDuplicated) - Padding( - padding: const EdgeInsets.only(right: 5), - child: Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).primaryColorLight), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - ), - child: Text( - curLangText!.uiRenameThis, - style: TextStyle( - fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), - ), + child: Text( + curLangText!.uiDuplicateModsInside, + style: TextStyle( + fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), ), ), - SizedBox( + ), + Visibility( + visible: !defaultCategoryNames.contains(processedFileList[index].category) || + processedFileList[index].category == defaultCategoryNames[13], + child: SizedBox( width: 40, - child: ModManTooltip( + child: Tooltip( message: curLangText!.uiEditName, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), child: MaterialButton( - onPressed: !_isNameEditing && curMod.toBeAdded + onPressed: !_isNameEditing && processedFileList[index].toBeAdded ? () { - renameTextBoxController.text = curMod.modName; + renameTextBoxController.text = processedFileList[index].itemName; renameTextBoxController.selection = TextSelection( baseOffset: 0, extentOffset: renameTextBoxController.text.length, ); _isNameEditing = true; - mainFolderRenameIndex[index][mIndex] = true; - _pathLengthInNameEdit = pathCharLengthList[index][mIndex]; + _itemNameRenameIndex[index] = true; setState( () {}, ); @@ -1283,399 +946,727 @@ void modsAdderHomePage(context) { ), ), ), - const SizedBox( - width: 5, - ), - if (curMod.toBeAdded) - SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiMarkThisNotToBeAdded, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: () { - curMod.toBeAdded = false; - for (var submod in curMod.submodList) { + ), + const SizedBox( + width: 5, + ), + if (processedFileList[index].toBeAdded) + SizedBox( + width: 40, + child: ModManTooltip( + message: curLangText!.uiMarkThisNotToBeAdded, + child: MaterialButton( + onPressed: () { + processedFileList[index].toBeAdded = false; + for (var mod in processedFileList[index].modList) { + mod.toBeAdded = false; + for (var submod in mod.submodList) { submod.toBeAdded = false; } - if (processedFileList[index].modList.where((element) => element.toBeAdded).isEmpty) { - processedFileList[index].toBeAdded = false; - } - setState( - () {}, - ); - }, - child: const Icon( - Icons.check_box_outlined, - color: Colors.green, - ), + } + setState( + () {}, + ); + }, + child: const Icon( + Icons.check_box_outlined, + color: Colors.green, ), ), ), - if (!curMod.toBeAdded) - SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiMarkThisToBeAdded, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: () { - curMod.toBeAdded = true; - for (var submod in curMod.submodList) { + ), + if (!processedFileList[index].toBeAdded) + SizedBox( + width: 40, + child: ModManTooltip( + message: curLangText!.uiMarkThisToBeAdded, + child: MaterialButton( + onPressed: () { + processedFileList[index].toBeAdded = true; + for (var mod in processedFileList[index].modList) { + mod.toBeAdded = true; + for (var submod in mod.submodList) { submod.toBeAdded = true; } - if (processedFileList[index].modList.where((element) => element.toBeAdded).isNotEmpty) { - processedFileList[index].toBeAdded = true; + } + setState( + () {}, + ); + }, + child: const Icon( + Icons.check_box_outline_blank_outlined, + color: Colors.red, + ), + ), + ), + ), + ], + ), + ) + ], + ), + ), + ], + ), + + textColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + iconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + collapsedTextColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + //childrenPadding: const EdgeInsets.only(left: 10), + children: [ + //mods list + SuperListView.builder( + shrinkWrap: true, + physics: const RangeMaintainingScrollPhysics(), + itemCount: processedFileList[index].modList.length, + itemBuilder: (context, mIndex) { + var curMod = processedFileList[index].modList[mIndex]; + // _isProcessingMoreFiles = false; + //rename trigger + // //List mainFolderRenameIndex = []; + // if (mainFolderRenameIndex.isEmpty || mainFolderRenameIndex.length != processedFileList[index].modList.length) { + // mainFolderRenameIndex = List.generate(processedFileList[index].modList.length, (index) => false); + // } + // if (pathCharLengthList[index].isNotEmpty) { + // pathCharLengthList[index].clear(); + // } + + int pathLength = 0; + for (var file in curMod.filesInMod) { + String tempPath = file.path.replaceFirst(modManModsAdderPath, modManModsDirPath); + if (tempPath.length > pathLength) { + pathLength = tempPath.length; + } + } + for (var sub in curMod.submodList) { + for (var modFile in sub.files) { + String tempPath = modFile.path.replaceFirst(modManModsAdderPath, modManModsDirPath); + if (tempPath.length > pathLength) { + pathLength = tempPath.length; + } + } + } + + pathCharLengthList[index].insert(mIndex, pathLength); + + return ExpansionTile( + initiallyExpanded: false, + childrenPadding: const EdgeInsets.only(left: 15), + textColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + iconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + collapsedTextColor: + MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + //Edit Name + title: mainFolderRenameIndex[index][mIndex] + ? Row( + children: [ + Expanded( + child: SizedBox( + //width: constraints.maxWidth * 0.4, + height: 40, + child: Form( + key: _subItemFormValidate, + child: TextFormField( + autofocus: true, + controller: renameTextBoxController, + maxLines: 1, + maxLength: 50, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 10, top: 10), + border: const OutlineInputBorder(), + hintText: curMod.modName, + counterText: '', + ), + inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]'))], + validator: (value) { + if (value == null || value.isEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameCannotBeEmpty; + } + + if (Directory(processedFileList[index].itemDirPath) + .listSync() + .whereType() + .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) + .isNotEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameAlreadyExisted; + } + + return null; + }, + onChanged: (value) { + int pathLength = 0; + for (var file in curMod.filesInMod) { + String tempPath = file.path.replaceFirst(modManModsAdderPath, modManModsDirPath); + if (tempPath.length > pathLength) { + pathLength = tempPath.length; + } + } + for (var sub in curMod.submodList) { + for (var modFile in sub.files) { + String tempPath = modFile.path + .replaceFirst(modManModsAdderPath, modManModsDirPath) + .replaceFirst(curMod.modName, value); + if (tempPath.length > pathLength) { + pathLength = tempPath.length; + } + } + } + + _pathLengthInNameEdit = pathLength; + setState( + () {}, + ); + }, + onEditingComplete: () async { + if (renameTextBoxController.text != curMod.modName && _subItemFormValidate.currentState!.validate()) { + if (renameTextBoxController.text.isNotEmpty) { + curMod.modName = renameTextBoxController.text; + var newModDir = await Directory(curMod.modDirPath) + .rename(Uri.file('${p.dirname(curMod.modDirPath)}/${renameTextBoxController.text}').toFilePath()); + curMod.setNewParentPathToChildren(newModDir.path.trim()); + curMod.modDirPath = newModDir.path; + } + + mainFolderRenameIndex[index][mIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + + setState( + () {}, + ); + } + }, + ), + ), + ), + ), + const SizedBox( + width: 5, + ), + Text('$_pathLengthInNameEdit/259 ${curLangText!.uiCharacters}', + style: TextStyle( + color: pathCharLengthList[index][mIndex] > 259 ? Colors.red : Theme.of(context).textTheme.bodyMedium!.color)), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: renameTextBoxController.text == curMod.modName + ? null + : () async { + if (_subItemFormValidate.currentState!.validate()) { + if (renameTextBoxController.text.isNotEmpty) { + curMod.modName = renameTextBoxController.text; + var newModDir = await Directory(curMod.modDirPath) + .rename(Uri.file('${p.dirname(curMod.modDirPath)}/${renameTextBoxController.text}').toFilePath()); + curMod.setNewParentPathToChildren(newModDir.path.trim()); + curMod.modDirPath = newModDir.path; } + + mainFolderRenameIndex[index][mIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + _pathLengthInNameEdit = 0; + setState( () {}, ); - }, - child: const Icon( - Icons.check_box_outline_blank_outlined, - color: Colors.red, - ), - ), - ), + } + }, + child: const Icon(Icons.check), + ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: () { + mainFolderRenameIndex[index][mIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + _pathLengthInNameEdit = 0; + + setState( + () {}, + ); + }, + child: const Icon(Icons.close), + ), + ), + ], + ) + : Row( + children: [ + Expanded( + child: Text(curMod.modName, + style: TextStyle( + fontWeight: FontWeight.w500, + color: + !curMod.toBeAdded ? Theme.of(context).disabledColor : Theme.of(context).textTheme.bodyMedium!.color)), + ), + const SizedBox( + width: 5, + ), + Text( + '${pathCharLengthList[index][mIndex]}/259 ${curLangText!.uiCharacters}', + style: TextStyle( + color: pathCharLengthList[index][mIndex] > 259 ? Colors.red : Theme.of(context).textTheme.bodyMedium!.color), + ), + const SizedBox( + width: 5, + ), + if (curMod.isChildrenDuplicated) + Padding( + padding: const EdgeInsets.only(right: 5), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), ), - ], + child: Text( + curLangText!.uiDuplicateModsInside, + style: TextStyle( + fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), + ), + ), + ), + if (curMod.isDuplicated) + Padding( + padding: const EdgeInsets.only(right: 5), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + ), + child: Text( + curLangText!.uiRenameThis, + style: TextStyle( + fontSize: 14, fontWeight: FontWeight.normal, color: Theme.of(context).textTheme.bodyMedium?.color), + ), + ), + ), + SizedBox( + width: 40, + child: ModManTooltip( + message: curLangText!.uiEditName, + child: MaterialButton( + onPressed: !_isNameEditing && curMod.toBeAdded + ? () { + renameTextBoxController.text = curMod.modName; + renameTextBoxController.selection = TextSelection( + baseOffset: 0, + extentOffset: renameTextBoxController.text.length, + ); + _isNameEditing = true; + mainFolderRenameIndex[index][mIndex] = true; + _pathLengthInNameEdit = pathCharLengthList[index][mIndex]; + setState( + () {}, + ); + } + : null, + child: const Icon(Icons.edit), + ), + ), + ), + const SizedBox( + width: 5, ), - children: [ - //if file in mod folder found - if (curMod.filesInMod.isNotEmpty) - SuperListView.builder( - shrinkWrap: true, - physics: const RangeMaintainingScrollPhysics(), - itemCount: curMod.filesInMod.length, - itemBuilder: (context, fIndex) { - return ListTile( - title: Padding( - padding: const EdgeInsets.only(left: 0), - child: Text(p.basename(curMod.filesInMod[fIndex].path), - style: TextStyle(color: !curMod.toBeAdded ? Theme.of(context).disabledColor : null)), + if (curMod.toBeAdded) + SizedBox( + width: 40, + child: Tooltip( + message: curLangText!.uiMarkThisNotToBeAdded, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: () { + curMod.toBeAdded = false; + for (var submod in curMod.submodList) { + submod.toBeAdded = false; + } + if (processedFileList[index].modList.where((element) => element.toBeAdded).isEmpty) { + processedFileList[index].toBeAdded = false; + } + setState( + () {}, + ); + }, + child: const Icon( + Icons.check_box_outlined, + color: Colors.green, + ), ), - ); - }), - //if submmod list found - if (curMod.submodList.isNotEmpty) - SuperListView.builder( - shrinkWrap: true, - physics: const RangeMaintainingScrollPhysics(), - itemCount: curMod.submodList.length, - itemBuilder: (context, sIndex) { - var curSubmod = curMod.submodList[sIndex]; - return ExpansionTile( - initiallyExpanded: false, - childrenPadding: const EdgeInsets.only(left: 20), - textColor: MyApp.themeNotifier.value == ThemeMode.light - ? Theme.of(context).primaryColor - : Theme.of(context).iconTheme.color, - iconColor: MyApp.themeNotifier.value == ThemeMode.light - ? Theme.of(context).primaryColor - : Theme.of(context).iconTheme.color, - collapsedTextColor: MyApp.themeNotifier.value == ThemeMode.light - ? Theme.of(context).primaryColor - : Theme.of(context).iconTheme.color, - //Edit Sub Name - title: subFoldersRenameIndex[index][mIndex][sIndex] - ? Row( - children: [ - Expanded( - child: SizedBox( - height: context.watch().itemAdderSubItemETHeight, - child: Form( - key: _subItemFormValidate, - child: TextFormField( - autofocus: true, - controller: renameTextBoxController, - maxLines: 1, - maxLength: 50, - decoration: InputDecoration( - contentPadding: const EdgeInsets.only(left: 10, top: 10), - border: const OutlineInputBorder(), - hintText: curSubmod.submodName.split(' > ').last, - counterText: '', - ), - inputFormatters: [ - FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]')) - ], - validator: (value) { - if (value == null || value.isEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameCannotBeEmpty; - } + ), + ), + if (!curMod.toBeAdded) + SizedBox( + width: 40, + child: Tooltip( + message: curLangText!.uiMarkThisToBeAdded, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: () { + curMod.toBeAdded = true; + for (var submod in curMod.submodList) { + submod.toBeAdded = true; + } + if (processedFileList[index].modList.where((element) => element.toBeAdded).isNotEmpty) { + processedFileList[index].toBeAdded = true; + } + setState( + () {}, + ); + }, + child: const Icon( + Icons.check_box_outline_blank_outlined, + color: Colors.red, + ), + ), + ), + ), + ], + ), + children: [ + //if file in mod folder found + if (curMod.filesInMod.isNotEmpty) + SuperListView.builder( + shrinkWrap: true, + physics: const RangeMaintainingScrollPhysics(), + itemCount: curMod.filesInMod.length, + itemBuilder: (context, fIndex) { + return ListTile( + title: Padding( + padding: const EdgeInsets.only(left: 0), + child: Text(p.basename(curMod.filesInMod[fIndex].path), + style: TextStyle(color: !curMod.toBeAdded ? Theme.of(context).disabledColor : null)), + ), + ); + }), + //if submmod list found + if (curMod.submodList.isNotEmpty) + SuperListView.builder( + shrinkWrap: true, + physics: const RangeMaintainingScrollPhysics(), + itemCount: curMod.submodList.length, + itemBuilder: (context, sIndex) { + var curSubmod = curMod.submodList[sIndex]; + return ExpansionTile( + initiallyExpanded: false, + childrenPadding: const EdgeInsets.only(left: 20), + textColor: MyApp.themeNotifier.value == ThemeMode.light + ? Theme.of(context).primaryColor + : Theme.of(context).iconTheme.color, + iconColor: MyApp.themeNotifier.value == ThemeMode.light + ? Theme.of(context).primaryColor + : Theme.of(context).iconTheme.color, + collapsedTextColor: MyApp.themeNotifier.value == ThemeMode.light + ? Theme.of(context).primaryColor + : Theme.of(context).iconTheme.color, + //Edit Sub Name + title: subFoldersRenameIndex[index][mIndex][sIndex] + ? Row( + children: [ + Expanded( + child: SizedBox( + height: context.watch().itemAdderSubItemETHeight, + child: Form( + key: _subItemFormValidate, + child: TextFormField( + autofocus: true, + controller: renameTextBoxController, + maxLines: 1, + maxLength: 50, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 10, top: 10), + border: const OutlineInputBorder(), + hintText: curSubmod.submodName.split(' > ').last, + counterText: '', + ), + inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\/:*?"<>|]'))], + validator: (value) { + if (value == null || value.isEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameCannotBeEmpty; + } + + if (Directory(curMod.modDirPath) + .listSync() + .whereType() + .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) + .isNotEmpty) { + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); + return curLangText!.uiNameAlreadyExisted; + } - if (Directory(curMod.modDirPath) - .listSync() - .whereType() - .where((element) => p.basename(element.path).toLowerCase() == value.toLowerCase()) - .isNotEmpty) { - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(65); - return curLangText!.uiNameAlreadyExisted; + return null; + }, + onChanged: (value) { + setState( + () {}, + ); + }, + onEditingComplete: (() async { + if (renameTextBoxController.text != curSubmod.submodName.split(' > ').last && + _subItemFormValidate.currentState!.validate()) { + if (renameTextBoxController.text.isNotEmpty) { + List submodNameParts = curSubmod.submodName.split(' > '); + submodNameParts.removeLast(); + submodNameParts.add(renameTextBoxController.text); + curSubmod.submodName = submodNameParts.join(' > '); + var newSubmodDir = await Directory(curSubmod.submodDirPath).rename( + Uri.file('${p.dirname(curSubmod.submodDirPath)}/${renameTextBoxController.text}') + .toFilePath()); + curSubmod.files = newSubmodDir.listSync(recursive: true).whereType().toList(); + curSubmod.submodDirPath = newSubmodDir.path; + } + + //Clear + // ignore: use_build_context_synchronously + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); + subFoldersRenameIndex[index][mIndex][sIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + setState( + () {}, + ); + } + }), + ), + ), + ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: renameTextBoxController.text == curSubmod.submodName + ? null + : () async { + if (_subItemFormValidate.currentState!.validate()) { + if (renameTextBoxController.text.isNotEmpty) { + List submodNameParts = curSubmod.submodName.split(' > '); + submodNameParts.removeLast(); + submodNameParts.add(renameTextBoxController.text); + curSubmod.submodName = submodNameParts.join(' > '); + var newSubmodDir = await Directory(curSubmod.submodDirPath).rename( + Uri.file('${p.dirname(curSubmod.submodDirPath)}/${renameTextBoxController.text}') + .toFilePath()); + curSubmod.files = newSubmodDir.listSync(recursive: true).whereType().toList(); + curSubmod.submodDirPath = newSubmodDir.path; } - return null; - }, - onChanged: (value) { + //Clear + subFoldersRenameIndex[index][mIndex][sIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + // ignore: use_build_context_synchronously + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); setState( () {}, ); - }, - onEditingComplete: (() async { - if (renameTextBoxController.text != curSubmod.submodName.split(' > ').last && - _subItemFormValidate.currentState!.validate()) { - if (renameTextBoxController.text.isNotEmpty) { - List submodNameParts = curSubmod.submodName.split(' > '); - submodNameParts.removeLast(); - submodNameParts.add(renameTextBoxController.text); - curSubmod.submodName = submodNameParts.join(' > '); - var newSubmodDir = await Directory(curSubmod.submodDirPath).rename( - Uri.file('${p.dirname(curSubmod.submodDirPath)}/${renameTextBoxController.text}') - .toFilePath()); - curSubmod.files = newSubmodDir.listSync(recursive: true).whereType().toList(); - curSubmod.submodDirPath = newSubmodDir.path; - } - - //Clear - // ignore: use_build_context_synchronously - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); - subFoldersRenameIndex[index][mIndex][sIndex] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - setState( - () {}, - ); - } - }), - ), - ), + } + }, + child: const Icon(Icons.check), + ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: 40, + child: MaterialButton( + onPressed: () { + subFoldersRenameIndex[index][mIndex][sIndex] = false; + renameTextBoxController.clear(); + _isNameEditing = false; + // ignore: use_build_context_synchronously + Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); + + setState( + () {}, + ); + }, + child: const Icon(Icons.close), + ), + ), + ], + ) + : Row( + children: [ + Expanded( + child: Text(curSubmod.submodName, + style: TextStyle( + fontWeight: FontWeight.w400, + color: !curSubmod.toBeAdded + ? Theme.of(context).disabledColor + : Theme.of(context).textTheme.bodyMedium!.color)), + ), + const SizedBox( + width: 5, + ), + if (curSubmod.isDuplicated) + Padding( + padding: const EdgeInsets.only(right: 5), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).primaryColorLight), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), ), - ), - const SizedBox( - width: 5, - ), - SizedBox( - width: 40, - child: MaterialButton( - onPressed: renameTextBoxController.text == curSubmod.submodName - ? null - : () async { - if (_subItemFormValidate.currentState!.validate()) { - if (renameTextBoxController.text.isNotEmpty) { - List submodNameParts = curSubmod.submodName.split(' > '); - submodNameParts.removeLast(); - submodNameParts.add(renameTextBoxController.text); - curSubmod.submodName = submodNameParts.join(' > '); - var newSubmodDir = await Directory(curSubmod.submodDirPath).rename( - Uri.file('${p.dirname(curSubmod.submodDirPath)}/${renameTextBoxController.text}') - .toFilePath()); - curSubmod.files = newSubmodDir.listSync(recursive: true).whereType().toList(); - curSubmod.submodDirPath = newSubmodDir.path; - } - - //Clear - subFoldersRenameIndex[index][mIndex][sIndex] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - // ignore: use_build_context_synchronously - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); - setState( - () {}, - ); - } - }, - child: const Icon(Icons.check), + child: Text( + curLangText!.uiRenameThis, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).textTheme.bodyMedium?.color), ), ), - const SizedBox( - width: 5, + ), + SizedBox( + width: 40, + child: Tooltip( + message: curLangText!.uiEditName, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: !_isNameEditing && curSubmod.toBeAdded + ? () { + renameTextBoxController.text = curSubmod.submodName.split(' > ').last; + renameTextBoxController.selection = TextSelection( + baseOffset: 0, + extentOffset: renameTextBoxController.text.length, + ); + subFoldersRenameIndex[index][mIndex][sIndex] = true; + _isNameEditing = true; + setState( + () {}, + ); + } + : null, + child: const Icon(Icons.edit), ), - SizedBox( - width: 40, + ), + ), + const SizedBox( + width: 5, + ), + if (curSubmod.toBeAdded) + SizedBox( + width: 40, + child: Tooltip( + message: curLangText!.uiMarkThisNotToBeAdded, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), child: MaterialButton( onPressed: () { - subFoldersRenameIndex[index][mIndex][sIndex] = false; - renameTextBoxController.clear(); - _isNameEditing = false; - // ignore: use_build_context_synchronously - Provider.of(context, listen: false).itemAdderSubItemETHeightSet(40); - + curSubmod.toBeAdded = false; + if (curMod.submodList.where((element) => element.toBeAdded).isEmpty) { + curMod.toBeAdded = false; + } + if (processedFileList[index].modList.where((element) => element.toBeAdded).isEmpty) { + processedFileList[index].toBeAdded = false; + } setState( () {}, ); }, - child: const Icon(Icons.close), - ), - ), - ], - ) - : Row( - children: [ - Expanded( - child: Text(curSubmod.submodName, - style: TextStyle( - fontWeight: FontWeight.w400, - color: !curSubmod.toBeAdded - ? Theme.of(context).disabledColor - : Theme.of(context).textTheme.bodyMedium!.color)), - ), - const SizedBox( - width: 5, - ), - if (curSubmod.isDuplicated) - Padding( - padding: const EdgeInsets.only(right: 5), - child: Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 3), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).primaryColorLight), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - ), - child: Text( - curLangText!.uiRenameThis, - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.normal, - color: Theme.of(context).textTheme.bodyMedium?.color), - ), + child: const Icon( + Icons.check_box_outlined, + color: Colors.green, ), ), - SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiEditName, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: !_isNameEditing && curSubmod.toBeAdded - ? () { - renameTextBoxController.text = curSubmod.submodName.split(' > ').last; - renameTextBoxController.selection = TextSelection( - baseOffset: 0, - extentOffset: renameTextBoxController.text.length, - ); - subFoldersRenameIndex[index][mIndex][sIndex] = true; - _isNameEditing = true; - setState( - () {}, - ); - } - : null, - child: const Icon(Icons.edit), - ), - ), - ), - const SizedBox( - width: 5, ), - if (curSubmod.toBeAdded) - SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiMarkThisNotToBeAdded, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: () { - curSubmod.toBeAdded = false; - if (curMod.submodList.where((element) => element.toBeAdded).isEmpty) { - curMod.toBeAdded = false; - } - if (processedFileList[index].modList.where((element) => element.toBeAdded).isEmpty) { - processedFileList[index].toBeAdded = false; - } - setState( - () {}, - ); - }, - child: const Icon( - Icons.check_box_outlined, - color: Colors.green, - ), - ), - ), - ), - if (!curSubmod.toBeAdded) - SizedBox( - width: 40, - child: Tooltip( - message: curLangText!.uiMarkThisToBeAdded, - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: () { - curSubmod.toBeAdded = true; - if (curMod.submodList.where((element) => element.toBeAdded).isNotEmpty) { - curMod.toBeAdded = true; - } - if (processedFileList[index].modList.where((element) => element.toBeAdded).isNotEmpty) { - processedFileList[index].toBeAdded = true; - } - setState( - () {}, - ); - }, - child: const Icon( - Icons.check_box_outline_blank_outlined, - color: Colors.red, - ), - ), + ), + if (!curSubmod.toBeAdded) + SizedBox( + width: 40, + child: Tooltip( + message: curLangText!.uiMarkThisToBeAdded, + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: () { + curSubmod.toBeAdded = true; + if (curMod.submodList.where((element) => element.toBeAdded).isNotEmpty) { + curMod.toBeAdded = true; + } + if (processedFileList[index].modList.where((element) => element.toBeAdded).isNotEmpty) { + processedFileList[index].toBeAdded = true; + } + setState( + () {}, + ); + }, + child: const Icon( + Icons.check_box_outline_blank_outlined, + color: Colors.red, ), ), - ], - ), - children: [ - SuperListView.builder( - shrinkWrap: true, - physics: const RangeMaintainingScrollPhysics(), - itemCount: curSubmod.files.length, - itemBuilder: (context, fIndex) { - return ListTile( - title: Text( - p.basename(curSubmod.files[fIndex].path), - style: TextStyle(color: !curSubmod.toBeAdded ? Theme.of(context).disabledColor : null), ), - ); - }) - ], - ); - }) - ], - ); - }), - ], + ), + ], + ), + children: [ + SuperListView.builder( + shrinkWrap: true, + physics: const RangeMaintainingScrollPhysics(), + itemCount: curSubmod.files.length, + itemBuilder: (context, fIndex) { + return ListTile( + title: Text( + p.basename(curSubmod.files[fIndex].path), + style: TextStyle(color: !curSubmod.toBeAdded ? Theme.of(context).disabledColor : null), + ), + ); + }) + ], + ); + }) + ], + ); + }), + ], + ), + ); + } else { + Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + Provider.of(context, listen: false).modAdderProgressStatus.isEmpty + ? curLangText!.uiProcessingFiles + : Provider.of(context, listen: false).modAdderProgressStatus, + style: const TextStyle(fontSize: 20), + textAlign: TextAlign.center, ), - ); - } else { - Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - Provider.of(context, listen: false).modAdderProgressStatus.isEmpty - ? curLangText!.uiProcessingFiles - : Provider.of(context, listen: false).modAdderProgressStatus, - style: const TextStyle(fontSize: 20), - textAlign: TextAlign.center, - ), - const SizedBox( - height: 20, - ), - const CircularProgressIndicator(), - ], + const SizedBox( + height: 20, ), - ); - } - return null; - }), + const CircularProgressIndicator(), + ], + ), + ); + } + return null; + }), ), ], ); @@ -1955,7 +1946,7 @@ Future> modsAdderFilesProcess(context, List xFilePath .toList(); if (extraItemName.isNotEmpty) { matchData.retainWhere((e) => e.getENName() == extraItemName || e.getJPName() == extraItemName); - } + } // else { // matchData.where((element) => (element.getENName().isNotEmpty || element.getJPName().isNotEmpty) || element.category == defaultCategoryDirs[17]); // } @@ -2264,6 +2255,7 @@ Future> replaceNamesOfDuplicates(List process var newModDir = await Directory(mod.modDirPath).rename(Uri.file('${p.dirname(mod.modDirPath)}/${mod.modName}').toFilePath()); mod.setNewParentPathToChildren(newModDir.path.trim()); mod.modDirPath = newModDir.path; + _duplicateCounter--; } else if (mod.isChildrenDuplicated) { for (var submod in mod.submodList) { if (submod.isDuplicated) { @@ -2278,6 +2270,7 @@ Future> replaceNamesOfDuplicates(List process var newSubmodDir = await Directory(submod.submodDirPath).rename(Uri.file('${p.dirname(submod.submodDirPath)}/$submodName').toFilePath()); submod.files = newSubmodDir.listSync(recursive: true).whereType().toList(); submod.submodDirPath = newSubmodDir.path; + _duplicateCounter--; } } }