Skip to content

Commit

Permalink
feat(gebura): add local steam library table
Browse files Browse the repository at this point in the history
  • Loading branch information
MuZhou233 committed Jan 18, 2024
1 parent b273a51 commit f30eaef
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
39 changes: 39 additions & 0 deletions lib/common/steam/local_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,41 @@ import '../platform.dart';
import 'acf_parser.dart';

const _defaultSteamInstallPath = r'C:\Program Files (x86)\Steam';
const _excludeAppIds = <String>{
'228980', // Steamworks Common Redistributables
'250820', // SteamVR
};

class InstalledSteamApps {
final String appId;
final String name;
final String launcherPath;
final String sizeOnDisk;
final String? iconFilePath;

InstalledSteamApps({
required this.appId,
required this.name,
required this.launcherPath,
required this.sizeOnDisk,
this.iconFilePath,
});

InstalledSteamApps copyWith({
String? appId,
String? name,
String? launcherPath,
String? sizeOnDisk,
String? iconFilePath,
}) {
return InstalledSteamApps(
appId: appId ?? this.appId,
name: name ?? this.name,
launcherPath: launcherPath ?? this.launcherPath,
sizeOnDisk: sizeOnDisk ?? this.sizeOnDisk,
iconFilePath: iconFilePath ?? this.iconFilePath,
);
}
}

enum SteamScanResult {
Expand Down Expand Up @@ -61,6 +83,11 @@ Future<(List<InstalledSteamApps>, SteamScanResult)> scanLocalLibrary() async {
}
}
}
for (var i = 0; i < apps.length; i += 1) {
apps[i] = apps[i].copyWith(
iconFilePath: _getAppIconFilePath(steamInstallPath, apps[i].appId),
);
}
} catch (e) {
return (apps, SteamScanResult.unknownError);
}
Expand Down Expand Up @@ -132,6 +159,9 @@ InstalledSteamApps? _getAppInfo(String path) {
final name = appState['name'];
final launcherPath = appState['LauncherPath'];
final sizeOnDisk = appState['SizeOnDisk'];
if (appId is String && _excludeAppIds.contains(appId)) {
return null;
}
if (appId is String &&
name is String &&
launcherPath is String &&
Expand All @@ -150,3 +180,12 @@ InstalledSteamApps? _getAppInfo(String path) {
}
return null;
}

String _getAppIconFilePath(String path, String appId) {
return p.join(
path,
'appcache',
'librarycache',
'${appId}_icon.jpg',
);
}
111 changes: 111 additions & 0 deletions lib/view/pages/gebura/gebura_library_settings.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'package:data_table_2/data_table_2.dart';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:universal_io/io.dart' as io;
import 'package:url_launcher/url_launcher_string.dart';

import '../../../bloc/gebura/gebura_bloc.dart';
import '../../../common/steam/local_library.dart';
Expand Down Expand Up @@ -86,6 +90,18 @@ class GeburaLibrarySettings extends StatelessWidget {
Text('发现${localSteamApps.length}个Steam游戏'),
],
),
Container(
height: 512,
margin: const EdgeInsets.only(top: 16),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).dividerColor,
),
color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(8),
),
child: _SteamGameList(apps: localSteamApps),
),
],
),
),
Expand Down Expand Up @@ -128,3 +144,98 @@ class GeburaLibrarySettings extends StatelessWidget {
);
}
}

class _SteamGameList extends StatefulWidget {
const _SteamGameList({
required this.apps,
});

final List<InstalledSteamApps> apps;

@override
State<_SteamGameList> createState() => _SteamGameListState();
}

class _SteamGameListState extends State<_SteamGameList> {
@override
void initState() {
super.initState();
selectedIndex = List.generate(widget.apps.length, (index) => false);
}

late List<bool> selectedIndex;

@override
Widget build(BuildContext context) {
return DataTable2(
onSelectAll: (isSelectedAll) {
if (isSelectedAll ?? false) {
setState(() {
selectedIndex = List.generate(widget.apps.length, (index) => true);
});
} else {
setState(() {
selectedIndex = List.generate(widget.apps.length, (index) => false);
});
}
},
columns: const [
DataColumn2(
label: Text('游戏列表'),
size: ColumnSize.L,
),
DataColumn2(
label: Align(
alignment: Alignment.centerRight,
child: ElevatedButton(onPressed: null, child: Text('导入选中')),
),
fixedWidth: 150,
),
],
rows: widget.apps
.map(
(e) => DataRow(
selected: selectedIndex[widget.apps.indexOf(e)],
onSelectChanged: (isSelected) {
setState(() {
selectedIndex[widget.apps.indexOf(e)] = isSelected ?? false;
});
},
cells: [
DataCell(Row(
children: [
if (e.iconFilePath != null)
Container(
padding: const EdgeInsets.only(right: 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(2),
child: ExtendedImage.file(
io.File(e.iconFilePath!),
width: 16,
height: 16,
)))
else
const Icon(Icons.image),
Text(e.name),
],
)),
DataCell(
Align(
alignment: Alignment.centerRight,
child: OutlinedButton.icon(
onPressed: () async {
await launchUrlString(
'steam://nav/games/details/${e.appId}');
},
icon: Icon(const FaIcon(FontAwesomeIcons.steam).icon,
size: 16),
label: const Text('查看'),
)),
),
],
),
)
.toList(),
);
}
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ dependencies:
device_info_plus: ^9.1.1
path: ^1.8.3
petitparser: ^6.0.2
url_launcher: ^6.2.3

# others
json_annotation: ^4.8.1
Expand Down

0 comments on commit f30eaef

Please sign in to comment.