Skip to content

Commit

Permalink
update retroarch core selector
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobaraujo7 committed Jan 22, 2024
1 parent 251504f commit 9207c47
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 15 deletions.
1 change: 1 addition & 0 deletions lib/app/(public)/config/edit_platform_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ class _EditPlatformPageState extends State<EditPlatformPage> {
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Folder',
suffixIcon: Icon(Icons.folder),
),
initialValue: beautifyPath(platform.folder),
readOnly: true,
Expand Down
19 changes: 6 additions & 13 deletions lib/app/(public)/config/widgets/player_select.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:math';

import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:yuno/app/core/widgets/searchable_dropdown.dart';
import 'package:yuno/app/interactor/models/embeds/player.dart';

import '../../../core/constants/retroarch_cores.dart';
Expand Down Expand Up @@ -113,23 +114,15 @@ class PlayerSelect extends StatelessWidget {
children: [
SizedBox(
width: 300,
child: DropdownButtonFormField<String>(
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Retroarch Core',
),
value: player?.extra,
onChanged: (String? newValue) {
child: SearchableDropdown(
onSearchTextChanged: (newValue) {
if (newValue != null) {
onChanged(player?.copyWith(extra: newValue));
}
},
items: retroarchCores.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
label: 'Retroarch Core',
item: player?.extra,
items: retroarchCores,
),
),
IconButton(
Expand Down
161 changes: 161 additions & 0 deletions lib/app/core/widgets/searchable_dropdown.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:routefly/routefly.dart';

class SearchableDropdown extends StatefulWidget {
final void Function(String? searchText) onSearchTextChanged;
final List<String> items;
final String? label;
final String? item;
const SearchableDropdown({
super.key,
this.item,
this.label,
required this.onSearchTextChanged,
required this.items,
});

@override
State<SearchableDropdown> createState() => _SearchableDropdownState();
}

class _SearchableDropdownState extends State<SearchableDropdown> {
final _searchController = TextEditingController();

@override
void initState() {
super.initState();
_searchController.text = widget.item ?? '';
}

@override
void didUpdateWidget(covariant SearchableDropdown oldWidget) {
super.didUpdateWidget(oldWidget);
_searchController.text = widget.item ?? '';
}

@override
void dispose() {
_searchController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return TextField(
controller: _searchController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: widget.label,
suffixIcon: const Icon(Icons.arrow_drop_down),
),
readOnly: true,
onTap: () async {
final item = await Navigator.push(
context,
PageRouteBuilder(
barrierDismissible: true,
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) {
return Center(
child: SizedBox(
width: 370,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: kToolbarHeight,
),
child: _SeachItems(
items: widget.items,
label: widget.label,
),
),
),
);
},
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(
opacity: animation,
child: child,
);
},
),
);

if(item is String){
widget.onSearchTextChanged(item);
_searchController.text = item;
}

},
);
}
}

class _SeachItems extends StatefulWidget {
final List<String> items;
final String? label;

const _SeachItems({super.key, required this.items, this.label});

@override
State<_SeachItems> createState() => _SeachItemsState();
}

class _SeachItemsState extends State<_SeachItems> {
var filteredItems = <String>[];
@override
void initState() {
super.initState();
filteredItems = widget.items;
}

void filter(String? value) {
if (value == null || value.isEmpty) {
setState(() {
filteredItems = widget.items;
});
return;
}

setState(() {
filteredItems = widget.items
.where((item) => item.toLowerCase().contains(value.toLowerCase()))
.toList();
});
}

@override
Widget build(BuildContext context) {
return Material(
elevation: 17,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: widget.label,
),
onChanged: filter,
),
Expanded(
child: Scrollbar(
thumbVisibility: true,
child: ListView.builder(
itemCount: filteredItems.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(filteredItems[index]),
onTap: () {
Navigator.pop(context, filteredItems[index]);
},
);
},
),
),
),
],
),
);
}
}
24 changes: 24 additions & 0 deletions lib/app/interactor/actions/platform_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ Future<void> syncPlatform(PlatformModel platform) async {

final repository = injector<SyncRepository>();

final folderGames = await _getGames(platform);
final currentGames = platform.games;
final games = syncGames(currentGames, folderGames);

platform = platform.copyWith(games: games);

for (var i = 0; i < platform.games.length; i++) {
if (platform.games[i].isSynced) continue;
if (platform.games[i].image.isNotEmpty) {
Expand All @@ -95,6 +101,24 @@ Future<void> syncPlatform(PlatformModel platform) async {
platformSyncState();
}

List<Game> syncGames(List<Game> currentGames, List<Game> folderGames) {
final games = <Game>[];

for (var i = 0; i < folderGames.length; i++) {
final folderGame = folderGames[i];
final currentGame = currentGames.firstWhere(
(game) => game.path == folderGame.path,
orElse: () => folderGame,
);
games.add(currentGame);
}

games.removeWhere((game) {
return folderGames.every((folderGame) => folderGame.path != game.path);
});
return games;
}

Future<Color?> getDominatingColor(String imagePath) async {
final imageFile = File(imagePath);
if (!imageFile.existsSync()) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ packages:
routefly:
dependency: "direct main"
description:
path: "D:\\Projects\\routefly"
path: "/Users/jacob/Projects/routefly"
relative: false
source: path
version: "1.0.8"
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 0.0.3+11
version: 0.0.5+13

environment:
sdk: '>=3.2.4 <4.0.0'
Expand Down
37 changes: 37 additions & 0 deletions test/app/interactor/actions/platform_action.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:yuno/app/interactor/actions/platform_action.dart';
import 'package:yuno/app/interactor/models/embeds/game.dart';

void main() {
test('Uri to path', () {
Expand All @@ -14,4 +15,40 @@ void main() {
final megaman = cleanName('Mega Man Zero 3.zip');
expect(megaman, 'Mega Man Zero 3');
});

test('Sync games add', () {
final currentGames = [
Game(name: 'game 1', description: 'aaa', image: '', path: '/path1',),
Game(name: 'game 2', description: 'aaa', image: '', path: '/path2',),
];
final folderGames = [
Game(name: 'game 1', description: '', image: '', path: '/path1',),
Game(name: 'game 2', description: '', image: '', path: '/path2',),
Game(name: 'game 3', description: '', image: '', path: '/path3',),
];

final games = syncGames(currentGames, folderGames);
expect(games.length, 3);
expect(games[0].description, 'aaa');
expect(games[1].description, 'aaa');

});

test('Sync games remove', () {
final currentGames = [
Game(name: 'game 1', description: 'aaa', image: '', path: '/path1',),
Game(name: 'game 2', description: 'aaa', image: '', path: '/path2',),
];
final folderGames = [
Game(name: 'game 1', description: '', image: '', path: '/path1',),
Game(name: 'game 3', description: '', image: '', path: '/path3',),
];

final games = syncGames(currentGames, folderGames);
expect(games.length, 2);
expect(games[0].description, 'aaa');
expect(games[1].description, '');
expect(games[1].name, 'game 3');

});
}

0 comments on commit 9207c47

Please sign in to comment.