From e828da45c9fa89be58e4acf4055da323bce10b2c Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Thu, 16 Jun 2022 17:11:58 -0700 Subject: [PATCH 1/6] More improvements, features --- lib/file_functions.dart | 8 +-- lib/home_page.dart | 50 ++++++++++++++-- lib/main.dart | 59 ++++++++++++++++++- lib/popup_handlers.dart | 3 +- lib/state_provider.dart | 12 ++++ linux/flutter/generated_plugin_registrant.cc | 4 ++ linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 4 ++ pubspec.lock | 56 ++++++++++++++++++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 6 ++ windows/flutter/generated_plugins.cmake | 2 + windows/runner/main.cpp | 4 ++ 13 files changed, 196 insertions(+), 14 deletions(-) diff --git a/lib/file_functions.dart b/lib/file_functions.dart index 09d22470..cddf0506 100644 --- a/lib/file_functions.dart +++ b/lib/file_functions.dart @@ -563,7 +563,7 @@ Future dragDropFilesAdd(context, List newItemDragDropList, String? final selectedCategory = cateList.firstWhere((element) => element.categoryName == categoryName); if (selectedCategory.itemNames.indexWhere((element) => element == modName) == -1) { dubItemFound = false; - selectedCategory.itemNames.add(modName); + selectedCategory.itemNames.insert(0, modName); } else { dubItemFound = true; } @@ -573,12 +573,12 @@ Future dragDropFilesAdd(context, List newItemDragDropList, String? if (cate.itemNames.indexWhere((e) => e == modName) != -1) { int index = 0; if (cate.itemNames.length > 1) { - index = cate.itemNames.indexOf(newItemName.toString()); + index = cate.itemNames.indexOf(modName); } cate.allModFiles.addAll(newModList); //cate.allModFiles = []; - cate.imageIcons.add(thumbnails); - cate.numOfMods.add(0); + cate.imageIcons.insert(0, thumbnails); + cate.numOfMods.insert(0, 0); cate.numOfMods[index] = numOfMods; cate.numOfItems++; cate.numOfApplied.add(0); diff --git a/lib/home_page.dart b/lib/home_page.dart index caf2d3d9..994434b2 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:cross_file/cross_file.dart'; +import 'package:dart_vlc/dart_vlc.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:dropdown_button2/custom_dropdown_button2.dart'; import 'package:flutter/material.dart'; @@ -63,6 +64,15 @@ final List _newModToItemDragDropList = []; int _newModToItemIndex = 0; bool isModAddBtnClicked = false; +//Media Player controls +Player previewPlayer = Player(id: 69, registerTexture: true); +MediaType mediaType = MediaType.file; +CurrentState current = CurrentState(); +List medias = [ + Media.file(File('E:\\Steam\\steamapps\\common\\PHANTASYSTARONLINE2_NA_STEAM\\pso2_bin\\PSO2 Mod Manager\\Mods\\Emotes\\Glow stick Wave 1\\FS_Cowgirl3_Over_Glowstickwave1\\FS_Cowgirl3_Preview.mp4')), + Media.file(File('E:\\Steam\\steamapps\\common\\PHANTASYSTARONLINE2_NA_STEAM\\pso2_bin\\PSO2 Mod Manager\\Mods\\Emotes\\Glow stick Wave 1\\FS_Cowgirl3_Over_Glowstickwave1\\FS_Cowgirl3_Preview.mp4')), +]; + class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @@ -71,7 +81,8 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State with TickerProviderStateMixin { - final MultiSplitViewController _viewsController = MultiSplitViewController(areas: [Area(weight: 0.3), Area(weight: 0.3)]); + final MultiSplitViewController _viewsController = MultiSplitViewController(areas: [Area(weight: 0.30), Area(weight: 0.325)]); + final MultiSplitViewController _viewsControllerNoPreview = MultiSplitViewController(areas: [Area(weight: 0.30), Area(weight: 0.5)]); final MultiSplitViewController _verticalViewsController = MultiSplitViewController(areas: [Area(weight: 0.5)]); String modsViewAppBarName = ''; List selectedIndex = List.generate(cateList.length, (index) => -1); @@ -81,6 +92,7 @@ class _HomePageState extends State with TickerProviderStateMixin { bool isModSelected = false; int currentImg = 0; bool isPreviewImgsOn = false; + bool isPreviewVidOn = true; bool modViewExpandAll = false; bool isErrorInSingleItemName = false; @@ -111,6 +123,10 @@ class _HomePageState extends State with TickerProviderStateMixin { itemAdderAniController.dispose(); modAdderAniController.dispose(); _itemAdderTabcontroller.dispose(); + previewPlayer.dispose(); + _viewsController.dispose(); + _viewsControllerNoPreview.dispose(); + _verticalViewsController.dispose(); super.dispose(); } @@ -124,7 +140,7 @@ class _HomePageState extends State with TickerProviderStateMixin { MultiSplitView( axis: Axis.vertical, controller: _verticalViewsController, - children: [modPreviewView(), filesView()], + children: context.watch().previewWindowVisible ? [modPreviewView(), filesView()] : [filesView()], ) ], ); @@ -840,7 +856,10 @@ class _HomePageState extends State with TickerProviderStateMixin { width: double.infinity, child: Padding( padding: const EdgeInsets.symmetric(vertical: 5), - child: Text(context.watch().newItemDropDisplay), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: Text(context.watch().newItemDropDisplay), + ), )), ), ), @@ -1110,6 +1129,10 @@ class _HomePageState extends State with TickerProviderStateMixin { setState(() { isPreviewImgsOn = true; futureImagesGet = modFilesList[index].first.images; + previewPlayer.stop(); + previewPlayer.setVolume(0); + previewPlayer.open(Playlist(medias: medias), autoStart: true); + ; }); } // else { @@ -1473,7 +1496,12 @@ class _HomePageState extends State with TickerProviderStateMixin { child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.only(right: 10), - child: SizedBox(width: double.infinity, child: Text(' ${context.watch().newModDropDisplay}')), + child: SizedBox( + width: double.infinity, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: Text(context.watch().newModDropDisplay), + )), ), ), ) @@ -1598,13 +1626,14 @@ class _HomePageState extends State with TickerProviderStateMixin { Widget modPreviewView() { return Column( children: [ + //if (context.watch().previewWindowVisible) AppBar( title: Container(padding: const EdgeInsets.only(bottom: 10), child: const Text('Preview')), backgroundColor: Theme.of(context).canvasColor, foregroundColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, toolbarHeight: 30, ), - if (isPreviewImgsOn) + if (isPreviewImgsOn && !isPreviewVidOn) Expanded( child: FutureBuilder( future: futureImagesGet, @@ -1693,7 +1722,16 @@ class _HomePageState extends State with TickerProviderStateMixin { ); } } - })) + })), + if (isPreviewVidOn) + Expanded( + child: Scaffold( + body: Video( + player: previewPlayer, + fit: BoxFit.fill, + ), + ), + ) ], ); } diff --git a/lib/main.dart b/lib/main.dart index d6d110e6..5b39740e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,10 +4,12 @@ import 'dart:async'; import 'dart:io'; import 'package:bitsdojo_window/bitsdojo_window.dart'; +import 'package:dart_vlc/dart_vlc.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/data_loading_page.dart'; +import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/mod_classes.dart'; import 'package:pso2_mod_manager/custom_window_button.dart'; import 'package:pso2_mod_manager/state_provider.dart'; @@ -26,18 +28,20 @@ String modSettingsPath = ''; String deletedItemsPath = ''; String? checkSumFilePath; FilePickerResult? checksumLocation; +bool _previewWindowVisible = false; double windowsWidth = 1280.0; double windowsHeight = 720.0; Future? filesData; List allModFiles = []; var dataStreamController = StreamController(); Future main() async { + DartVLC.initialize(useFlutterNativeView: true); WidgetsFlutterBinding.ensureInitialized(); await windowManager.ensureInitialized(); final prefs = await SharedPreferences.getInstance(); windowsWidth = (prefs.getDouble('windowsWidth') ?? 1280.0); windowsHeight = (prefs.getDouble('windowsHeight') ?? 720.0); - + // WindowOptions windowOptions = const WindowOptions( // size: Size(1280, 720), // center: true, @@ -51,7 +55,7 @@ Future main() async { ], child: const RestartWidget(child: MyApp()))); doWhenWindowReady(() { Size initialSize = Size(windowsWidth, windowsHeight); - appWindow.minSize = const Size(1030, 500); + appWindow.minSize = const Size(1160, 500); appWindow.size = initialSize; appWindow.alignment = Alignment.center; appWindow.title = 'PSO2NGS Mod Manager'; @@ -133,6 +137,13 @@ class _MyHomePageState extends State with WindowListener { if (isDarkModeOn) { MyApp.themeNotifier.value = ThemeMode.dark; } + //previewWindows Check + _previewWindowVisible = (prefs.getBool('previewWindowVisible') ?? false); + if (_previewWindowVisible) { + Provider.of(context, listen: false).previewWindowVisibleSetTrue(); + } else { + Provider.of(context, listen: false).previewWindowVisibleSetFalse(); + } }); } @@ -399,6 +410,48 @@ class _MyHomePageState extends State with WindowListener { ), ), + //Preview + Tooltip( + message: 'Open/Hide Preview Window', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + //visualDensity: VisualDensity.compact, + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + if (Provider.of(context, listen: false).previewWindowVisible) { + Provider.of(context, listen: false).previewWindowVisibleSetFalse(); + prefs.setBool('previewWindowVisible', false); + previewPlayer.stop(); + } else { + Provider.of(context, listen: false).previewWindowVisibleSetTrue(); + prefs.setBool('previewWindowVisible', true); + } + }), + child: Row( + children: [ + const Icon( + Icons.preview_outlined, + size: 18, + ), + const SizedBox(width: 5), + const Text('Preview: ', style: TextStyle(fontWeight: FontWeight.w400)), + if (context.watch().previewWindowVisible) + SizedBox( + width: 23, + child: Text('ON', + style: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 13, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color))), + if (context.watch().previewWindowVisible == false) + const SizedBox(width: 23, child: Text('OFF', style: TextStyle(fontWeight: FontWeight.w600, fontSize: 13))) + ], + ), + ), + ), + //Dark theme if (MyApp.themeNotifier.value == ThemeMode.dark) MaterialButton( @@ -451,7 +504,7 @@ class _MyHomePageState extends State with WindowListener { : Column( children: const [ Text( - 'Waiting for user action', + 'Waiting for user\'s action', style: TextStyle(fontSize: 20), ), SizedBox( diff --git a/lib/popup_handlers.dart b/lib/popup_handlers.dart index d15ca0ff..9c5aeb24 100644 --- a/lib/popup_handlers.dart +++ b/lib/popup_handlers.dart @@ -334,13 +334,14 @@ Future itemDeleteDialog(context, double height, String popupTitle, String popupM final subFolderList = Directory(curCate.categoryPath).listSync().whereType(); for (var folder in subFolderList) { - if (Directory(folder.path).listSync(recursive: true).whereType().isEmpty && Directory(folder.path).listSync(recursive: true).whereType().isEmpty) { + if (Directory(folder.path).listSync(recursive: true).whereType().isEmpty) { Directory(folder.path).deleteSync(recursive: true); } } } curCate.imageIcons.removeAt(curCate.itemNames.indexOf(curItem)); + curCate.numOfMods.removeAt(curCate.itemNames.indexWhere((element) => element == curItem)); curCate.itemNames.removeWhere((element) => element == curItem); curCate.allModFiles.removeWhere((element) => element.modName == curItem); curCate.numOfItems--; diff --git a/lib/state_provider.dart b/lib/state_provider.dart index 62a45dab..9927f3ed 100644 --- a/lib/state_provider.dart +++ b/lib/state_provider.dart @@ -3,11 +3,13 @@ import 'package:flutter/cupertino.dart'; class stateProvider with ChangeNotifier { bool _isMainBinFound = false; + bool _previewWindowVisible = false; String _newItemDropDisplay = ''; String _newSingleItemDropDisplay = ''; String _newModDropDisplay = ''; bool get isMainBinFound => _isMainBinFound; + bool get previewWindowVisible => _previewWindowVisible; String get newItemDropDisplay => _newItemDropDisplay; String get newSingleItemDropDisplay => _newSingleItemDropDisplay; String get newModDropDisplay => _newModDropDisplay; @@ -22,6 +24,16 @@ class stateProvider with ChangeNotifier { notifyListeners(); } + void previewWindowVisibleSetTrue() { + _previewWindowVisible = true; + notifyListeners(); + } + + void previewWindowVisibleSetFalse() { + _previewWindowVisible = false; + notifyListeners(); + } + //itemList Display void singleItemsDropAdd(List paramList) { for (var file in paramList) { diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 0a0a8976..61b49a5b 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include #include @@ -16,6 +17,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) bitsdojo_window_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "BitsdojoWindowPlugin"); bitsdojo_window_plugin_register_with_registrar(bitsdojo_window_linux_registrar); + g_autoptr(FlPluginRegistrar) dart_vlc_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DartVlcPlugin"); + dart_vlc_plugin_register_with_registrar(dart_vlc_registrar); g_autoptr(FlPluginRegistrar) desktop_drop_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DesktopDropPlugin"); desktop_drop_plugin_register_with_registrar(desktop_drop_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index db194301..41254e3d 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_linux + dart_vlc desktop_drop screen_retriever url_launcher_linux diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index f8cd1c18..fa9aa5a4 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import bitsdojo_window_macos +import dart_vlc import desktop_drop +import path_provider_macos import screen_retriever import shared_preferences_macos import url_launcher_macos @@ -14,7 +16,9 @@ import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) + DartVlcPlugin.register(with: registry.registrar(forPlugin: "DartVlcPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) diff --git a/pubspec.lock b/pubspec.lock index c36a4368..9c1142ac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" + audio_video_progress_bar: + dependency: transitive + description: + name: audio_video_progress_bar + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.0" bitsdojo_window: dependency: "direct main" description: @@ -99,6 +106,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + dart_vlc: + dependency: "direct main" + description: + name: dart_vlc + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1" + dart_vlc_ffi: + dependency: transitive + description: + name: dart_vlc_ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.8" desktop_drop: dependency: "direct main" description: @@ -153,6 +174,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_native_view: + dependency: transitive + description: + name: flutter_native_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -233,6 +261,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.1" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.15" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" path_provider_linux: dependency: transitive description: @@ -240,6 +289,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" path_provider_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 612e6022..0363b06b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: url_launcher: ^6.1.2 intl: ^0.17.0 window_manager: ^0.2.5 + dart_vlc: ^0.2.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index db0f73ab..681ac6e4 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,7 +7,9 @@ #include "generated_plugin_registrant.h" #include +#include #include +#include #include #include #include @@ -15,8 +17,12 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { BitsdojoWindowPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("BitsdojoWindowPlugin")); + DartVlcPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DartVlcPlugin")); DesktopDropPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("DesktopDropPlugin")); + FlutterNativeViewPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterNativeViewPlugin")); ScreenRetrieverPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 79139113..485fe01c 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -4,7 +4,9 @@ list(APPEND FLUTTER_PLUGIN_LIST bitsdojo_window_windows + dart_vlc desktop_drop + flutter_native_view screen_retriever url_launcher_windows window_manager diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index 7c81bf55..e65a352d 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -4,6 +4,8 @@ auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); #include #include +#include "flutter_native_view/flutter_native_view_plugin.h" + #include "flutter_window.h" #include "utils.h" @@ -34,6 +36,8 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, } window.SetQuitOnClose(true); + flutternativeview::NativeViewContainer::GetInstance()->Create(); + ::MSG msg; while (::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); From 6340a6b16ab8d0bfc14ee53f30aa76527737d211 Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Thu, 16 Jun 2022 22:49:58 -0700 Subject: [PATCH 2/6] Improvements --- lib/file_functions.dart | 84 ++++++++++++++++++++++++++++++-- lib/home_page.dart | 104 +++++++++++++++++++++++++++++----------- lib/mod_classes.dart | 28 ++++++----- lib/mods_loader.dart | 16 +++++-- lib/popup_handlers.dart | 26 ++++++---- 5 files changed, 201 insertions(+), 57 deletions(-) diff --git a/lib/file_functions.dart b/lib/file_functions.dart index cddf0506..a13bbd49 100644 --- a/lib/file_functions.dart +++ b/lib/file_functions.dart @@ -351,7 +351,7 @@ Future dragDropSingleFilesAdd(context, List newItemDragDropList, St List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true); + ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, []); newModFile.categoryName = selectedCategoryName.toString(); newModFile.categoryPath = catePath; newModList.add(newModFile); @@ -542,7 +542,9 @@ Future dragDropFilesAdd(context, List newItemDragDropList, String? List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true); + List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); + + ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); newModFile.categoryName = selectedCategoryName.toString(); newModFile.categoryPath = catePath; newModList.add(newModFile); @@ -648,8 +650,9 @@ Future dragDropModsAdd(context, List newModDragDropList, String cur final iceName = file.path.split('\\').last; final iceParents = file.path.split(curItemName).last.split('\\$iceName').first.replaceAll('\\', ' > ').trim(); List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); + List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true); + ModFile newModFile = ModFile(0, newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); newModFile.categoryName = matchedCategory.categoryName; newModFile.categoryPath = matchedCategory.categoryPath; newMods.add(newModFile); @@ -677,3 +680,78 @@ Future dragDropModsAdd(context, List newModDragDropList, String cur matchedCategory.allModFiles.addAll(newMods); matchedCategory.numOfMods[index] += parents.length; } + +// New Mod Adders Folder Only +Future dragDropModsAddFoldersOnly(context, List newModDragDropList, String curItemName, String itemPath, int index, String? newItemName) async { + for (var xFile in newModDragDropList) { + await Future( + () { + final files = Directory(xFile.path).listSync(recursive: true).whereType(); + if (files.isNotEmpty) { + for (var file in files) { + final fileTailPath = file.path.split('${xFile.name}\\').last.split('\\'); + String newPath = itemPath; + if (fileTailPath.indexWhere((e) => e == 'win32' || e == 'win32_na' || e == 'win32reboot' || e == 'win32reboot_na') != -1) { + fileTailPath.removeRange(fileTailPath.indexWhere((e) => e == 'win32' || e == 'win32_na' || e == 'win32reboot' || e == 'win32reboot_na'), fileTailPath.indexOf(fileTailPath.last)); + String finalTailPath = fileTailPath.join('\\'); + if (newItemName == null) { + newPath += '\\${xFile.name}\\$finalTailPath'; + } + } else { + String finalTailPath = fileTailPath.join('\\'); + if (newItemName == null) { + newPath += '\\${xFile.name}\\$finalTailPath'; + } + } + + File(newPath).createSync(recursive: true); + File(file.path).copySync(newPath); + } + } + + String newModPath = '$itemPath\\${xFile.name}'; + + //Add to list + List newMods = []; + final matchedCategory = cateList.firstWhere((element) => element.itemNames.indexWhere((e) => e == curItemName) != -1); + final filesList = Directory(newModPath).listSync(recursive: true).whereType(); + List parentsList = []; + for (var file in filesList) { + if (p.extension(file.path) == '') { + final iceName = file.path.split('\\').last; + final iceParents = file.path.split(curItemName).last.split('\\$iceName').first.replaceAll('\\', ' > ').trim(); + List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); + List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); + + ModFile newModFile = ModFile(0, newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); + newModFile.categoryName = matchedCategory.categoryName; + newModFile.categoryPath = matchedCategory.categoryPath; + newMods.add(newModFile); + parentsList.add(newModFile.iceParent); + + //Json Write + allModFiles.add(newModFile); + allModFiles.map((mod) => mod.toJson()).toList(); + File(modSettingsPath).writeAsStringSync(json.encode(allModFiles)); + } + } + + final parents = parentsList.toSet().toList(); + for (var parent in parents) { + final sameParentMods = newMods.where((element) => element.iceParent == parent); + modFilesList.add(sameParentMods.toList()); + } + + int index = 0; + if (matchedCategory.itemNames.length > 1) { + index = matchedCategory.itemNames.indexOf(curItemName); + } + + isLoading.clear(); + matchedCategory.allModFiles.addAll(newMods); + matchedCategory.numOfMods[index] += parents.length; + }, + ); + Provider.of(context, listen: false).modsDropAddRemoveFirst(); + } +} diff --git a/lib/home_page.dart b/lib/home_page.dart index 994434b2..d28261d2 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -32,6 +32,7 @@ List modAppliedDup = []; List originalFilesMissingList = []; List backupFilesMissingList = []; List isLoading = []; +bool isModAddFolderOnly = true; //New Cate bool addCategoryVisible = false; @@ -65,13 +66,10 @@ int _newModToItemIndex = 0; bool isModAddBtnClicked = false; //Media Player controls -Player previewPlayer = Player(id: 69, registerTexture: true); +Player previewPlayer = Player(id: 69, registerTexture: true, commandlineArguments: ['--no-video-title-show']); MediaType mediaType = MediaType.file; CurrentState current = CurrentState(); -List medias = [ - Media.file(File('E:\\Steam\\steamapps\\common\\PHANTASYSTARONLINE2_NA_STEAM\\pso2_bin\\PSO2 Mod Manager\\Mods\\Emotes\\Glow stick Wave 1\\FS_Cowgirl3_Over_Glowstickwave1\\FS_Cowgirl3_Preview.mp4')), - Media.file(File('E:\\Steam\\steamapps\\common\\PHANTASYSTARONLINE2_NA_STEAM\\pso2_bin\\PSO2 Mod Manager\\Mods\\Emotes\\Glow stick Wave 1\\FS_Cowgirl3_Over_Glowstickwave1\\FS_Cowgirl3_Preview.mp4')), -]; +List medias = []; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @@ -92,7 +90,7 @@ class _HomePageState extends State with TickerProviderStateMixin { bool isModSelected = false; int currentImg = 0; bool isPreviewImgsOn = false; - bool isPreviewVidOn = true; + bool isPreviewVidOn = false; bool modViewExpandAll = false; bool isErrorInSingleItemName = false; @@ -1127,19 +1125,46 @@ class _HomePageState extends State with TickerProviderStateMixin { onHover: (value) { if (value) { setState(() { - isPreviewImgsOn = true; - futureImagesGet = modFilesList[index].first.images; - previewPlayer.stop(); - previewPlayer.setVolume(0); - previewPlayer.open(Playlist(medias: medias), autoStart: true); - ; + if (modFilesList[index].first.images != null) { + isPreviewImgsOn = true; + futureImagesGet = modFilesList[index].first.images; + } + //print(modFilesList[index].first.previewVids!.length); + if (modFilesList[index].first.previewVids!.isNotEmpty) { + isPreviewVidOn = true; + isPreviewImgsOn = false; + previewPlayer.setVolume(0.0); + bool itemFound = false; + for (var vid in modFilesList[index].first.previewVids!) { + if (medias.contains(Media.file(vid))) { + itemFound = true; + } else { + medias.clear(); + } + } + + if (medias.isEmpty || !itemFound) { + for (var vid in modFilesList[index].first.previewVids!) { + medias.add(Media.file(vid)); + } + previewPlayer.open(Playlist(medias: medias, playlistMode: PlaylistMode.single), autoStart: true); + } else { + previewPlayer.bufferingProgressController.done; + previewPlayer.play(); + } + } + }); + } else { + setState(() { + isPreviewImgsOn = false; + isPreviewVidOn = false; + previewPlayer.pause(); + //isPreviewImgsOn = false; + // { + // previewPlayer.pause(); + // } }); } - // else { - // setState(() { - // isPreviewImgsOn = false; - // }); - // } }, child: Card( shape: RoundedRectangleBorder( @@ -1467,6 +1492,12 @@ class _HomePageState extends State with TickerProviderStateMixin { detail.files.sort(((a, b) => a.name.compareTo(b.name))); _newModToItemDragDropList.addAll(detail.files); context.read().modsDropAdd(detail.files); + for (var element in detail.files) { + if (!Directory(element.path).existsSync()) { + isModAddFolderOnly = false; + break; + } + } }); }, onDragEntered: (detail) { @@ -1518,6 +1549,7 @@ class _HomePageState extends State with TickerProviderStateMixin { child: Padding( padding: const EdgeInsets.only(top: 10, left: 10, right: 10), child: TextFormField( + enabled: !isModAddFolderOnly, controller: newModToItemAddController, //maxLengthEnforcement: MaxLengthEnforcement.enforced, //maxLength: 100, @@ -1528,7 +1560,7 @@ class _HomePageState extends State with TickerProviderStateMixin { isDense: true, ), validator: (value) { - if (value == null || value.isEmpty) { + if (!isModAddFolderOnly && (value == null || value.isEmpty)) { return 'Mod name can\'t be empty'; } if (modFilesList.indexWhere((e) => e.indexWhere((element) => element.iceParent.split(' > ').last == value) != -1) != -1) { @@ -1566,6 +1598,7 @@ class _HomePageState extends State with TickerProviderStateMixin { setState(() { _newModToItemDragDropList.clear(); newModToItemAddController.clear(); + isModAddFolderOnly = true; context.read().modsDropAddClear(); //addModToItemVisible = false; switch (modAdderAniController.status) { @@ -1592,17 +1625,30 @@ class _HomePageState extends State with TickerProviderStateMixin { if (newModToItemFormKey.currentState!.validate()) { if (modFilesList.isNotEmpty) { isModAddBtnClicked = true; - dragDropModsAdd(context, _newModToItemDragDropList, modsViewAppBarName, modFilesList.first.first.modPath, _newModToItemIndex, - newModToItemAddController.text.isEmpty ? null : newModToItemAddController.text) - .then((_) { - setState(() { - //setstate to refresh list - _newModToItemDragDropList.clear(); - newModToItemAddController.clear(); - isModAddBtnClicked = false; - isPreviewImgsOn = false; + if (isModAddFolderOnly) { + dragDropModsAddFoldersOnly(context, _newModToItemDragDropList, modsViewAppBarName, modFilesList.first.first.modPath, _newModToItemIndex, null).then((_) { + setState(() { + //setstate to refresh list + _newModToItemDragDropList.clear(); + newModToItemAddController.clear(); + isModAddBtnClicked = false; + isPreviewImgsOn = false; + }); }); - }); + } else { + isModAddFolderOnly = true; + dragDropModsAdd(context, _newModToItemDragDropList, modsViewAppBarName, modFilesList.first.first.modPath, _newModToItemIndex, + newModToItemAddController.text.isEmpty ? null : newModToItemAddController.text) + .then((_) { + setState(() { + //setstate to refresh list + _newModToItemDragDropList.clear(); + newModToItemAddController.clear(); + isModAddBtnClicked = false; + isPreviewImgsOn = false; + }); + }); + } } //addItemVisible = false; @@ -1633,7 +1679,7 @@ class _HomePageState extends State with TickerProviderStateMixin { foregroundColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, toolbarHeight: 30, ), - if (isPreviewImgsOn && !isPreviewVidOn) + if (isPreviewImgsOn) Expanded( child: FutureBuilder( future: futureImagesGet, diff --git a/lib/mod_classes.dart b/lib/mod_classes.dart index b3745f1b..e206e453 100644 --- a/lib/mod_classes.dart +++ b/lib/mod_classes.dart @@ -33,19 +33,20 @@ class ModCategory { class ModFile extends ModCategory { ModFile( - this.numOfSubItems, - this.modPath, //mod folder path - this.modName, //mod folder name, - this.icePath, - this.iceName, - this.iceParent, - this.originalIcePath, - this.backupIcePath, - this.images, - this.isApplied, - this.isSFW, - this.isNew - ) : super('', '', [], [], 0, [], [], []); + this.numOfSubItems, + this.modPath, //mod folder path + this.modName, //mod folder name, + this.icePath, + this.iceName, + this.iceParent, + this.originalIcePath, + this.backupIcePath, + this.images, + this.isApplied, + this.isSFW, + this.isNew, + this.previewVids) + : super('', '', [], [], 0, [], [], []); int numOfSubItems; String modPath; @@ -59,6 +60,7 @@ class ModFile extends ModCategory { bool isApplied; bool isSFW; bool isNew; + List? previewVids; fromJson(Map json) { categoryName = json['categoryName']; diff --git a/lib/mods_loader.dart b/lib/mods_loader.dart index b0e04420..e1968af1 100644 --- a/lib/mods_loader.dart +++ b/lib/mods_loader.dart @@ -26,7 +26,8 @@ Future> modsLoader() async { //JSON Loader void convertData(var jsonResponse) { for (var b in jsonResponse) { - ModFile mod = ModFile(0, b['modPath'], b['modName'], b['icePath'], b['iceName'], b['iceParent'], b['originalIcePath'], b['backupIcePath'], null, b['isApplied'], b['isSFW'], b['isNew']); + ModFile mod = + ModFile(0, b['modPath'], b['modName'], b['icePath'], b['iceName'], b['iceParent'], b['originalIcePath'], b['backupIcePath'], null, b['isApplied'], b['isSFW'], b['isNew'], null); mod.categoryPath = b['categoryPath']; mod.categoryName = b['categoryName']; modFilesFromJson.add(mod); @@ -44,6 +45,7 @@ Future> modsLoader() async { String modName = '', modPath = ''; String iceParents = ''; List imgFiles = []; + List vidFiles = []; //Helpers for (var element in iceFilePathSplit) { @@ -69,12 +71,19 @@ Future> modsLoader() async { } var imgList = getImagesList(imgFiles); + //Vids helper + for (var vidFile in Directory(iceFile.parent.path).listSync(recursive: false).whereType()) { + if (p.extension(vidFile.path) == '.mp4' || p.extension(vidFile.path) == '.webm') { + vidFiles.add(vidFile); + } + } + //New ModFile - ModFile newModFile = ModFile(0, modPath, modName, iceFile.path, iceFilePathSplit.last, iceParents, '', '', imgList, false, true, false); + ModFile newModFile = ModFile(0, modPath, modName, iceFile.path, iceFilePathSplit.last, iceParents, '', '', imgList, false, true, false, vidFiles); newModFile.categoryName = categoryName; newModFile.categoryPath = categoryPath; var jsonModFile = modFilesFromJson.firstWhere((e) => e.icePath == newModFile.icePath, orElse: () { - return ModFile(0, '', '', '', '', '', '', '', null, false, true, false); + return ModFile(0, '', '', '', '', '', '', '', null, false, true, false, []); }); if (jsonModFile.icePath.isNotEmpty) { newModFile.backupIcePath = jsonModFile.backupIcePath; @@ -112,6 +121,7 @@ List categories(List allModFiles) { imgFilesGet.add(file); } } + if (imgFilesGet.isNotEmpty) { imgFiles.addAll(imgFilesGet); } else { diff --git a/lib/popup_handlers.dart b/lib/popup_handlers.dart index 9c5aeb24..002976f5 100644 --- a/lib/popup_handlers.dart +++ b/lib/popup_handlers.dart @@ -6,6 +6,7 @@ import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/main.dart'; import 'package:pso2_mod_manager/mod_classes.dart'; +import 'package:pso2_mod_manager/mods_loader.dart'; import 'package:pso2_mod_manager/state_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; @@ -426,21 +427,28 @@ Future modDeleteDialog(context, double height, String popupTitle, String popupMe } } - final subFolderList = Directory(curModPath).listSync().whereType(); - for (var folder in subFolderList) { - if (Directory(folder.path).listSync(recursive: true).whereType().isEmpty && Directory(folder.path).listSync(recursive: true).whereType().isEmpty) { - Directory(folder.path).deleteSync(recursive: true); + if (Directory(curModPath).existsSync()) { + final subFolderList = Directory(curModPath).listSync().whereType(); + for (var folder in subFolderList) { + if (Directory(folder.path).listSync(recursive: true).whereType().isEmpty && Directory(folder.path).listSync(recursive: true).whereType().isEmpty) { + Directory(folder.path).deleteSync(recursive: true); + } + } + + if (Directory(curModPath).listSync(recursive: true).whereType().isEmpty && Directory(curModPath).listSync(recursive: true).whereType().isEmpty) { + Directory(curModPath).deleteSync(recursive: true); } - } - if (Directory(curModPath).listSync(recursive: true).whereType().isEmpty && Directory(curModPath).listSync(recursive: true).whereType().isEmpty) { - Directory(curModPath).deleteSync(recursive: true); } ModCategory curCate = cateList.firstWhere((cate) => cate.allModFiles.indexWhere((file) => file.modPath == curModPath) != -1); final curModIndex = curCate.itemNames.indexOf(curModName); curCate.numOfMods[curModIndex]--; - modFilesList.removeWhere((element) => element == modsList); - allModFiles.removeWhere((element) => element.categoryPath == curCate.categoryPath && element.modName == curModName); + modFilesList.removeAt(modFilesList.indexOf(modsList)); + for (var element in modsList) { + curCate.allModFiles.remove(element); + allModFiles.remove(element); + } + } }), child: const Text('Sure')) From ee39cf269de1d943c17b3ec53d40f634837f1ceb Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Sun, 19 Jun 2022 17:04:25 -0700 Subject: [PATCH 3/6] More features, bug fixes --- lib/file_functions.dart | 61 +- lib/home_page.dart | 1488 ++++++++++------- lib/main.dart | 92 +- lib/mod_classes.dart | 10 +- lib/mods_loader.dart | 62 +- lib/popup_handlers.dart | 116 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 70 + pubspec.yaml | 2 + windows/runner/main.cpp | 2 - 10 files changed, 1243 insertions(+), 662 deletions(-) diff --git a/lib/file_functions.dart b/lib/file_functions.dart index a13bbd49..78551cec 100644 --- a/lib/file_functions.dart +++ b/lib/file_functions.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'dart:io'; import 'package:cross_file/cross_file.dart'; +import 'package:flutter/foundation.dart'; +import 'package:intl/intl.dart'; import 'package:pso2_mod_manager/mod_classes.dart'; import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/mods_loader.dart'; @@ -154,8 +156,11 @@ Future modsToDataAdder(List modList) async { //Applied mods to app list for (var mod in actualAppliedMods) { + DateTime now = DateTime.now(); + String formattedDate = DateFormat('MM-dd-yyyy').format(now); if (appliedModsList.isEmpty) { - appliedModsList.add([mod]); + mod.appliedDate = formattedDate; + appliedModsList.insert(0, [mod]); } else { final tempMods = appliedModsList.firstWhere( (modList) => modList.indexWhere((applied) => applied.iceParent == mod.iceParent && applied.modName == mod.modName) != -1, @@ -166,9 +171,11 @@ Future modsToDataAdder(List modList) async { if (tempMods.isNotEmpty) { tempMods.add(mod); } else { - appliedModsList.add([mod]); + mod.appliedDate = formattedDate; + appliedModsList.insert(0, [mod]); } } + appliedModsList.sort(((a, b) => a.first.appliedDate.compareTo(b.first.appliedDate))); } allModFiles.map((mod) => mod.toJson()).toList(); @@ -351,7 +358,7 @@ Future dragDropSingleFilesAdd(context, List newItemDragDropList, St List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, []); + ModFile newModFile = ModFile('', newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, false, []); newModFile.categoryName = selectedCategoryName.toString(); newModFile.categoryPath = catePath; newModList.add(newModFile); @@ -544,7 +551,7 @@ Future dragDropFilesAdd(context, List newItemDragDropList, String? List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); + ModFile newModFile = ModFile('', newItemPath, modName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, false, vidList); newModFile.categoryName = selectedCategoryName.toString(); newModFile.categoryPath = catePath; newModList.add(newModFile); @@ -652,7 +659,7 @@ Future dragDropModsAdd(context, List newModDragDropList, String cur List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); + ModFile newModFile = ModFile('', newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, false, vidList); newModFile.categoryName = matchedCategory.categoryName; newModFile.categoryPath = matchedCategory.categoryPath; newMods.add(newModFile); @@ -723,7 +730,7 @@ Future dragDropModsAddFoldersOnly(context, List newModDragDropList, List imgList = filesList.where((e) => (p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png') && e.parent.path == file.parent.path).toList(); List vidList = filesList.where((e) => (p.extension(e.path) == '.mp4' || p.extension(e.path) == '.webm') && e.parent.path == file.parent.path).toList(); - ModFile newModFile = ModFile(0, newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, vidList); + ModFile newModFile = ModFile('', newModPath, curItemName, file.path, iceName, iceParents, '', '', getImagesList(imgList), false, true, true, false, vidList); newModFile.categoryName = matchedCategory.categoryName; newModFile.categoryPath = matchedCategory.categoryPath; newMods.add(newModFile); @@ -755,3 +762,45 @@ Future dragDropModsAddFoldersOnly(context, List newModDragDropList, Provider.of(context, listen: false).modsDropAddRemoveFirst(); } } + +ModCategory addOrRemoveFav(List categoryList, List paramModFileList, ModCategory paramFavCate, bool isAdding) { + ModCategory tempFavCate = paramFavCate; + var curCate = categoryList.singleWhere((element) => element.categoryName == paramModFileList.first.categoryName); + if (isAdding) { + for (var element in paramModFileList) { + element.isFav = true; + tempFavCate.allModFiles.add(element); + } + if (tempFavCate.itemNames.indexWhere((element) => element == paramModFileList.first.modName) == -1) { + tempFavCate.itemNames.insert(0, paramModFileList.first.modName); + tempFavCate.imageIcons.insert(0, curCate.imageIcons[curCate.itemNames.indexOf(paramModFileList.first.modName)]); + tempFavCate.numOfMods.insert(0, 1); + tempFavCate.numOfApplied.insert(0, curCate.numOfApplied[curCate.itemNames.indexOf(paramModFileList.first.modName)]); + tempFavCate.numOfItems++; + } else { + tempFavCate.numOfMods[tempFavCate.itemNames.indexOf(paramModFileList.first.modName)] += 1; + tempFavCate.numOfApplied[tempFavCate.itemNames.indexOf(paramModFileList.first.modName)] = curCate.numOfApplied[curCate.itemNames.indexOf(paramModFileList.first.modName)]; + } + } else { + for (var element in paramModFileList) { + element.isFav = false; + tempFavCate.allModFiles.remove(element); + } + if (isViewingFav) { + modFilesList.remove(paramModFileList); + } + if (tempFavCate.allModFiles.indexWhere((element) => element.modName == paramModFileList.first.modName) == -1) { + tempFavCate.imageIcons.removeAt(tempFavCate.itemNames.indexOf(paramModFileList.first.modName)); + tempFavCate.numOfMods.removeAt(tempFavCate.itemNames.indexOf(paramModFileList.first.modName)); + tempFavCate.numOfApplied.removeAt(tempFavCate.itemNames.indexOf(paramModFileList.first.modName)); + tempFavCate.itemNames.remove(paramModFileList.first.modName); + tempFavCate.numOfItems--; + } + } + + tempFavCate.itemNames.sort(); + allModFiles.map((mod) => mod.toJson()).toList(); + File(modSettingsPath).writeAsStringSync(json.encode(allModFiles)); + + return tempFavCate; +} diff --git a/lib/home_page.dart b/lib/home_page.dart index d28261d2..906ed274 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -9,6 +9,7 @@ import 'package:dart_vlc/dart_vlc.dart'; import 'package:desktop_drop/desktop_drop.dart'; import 'package:dropdown_button2/custom_dropdown_button2.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:multi_split_view/multi_split_view.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/data_loading_page.dart'; @@ -33,6 +34,7 @@ List originalFilesMissingList = []; List backupFilesMissingList = []; List isLoading = []; bool isModAddFolderOnly = true; +bool isViewingFav = false; //New Cate bool addCategoryVisible = false; @@ -66,7 +68,7 @@ int _newModToItemIndex = 0; bool isModAddBtnClicked = false; //Media Player controls -Player previewPlayer = Player(id: 69, registerTexture: true, commandlineArguments: ['--no-video-title-show']); +Player previewPlayer = Player(id: 69, commandlineArguments: ['--no-video-title-show']); MediaType mediaType = MediaType.file; CurrentState current = CurrentState(); List medias = []; @@ -79,12 +81,13 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State with TickerProviderStateMixin { - final MultiSplitViewController _viewsController = MultiSplitViewController(areas: [Area(weight: 0.30), Area(weight: 0.325)]); + final MultiSplitViewController _viewsController = MultiSplitViewController(areas: [Area(weight: 0.285), Area(weight: 0.335)]); final MultiSplitViewController _viewsControllerNoPreview = MultiSplitViewController(areas: [Area(weight: 0.30), Area(weight: 0.5)]); final MultiSplitViewController _verticalViewsController = MultiSplitViewController(areas: [Area(weight: 0.5)]); String modsViewAppBarName = ''; List selectedIndex = List.generate(cateList.length, (index) => -1); CarouselController imgSliderController = CarouselController(); + List previewImageSliders = []; int modNameCatSelected = -1; bool isModSelected = false; @@ -275,6 +278,19 @@ class _HomePageState extends State with TickerProviderStateMixin { 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, + collapsedIconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + // textColor: cateList[index].categoryName != 'Favorites' + // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color + // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, + // iconColor: cateList[index].categoryName != 'Favorites' + // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color + // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, + // collapsedTextColor: cateList[index].categoryName != 'Favorites' + // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color + // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, + // collapsedIconColor: cateList[index].categoryName != 'Favorites' + // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color + // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, onExpansionChanged: (newState) { setState(() { if (!newState) { @@ -290,7 +306,12 @@ class _HomePageState extends State with TickerProviderStateMixin { children: [ Row( children: [ - Text(cateList[index].categoryName), + if (cateList[index].categoryName == 'Favorites') + Text( + cateList[index].categoryName, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + if (cateList[index].categoryName != 'Favorites') Text(cateList[index].categoryName), Padding( padding: const EdgeInsets.only(left: 10, top: 3), child: Container( @@ -308,176 +329,331 @@ class _HomePageState extends State with TickerProviderStateMixin { ), Row( children: [ - Tooltip( - message: 'Remove ${cateList[index].categoryName}', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 40, - height: 40, - child: MaterialButton( - onPressed: (() { - setState(() { - if (cateList[index].allModFiles.indexWhere((element) => element.isApplied == true) == -1) { - categoryDeleteDialog( - context, - 100, - 'Remove Category', - 'Remove "${cateList[index].categoryName}" and move it to Deleted Items folder?\nThis will also remove all items in this category', - true, - cateList[index].categoryPath, - cateList[index].allModFiles) - .then((_) { - setState(() { - //setstate to refresh list + if (cateList[index].categoryName != 'Favorites') + Tooltip( + message: 'Remove ${cateList[index].categoryName}', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 40, + height: 40, + child: MaterialButton( + onPressed: (() { + setState(() { + if (cateList[index].allModFiles.indexWhere((element) => element.isApplied == true) == -1) { + categoryDeleteDialog( + context, + 100, + 'Remove Category', + 'Remove "${cateList[index].categoryName}" and move it to Deleted Items folder?\nThis will also remove all items in this category', + true, + cateList[index].categoryPath, + cateList[index].allModFiles) + .then((_) { + setState(() { + //setstate to refresh list + }); }); - }); - } else { - List tempList = cateList[index].allModFiles.where((element) => element.isApplied == true).toList(); - List stillAppliedList = []; - double popupHeight = 40; - for (var element in tempList) { - stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); - popupHeight += 24; + } else { + List tempList = cateList[index].allModFiles.where((element) => element.isApplied == true).toList(); + List stillAppliedList = []; + double popupHeight = 40; + for (var element in tempList) { + stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + popupHeight += 24; + } + String stillApplied = stillAppliedList.join('\n'); + categoryDeleteDialog(context, popupHeight, 'Remove Category', 'Cannot remove "${cateList[index].categoryName}". Unaplly these mods first:\n\n$stillApplied', + false, cateList[index].categoryPath, []); } - String stillApplied = stillAppliedList.join('\n'); - categoryDeleteDialog(context, popupHeight, 'Remove Category', 'Cannot remove "${cateList[index].categoryName}". Unaplly these mods first:\n\n$stillApplied', - false, cateList[index].categoryPath, []); - } - }); - }), - child: Row( - children: [ - Icon( - Icons.delete_sweep_rounded, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - ) - ], - )), - )), + }); + }), + child: Row( + children: [ + Icon( + Icons.delete_sweep_rounded, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ) + ], + )), + )), ], ) ], ), children: [ - for (int i = 0; i < cateList[index].itemNames.length; i++) - Ink( - color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, - child: ListTile( - leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' - ? SizedBox( - width: 50, - height: 50, - child: Image.file( - cateList[index].imageIcons[i].first, - fit: BoxFit.fitWidth, - )) - : SizedBox( - width: 50, - height: 50, - child: Image.asset( - cateList[index].imageIcons[i].first.path, - fit: BoxFit.fitWidth, - )), - title: Text(cateList[index].itemNames[i]), - subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Applied: ${cateList[index].numOfApplied[i]}'), - trailing: Wrap( - children: [ - if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) - const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + //Fav list + if (cateList[index].categoryName == 'Favorites') + for (int i = 0; i < cateList[index].itemNames.length; i++) + Ink( + color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, + height: 50, + child: Image.file( + cateList[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateList[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateList[index].itemNames[i]), + subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Applied: ${cateList[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), - //Buttons - Tooltip( - message: 'Open ${cateList[index].itemNames[i]} in File Explorer', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( + //Buttons + Tooltip( + message: 'Open ${cateList[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + if (cateList[index].categoryName == 'Favorites') + SizedBox( width: 34, height: 50, - child: MaterialButton( - onPressed: (() async { - await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); - }), - child: Row( - children: const [ - Icon( - Icons.folder_open_rounded, - size: 18, - ) - ], - )), - )), - Tooltip( - message: 'Remove ${cateList[index].itemNames[i]}', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 36, + child: Tooltip( + message: 'Remove "${cateList[index].itemNames[i]}" from favorites', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() async { + List> modListToRemoveFav = await getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + for (var element in modListToRemoveFav) { + cateList[index] = addOrRemoveFav(cateList, element, cateList[index], false); + } + setState(() {}); + }), + child: const FaIcon( + FontAwesomeIcons.heartCircleXmark, + size: 17, + //color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).hintColor : Theme.of(context).hintColor, + )), + ), + ), + + // if (cateList[index].categoryName != 'Favorites') + // Tooltip( + // message: 'Remove ${cateList[index].itemNames[i]}', + // height: 25, + // textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + // waitDuration: const Duration(seconds: 2), + // child: SizedBox( + // width: 36, + // height: 50, + // child: MaterialButton( + // onPressed: (() { + // setState(() { + // if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { + // itemDeleteDialog( + // context, + // 100, + // 'Remove Item', + // 'Remove "${cateList[index].itemNames[i]}" and move it to Deleted Items folder?\nThis will also remove all mods in this item', + // true, + // cateList[index], + // cateList[index].itemNames[i], + // cateList[index].allModFiles) + // .then((_) { + // setState(() { + // modsViewAppBarName = 'Available Mods'; + // isModSelected = false; + // //setstate + // }); + // }); + // } else { + // List tempList = + // cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); + // List stillAppliedList = []; + // double popupHeight = 40; + // for (var element in tempList) { + // stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + // popupHeight += 24; + // } + // String stillApplied = stillAppliedList.join('\n'); + // itemDeleteDialog(context, popupHeight, 'Remove Item', 'Cannot remove "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', + // false, cateList[index], cateList[index].itemNames[i], []); + // } + // }); + // }), + // child: Row( + // children: const [ + // Icon( + // Icons.delete_forever_outlined, + // size: 20, + // ) + // ], + // )), + // )), + ], + ), + onTap: () { + setState(() { + isViewingFav = true; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + selectedIndex = List.filled(cateList.length, -1); + selectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateList[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, + ), + ), + + //Non fav + if (cateList[index].categoryName != 'Favorites') + for (int i = 0; i < cateList[index].itemNames.length; i++) + Ink( + color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, height: 50, - child: MaterialButton( - onPressed: (() { - setState(() { - if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { - itemDeleteDialog( - context, - 100, - 'Remove Item', - 'Remove "${cateList[index].itemNames[i]}" and move it to Deleted Items folder?\nThis will also remove all mods in this item', - true, - cateList[index], - cateList[index].itemNames[i], - cateList[index].allModFiles) - .then((_) { - setState(() { - modsViewAppBarName = 'Available Mods'; - isModSelected = false; - //setstate + child: Image.file( + cateList[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateList[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateList[index].itemNames[i]), + subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Files applied: ${cateList[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + + //Buttons + Tooltip( + message: 'Open ${cateList[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + Tooltip( + message: 'Delete ${cateList[index].itemNames[i]}', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 36, + height: 50, + child: MaterialButton( + onPressed: (() { + setState(() { + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { + itemDeleteDialog( + context, + 100, + 'Delete Item', + 'Delete "${cateList[index].itemNames[i]}" and move it to \'Deleted\' Items folder?\nThis will also delete all mods in this item', + true, + cateList[index], + cateList[index].itemNames[i], + cateList[index].allModFiles) + .then((_) { + setState(() { + modsViewAppBarName = 'Available Mods'; + isModSelected = false; + //setstate + }); }); - }); - } else { - List tempList = - cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); - List stillAppliedList = []; - double popupHeight = 40; - for (var element in tempList) { - stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); - popupHeight += 24; + } else if (cateList[index].allModFiles.indexWhere((element) => element.isFav && element.modName == cateList[index].itemNames[i]) != -1) { + double popupHeight = 40; + itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Remove from Favorites first', false, + cateList[index], cateList[index].itemNames[i], []); + } else { + List tempList = + cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); + List stillAppliedList = []; + double popupHeight = 40; + for (var element in tempList) { + stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + popupHeight += 24; + } + String stillApplied = stillAppliedList.join('\n'); + itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', + false, cateList[index], cateList[index].itemNames[i], []); } - String stillApplied = stillAppliedList.join('\n'); - itemDeleteDialog(context, popupHeight, 'Remove Item', 'Cannot remove "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', - false, cateList[index], cateList[index].itemNames[i], []); - } - }); - }), - child: Row( - children: const [ - Icon( - Icons.delete_forever_outlined, - size: 20, - ) - ], - )), - )), - ], + }); + }), + child: Row( + children: const [ + Icon( + Icons.delete_forever_outlined, + size: 20, + ) + ], + )), + )), + ], + ), + onTap: () { + setState(() { + isViewingFav = false; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + selectedIndex = List.filled(cateList.length, -1); + selectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateList[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, ), - onTap: () { - setState(() { - isPreviewImgsOn = false; - modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); - selectedIndex = List.filled(cateList.length, -1); - selectedIndex[index] = i; - modNameCatSelected = -1; - modsViewAppBarName = cateList[index].itemNames[i]; - _newModToItemIndex = index; - isModSelected = true; - isLoading.clear(); - }); - }, - ), - ) + ) ], ); }, @@ -685,7 +861,14 @@ class _HomePageState extends State with TickerProviderStateMixin { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (_newSingleItemDragDropList.isEmpty) const Center(child: Text("Drop Modded .ice Files And Folder(s) Here To Add")), + if (_newSingleItemDragDropList.isEmpty) + Center( + child: Column( + children: const [ + Text("Drop Modded .ice Files And Folder(s)"), + Text('Here To Add'), + ], + )), if (_newSingleItemDragDropList.isNotEmpty) Expanded( child: SingleChildScrollView( @@ -760,9 +943,19 @@ class _HomePageState extends State with TickerProviderStateMixin { isErrorInSingleItemName = true; return 'Name can\'t be empty'; } - if (cateList.indexWhere((e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element == value) != -1) != -1) { - isErrorInSingleItemName = true; - return 'The name already exist'; + if (selectedCategoryForSingleItem == 'Basewears' || + selectedCategoryForSingleItem == 'Setwears' || + selectedCategoryForSingleItem == 'Outerewears' || + selectedCategoryForSingleItem == 'Innerwears') { + if (cateList.indexWhere((e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase().contains(value.toLowerCase())) != -1) != -1) { + isErrorInSingleItemName = true; + return 'The name already exist'; + } + } else { + if (cateList.indexWhere((e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase() == value.toLowerCase()) != -1) != -1) { + isErrorInSingleItemName = true; + return 'The name already exist'; + } } return null; }, @@ -1102,7 +1295,7 @@ class _HomePageState extends State with TickerProviderStateMixin { AsyncSnapshot snapshot, ) { if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); + return const CircularProgressIndicator(); } else { if (snapshot.hasError) { return const Text('Error'); @@ -1159,77 +1352,310 @@ class _HomePageState extends State with TickerProviderStateMixin { isPreviewImgsOn = false; isPreviewVidOn = false; previewPlayer.pause(); - //isPreviewImgsOn = false; - // { - // previewPlayer.pause(); - // } }); } }, - child: Card( - shape: RoundedRectangleBorder( - borderRadius: const BorderRadius.all(Radius.circular(5.0)), - side: BorderSide(width: 1, color: modFilesList[index].indexWhere((e) => e.isNew == true) != -1 ? Colors.amber : Theme.of(context).primaryColorLight)), - child: ExpansionTile( - initiallyExpanded: modViewExpandAll, - 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, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: Text(modFilesList[index].first.iceParent), - ), - //if (modFilesList[index].length > 1) - Row( - children: [ - if (isLoading[index]) - const SizedBox( - width: 40, - height: 40, - child: CircularProgressIndicator(), - ), - //Buttons - if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == true) != -1 && !isLoading[index]) + child: GestureDetector( + onSecondaryTap: () => previewImageSliders.isNotEmpty ? pictureDialog(context, previewImageSliders) : null, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + side: BorderSide(width: 1, color: modFilesList[index].indexWhere((e) => e.isNew == true) != -1 ? Colors.amber : Theme.of(context).primaryColor)), + child: ExpansionTile( + initiallyExpanded: modViewExpandAll, + 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, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Text(modFilesList[index].first.iceParent), + ), + //if (modFilesList[index].length > 1) + Row( + children: [ + //Buttons SizedBox( width: 40, height: 40, child: Tooltip( - message: 'Remove all mods under "$modsViewAppBarName ${modFilesList[index].first.iceParent}" from the game', + message: modFilesList[index].first.isFav + ? 'Remove "$modsViewAppBarName ${modFilesList[index].first.iceParent}" to favorites' + : 'Add "$modsViewAppBarName ${modFilesList[index].first.iceParent}" to favorites', height: 25, textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), waitDuration: const Duration(seconds: 1), child: MaterialButton( onPressed: (() { setState(() { - modsRemover(modFilesList[index].toList()); + var favCate = cateList.singleWhere((element) => element.categoryName == 'Favorites'); + if (modFilesList[index].first.isFav) { + favCate = addOrRemoveFav(cateList, modFilesList[index], favCate, false); + } else { + favCate = addOrRemoveFav(cateList, modFilesList[index], favCate, true); + } }); }), - child: Icon( - Icons.playlist_remove, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - ), + child: modFilesList[index].first.isFav + ? FaIcon( + FontAwesomeIcons.heartCircleMinus, + size: 19, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).hintColor : Theme.of(context).hintColor, + ) + : FaIcon( + FontAwesomeIcons.heartCirclePlus, + size: 19, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ), ), ), ), - if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == false) != -1 && !isLoading[index]) - SizedBox( - width: 40, - height: 40, - child: Tooltip( - message: 'Apply mods under ${modFilesList[index].first.iceParent} to the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: (() { - setState(() { - isLoading[index] = true; - modsToDataAdder(modFilesList[index]).then((_) { + //loading && add + if (isLoading[index]) + const SizedBox( + width: 40, + height: 40, + child: CircularProgressIndicator(), + ), + + if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == true) != -1 && !isLoading[index]) + SizedBox( + width: 40, + height: 40, + child: Tooltip( + message: 'Remove all mods under "$modsViewAppBarName ${modFilesList[index].first.iceParent}" from the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() { + setState(() { + modsRemover(modFilesList[index].toList()); + }); + }), + child: Icon( + Icons.playlist_remove, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ), + ), + ), + ), + //if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == false) != -1 && !isLoading[index]) + if (modFilesList[index].indexWhere((element) => element.isApplied == false) != -1 && !isLoading[index]) + SizedBox( + width: 40, + height: 40, + child: Tooltip( + message: 'Apply mods under ${modFilesList[index].first.iceParent} to the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() { + setState(() { + isLoading[index] = true; + modsToDataAdder(modFilesList[index]).then((_) { + setState(() { + isLoading[index] = false; + //Messages + if (originalFilesMissingList.isNotEmpty) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + duration: const Duration(seconds: 2), + //backgroundColor: Theme.of(context).focusColor, + content: SizedBox( + height: originalFilesMissingList.length * 20, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < originalFilesMissingList.length; i++) + Text( + 'Original file of "${originalFilesMissingList[i].modName} ${originalFilesMissingList[i].iceParent} > ${originalFilesMissingList[i].iceName}" is not found'), + ], + ), + ))); + } + + if (modAppliedDup.isNotEmpty) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + duration: Duration(seconds: modAppliedDup.length), + //backgroundColor: Theme.of(context).focusColor, + content: SizedBox( + height: modAppliedDup.length * 20, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < modAppliedDup.length; i++) + Text( + 'Replaced: ${modAppliedDup[i].categoryName} > ${modAppliedDup[i].modName} ${modAppliedDup[i].iceParent} > ${modAppliedDup[i].iceName}'), + ], + ), + ))); + modAppliedDup.clear(); + } + }); + }); + }); + }), + child: Icon( + Icons.playlist_add, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ), + ), + ), + ), + if (!isViewingFav) + Tooltip( + message: 'Delete $modsViewAppBarName ${modFilesList[index].first.iceParent}', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 36, + height: 40, + child: MaterialButton( + onPressed: (() { + setState(() { + if (modFilesList[index].indexWhere((element) => element.isApplied == true) == -1) { + modDeleteDialog( + context, + 100, + 'Delete Mods', + 'Delete "$modsViewAppBarName ${modFilesList[index].first.iceParent}" and move it to \'Deleted Items\' folder?\nThis will also delete all files in this mod', + true, + modFilesList[index].first.modPath, + modFilesList[index].first.iceParent, + modFilesList[index].first.modName, + modFilesList[index]) + .then((_) { + setState(() { + //setstate to refresh list + }); + }); + } else if (modFilesList[index].first.isFav) { + double popupHeight = 40; + modDeleteDialog( + context, + popupHeight, + 'Delete Mod', + 'Cannot delete "$modsViewAppBarName ${modFilesList[index].first.iceParent}". Remove from Favorites first', + false, + modFilesList[index].first.modPath, + modFilesList[index].first.iceParent, + modFilesList[index].first.modName, []); + } else { + List tempList = cateList[index] + .allModFiles + .where((element) => element.modName == modFilesList[index].first.modName && element.isApplied == true) + .toList(); + List stillAppliedList = []; + double popupHeight = 40; + for (var element in tempList) { + stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + popupHeight += 24; + } + String stillApplied = stillAppliedList.join('\n'); + modDeleteDialog( + context, + popupHeight, + 'Delete Mod', + 'Cannot delete "$modsViewAppBarName ${modFilesList[index].first.iceParent}". Unaplly these files first:\n\n$stillApplied', + false, + modFilesList[index].first.modPath, + modFilesList[index].first.iceParent, + modFilesList[index].first.modName, []); + } + }); + }), + child: Row( + children: [ + Icon( + Icons.delete_rounded, + size: 20, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ) + ], + )), + )), + ], + ) + ], + ), + children: [ + for (int i = 0; i < modFilesList[index].length; i++) + InkWell( + // onHover: (value) { + // if (value && + // modPreviewImgList.indexWhere((e) => + // e.path.contains( + // modFilesList[ + // index] + // .first + // .iceParent)) == + // -1) { + // setState(() { + // isPreviewImgsOn = true; + // futureImagesGet = + // modFilesList[index] + // [i] + // .images; + // }); + // } + // }, + child: ListTile( + leading: modFilesList[index][i].isNew == true + ? const Icon( + Icons.new_releases, + color: Colors.amber, + ) + : null, + title: Text(modFilesList[index][i].iceName), + //subtitle: Text(modFilesList[index][i].icePath), + minLeadingWidth: 10, + trailing: SizedBox( + width: 40, + height: 40, + child: modFilesList[index][i].isApplied + ? Tooltip( + message: 'Remove this mod from the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: MaterialButton( + onPressed: (() { + setState(() { + modsRemover([modFilesList[index][i]]); + //appliedModsList.remove(modFilesList[index]); + if (backupFilesMissingList.isNotEmpty) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + duration: const Duration(seconds: 2), + //backgroundColor: Theme.of(context).focusColor, + content: SizedBox( + height: backupFilesMissingList.length * 20, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < backupFilesMissingList.length; i++) + Text( + 'Backup file of "${backupFilesMissingList[i].modName} ${backupFilesMissingList[i].iceParent} > ${backupFilesMissingList[i].iceName}" is not found'), + ], + ), + ))); + } + }); + }), + child: const Icon(Icons.replay), + )) + : Tooltip( + message: 'Apply this mod to the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: MaterialButton( + onPressed: (() { setState(() { - isLoading[index] = false; - //Messages + modsToDataAdder([modFilesList[index][i]]); + //appliedModsList.add(modFilesList[index]); if (originalFilesMissingList.isNotEmpty) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( duration: const Duration(seconds: 2), @@ -1262,203 +1688,19 @@ class _HomePageState extends State with TickerProviderStateMixin { ], ), ))); - modAppliedDup.clear(); } + + modAppliedDup.clear(); }); - }); - }); - }), - child: Icon( - Icons.playlist_add, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + }), + child: const Icon(Icons.add_to_drive), + ), ), - ), - ), - ), - Tooltip( - message: 'Remove $modsViewAppBarName ${modFilesList[index].first.iceParent}', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 36, - height: 40, - child: MaterialButton( - onPressed: (() { - setState(() { - if (modFilesList[index].indexWhere((element) => element.isApplied == true) == -1) { - modDeleteDialog( - context, - 100, - 'Remove Mods', - 'Remove "$modsViewAppBarName ${modFilesList[index].first.iceParent}" and move it to Deleted Items folder?\nThis will also remove all filess in this mod', - true, - modFilesList[index].first.modPath, - modFilesList[index].first.iceParent, - modFilesList[index].first.modName, - modFilesList[index]) - .then((_) { - setState(() { - //setstate to refresh list - }); - }); - } else { - List tempList = cateList[index] - .allModFiles - .where((element) => element.modName == modFilesList[index].first.modName && element.isApplied == true) - .toList(); - List stillAppliedList = []; - double popupHeight = 40; - for (var element in tempList) { - stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); - popupHeight += 24; - } - String stillApplied = stillAppliedList.join('\n'); - modDeleteDialog( - context, - popupHeight, - 'Remove Mod', - 'Cannot remove "$modsViewAppBarName ${modFilesList[index].first.iceParent}". Unaplly these files first:\n\n$stillApplied', - false, - modFilesList[index].first.modPath, - modFilesList[index].first.iceParent, - modFilesList[index].first.modName, []); - } - }); - }), - child: Row( - children: [ - Icon( - Icons.delete_rounded, - size: 20, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - ) - ], - )), - )), - ], - ) + ), + )) ], - ), - children: [ - for (int i = 0; i < modFilesList[index].length; i++) - InkWell( - // onHover: (value) { - // if (value && - // modPreviewImgList.indexWhere((e) => - // e.path.contains( - // modFilesList[ - // index] - // .first - // .iceParent)) == - // -1) { - // setState(() { - // isPreviewImgsOn = true; - // futureImagesGet = - // modFilesList[index] - // [i] - // .images; - // }); - // } - // }, - child: ListTile( - leading: modFilesList[index][i].isNew == true - ? const Icon( - Icons.new_releases, - color: Colors.amber, - ) - : null, - title: Text(modFilesList[index][i].iceName), - //subtitle: Text(modFilesList[index][i].icePath), - minLeadingWidth: 10, - trailing: SizedBox( - width: 40, - height: 40, - child: modFilesList[index][i].isApplied - ? Tooltip( - message: 'Remove this mod from the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: MaterialButton( - onPressed: (() { - setState(() { - modsRemover([modFilesList[index][i]]); - //appliedModsList.remove(modFilesList[index]); - if (backupFilesMissingList.isNotEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: const Duration(seconds: 2), - //backgroundColor: Theme.of(context).focusColor, - content: SizedBox( - height: backupFilesMissingList.length * 20, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (int i = 0; i < backupFilesMissingList.length; i++) - Text( - 'Backup file of "${backupFilesMissingList[i].modName} ${backupFilesMissingList[i].iceParent} > ${backupFilesMissingList[i].iceName}" is not found'), - ], - ), - ))); - } - }); - }), - child: const Icon(Icons.replay), - )) - : Tooltip( - message: 'Apply this mod to the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: MaterialButton( - onPressed: (() { - setState(() { - modsToDataAdder([modFilesList[index][i]]); - //appliedModsList.add(modFilesList[index]); - if (originalFilesMissingList.isNotEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: const Duration(seconds: 2), - //backgroundColor: Theme.of(context).focusColor, - content: SizedBox( - height: originalFilesMissingList.length * 20, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (int i = 0; i < originalFilesMissingList.length; i++) - Text( - 'Original file of "${originalFilesMissingList[i].modName} ${originalFilesMissingList[i].iceParent} > ${originalFilesMissingList[i].iceName}" is not found'), - ], - ), - ))); - } - - if (modAppliedDup.isNotEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: Duration(seconds: modAppliedDup.length), - //backgroundColor: Theme.of(context).focusColor, - content: SizedBox( - height: modAppliedDup.length * 20, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (int i = 0; i < modAppliedDup.length; i++) - Text( - 'Replaced: ${modAppliedDup[i].categoryName} > ${modAppliedDup[i].modName} ${modAppliedDup[i].iceParent} > ${modAppliedDup[i].iceName}'), - ], - ), - ))); - } - - modAppliedDup.clear(); - }); - }), - child: const Icon(Icons.add_to_drive), - ), - ), - ), - )) - ], - ))); + )), + )); })); } } @@ -1496,7 +1738,7 @@ class _HomePageState extends State with TickerProviderStateMixin { if (!Directory(element.path).existsSync()) { isModAddFolderOnly = false; break; - } + } } }); }, @@ -1679,7 +1921,7 @@ class _HomePageState extends State with TickerProviderStateMixin { foregroundColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, toolbarHeight: 30, ), - if (isPreviewImgsOn) + if (isPreviewImgsOn && context.watch().previewWindowVisible) Expanded( child: FutureBuilder( future: futureImagesGet, @@ -1695,7 +1937,7 @@ class _HomePageState extends State with TickerProviderStateMixin { } else { modPreviewImgList = snapshot.data; //print(modPreviewImgList.toString()); - List previewImageSliders = modPreviewImgList + previewImageSliders = modPreviewImgList .map((item) => Container( margin: const EdgeInsets.all(2.0), child: ClipRRect( @@ -1708,44 +1950,56 @@ class _HomePageState extends State with TickerProviderStateMixin { )), )) .toList(); + List previewImageSlidersBox = []; + for (var element in previewImageSliders) { + previewImageSlidersBox.add(FittedBox( + fit: BoxFit.fitHeight, + child: element, + )); + } + previewImageSliders = previewImageSlidersBox; return Column( children: [ Expanded( - child: CarouselSlider( - items: previewImageSliders, - carouselController: imgSliderController, - options: CarouselOptions( - autoPlay: previewImageSliders.length > 1, - reverse: true, - viewportFraction: 1, - enlargeCenterPage: true, - //aspectRatio: 1.0, - onPageChanged: (index, reason) { - setState(() { - currentImg = index; - }); - }), + child: GestureDetector( + onSecondaryTap: (() => previewImageSliders.isNotEmpty ? pictureDialog(context, previewImageSliders) : null), + child: CarouselSlider( + items: previewImageSliders, + carouselController: imgSliderController, + options: CarouselOptions( + autoPlayAnimationDuration: const Duration(milliseconds: 500), + autoPlay: previewImageSliders.length > 1, + reverse: true, + viewportFraction: 1, + enlargeCenterPage: true, + //aspectRatio: 1.0, + onPageChanged: (index, reason) { + setState(() { + currentImg = index; + }); + }), + ), ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (previewImageSliders.isNotEmpty) - SizedBox( - width: 40, - child: MaterialButton( - onPressed: (() => imgSliderController.previousPage()), - child: const Icon(Icons.arrow_left), - ), - ), + // if (previewImageSliders.isNotEmpty) + // SizedBox( + // width: 40, + // child: MaterialButton( + // onPressed: (() => imgSliderController.previousPage()), + // child: const Icon(Icons.arrow_left), + // ), + // ), Row( mainAxisAlignment: MainAxisAlignment.center, children: modPreviewImgList.asMap().entries.map((entry) { return GestureDetector( onTap: () => imgSliderController.animateToPage(entry.key), child: Container( - width: 10.0, - height: 10.0, + width: 5.0, + height: 5.0, margin: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 4.0), decoration: BoxDecoration( shape: BoxShape.circle, @@ -1754,14 +2008,14 @@ class _HomePageState extends State with TickerProviderStateMixin { ); }).toList(), ), - if (previewImageSliders.isNotEmpty) - SizedBox( - width: 40, - child: MaterialButton( - onPressed: (() => imgSliderController.nextPage()), - child: const Icon(Icons.arrow_right), - ), - ), + // if (previewImageSliders.isNotEmpty) + // SizedBox( + // width: 40, + // child: MaterialButton( + // onPressed: (() => imgSliderController.nextPage()), + // child: const Icon(Icons.arrow_right), + // ), + // ), ], ), ], @@ -1769,7 +2023,7 @@ class _HomePageState extends State with TickerProviderStateMixin { } } })), - if (isPreviewVidOn) + if (isPreviewVidOn && context.watch().previewWindowVisible) Expanded( child: Scaffold( body: Video( @@ -1811,6 +2065,8 @@ class _HomePageState extends State with TickerProviderStateMixin { } } modsRemover(tempDelete); + isPreviewImgsOn = false; + isPreviewVidOn = false; }); }), onPressed: appliedModsList.isEmpty ? null : () {}, @@ -1855,168 +2111,202 @@ class _HomePageState extends State with TickerProviderStateMixin { onHover: (value) { if (value) { setState(() { - isPreviewImgsOn = true; - futureImagesGet = appliedModsList[index].first.images; + if (appliedModsList[index].first.images != null) { + isPreviewImgsOn = true; + futureImagesGet = appliedModsList[index].first.images; + } + //print(modFilesList[index].first.previewVids!.length); + if (appliedModsList[index].first.previewVids!.isNotEmpty) { + isPreviewVidOn = true; + isPreviewImgsOn = false; + previewPlayer.setVolume(0.0); + bool itemFound = false; + for (var vid in appliedModsList[index].first.previewVids!) { + if (medias.contains(Media.file(vid))) { + itemFound = true; + } else { + medias.clear(); + } + } + + if (medias.isEmpty || !itemFound) { + for (var vid in appliedModsList[index].first.previewVids!) { + medias.add(Media.file(vid)); + } + previewPlayer.open(Playlist(medias: medias, playlistMode: PlaylistMode.single), autoStart: true); + } else { + previewPlayer.bufferingProgressController.done; + previewPlayer.play(); + } + } + }); + } else { + setState(() { + isPreviewImgsOn = false; + isPreviewVidOn = false; + previewPlayer.pause(); }); } - // else { - // setState(() { - // isPreviewImgsOn = false; - // }); - // } }, - child: Card( - shape: RoundedRectangleBorder(borderRadius: const BorderRadius.all(Radius.circular(5.0)), side: BorderSide(width: 1, color: Theme.of(context).primaryColor)), - child: ExpansionTile( - initiallyExpanded: false, - 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, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('${appliedModsList[index].first.categoryName} > ${appliedModsList[index].first.modName}', - style: const TextStyle( - fontWeight: FontWeight.w600, - )), - Text(appliedModsList[index].first.iceParent.trimLeft()), - ], - )), - //if (appliedModsList[index].length > 1) - Row( - children: [ - if (appliedModsList.indexWhere((element) => element.indexWhere((e) => e.isApplied == true) != -1) != -1) - SizedBox( - width: 40, - height: 40, - child: Tooltip( - message: 'Remove mods under "$modsViewAppBarName ${appliedModsList[index].first.iceParent}" from the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: MaterialButton( - onPressed: (() { - setState(() { - modsRemover(appliedModsList[index].toList()); - }); - }), - child: Icon( - Icons.playlist_remove, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + child: GestureDetector( + onSecondaryTap: () => previewImageSliders.isNotEmpty ? pictureDialog(context, previewImageSliders) : null, + child: Card( + shape: RoundedRectangleBorder(borderRadius: const BorderRadius.all(Radius.circular(5.0)), side: BorderSide(width: 1, color: Theme.of(context).primaryColor)), + child: ExpansionTile( + initiallyExpanded: false, + 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, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('${appliedModsList[index].first.categoryName} > ${appliedModsList[index].first.modName}', + style: const TextStyle( + fontWeight: FontWeight.w600, + )), + Text(appliedModsList[index].first.iceParent.trimLeft()), + ], + )), + //if (appliedModsList[index].length > 1) + Row( + children: [ + if (appliedModsList.indexWhere((element) => element.indexWhere((e) => e.isApplied == true) != -1) != -1) + SizedBox( + width: 40, + height: 40, + child: Tooltip( + message: 'Remove mods under "$modsViewAppBarName ${appliedModsList[index].first.iceParent}" from the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: MaterialButton( + onPressed: (() { + setState(() { + isPreviewImgsOn = false; + isPreviewVidOn = false; + modsRemover(appliedModsList[index].toList()); + }); + }), + child: Icon( + Icons.playlist_remove, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + ), ), ), ), - ), - ], - ) - ], - ), - children: [ - for (int i = 0; i < appliedModsList[index].length; i++) - InkWell( - // onHover: (value) { - // if (value && - // modPreviewImgList.indexWhere((e) => - // e.path.contains( - // modFilesList[ - // index] - // .first - // .iceParent)) == - // -1) { - // setState(() { - // isPreviewImgsOn = true; - // futureImagesGet = - // modFilesList[index] - // [i] - // .images; - // }); - // } - // }, - child: ListTile( - // leading: appliedModsList[index][i].isNew == true - // ? Icon( - // Icons.new_releases, - // color: Theme.of(context).indicatorColor, - // ) - // : null, - title: Text(appliedModsList[index][i].iceName), - //subtitle: Text(modFilesList[index][i].icePath), - minLeadingWidth: 10, - trailing: SizedBox( - width: 40, - height: 40, - child: appliedModsList[index][i].isApplied - ? Tooltip( - message: 'Remove this mod from the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: MaterialButton( - onPressed: (() { - setState(() { - modsRemover([appliedModsList[index][i]]); - //appliedModsList.remove(modFilesList[index]); - if (backupFilesMissingList.isNotEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: const Duration(seconds: 2), - //backgroundColor: Theme.of(context).focusColor, - content: SizedBox( - height: backupFilesMissingList.length * 20, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (int i = 0; i < backupFilesMissingList.length; i++) - Text( - 'Backup file of "${backupFilesMissingList[i].modName} ${backupFilesMissingList[i].iceParent} > ${backupFilesMissingList[i].iceName}" is not found'), - ], - ), - ))); - } - }); - }), - child: const Icon(Icons.replay), - )) - : Tooltip( - message: 'Apply this mod to the game', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: (() { - setState(() { - modsToDataAdder([appliedModsList[index][i]]); - //appliedModsList.add(modFilesList[index]); - if (originalFilesMissingList.isNotEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - duration: const Duration(seconds: 2), - //backgroundColor: Theme.of(context).focusColor, - content: SizedBox( - height: originalFilesMissingList.length * 20, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - for (int i = 0; i < originalFilesMissingList.length; i++) - Text( - 'Original file of "${originalFilesMissingList[i].modName} ${originalFilesMissingList[i].iceParent} > ${originalFilesMissingList[i].iceName}" is not found'), - ], - ), - ))); - } - }); - }), - child: const Icon(Icons.add_to_drive), + ], + ) + ], + ), + children: [ + for (int i = 0; i < appliedModsList[index].length; i++) + InkWell( + // onHover: (value) { + // if (value && + // modPreviewImgList.indexWhere((e) => + // e.path.contains( + // modFilesList[ + // index] + // .first + // .iceParent)) == + // -1) { + // setState(() { + // isPreviewImgsOn = true; + // futureImagesGet = + // modFilesList[index] + // [i] + // .images; + // }); + // } + // }, + child: ListTile( + // leading: appliedModsList[index][i].isNew == true + // ? Icon( + // Icons.new_releases, + // color: Theme.of(context).indicatorColor, + // ) + // : null, + title: Text(appliedModsList[index][i].iceName), + //subtitle: Text(modFilesList[index][i].icePath), + minLeadingWidth: 10, + trailing: SizedBox( + width: 40, + height: 40, + child: appliedModsList[index][i].isApplied + ? Tooltip( + message: 'Remove this mod from the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: MaterialButton( + onPressed: (() { + setState(() { + isPreviewImgsOn = false; + isPreviewVidOn = false; + modsRemover([appliedModsList[index][i]]); + //appliedModsList.remove(modFilesList[index]); + if (backupFilesMissingList.isNotEmpty) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + duration: const Duration(seconds: 2), + //backgroundColor: Theme.of(context).focusColor, + content: SizedBox( + height: backupFilesMissingList.length * 20, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < backupFilesMissingList.length; i++) + Text( + 'Backup file of "${backupFilesMissingList[i].modName} ${backupFilesMissingList[i].iceParent} > ${backupFilesMissingList[i].iceName}" is not found'), + ], + ), + ))); + } + }); + }), + child: const Icon(Icons.replay), + )) + : Tooltip( + message: 'Apply this mod to the game', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() { + setState(() { + modsToDataAdder([appliedModsList[index][i]]); + //appliedModsList.add(modFilesList[index]); + if (originalFilesMissingList.isNotEmpty) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + duration: const Duration(seconds: 2), + //backgroundColor: Theme.of(context).focusColor, + content: SizedBox( + height: originalFilesMissingList.length * 20, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for (int i = 0; i < originalFilesMissingList.length; i++) + Text( + 'Original file of "${originalFilesMissingList[i].modName} ${originalFilesMissingList[i].iceParent} > ${originalFilesMissingList[i].iceName}" is not found'), + ], + ), + ))); + } + }); + }), + child: const Icon(Icons.add_to_drive), + ), ), - ), + ), ), - ), - ) - ], - ))); + ) + ], + )), + )); })); } } diff --git a/lib/main.dart b/lib/main.dart index 5b39740e..d145ad23 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:dart_vlc/dart_vlc.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; import 'package:pso2_mod_manager/data_loading_page.dart'; import 'package:pso2_mod_manager/home_page.dart'; @@ -34,8 +35,9 @@ double windowsHeight = 720.0; Future? filesData; List allModFiles = []; var dataStreamController = StreamController(); + Future main() async { - DartVLC.initialize(useFlutterNativeView: true); + DartVLC.initialize(); WidgetsFlutterBinding.ensureInitialized(); await windowManager.ensureInitialized(); final prefs = await SharedPreferences.getInstance(); @@ -105,15 +107,22 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State with WindowListener { final imgStream = StreamController(); bool isDarkModeOn = false; + String appVersion = ''; @override void initState() { windowManager.addListener(this); miscCheck(); dirPathCheck(); + getAppVer(); super.initState(); } + Future getAppVer() async { + PackageInfo packageInfo = await PackageInfo.fromPlatform(); + appVersion = packageInfo.version; + } + @override void onWindowFocus() { // Make sure to call once. @@ -228,11 +237,16 @@ class _MyHomePageState extends State with WindowListener { child: MoveWindow( child: Container( padding: const EdgeInsets.only(left: 10), - child: const Text( + child: Tooltip( + message: 'Version: $appVersion | Build by キス★', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: const Text( 'PSO2NGS Mod Manager', style: TextStyle(fontWeight: FontWeight.w500), )), - )), + )),), //Buttons Padding( padding: const EdgeInsets.only(bottom: 9), @@ -412,7 +426,7 @@ class _MyHomePageState extends State with WindowListener { //Preview Tooltip( - message: 'Open/Hide Preview Window', + message: 'Show/Hide Preview Window', height: 25, textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), waitDuration: const Duration(seconds: 1), @@ -454,41 +468,47 @@ class _MyHomePageState extends State with WindowListener { //Dark theme if (MyApp.themeNotifier.value == ThemeMode.dark) - MaterialButton( - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - MyApp.themeNotifier.value = ThemeMode.light; - prefs.setBool('isDarkModeOn', false); - //setState(() {}); - }), - child: Row( - children: const [ - Icon( - Icons.light_mode_outlined, - size: 18, - ), - SizedBox(width: 5), - Text('Light', style: TextStyle(fontWeight: FontWeight.w400)) - ], + SizedBox( + width: 70, + child: MaterialButton( + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + MyApp.themeNotifier.value = ThemeMode.light; + prefs.setBool('isDarkModeOn', false); + //setState(() {}); + }), + child: Row( + children: const [ + Icon( + Icons.light_mode_outlined, + size: 18, + ), + SizedBox(width: 5), + Text('Light', style: TextStyle(fontWeight: FontWeight.w400)) + ], + ), ), ), if (MyApp.themeNotifier.value == ThemeMode.light) - MaterialButton( - onPressed: (() async { - final prefs = await SharedPreferences.getInstance(); - MyApp.themeNotifier.value = ThemeMode.dark; - prefs.setBool('isDarkModeOn', true); - //setState(() {}); - }), - child: Row( - children: const [ - Icon( - Icons.dark_mode_outlined, - size: 18, - ), - SizedBox(width: 5), - Text('Dark', style: TextStyle(fontWeight: FontWeight.w400)) - ], + SizedBox( + width: 70, + child: MaterialButton( + onPressed: (() async { + final prefs = await SharedPreferences.getInstance(); + MyApp.themeNotifier.value = ThemeMode.dark; + prefs.setBool('isDarkModeOn', true); + //setState(() {}); + }), + child: Row( + children: const [ + Icon( + Icons.dark_mode_outlined, + size: 18, + ), + SizedBox(width: 5), + Text('Dark', style: TextStyle(fontWeight: FontWeight.w400)) + ], + ), ), ), ], diff --git a/lib/mod_classes.dart b/lib/mod_classes.dart index e206e453..0825b097 100644 --- a/lib/mod_classes.dart +++ b/lib/mod_classes.dart @@ -33,7 +33,7 @@ class ModCategory { class ModFile extends ModCategory { ModFile( - this.numOfSubItems, + this.appliedDate, this.modPath, //mod folder path this.modName, //mod folder name, this.icePath, @@ -45,10 +45,11 @@ class ModFile extends ModCategory { this.isApplied, this.isSFW, this.isNew, + this.isFav, this.previewVids) : super('', '', [], [], 0, [], [], []); - int numOfSubItems; + String appliedDate; String modPath; String modName; String icePath; @@ -60,11 +61,13 @@ class ModFile extends ModCategory { bool isApplied; bool isSFW; bool isNew; + bool isFav; List? previewVids; fromJson(Map json) { categoryName = json['categoryName']; categoryPath = json['categoryPath']; + appliedDate = json['appliedDate']; modPath = json['modPath']; modName = json['modName']; icePath = json['icePath']; @@ -75,12 +78,14 @@ class ModFile extends ModCategory { isApplied = json['isApplied']; isSFW = json['isSFW']; isNew = json['isNew']; + isFav = json['isFav']; } Map toJson() { final Map data = {}; data['categoryPath'] = categoryPath; data['categoryName'] = categoryName; + data['appliedDate'] = appliedDate; data['modPath'] = modPath; data['modName'] = modName; data['iceName'] = iceName; @@ -91,6 +96,7 @@ class ModFile extends ModCategory { data['isApplied'] = isApplied; data['isSFW'] = isSFW; data['isNew'] = isNew; + data['isFav'] = isFav; return data; } diff --git a/lib/mods_loader.dart b/lib/mods_loader.dart index e1968af1..d892f6e9 100644 --- a/lib/mods_loader.dart +++ b/lib/mods_loader.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; +import 'package:pso2_mod_manager/file_functions.dart'; import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/main.dart'; import 'package:path/path.dart' as p; @@ -26,8 +27,8 @@ Future> modsLoader() async { //JSON Loader void convertData(var jsonResponse) { for (var b in jsonResponse) { - ModFile mod = - ModFile(0, b['modPath'], b['modName'], b['icePath'], b['iceName'], b['iceParent'], b['originalIcePath'], b['backupIcePath'], null, b['isApplied'], b['isSFW'], b['isNew'], null); + ModFile mod = ModFile(b['appliedDate'], b['modPath'], b['modName'], b['icePath'], b['iceName'], b['iceParent'], b['originalIcePath'], b['backupIcePath'], null, b['isApplied'], b['isSFW'], + b['isNew'], b['isFav'], null); mod.categoryPath = b['categoryPath']; mod.categoryName = b['categoryName']; modFilesFromJson.add(mod); @@ -79,18 +80,20 @@ Future> modsLoader() async { } //New ModFile - ModFile newModFile = ModFile(0, modPath, modName, iceFile.path, iceFilePathSplit.last, iceParents, '', '', imgList, false, true, false, vidFiles); + ModFile newModFile = ModFile('', modPath, modName, iceFile.path, iceFilePathSplit.last, iceParents, '', '', imgList, false, true, false, false, vidFiles); newModFile.categoryName = categoryName; newModFile.categoryPath = categoryPath; var jsonModFile = modFilesFromJson.firstWhere((e) => e.icePath == newModFile.icePath, orElse: () { - return ModFile(0, '', '', '', '', '', '', '', null, false, true, false, []); + return ModFile('', '', '', '', '', '', '', '', null, false, true, false, false, []); }); if (jsonModFile.icePath.isNotEmpty) { + newModFile.appliedDate = jsonModFile.appliedDate; newModFile.backupIcePath = jsonModFile.backupIcePath; newModFile.originalIcePath = jsonModFile.originalIcePath; newModFile.isApplied = jsonModFile.isApplied; newModFile.isSFW = jsonModFile.isSFW; newModFile.isNew = jsonModFile.isNew; + newModFile.isFav = jsonModFile.isFav; } allModFiles.add(newModFile); } @@ -121,7 +124,7 @@ List categories(List allModFiles) { imgFilesGet.add(file); } } - + if (imgFilesGet.isNotEmpty) { imgFiles.addAll(imgFilesGet); } else { @@ -218,6 +221,52 @@ List categories(List allModFiles) { } } + //Fav + List favModListGet = []; + for (var cate in categories) { + for (var mod in cate.allModFiles) { + if (mod.isFav) { + favModListGet.add(mod); + } + } + } + + List modNames = []; + for (var mod in favModListGet) { + if (modNames.isEmpty || modNames.indexWhere((element) => element == mod.modName) == -1) { + modNames.add(mod.modName); + } + } + + List> favModsList = []; + for (var name in modNames) { + List sameMods = []; + for (var modFile in favModListGet) { + if (modFile.modName == name) { + sameMods.add(modFile); + } + } + + List parents = []; + for (var modFile in sameMods) { + if (parents.indexWhere((element) => element == modFile.iceParent) == -1) { + parents.add(modFile.iceParent); + } + } + + for (var parent in parents) { + List sameParent = sameMods.where((element) => element.iceParent == parent).toList(); + favModsList.add(sameParent); + } + } + + ModCategory tempFavCate = ModCategory('Favorites', '', [], [], 0, [], [], []); + for (var list in favModsList) { + tempFavCate = addOrRemoveFav(categories, list, tempFavCate, true); + } + tempFavCate.itemNames.sort(); + categories.insert(0, tempFavCate); + return categories; } @@ -267,10 +316,11 @@ Future>> getAppliedModsList() async { if (tempMods.isNotEmpty) { tempMods.add(mod); } else { - appliedList.add([mod]); + appliedList.insert(0, [mod]); } } } + appliedList.sort(((a, b) => b.first.appliedDate.compareTo(b.first.appliedDate))); return appliedList; } diff --git a/lib/popup_handlers.dart b/lib/popup_handlers.dart index 002976f5..aed055e9 100644 --- a/lib/popup_handlers.dart +++ b/lib/popup_handlers.dart @@ -1,8 +1,12 @@ +import 'dart:convert'; import 'dart:io'; +import 'package:carousel_slider/carousel_slider.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; +import 'package:pso2_mod_manager/file_functions.dart'; import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/main.dart'; import 'package:pso2_mod_manager/mod_classes.dart'; @@ -448,7 +452,6 @@ Future modDeleteDialog(context, double height, String popupTitle, String popupMe curCate.allModFiles.remove(element); allModFiles.remove(element); } - } }), child: const Text('Sure')) @@ -458,14 +461,105 @@ Future modDeleteDialog(context, double height, String popupTitle, String popupMe }); } -class _SystemPadding extends StatelessWidget { - final Widget child; - - const _SystemPadding({Key? key, required this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - var mediaQuery = MediaQuery.of(context); - return AnimatedContainer(padding: mediaQuery.viewInsets, duration: const Duration(milliseconds: 300), child: child); - } +//Remove Mod Dialog +Future pictureDialog(context, List previewImageSliders) async { + CarouselController imgSliderController = CarouselController(); + int currentImg = 0; + await showDialog( + context: context, + builder: (BuildContext context) { + return StatefulBuilder(builder: (context, setState) { + return AlertDialog( + contentPadding: const EdgeInsets.only(top: 5, left: 5, right: 5), + content: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + InteractiveViewer( + scaleEnabled: true, + panEnabled: true, + child: AspectRatio( + aspectRatio: 16/9, + child: CarouselSlider( + items: previewImageSliders, + carouselController: imgSliderController, + options: CarouselOptions( + //height: double.maxFinite, + autoPlay: false, + reverse: true, + viewportFraction: 1.0, + enlargeCenterPage: true, + aspectRatio: 1, + onPageChanged: (index, reason) { + setState(() { + currentImg = index; + }); + }), + ), + ), + ), + ], + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const SizedBox(width: 250, child: Text('Scroll wheel: Zoom | Right mouse: Pan',)), + Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (previewImageSliders.isNotEmpty) + SizedBox( + width: 40, + child: MaterialButton( + onPressed: (() => imgSliderController.previousPage()), + child: const Icon(Icons.arrow_left), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: modPreviewImgList.asMap().entries.map((entry) { + return GestureDetector( + onTap: () => imgSliderController.animateToPage(entry.key), + child: Container( + width: 10.0, + height: 10.0, + margin: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 4.0), + decoration: BoxDecoration( + shape: BoxShape.circle, color: (Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black).withOpacity(currentImg == entry.key ? 0.9 : 0.4)), + ), + ); + }).toList(), + ), + if (previewImageSliders.isNotEmpty) + SizedBox( + width: 40, + child: MaterialButton( + onPressed: (() => imgSliderController.nextPage()), + child: const Icon(Icons.arrow_right), + ), + ), + ], + ), + ), + SizedBox( + width: 250, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + ElevatedButton( + child: const Text('Close'), + onPressed: () { + Navigator.of(context).pop(); + }), + ], + ), + ), + ], + ), + ], + ); + }); + }); } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index fa9aa5a4..fd3aaf54 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,6 +8,7 @@ import Foundation import bitsdojo_window_macos import dart_vlc import desktop_drop +import package_info_plus_macos import path_provider_macos import screen_retriever import shared_preferences_macos @@ -18,6 +19,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { BitsdojoWindowPlugin.register(with: registry.registrar(forPlugin: "BitsdojoWindowPlugin")) DartVlcPlugin.register(with: registry.registrar(forPlugin: "DartVlcPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) + FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 9c1142ac..cd4982a7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -198,6 +198,27 @@ packages: description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "10.1.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" intl: dependency: "direct main" description: @@ -254,6 +275,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + package_info_plus: + dependency: "direct main" + description: + name: package_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.2" + package_info_plus_linux: + dependency: transitive + description: + name: package_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + package_info_plus_macos: + dependency: transitive + description: + name: package_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + package_info_plus_web: + dependency: transitive + description: + name: package_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" + package_info_plus_windows: + dependency: transitive + description: + name: package_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.5" path: dependency: transitive description: @@ -448,6 +511,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.9" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" url_launcher: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 0363b06b..e8c2c108 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,6 +42,8 @@ dependencies: intl: ^0.17.0 window_manager: ^0.2.5 dart_vlc: ^0.2.1 + font_awesome_flutter: ^10.1.0 + package_info_plus: ^1.4.2 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp index e65a352d..c832ac55 100644 --- a/windows/runner/main.cpp +++ b/windows/runner/main.cpp @@ -4,7 +4,6 @@ auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); #include #include -#include "flutter_native_view/flutter_native_view_plugin.h" #include "flutter_window.h" #include "utils.h" @@ -36,7 +35,6 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, } window.SetQuitOnClose(true); - flutternativeview::NativeViewContainer::GetInstance()->Create(); ::MSG msg; while (::GetMessage(&msg, nullptr, 0, 0)) { From 491ec4661f2adc79eacad3d3be8a469f8c12b518 Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Thu, 23 Jun 2022 19:56:36 -0700 Subject: [PATCH 4/6] search + fixes --- lib/file_functions.dart | 2 +- lib/home_page.dart | 1151 +++++++++++++++++++++++++++------------ lib/mods_loader.dart | 82 +++ lib/popup_handlers.dart | 4 - pubspec.yaml | 2 +- 5 files changed, 877 insertions(+), 364 deletions(-) diff --git a/lib/file_functions.dart b/lib/file_functions.dart index 78551cec..b519f901 100644 --- a/lib/file_functions.dart +++ b/lib/file_functions.dart @@ -175,7 +175,7 @@ Future modsToDataAdder(List modList) async { appliedModsList.insert(0, [mod]); } } - appliedModsList.sort(((a, b) => a.first.appliedDate.compareTo(b.first.appliedDate))); + //appliedModsList.sort(((a, b) => a.first.appliedDate.compareTo(b.first.appliedDate))); } allModFiles.map((mod) => mod.toJson()).toList(); diff --git a/lib/home_page.dart b/lib/home_page.dart index 906ed274..5bf89af4 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -23,6 +23,7 @@ import 'package:pso2_mod_manager/state_provider.dart'; import 'package:url_launcher/url_launcher.dart'; List cateList = []; +List cateListSearchResult = []; Future? modFilesListGet; Future? futureImagesGet; Future? appliedModsListGet; @@ -35,6 +36,8 @@ List backupFilesMissingList = []; List isLoading = []; bool isModAddFolderOnly = true; bool isViewingFav = false; +bool isSearching = false; +TextEditingController searchBoxTextController = TextEditingController(); //New Cate bool addCategoryVisible = false; @@ -86,6 +89,7 @@ class _HomePageState extends State with TickerProviderStateMixin { final MultiSplitViewController _verticalViewsController = MultiSplitViewController(areas: [Area(weight: 0.5)]); String modsViewAppBarName = ''; List selectedIndex = List.generate(cateList.length, (index) => -1); + List searchListSelectedIndex = List.generate(cateListSearchResult.length, (index) => -1); CarouselController imgSliderController = CarouselController(); List previewImageSliders = []; @@ -96,6 +100,7 @@ class _HomePageState extends State with TickerProviderStateMixin { bool isPreviewVidOn = false; bool modViewExpandAll = false; bool isErrorInSingleItemName = false; + double searchBoxLeftPadding = 80; late AnimationController cateAdderAniController; late Animation cateAdderAniOffset; @@ -170,10 +175,74 @@ class _HomePageState extends State with TickerProviderStateMixin { return Column( children: [ AppBar( - title: Container(padding: const EdgeInsets.only(bottom: 10), child: const Text('Items')), + title: searchBoxLeftPadding == 15 ? null : Container(padding: const EdgeInsets.only(bottom: 10), child: const Text('Items')), backgroundColor: Theme.of(context).canvasColor, foregroundColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColorDark : Theme.of(context).iconTheme.color, toolbarHeight: 30, + flexibleSpace: Container( + height: 30, + width: double.maxFinite, + padding: EdgeInsets.only(left: searchBoxLeftPadding, right: 100, bottom: 3), + child: Focus( + onFocusChange: (hasFocus) { + setState(() { + if (hasFocus) { + searchBoxLeftPadding = 15; + } else { + if (searchBoxTextController.text.isEmpty) { + searchBoxLeftPadding = 80; + } else { + searchBoxLeftPadding = 15; + } + } + }); + }, + child: TextFormField( + controller: searchBoxTextController, + enableSuggestions: true, + maxLines: 1, + onChanged: (value) { + if (value != '') { + setState(() { + modFilesList.clear(); + modsViewAppBarName = 'Available Mods'; + isSearching = true; + cateListSearchResult = searchFilterResults(cateList, value); + searchListSelectedIndex = List.generate(cateListSearchResult.length, (index) => -1); + }); + } else { + setState(() { + isSearching = false; + modFilesList.clear(); + modsViewAppBarName = 'Available Mods'; + cateListSearchResult = []; + }); + } + }, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only(left: 10, top: 10), + border: const OutlineInputBorder(), + hintText: 'Search', + suffixIcon: searchBoxTextController.text == '' + ? null + : SizedBox( + width: 25, + child: MaterialButton( + onPressed: searchBoxTextController.text == '' + ? null + : (() { + setState(() { + searchBoxTextController.clear(); + modFilesList.clear(); + modsViewAppBarName = 'Available Mods'; + isSearching = false; + searchBoxLeftPadding = 80; + }); + }), + child: const Icon(Icons.clear)), + )), + ), + )), actions: [ Padding( padding: const EdgeInsets.only(right: 2.5), @@ -265,356 +334,89 @@ class _HomePageState extends State with TickerProviderStateMixin { ), //Category List - Expanded( - child: SingleChildScrollView( - controller: AdjustableScrollController(80), - child: ListView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: cateList.length, - itemBuilder: (context, index) { - return ExpansionTile( - initiallyExpanded: false, - 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, - collapsedIconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - // textColor: cateList[index].categoryName != 'Favorites' - // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color - // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, - // iconColor: cateList[index].categoryName != 'Favorites' - // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color - // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, - // collapsedTextColor: cateList[index].categoryName != 'Favorites' - // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color - // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, - // collapsedIconColor: cateList[index].categoryName != 'Favorites' - // ? MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color - // : MyApp.themeNotifier.value == ThemeMode.light ? Colors.orange.shade900 : Theme.of(context).iconTheme.color, - onExpansionChanged: (newState) { - setState(() { - if (!newState) { - selectedIndex = List.filled(cateList.length, -1); - } else { - selectedIndex = List.filled(cateList.length, -1); - } - }); - }, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( + if (!isSearching) + Expanded( + child: SingleChildScrollView( + controller: AdjustableScrollController(80), + child: ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: cateList.length, + itemBuilder: (context, index) { + return AbsorbPointer( + absorbing: isSearching, + child: ExpansionTile( + initiallyExpanded: false, + 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, + collapsedIconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + onExpansionChanged: (newState) { + setState(() { + if (!newState) { + selectedIndex = List.filled(cateList.length, -1); + } else { + selectedIndex = List.filled(cateList.length, -1); + } + }); + }, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (cateList[index].categoryName == 'Favorites') - Text( - cateList[index].categoryName, - style: const TextStyle(fontWeight: FontWeight.w500), - ), - if (cateList[index].categoryName != 'Favorites') Text(cateList[index].categoryName), - Padding( - padding: const EdgeInsets.only(left: 10, top: 3), - child: Container( - padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), - decoration: BoxDecoration( - border: Border.all(color: Theme.of(context).highlightColor), - borderRadius: const BorderRadius.all(Radius.circular(5.0)), + Row( + children: [ + if (cateList[index].categoryName == 'Favorites') + Text( + cateList[index].categoryName, + style: const TextStyle(fontWeight: FontWeight.w500), ), - child: Text('${cateList[index].numOfItems} Items', - style: const TextStyle( - fontSize: 13, - ))), - ), - ], - ), - Row( - children: [ - if (cateList[index].categoryName != 'Favorites') - Tooltip( - message: 'Remove ${cateList[index].categoryName}', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 40, - height: 40, - child: MaterialButton( - onPressed: (() { - setState(() { - if (cateList[index].allModFiles.indexWhere((element) => element.isApplied == true) == -1) { - categoryDeleteDialog( - context, - 100, - 'Remove Category', - 'Remove "${cateList[index].categoryName}" and move it to Deleted Items folder?\nThis will also remove all items in this category', - true, - cateList[index].categoryPath, - cateList[index].allModFiles) - .then((_) { - setState(() { - //setstate to refresh list - }); - }); - } else { - List tempList = cateList[index].allModFiles.where((element) => element.isApplied == true).toList(); - List stillAppliedList = []; - double popupHeight = 40; - for (var element in tempList) { - stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); - popupHeight += 24; - } - String stillApplied = stillAppliedList.join('\n'); - categoryDeleteDialog(context, popupHeight, 'Remove Category', 'Cannot remove "${cateList[index].categoryName}". Unaplly these mods first:\n\n$stillApplied', - false, cateList[index].categoryPath, []); - } - }); - }), - child: Row( - children: [ - Icon( - Icons.delete_sweep_rounded, - color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, - ) - ], - )), - )), - ], - ) - ], - ), - children: [ - //Fav list - if (cateList[index].categoryName == 'Favorites') - for (int i = 0; i < cateList[index].itemNames.length; i++) - Ink( - color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, - child: ListTile( - leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' - ? SizedBox( - width: 50, - height: 50, - child: Image.file( - cateList[index].imageIcons[i].first, - fit: BoxFit.fitWidth, - )) - : SizedBox( - width: 50, - height: 50, - child: Image.asset( - cateList[index].imageIcons[i].first.path, - fit: BoxFit.fitWidth, - )), - title: Text(cateList[index].itemNames[i]), - subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Applied: ${cateList[index].numOfApplied[i]}'), - trailing: Wrap( - children: [ - if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) - const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), - - //Buttons - Tooltip( - message: 'Open ${cateList[index].itemNames[i]} in File Explorer', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 34, - height: 50, - child: MaterialButton( - onPressed: (() async { - await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); - }), - child: Row( - children: const [ - Icon( - Icons.folder_open_rounded, - size: 18, - ) - ], - )), - )), - if (cateList[index].categoryName == 'Favorites') - SizedBox( - width: 34, - height: 50, - child: Tooltip( - message: 'Remove "${cateList[index].itemNames[i]}" from favorites', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 1), - child: MaterialButton( - onPressed: (() async { - List> modListToRemoveFav = await getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); - for (var element in modListToRemoveFav) { - cateList[index] = addOrRemoveFav(cateList, element, cateList[index], false); - } - setState(() {}); - }), - child: const FaIcon( - FontAwesomeIcons.heartCircleXmark, - size: 17, - //color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).hintColor : Theme.of(context).hintColor, - )), + if (cateList[index].categoryName != 'Favorites') Text(cateList[index].categoryName), + Padding( + padding: const EdgeInsets.only(left: 10, top: 3), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).highlightColor), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), ), - ), - - // if (cateList[index].categoryName != 'Favorites') - // Tooltip( - // message: 'Remove ${cateList[index].itemNames[i]}', - // height: 25, - // textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - // waitDuration: const Duration(seconds: 2), - // child: SizedBox( - // width: 36, - // height: 50, - // child: MaterialButton( - // onPressed: (() { - // setState(() { - // if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { - // itemDeleteDialog( - // context, - // 100, - // 'Remove Item', - // 'Remove "${cateList[index].itemNames[i]}" and move it to Deleted Items folder?\nThis will also remove all mods in this item', - // true, - // cateList[index], - // cateList[index].itemNames[i], - // cateList[index].allModFiles) - // .then((_) { - // setState(() { - // modsViewAppBarName = 'Available Mods'; - // isModSelected = false; - // //setstate - // }); - // }); - // } else { - // List tempList = - // cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); - // List stillAppliedList = []; - // double popupHeight = 40; - // for (var element in tempList) { - // stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); - // popupHeight += 24; - // } - // String stillApplied = stillAppliedList.join('\n'); - // itemDeleteDialog(context, popupHeight, 'Remove Item', 'Cannot remove "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', - // false, cateList[index], cateList[index].itemNames[i], []); - // } - // }); - // }), - // child: Row( - // children: const [ - // Icon( - // Icons.delete_forever_outlined, - // size: 20, - // ) - // ], - // )), - // )), - ], - ), - onTap: () { - setState(() { - isViewingFav = true; - isPreviewImgsOn = false; - modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); - selectedIndex = List.filled(cateList.length, -1); - selectedIndex[index] = i; - modNameCatSelected = -1; - modsViewAppBarName = cateList[index].itemNames[i]; - _newModToItemIndex = index; - isModSelected = true; - isLoading.clear(); - }); - }, + child: Text('${cateList[index].numOfItems} Items', + style: const TextStyle( + fontSize: 13, + ))), + ), + ], ), - ), - - //Non fav - if (cateList[index].categoryName != 'Favorites') - for (int i = 0; i < cateList[index].itemNames.length; i++) - Ink( - color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, - child: ListTile( - leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' - ? SizedBox( - width: 50, - height: 50, - child: Image.file( - cateList[index].imageIcons[i].first, - fit: BoxFit.fitWidth, - )) - : SizedBox( - width: 50, - height: 50, - child: Image.asset( - cateList[index].imageIcons[i].first.path, - fit: BoxFit.fitWidth, - )), - title: Text(cateList[index].itemNames[i]), - subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Files applied: ${cateList[index].numOfApplied[i]}'), - trailing: Wrap( - children: [ - if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) - const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), - - //Buttons - Tooltip( - message: 'Open ${cateList[index].itemNames[i]} in File Explorer', - height: 25, - textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), - waitDuration: const Duration(seconds: 2), - child: SizedBox( - width: 34, - height: 50, - child: MaterialButton( - onPressed: (() async { - await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); - }), - child: Row( - children: const [ - Icon( - Icons.folder_open_rounded, - size: 18, - ) - ], - )), - )), + Row( + children: [ + if (cateList[index].categoryName != 'Favorites') Tooltip( - message: 'Delete ${cateList[index].itemNames[i]}', + message: 'Remove ${cateList[index].categoryName}', height: 25, textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), waitDuration: const Duration(seconds: 2), child: SizedBox( - width: 36, - height: 50, + width: 40, + height: 40, child: MaterialButton( onPressed: (() { setState(() { - if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { - itemDeleteDialog( + if (cateList[index].allModFiles.indexWhere((element) => element.isApplied == true) == -1) { + categoryDeleteDialog( context, 100, - 'Delete Item', - 'Delete "${cateList[index].itemNames[i]}" and move it to \'Deleted\' Items folder?\nThis will also delete all mods in this item', + 'Remove Category', + 'Remove "${cateList[index].categoryName}" and move it to Deleted Items folder?\nThis will also remove all items in this category', true, - cateList[index], - cateList[index].itemNames[i], + cateList[index].categoryPath, cateList[index].allModFiles) .then((_) { setState(() { - modsViewAppBarName = 'Available Mods'; - isModSelected = false; - //setstate + //setstate to refresh list }); }); - } else if (cateList[index].allModFiles.indexWhere((element) => element.isFav && element.modName == cateList[index].itemNames[i]) != -1) { - double popupHeight = 40; - itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Remove from Favorites first', false, - cateList[index], cateList[index].itemNames[i], []); } else { - List tempList = - cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); + List tempList = cateList[index].allModFiles.where((element) => element.isApplied == true).toList(); List stillAppliedList = []; double popupHeight = 40; for (var element in tempList) { @@ -622,44 +424,672 @@ class _HomePageState extends State with TickerProviderStateMixin { popupHeight += 24; } String stillApplied = stillAppliedList.join('\n'); - itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', - false, cateList[index], cateList[index].itemNames[i], []); + categoryDeleteDialog(context, popupHeight, 'Remove Category', + 'Cannot remove "${cateList[index].categoryName}". Unaplly these mods first:\n\n$stillApplied', false, cateList[index].categoryPath, []); } }); }), child: Row( - children: const [ + children: [ Icon( - Icons.delete_forever_outlined, - size: 20, + Icons.delete_sweep_rounded, + color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, ) ], )), )), - ], + ], + ) + ], + ), + children: [ + //Fav list + if (cateList[index].categoryName == 'Favorites') + for (int i = 0; i < cateList[index].itemNames.length; i++) + Ink( + color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, + height: 50, + child: Image.file( + cateList[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateList[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateList[index].itemNames[i]), + subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Applied: ${cateList[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + + //Buttons + Tooltip( + message: 'Open ${cateList[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + if (cateList[index].categoryName == 'Favorites') + SizedBox( + width: 34, + height: 50, + child: Tooltip( + message: 'Remove "${cateList[index].itemNames[i]}" from favorites', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() async { + List> modListToRemoveFav = await getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + for (var element in modListToRemoveFav) { + cateList[index] = addOrRemoveFav(cateList, element, cateList[index], false); + } + setState(() {}); + }), + child: const FaIcon( + FontAwesomeIcons.heartCircleXmark, + size: 17, + //color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).hintColor : Theme.of(context).hintColor, + )), + ), + ), + + // if (cateList[index].categoryName != 'Favorites') + // Tooltip( + // message: 'Remove ${cateList[index].itemNames[i]}', + // height: 25, + // textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + // waitDuration: const Duration(seconds: 2), + // child: SizedBox( + // width: 36, + // height: 50, + // child: MaterialButton( + // onPressed: (() { + // setState(() { + // if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { + // itemDeleteDialog( + // context, + // 100, + // 'Remove Item', + // 'Remove "${cateList[index].itemNames[i]}" and move it to Deleted Items folder?\nThis will also remove all mods in this item', + // true, + // cateList[index], + // cateList[index].itemNames[i], + // cateList[index].allModFiles) + // .then((_) { + // setState(() { + // modsViewAppBarName = 'Available Mods'; + // isModSelected = false; + // //setstate + // }); + // }); + // } else { + // List tempList = + // cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); + // List stillAppliedList = []; + // double popupHeight = 40; + // for (var element in tempList) { + // stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + // popupHeight += 24; + // } + // String stillApplied = stillAppliedList.join('\n'); + // itemDeleteDialog(context, popupHeight, 'Remove Item', 'Cannot remove "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', + // false, cateList[index], cateList[index].itemNames[i], []); + // } + // }); + // }), + // child: Row( + // children: const [ + // Icon( + // Icons.delete_forever_outlined, + // size: 20, + // ) + // ], + // )), + // )), + ], + ), + onTap: () { + setState(() { + isViewingFav = true; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + selectedIndex = List.filled(cateList.length, -1); + selectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateList[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, + ), ), - onTap: () { - setState(() { - isViewingFav = false; - isPreviewImgsOn = false; - modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); - selectedIndex = List.filled(cateList.length, -1); - selectedIndex[index] = i; - modNameCatSelected = -1; - modsViewAppBarName = cateList[index].itemNames[i]; - _newModToItemIndex = index; - isModSelected = true; - isLoading.clear(); - }); - }, + + //Non fav + if (cateList[index].categoryName != 'Favorites') + for (int i = 0; i < cateList[index].itemNames.length; i++) + Ink( + color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, + height: 50, + child: Image.file( + cateList[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateList[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateList[index].itemNames[i]), + subtitle: Text('Mods: ${cateList[index].numOfMods[i]} | Files applied: ${cateList[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + + //Buttons + Tooltip( + message: 'Open ${cateList[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateList[index].categoryPath}\\${cateList[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + Tooltip( + message: 'Delete ${cateList[index].itemNames[i]}', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 36, + height: 50, + child: MaterialButton( + onPressed: (() { + setState(() { + if (cateList[index].allModFiles.indexWhere((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true) == -1) { + itemDeleteDialog( + context, + 100, + 'Delete Item', + 'Delete "${cateList[index].itemNames[i]}" and move it to \'Deleted\' Items folder?\nThis will also delete all mods in this item', + true, + cateList[index], + cateList[index].itemNames[i], + cateList[index].allModFiles) + .then((_) { + setState(() { + modsViewAppBarName = 'Available Mods'; + isModSelected = false; + //setstate + }); + }); + } else if (cateList[index].allModFiles.indexWhere((element) => element.isFav && element.modName == cateList[index].itemNames[i]) != -1) { + double popupHeight = 40; + itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Remove from Favorites first', false, + cateList[index], cateList[index].itemNames[i], []); + } else { + List tempList = + cateList[index].allModFiles.where((element) => element.modName == cateList[index].itemNames[i] && element.isApplied == true).toList(); + List stillAppliedList = []; + double popupHeight = 40; + for (var element in tempList) { + stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + popupHeight += 24; + } + String stillApplied = stillAppliedList.join('\n'); + itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateList[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', + false, cateList[index], cateList[index].itemNames[i], []); + } + }); + }), + child: Row( + children: const [ + Icon( + Icons.delete_forever_outlined, + size: 20, + ) + ], + )), + )), + ], + ), + onTap: () { + setState(() { + isViewingFav = false; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateList[index].allModFiles, cateList[index].itemNames[i]); + selectedIndex = List.filled(cateList.length, -1); + selectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateList[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, + ), + ) + ], + ), + ); + }, + ), + ), + ), + + //Search Result Category List + if (isSearching && cateListSearchResult.isEmpty) + const Expanded( + child: Padding( + padding: EdgeInsets.only(top: 5.0), + child: Text('No Results Found'), + )), + if (isSearching && cateListSearchResult.isNotEmpty) + Expanded( + child: SingleChildScrollView( + controller: AdjustableScrollController(80), + child: AbsorbPointer( + absorbing: !isSearching, + child: ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: cateListSearchResult.length, + itemBuilder: (context, index) { + return ExpansionTile( + initiallyExpanded: false, + 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, + collapsedIconColor: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + onExpansionChanged: (newState) { + setState(() { + if (!newState) { + searchListSelectedIndex = List.filled(cateListSearchResult.length, -1); + } else { + searchListSelectedIndex = List.filled(cateListSearchResult.length, -1); + } + }); + }, + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + if (cateListSearchResult[index].categoryName == 'Favorites') + Text( + cateListSearchResult[index].categoryName, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + if (cateListSearchResult[index].categoryName != 'Favorites') Text(cateListSearchResult[index].categoryName), + Padding( + padding: const EdgeInsets.only(left: 10, top: 3), + child: Container( + padding: const EdgeInsets.only(left: 2, right: 2, bottom: 1), + decoration: BoxDecoration( + border: Border.all(color: Theme.of(context).highlightColor), + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + ), + child: Text('${cateListSearchResult[index].numOfItems} Items', + style: const TextStyle( + fontSize: 13, + ))), + ), + ], ), - ) - ], - ); - }, + // Row( + // children: [ + // if (cateListSearchResult[index].categoryName != 'Favorites') + // Tooltip( + // message: 'Remove ${cateListSearchResult[index].categoryName}', + // height: 25, + // textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + // waitDuration: const Duration(seconds: 2), + // child: SizedBox( + // width: 40, + // height: 40, + // child: MaterialButton( + // onPressed: (() { + // setState(() { + // if (cateListSearchResult[index].allModFiles.indexWhere((element) => element.isApplied == true) == -1) { + // categoryDeleteDialog( + // context, + // 100, + // 'Remove Category', + // 'Remove "${cateListSearchResult[index].categoryName}" and move it to Deleted Items folder?\nThis will also remove all items in this category', + // true, + // cateListSearchResult[index].categoryPath, + // cateListSearchResult[index].allModFiles) + // .then((_) { + // setState(() { + // //setstate to refresh list + // }); + // }); + // } else { + // List tempList = cateListSearchResult[index].allModFiles.where((element) => element.isApplied == true).toList(); + // List stillAppliedList = []; + // double popupHeight = 40; + // for (var element in tempList) { + // stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + // popupHeight += 24; + // } + // String stillApplied = stillAppliedList.join('\n'); + // categoryDeleteDialog( + // context, + // popupHeight, + // 'Remove Category', + // 'Cannot remove "${cateListSearchResult[index].categoryName}". Unaplly these mods first:\n\n$stillApplied', + // false, + // cateListSearchResult[index].categoryPath, []); + // } + // }); + // }), + // child: Row( + // children: [ + // Icon( + // Icons.delete_sweep_rounded, + // color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).primaryColor : Theme.of(context).iconTheme.color, + // ) + // ], + // )), + // )), + // ], + // ) + ], + ), + children: [ + //Fav list + if (cateListSearchResult[index].categoryName == 'Favorites') + for (int i = 0; i < cateListSearchResult[index].itemNames.length; i++) + Ink( + color: searchListSelectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, + height: 50, + child: Image.file( + cateListSearchResult[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateListSearchResult[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateListSearchResult[index].itemNames[i]), + subtitle: Text('Mods: ${cateListSearchResult[index].numOfMods[i]} | Applied: ${cateListSearchResult[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateListSearchResult[index].allModFiles.indexWhere((element) => element.modName == cateListSearchResult[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + + //Buttons + Tooltip( + message: 'Open ${cateListSearchResult[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateListSearchResult[index].categoryPath}\\${cateListSearchResult[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + if (cateListSearchResult[index].categoryName == 'Favorites') + SizedBox( + width: 34, + height: 50, + child: Tooltip( + message: 'Remove "${cateListSearchResult[index].itemNames[i]}" from favorites', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 1), + child: MaterialButton( + onPressed: (() async { + List> modListToRemoveFav = await getModFilesByCategory(cateListSearchResult[index].allModFiles, cateListSearchResult[index].itemNames[i]); + for (var element in modListToRemoveFav) { + cateListSearchResult[index] = addOrRemoveFav(cateListSearchResult, element, cateListSearchResult[index], false); + } + setState(() {}); + }), + child: const FaIcon( + FontAwesomeIcons.heartCircleXmark, + size: 17, + //color: MyApp.themeNotifier.value == ThemeMode.light ? Theme.of(context).hintColor : Theme.of(context).hintColor, + )), + ), + ), + ], + ), + onTap: () { + setState(() { + isViewingFav = true; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateListSearchResult[index].allModFiles, cateListSearchResult[index].itemNames[i]); + searchListSelectedIndex = List.filled(cateListSearchResult.length, -1); + searchListSelectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateListSearchResult[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, + ), + ), + + //Non fav + if (cateListSearchResult[index].categoryName != 'Favorites') + for (int i = 0; i < cateListSearchResult[index].itemNames.length; i++) + Ink( + color: searchListSelectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, + child: ListTile( + leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + ? SizedBox( + width: 50, + height: 50, + child: Image.file( + cateListSearchResult[index].imageIcons[i].first, + fit: BoxFit.fitWidth, + )) + : SizedBox( + width: 50, + height: 50, + child: Image.asset( + cateListSearchResult[index].imageIcons[i].first.path, + fit: BoxFit.fitWidth, + )), + title: Text(cateListSearchResult[index].itemNames[i]), + subtitle: Text('Mods: ${cateListSearchResult[index].numOfMods[i]} | Files applied: ${cateListSearchResult[index].numOfApplied[i]}'), + trailing: Wrap( + children: [ + if (cateListSearchResult[index].allModFiles.indexWhere((element) => element.modName == cateListSearchResult[index].itemNames[i] && element.isNew == true) != -1) + const SizedBox(height: 50, child: Icon(Icons.new_releases, color: Colors.amber)), + + //Buttons + Tooltip( + message: 'Open ${cateListSearchResult[index].itemNames[i]} in File Explorer', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 34, + height: 50, + child: MaterialButton( + onPressed: (() async { + await launchUrl(Uri.parse('file:${cateListSearchResult[index].categoryPath}\\${cateListSearchResult[index].itemNames[i]}')); + }), + child: Row( + children: const [ + Icon( + Icons.folder_open_rounded, + size: 18, + ) + ], + )), + )), + Tooltip( + message: 'Delete ${cateListSearchResult[index].itemNames[i]}', + height: 25, + textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), + waitDuration: const Duration(seconds: 2), + child: SizedBox( + width: 36, + height: 50, + child: MaterialButton( + onPressed: (() { + setState(() { + if (cateListSearchResult[index] + .allModFiles + .indexWhere((element) => element.modName == cateListSearchResult[index].itemNames[i] && element.isApplied == true) == + -1) { + ModCategory curCate = cateList.firstWhere((element) => element.categoryName == cateListSearchResult[index].categoryName); + String curItem = cateListSearchResult[index].itemNames[i]; + itemDeleteDialog( + context, + 100, + 'Delete Item', + 'Delete "${cateListSearchResult[index].itemNames[i]}" and move it to \'Deleted\' Items folder?\nThis will also delete all mods in this item', + true, + cateListSearchResult[index], + cateListSearchResult[index].itemNames[i], + cateListSearchResult[index].allModFiles) + .then((_) { + //Remove from normal Item List + + curCate.imageIcons.removeAt(curCate.itemNames.indexOf(curItem)); + curCate.numOfMods.removeAt(curCate.itemNames.indexWhere((element) => element == curItem)); + curCate.itemNames.removeWhere((element) => element == curItem); + curCate.allModFiles.removeWhere((element) => element.modName == curItem); + curCate.numOfItems--; + setState(() { + modsViewAppBarName = 'Available Mods'; + isModSelected = false; + //setstate + }); + }); + } else if (cateListSearchResult[index] + .allModFiles + .indexWhere((element) => element.isFav && element.modName == cateListSearchResult[index].itemNames[i]) != + -1) { + double popupHeight = 40; + itemDeleteDialog(context, popupHeight, 'Delete Item', 'Cannot delete "${cateListSearchResult[index].itemNames[i]}". Remove from Favorites first', + false, cateListSearchResult[index], cateListSearchResult[index].itemNames[i], []); + } else { + List tempList = cateListSearchResult[index] + .allModFiles + .where((element) => element.modName == cateListSearchResult[index].itemNames[i] && element.isApplied == true) + .toList(); + List stillAppliedList = []; + double popupHeight = 40; + for (var element in tempList) { + stillAppliedList.add('${element.modName}${element.iceParent} > ${element.iceName}'); + popupHeight += 24; + } + String stillApplied = stillAppliedList.join('\n'); + itemDeleteDialog( + context, + popupHeight, + 'Delete Item', + 'Cannot delete "${cateListSearchResult[index].itemNames[i]}". Unaplly these mods first:\n\n$stillApplied', + false, + cateListSearchResult[index], + cateListSearchResult[index].itemNames[i], []); + } + }); + }), + child: Row( + children: const [ + Icon( + Icons.delete_forever_outlined, + size: 20, + ) + ], + )), + )), + ], + ), + onTap: () { + setState(() { + isViewingFav = false; + isPreviewImgsOn = false; + modFilesListGet = getModFilesByCategory(cateListSearchResult[index].allModFiles, cateListSearchResult[index].itemNames[i]); + searchListSelectedIndex = List.filled(cateListSearchResult.length, -1); + searchListSelectedIndex[index] = i; + modNameCatSelected = -1; + modsViewAppBarName = cateListSearchResult[index].itemNames[i]; + _newModToItemIndex = index; + isModSelected = true; + isLoading.clear(); + }); + }, + ), + ) + ], + ); + }, + ), + ), ), ), - ), //Add Category Panel if (addCategoryVisible) @@ -947,12 +1377,16 @@ class _HomePageState extends State with TickerProviderStateMixin { selectedCategoryForSingleItem == 'Setwears' || selectedCategoryForSingleItem == 'Outerewears' || selectedCategoryForSingleItem == 'Innerwears') { - if (cateList.indexWhere((e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase().contains(value.toLowerCase())) != -1) != -1) { + if (cateList.indexWhere((e) => + e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase().contains(value.toLowerCase())) != -1) != + -1) { isErrorInSingleItemName = true; return 'The name already exist'; } } else { - if (cateList.indexWhere((e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase() == value.toLowerCase()) != -1) != -1) { + if (cateList.indexWhere( + (e) => e.categoryName == selectedCategoryForSingleItem && e.itemNames.indexWhere((element) => element.toLowerCase() == value.toLowerCase()) != -1) != + -1) { isErrorInSingleItemName = true; return 'The name already exist'; } @@ -1419,7 +1853,8 @@ class _HomePageState extends State with TickerProviderStateMixin { child: CircularProgressIndicator(), ), - if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == true) != -1 && !isLoading[index]) + //if (modFilesList[index].length > 1 && modFilesList[index].indexWhere((element) => element.isApplied == true) != -1 && !isLoading[index]) + if (modFilesList[index].indexWhere((element) => element.isApplied == true) != -1 && !isLoading[index]) SizedBox( width: 40, height: 40, diff --git a/lib/mods_loader.dart b/lib/mods_loader.dart index d892f6e9..e9ad6964 100644 --- a/lib/mods_loader.dart +++ b/lib/mods_loader.dart @@ -270,6 +270,88 @@ List categories(List allModFiles) { return categories; } +//Search result +List searchFilterResults(List paramCateList, String searchText) { + List resultList = []; + + for (var cate in paramCateList) { + if (cate.categoryName != 'Favorites') { + List itemNameResults = []; + if (cate.categoryName == 'Basewears' || cate.categoryName == 'Outerwears' || cate.categoryName == 'Innerwears' || cate.categoryName == 'Setwears') { + itemNameResults = cate.itemNames.where((element) => element.replaceRange(element.length - 4, null, '').toLowerCase().contains(searchText.toLowerCase())).toList(); + } else { + itemNameResults = cate.itemNames.where((element) => element.toLowerCase().contains(searchText.toLowerCase())).toList(); + } + + if (itemNameResults.isNotEmpty) { + ModCategory newCate = ModCategory(cate.categoryName, cate.categoryPath, [], [], itemNameResults.length, [], [], []); + for (var itemName in itemNameResults) { + int itemIndex = cate.itemNames.indexOf(itemName); + List imgFiles = cate.imageIcons[itemIndex]; + int numofMod = cate.numOfMods[itemIndex]; + int numofApplied = cate.numOfApplied[itemIndex]; + List modsInItems = cate.allModFiles.where((element) => element.modName == itemName).toList(); + + //Populate newcate + newCate.itemNames.add(itemName); + newCate.imageIcons.add(imgFiles); + newCate.numOfMods.add(numofMod); + newCate.numOfApplied.add(numofApplied); + newCate.allModFiles.addAll(modsInItems); + } + resultList.add(newCate); + } else { + List modFileResults = + cate.allModFiles.where((element) => element.iceName.toLowerCase().contains(searchText.toLowerCase()) || element.iceParent.toLowerCase().contains(searchText.toLowerCase())).toList(); + + if (modFileResults.isNotEmpty) { + // List parentsFromMods = []; + // for (var element in modFileResults) { + // if (parentsFromMods.indexWhere((e) => e == element.iceParent) == -1) { + // parentsFromMods.add(element.iceParent); + // } + // } + List itemNamesfromMods = []; + for (var element in modFileResults) { + if (itemNamesfromMods.indexWhere((e) => e == element.modName) == -1) { + itemNamesfromMods.add(element.modName); + } + } + + ModCategory newCate = ModCategory(cate.categoryName, cate.categoryPath, [], [], itemNamesfromMods.length, [], [], []); + for (var itemName in itemNamesfromMods) { + int itemIndex = cate.itemNames.indexOf(itemName); + List imgFiles = cate.imageIcons[itemIndex]; + List parentsInItems = []; + for (var element in modFileResults.where((element) => element.modName == itemName)) { + if (parentsInItems.indexWhere((e) => e == element.iceParent) == -1) { + parentsInItems.add(element.iceParent); + } + } + int numofMod = parentsInItems.length; + int numofApplied = modFileResults.where((element) => element.isApplied == true).length; // need to change + List modsInItems = modFileResults.where((element) => element.modName == itemName).toList(); + //List modsInItems = []; + // for (var parent in parentsFromMods) { + // modsInItems = modFileResults.where((element) => element.modName == itemName).toList(); + // } + + //Populate newcate + newCate.itemNames.add(itemName); + newCate.imageIcons.add(imgFiles); + newCate.numOfMods.add(numofMod); + newCate.numOfApplied.add(numofApplied); + newCate.allModFiles.addAll(modsInItems); + } + resultList.add(newCate); + } + } + } + } + + return resultList; +} + //Mod List Future>> getModFilesByCategory(List allModFiles, String modName) async { List> modFilesList = []; diff --git a/lib/popup_handlers.dart b/lib/popup_handlers.dart index aed055e9..d7683e02 100644 --- a/lib/popup_handlers.dart +++ b/lib/popup_handlers.dart @@ -1,16 +1,12 @@ -import 'dart:convert'; import 'dart:io'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; -import 'package:pso2_mod_manager/file_functions.dart'; import 'package:pso2_mod_manager/home_page.dart'; import 'package:pso2_mod_manager/main.dart'; import 'package:pso2_mod_manager/mod_classes.dart'; -import 'package:pso2_mod_manager/mods_loader.dart'; import 'package:pso2_mod_manager/state_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index e8c2c108..da6194d4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 +version: 1.1.0+1 environment: sdk: ">=2.17.0 <3.0.0" From f2d8ce02a9163478df9c6ff5aa28cdbe25601149 Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Thu, 23 Jun 2022 20:18:24 -0700 Subject: [PATCH 5/6] bug fix --- lib/main.dart | 17 +++++++++-------- pubspec.lock | 12 ++++++------ windows/runner/Runner.rc | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index d145ad23..a81bc3a6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -234,19 +234,20 @@ class _MyHomePageState extends State with WindowListener { child: Row( children: [ Expanded( - child: MoveWindow( - child: Container( - padding: const EdgeInsets.only(left: 10), - child: Tooltip( + child: MoveWindow( + child: Container( + padding: const EdgeInsets.only(left: 10), + child: Tooltip( message: 'Version: $appVersion | Build by キス★', height: 25, textStyle: TextStyle(fontSize: 15, color: Theme.of(context).canvasColor), waitDuration: const Duration(seconds: 2), child: const Text( - 'PSO2NGS Mod Manager', - style: TextStyle(fontWeight: FontWeight.w500), - )), - )),), + 'PSO2NGS Mod Manager', + style: TextStyle(fontWeight: FontWeight.w500), + )), + )), + ), //Buttons Padding( padding: const EdgeInsets.only(bottom: 9), diff --git a/pubspec.lock b/pubspec.lock index cd4982a7..badaf757 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -105,7 +105,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.5" dart_vlc: dependency: "direct main" description: @@ -133,7 +133,7 @@ packages: name: dropdown_button2 url: "https://pub.dartlang.org" source: hosted - version: "1.5.2" + version: "1.6.2" fake_async: dependency: transitive description: @@ -267,7 +267,7 @@ packages: name: multi_split_view url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.1.0" nested: dependency: transitive description: @@ -524,7 +524,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.1.2" + version: "6.1.4" url_launcher_android: dependency: transitive description: @@ -559,14 +559,14 @@ packages: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.1.0" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.12" url_launcher_windows: dependency: transitive description: diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index daa3bca0..e87ab56a 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -69,7 +69,7 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" #ifdef FLUTTER_BUILD_NAME #define VERSION_AS_STRING #FLUTTER_BUILD_NAME #else -#define VERSION_AS_STRING "1.0.0" +#define VERSION_AS_STRING "1.1.0" #endif VS_VERSION_INFO VERSIONINFO From 77418a700be15d9e0caec90a92830d1d4ac0f7c8 Mon Sep 17 00:00:00 2001 From: KizKizz <101075148+KizKizz@users.noreply.github.com> Date: Fri, 24 Jun 2022 12:23:41 -0700 Subject: [PATCH 6/6] More updates --- assets/img/placeholdersquare.jpg | Bin 32878 -> 0 bytes assets/img/placeholdersquare.png | Bin 0 -> 4096 bytes lib/file_functions.dart | 4 ++-- lib/home_page.dart | 12 ++++++++---- lib/main.dart | 2 +- lib/mods_loader.dart | 2 +- pubspec.yaml | 2 +- windows/runner/resources/app_icon.ico | Bin 270986 -> 343700 bytes 8 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 assets/img/placeholdersquare.jpg create mode 100644 assets/img/placeholdersquare.png diff --git a/assets/img/placeholdersquare.jpg b/assets/img/placeholdersquare.jpg deleted file mode 100644 index ab6d0e3cc5745cfc032586bc57537a4c1ee3ffcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32878 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 CWm9DU diff --git a/assets/img/placeholdersquare.png b/assets/img/placeholdersquare.png new file mode 100644 index 0000000000000000000000000000000000000000..c229e4356463bef652c13f63b65468185bcc95c7 GIT binary patch literal 4096 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 dragDropSingleFilesAdd(context, List newItemDragDropList, St final newModRoot = Directory(newItemPath).listSync(recursive: false).whereType(); final thumbnails = newModRoot.where((e) => p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png').toList(); if (thumbnails.isEmpty) { - thumbnails.add(File('assets/img/placeholdersquare.jpg')); + thumbnails.add(File('assets/img/placeholdersquare.png')); } final selectedCategory = cateList.firstWhere((element) => element.categoryName == categoryName); if (selectedCategory.itemNames.indexWhere((element) => element == modName) == -1) { @@ -567,7 +567,7 @@ Future dragDropFilesAdd(context, List newItemDragDropList, String? final newModRoot = Directory(newItemPath).listSync(recursive: false).whereType(); final thumbnails = newModRoot.where((e) => p.extension(e.path) == '.jpg' || p.extension(e.path) == '.png').toList(); if (thumbnails.isEmpty) { - thumbnails.add(File('assets/img/placeholdersquare.jpg')); + thumbnails.add(File('assets/img/placeholdersquare.png')); } final selectedCategory = cateList.firstWhere((element) => element.categoryName == categoryName); if (selectedCategory.itemNames.indexWhere((element) => element == modName) == -1) { diff --git a/lib/home_page.dart b/lib/home_page.dart index 5bf89af4..2eba52d3 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -449,7 +449,7 @@ class _HomePageState extends State with TickerProviderStateMixin { Ink( color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, child: ListTile( - leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.png' ? SizedBox( width: 50, height: 50, @@ -462,6 +462,7 @@ class _HomePageState extends State with TickerProviderStateMixin { height: 50, child: Image.asset( cateList[index].imageIcons[i].first.path, + filterQuality: FilterQuality.none, fit: BoxFit.fitWidth, )), title: Text(cateList[index].itemNames[i]), @@ -596,7 +597,7 @@ class _HomePageState extends State with TickerProviderStateMixin { Ink( color: selectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, child: ListTile( - leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + leading: cateList[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.png' ? SizedBox( width: 50, height: 50, @@ -609,6 +610,7 @@ class _HomePageState extends State with TickerProviderStateMixin { height: 50, child: Image.asset( cateList[index].imageIcons[i].first.path, + filterQuality: FilterQuality.none, fit: BoxFit.fitWidth, )), title: Text(cateList[index].itemNames[i]), @@ -849,7 +851,7 @@ class _HomePageState extends State with TickerProviderStateMixin { Ink( color: searchListSelectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, child: ListTile( - leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.png' ? SizedBox( width: 50, height: 50, @@ -862,6 +864,7 @@ class _HomePageState extends State with TickerProviderStateMixin { height: 50, child: Image.asset( cateListSearchResult[index].imageIcons[i].first.path, + filterQuality: FilterQuality.none, fit: BoxFit.fitWidth, )), title: Text(cateListSearchResult[index].itemNames[i]), @@ -942,7 +945,7 @@ class _HomePageState extends State with TickerProviderStateMixin { Ink( color: searchListSelectedIndex[index] == i ? Theme.of(context).highlightColor : Colors.transparent, child: ListTile( - leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.jpg' + leading: cateListSearchResult[index].imageIcons[i].first.path.split('/').last != 'placeholdersquare.png' ? SizedBox( width: 50, height: 50, @@ -955,6 +958,7 @@ class _HomePageState extends State with TickerProviderStateMixin { height: 50, child: Image.asset( cateListSearchResult[index].imageIcons[i].first.path, + filterQuality: FilterQuality.none, fit: BoxFit.fitWidth, )), title: Text(cateListSearchResult[index].itemNames[i]), diff --git a/lib/main.dart b/lib/main.dart index a81bc3a6..463caca9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -372,7 +372,7 @@ class _MyHomePageState extends State with WindowListener { color: Colors.red, ), SizedBox(width: 5), - Text('Checksum file missing. Click here!', style: TextStyle(fontWeight: FontWeight.w400, color: Colors.red)) + Text('Checksum missing. Click!', style: TextStyle(fontWeight: FontWeight.w400, color: Colors.red)) ], ), ), diff --git a/lib/mods_loader.dart b/lib/mods_loader.dart index e9ad6964..72ca8999 100644 --- a/lib/mods_loader.dart +++ b/lib/mods_loader.dart @@ -107,7 +107,7 @@ Future> modsLoader() async { //Category List List categories(List allModFiles) { - File defaultCategoryItemIcon = File('assets/img/placeholdersquare.jpg'); + File defaultCategoryItemIcon = File('assets/img/placeholdersquare.png'); List categories = []; //Get categories diff --git a/pubspec.yaml b/pubspec.yaml index da6194d4..aeab311b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -71,7 +71,7 @@ flutter: # the material Icons class. uses-material-design: true assets: - - assets/img/placeholdersquare.jpg + - assets/img/placeholdersquare.png # To add assets to your application, add an assets section, like this: # assets: diff --git a/windows/runner/resources/app_icon.ico b/windows/runner/resources/app_icon.ico index 9fa0384503aea6658c43cb6567aa8fccee9a83ed..41c9dc069c86a43072b968079f790e32750a98a8 100644 GIT binary patch literal 343700 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

|}O^-2cki}YVoYSl5ry?Jbp=+WaX>$5G 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%0A#+8w55)>G2p?9sc37;_>N*ru~3CJxTYJEu#ko0 zF{klh>ucdH!3{;bdCYs9Cz^$X$?D%!Q{=lc*)({=65vuK*GTi!e)kggB3Upoz% zw%zj5NnqM8*H4^~X1=_I@awVHf1lRl$H;g-{HuSwRshCHwMad?5&$sWcl3*nsVXD({5uW-U8CAHGFdt3t}9fUW@SHxe<023{Q~1m1qP-7`WeB)ePy7J#D)ytHb)KEfrX${PKHhMfm@>cWt|I+d%ZpP9B)_4!6gy+NR;yg`rB@>S{-IwRphUagA})?Uw#-2K@(vDNCmfM0Lp z{Dpg?mPN|beYZ6Ko9D#Fx@o>X(trN!Dagpnr+cK!_%KwZhu zr>hSG?F?YItpp0cnOoaGZ$U~fuHD^IEsbhvOtHM7u*_y@9V!f{X9L2%i!$-TT0=?| z%nME#kdTk46Z7Iq)P0EJNNlmNQc;}vyRa10B~}Viw@8=$YN0q61ZsEGmfZ;Qbr!X< z2yU1%Ts1kKkeG){TjGwGYWfz;ss~;Bs7PRx)_|hA<+xI+5Yqh8as*wix&xX6c%L2SwyFn~e3A%hHZ zU2o^{qf`knyb@U1{$*QaWFQwsv2bq_Y7NhQvjHuQsxTKf@2UzDEUPM;;>Mb)utJCc zVqRRUSb;AA5ihQ~1EHWob+MQiR+`6{1MVa;N6~NkDoNg?XOu{GFIR@9^R+vtwn{Xa zhyv&V%&xXjAV?!o+6rHi8xPDJd%R;;Mhp)M#*}&OY=pB<$a_$g6KY zmq|NK`f2i*#XUZ-G)|eL@_<6*{3uE0QR3d!7yI_meUs0Do`}Sjrw8s0K2m^1?CaX{ zqqh1iEk*qEs<89Va!N=yVAX zumRQ5sEo|~_515kB|kzyu`&>XDsyr3TX^tS3c>q01ORMq+(xY&K+tNGGYmYvZwE}# zIXm;!uWbGA7Y2N;LZ(q9?R4$>T)rK`=s{OFvb~Sav~ho*=>8F_bF?dvzd7`ORIY$} zYVZCpU%!Aqu0UUoPKE?hqQZhm-@Sb@BrYt`yd^TB)$gGEgN`SiOqv?gc98GY&)`h-TOmCL$Bvy@3e&3f<`@ zyL_bY&YldN;%I?BwC?p{Jm|9etm+;#CL)G^BdvK7U6kmPQbVFT4hh!sJoBzSrA zhjphA+=gmWznA&z5AKdr4xgrcfu8V3lgqZ{l}0PtAbqH|83rk;)p$cdhsP=CHQXxTXW3b1#IMi5ZzZ(? z_&`FzZ>kK^Ury2hdF8=9@BLN2%2i4V>I%R>4Cqt=C^DcAuDf#iA0}1UJAF}QvH$=8 M07*qoM6N<$g23Wq6951J literal 270986 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%0DOB8d`q6lU7=Nb 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