Skip to content

Commit

Permalink
25.1.26 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmo2233 committed Jan 26, 2025
1 parent 4e839be commit 5290c39
Show file tree
Hide file tree
Showing 17 changed files with 865 additions and 434 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/

# IntelliJ related
Expand Down
30 changes: 18 additions & 12 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ PODS:
- FlutterMacOS
- permission_handler_apple (9.3.0):
- Flutter
- share_plus (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
Expand All @@ -45,6 +47,7 @@ DEPENDENCIES:
- native_flutter_proxy (from `.symlinks/plugins/native_flutter_proxy/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
Expand Down Expand Up @@ -74,6 +77,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
share_plus:
:path: ".symlinks/plugins/share_plus/ios"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
sqflite_darwin:
Expand All @@ -82,20 +87,21 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/url_launcher_ios/ios"

SPEC CHECKSUMS:
app_settings: 017320c6a680cdc94c799949d95b84cb69389ebc
audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40
app_settings: 3507c575c2b18a462c99948f61d5de21d4420999
audioplayers_darwin: ccf9c770ee768abb07e26d90af093f7bab1c12ab
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
image_gallery_saver_plus: 782ade975fe6a4600b53e7c1983e3a2979d1e9e5
native_flutter_proxy: 9d5ce4f6db3e1bf1e0c796020393f6500abd3126
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_local_notifications: 395056b3175ba4f08480a7c5de30cd36d69827e4
flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
image_gallery_saver_plus: e597bf65a7846979417a3eae0763b71b6dfec6c3
native_flutter_proxy: a96434620247e3a0e3ebffde6dae1c31e2745256
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d

PODFILE CHECKSUM: 4bb0d5af7b0a7a18570b26cd09a55bf9a905f81f

Expand Down
57 changes: 24 additions & 33 deletions lib/src/model/mai_song_filter_data.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_date_range_picker/flutter_date_range_picker.dart';
import 'package:rank_hub/src/model/mai_types.dart';
import 'package:rank_hub/src/model/maimai/song_genre.dart';
import 'package:rank_hub/src/model/maimai/song_version.dart';
Expand All @@ -6,10 +8,8 @@ class MaiSongFilterData {
List<LevelIndex>? levelIndex;
List<SongGenre>? genre;
List<SongVersion>? version;
DateTime? uploadTimeStart;
DateTime? uploadTimeEnd;
double? levelValueStart;
double? levelValueEnd;
DateRange? uploadTimeRange;
RangeValues? levelValueRange;
List<FCType>? fcType;
List<FSType>? fsType;
List<SongType>? songType;
Expand All @@ -18,53 +18,46 @@ class MaiSongFilterData {
this.levelIndex,
this.genre,
this.version,
this.uploadTimeStart,
this.uploadTimeEnd,
this.levelValueStart,
this.levelValueEnd,
this.uploadTimeRange,
this.levelValueRange,
this.fcType,
this.fsType,
this.songType,
});

void updateLevelIndex(List<LevelIndex>? levelIndex) => this.levelIndex = levelIndex;
void updateLevelIndex(List<LevelIndex>? levelIndex) =>
this.levelIndex = levelIndex;
void updateGenre(List<SongGenre>? songGenre) => genre = songGenre;
void updateVersion(List<SongVersion>? songVersion) => version = songVersion;
void updateUploadTimeStart(DateTime? uploadTimeStart) =>
this.uploadTimeStart = uploadTimeStart;
void updateUploadTimeEnd(DateTime? uploadTimeEnd) =>
this.uploadTimeEnd = uploadTimeEnd;
void updateLevelValueStart(double? levelValueStart) =>
this.levelValueStart = levelValueStart;
void updateLevelValueEnd(double? levelValueEnd) =>
this.levelValueEnd = levelValueEnd;
void updateUploadTimeRange(DateRange? uploadTimeRange) =>
this.uploadTimeRange = uploadTimeRange;
void updateLevelValueRange(RangeValues? levelValueRange) =>
this.levelValueRange = levelValueRange;
void updateFCType(List<FCType>? fcType) => this.fcType = fcType;
void updateFSType(List<FSType>? fsType) => this.fsType = fsType;
void updateSongType(List<SongType>? songType) => this.songType = songType;

List<String>? get levelLabel => levelIndex?.map((item) => item.label).toList();
List<String>? get levelLabel =>
levelIndex?.map((item) => item.label).toList();
List<String>? get genreLabel => genre?.map((item) => item.title).toList();
List<String>? get versionLabel => version?.map((item) => item.title).toList();
String? get uploadTimeRange => (uploadTimeStart != null &&
uploadTimeEnd != null)
? '${uploadTimeStart!.year}/${uploadTimeStart!.month}/${uploadTimeStart!.day} - ${uploadTimeEnd!.year}/${uploadTimeEnd!.month}/${uploadTimeEnd!.day}'
String? get uploadTimeRangeLabel => (uploadTimeRange != null)
? '${uploadTimeRange!.start.year}/${uploadTimeRange!.start.month}/${uploadTimeRange!.start.day} - ${uploadTimeRange!.end.year}/${uploadTimeRange!.end.month}/${uploadTimeRange!.end.day}'
: null;
String? get levelValueRange => (levelValueStart != null &&
levelValueEnd != null)
? '${levelValueStart!.toStringAsFixed(1)} - ${levelValueEnd!.toStringAsFixed(1)}'
String? get levelValueRangeLabel => (levelValueRange != null)
? '${levelValueRange!.start} - ${levelValueRange!.end}'
: null;
List<String>? get fcTypeLabel => fcType?.map((item) => item.label).toList();
List<String>? get fsTypeLabel => fsType?.map((item) => item.label).toList();
List<String>? get songTypeLabel => songType?.map((item) => item.label).toList();
List<String>? get songTypeLabel =>
songType?.map((item) => item.label).toList();

bool get areAllValuesNull =>
levelIndex == null &&
genre == null &&
version == null &&
uploadTimeStart == null &&
uploadTimeEnd == null &&
levelValueStart == null &&
levelValueEnd == null &&
uploadTimeRange == null &&
levelValueRange == null &&
fcType == null &&
fsType == null &&
songType == null;
Expand All @@ -73,10 +66,8 @@ class MaiSongFilterData {
levelIndex = null;
genre = null;
version = null;
uploadTimeStart = null;
uploadTimeEnd = null;
levelValueStart = null;
levelValueEnd = null;
uploadTimeRange = null;
levelValueRange = null;
fcType = null;
fsType = null;
songType = null;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/pages/main_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class _MainPageState extends State<MainPage> {
filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),
child: NavigationBar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.9),
Theme.of(context).scaffoldBackgroundColor.withValues(alpha: 0.95),
destinations: _navItems,
selectedIndex: _selectedIndex,
onDestinationSelected: _onNavItemTapped,
Expand All @@ -110,9 +110,9 @@ class _MainPageState extends State<MainPage> {
opacity: _selectedIndex == entry.key ? 1.0 : 0.0,
duration: const Duration(milliseconds: 300),
child: AnimatedScale(
scale: _selectedIndex == entry.key ? 1.0 : 0.99,
scale: _selectedIndex == entry.key ? 1.0 : 0.995,
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutExpo,
curve: Curves.easeInOut,
child: IgnorePointer(
ignoring: _selectedIndex != entry.key,
child: entry.value),
Expand Down
4 changes: 3 additions & 1 deletion lib/src/provider/data_source_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:collection';

import 'package:flutter/material.dart';

abstract class DataSourceProvider<R, P, S> {
abstract class DataSourceProvider<R, P, S, F> {
Widget buildOverviewCard();

Widget buildRecordCard(R recordData);
Expand Down Expand Up @@ -45,6 +45,8 @@ abstract class DataSourceProvider<R, P, S> {

Future<void> deletePlayer();

Future<List<R>> filterRecords(F filterData);

Future<dynamic>? updateRecord() {
return null;
}
Expand Down
115 changes: 104 additions & 11 deletions lib/src/provider/lx_mai_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:rank_hub/src/model/mai_song_filter_data.dart';
import 'package:rank_hub/src/model/mai_types.dart';
import 'package:rank_hub/src/model/maimai/player_data.dart';
import 'package:rank_hub/src/model/maimai/song_difficulty.dart';
import 'package:rank_hub/src/model/maimai/song_info.dart';
import 'package:rank_hub/src/model/maimai/song_score.dart';
import 'package:rank_hub/src/pages/add_lx_mai_screen.dart';
Expand All @@ -15,7 +18,8 @@ import 'package:rank_hub/src/provider/player_manager.dart';
import 'package:rank_hub/src/services/lx_api_services.dart';
import 'package:rank_hub/src/view/maimai/lx_mai_record_card.dart';

class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo> {
class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo,
MaiSongFilterData> {
late PlayerManager _playerManager;
late LxApiService _lxApiService;

Expand All @@ -26,10 +30,9 @@ class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo>
_lxApiService = LxApiService(_playerManager, this);

lxApiService.getAllPlayerUUID().then((players) => {
for (String playerUUID in players) {
_playerManager.addPlayer(playerUUID, getProviderName())
}
});
for (String playerUUID in players)
{_playerManager.addPlayer(playerUUID, getProviderName())}
});
}
@override
Future<PlayerData> addPlayer(String? token) async {
Expand Down Expand Up @@ -123,7 +126,7 @@ class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo>

@override
Widget buildRecordList() {
return MaiRankPage();
return const MaiRankPage();
}

@override
Expand All @@ -138,7 +141,7 @@ class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo>

@override
Widget buildSongList() {
return WikiPage();
return const WikiPage();
}

@override
Expand Down Expand Up @@ -174,9 +177,11 @@ class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo>
}

@override
Future<Map<String, List<SongScore>>> getRankedRecords() {
// TODO: implement getRankedRecords
throw UnimplementedError();
Future<Map<String, List<SongScore>>> getRankedRecords() async {
return {
'B15': await lxApiService.getB15Records(),
'B35': await lxApiService.getB35Records(),
};
}

@override
Expand All @@ -189,7 +194,95 @@ class LxMaiProvider extends DataSourceProvider<SongScore, PlayerData, SongInfo>
// TODO: implement getSongDetail
throw UnimplementedError();
}


@override
Future<List<SongScore>> filterRecords(MaiSongFilterData filterData) async {
// Pre-fetch data
final songs = await getAllSongs();
final records = await getRecords();

// Return early if no filters are applied
if (filterData.areAllValuesNull) {
return records;
}

// Convert filter data into efficient lookup sets/maps
final levelIndexSet = filterData.levelIndex?.map((e) => e.value).toSet();
final genreSet = filterData.genre?.map((e) => e.genre).toSet();
final versionSet = filterData.version?.map((e) => e.version).toSet();
final fcTypeSet = filterData.fcType?.map((e) => e.value).toSet();
final fsTypeSet = filterData.fsType?.map((e) => e.value).toSet();
final levelValueStart = filterData.levelValueRange?.start;
final levelValueEnd = filterData.levelValueRange?.end;
final uploadTimeStart = filterData.uploadTimeRange?.start;
final uploadTimeEnd = filterData.uploadTimeRange?.end;

// Pre-filter songs based on genre and version
final preFilteredSongIds = songs
.where((song) =>
(genreSet == null || genreSet.contains(song.genre)) &&
(versionSet == null || versionSet.contains(song.version)))
.map((song) => song.id)
.toSet();

// Filter records based on song and record-specific criteria
return records.where((record) {
// Check if the song ID matches pre-filtered IDs
if (!preFilteredSongIds.contains(record.id)) {
return false;
}

// Check level index
if (levelIndexSet != null && !levelIndexSet.contains(record.levelIndex)) {
return false;
}

// Retrieve the corresponding song and difficulties
final song = songs.firstWhere((song) => song.id == record.id);
final difficulties = song.difficulties;
final recordType = record.type;

// Helper function for level value filtering
bool isLevelValueOutOfRange(List<SongDifficulty>? diffs) {
if (diffs == null) return false;
return diffs.any((diff) =>
diff.difficulty == record.levelIndex &&
((levelValueStart != null && diff.levelValue < levelValueStart) ||
(levelValueEnd != null && diff.levelValue > levelValueEnd)));
}

// Check level value range based on record type
if (recordType == SongType.dx.value &&
isLevelValueOutOfRange(difficulties.dx) ||
recordType == SongType.standard.value &&
isLevelValueOutOfRange(difficulties.standard) ||
recordType == SongType.utage.value &&
isLevelValueOutOfRange(difficulties.utage)) {
return false;
}

// Check upload time
if (uploadTimeStart != null && uploadTimeEnd != null) {
final uploadTime = record.uploadTime != null
? DateTime.tryParse(record.uploadTime!)
: null;
if (uploadTime == null ||
uploadTime.isBefore(uploadTimeStart) ||
uploadTime.isAfter(uploadTimeEnd)) {
return false;
}
}

// Check FC type and FS type
if ((fcTypeSet != null && !fcTypeSet.contains(record.fc)) ||
(fsTypeSet != null && !fsTypeSet.contains(record.fs))) {
return false;
}

return true;
}).toList();
}

@override
Future<List<SongInfo>> searchSongs(String query) async {
final aliases = await _lxApiService.getAliasList();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/view/maimai/lx_level_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class _LxMaiLevelViewState extends State<LxMaiLevelView> {
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8),
Theme.of(context).scaffoldBackgroundColor.withValues(alpha: 0.8),
surfaceTintColor: Colors.transparent,
centerTitle: false,
title: Column(
Expand Down
Loading

0 comments on commit 5290c39

Please sign in to comment.