188 lines
8.2 KiB
Dart
188 lines
8.2 KiB
Dart
import 'package:get/get.dart';
|
|
import 'package:tone_snap/components/view_state_widget.dart';
|
|
import 'package:tone_snap/data/api/music_api.dart';
|
|
import 'package:tone_snap/data/enum/music_type.dart';
|
|
import 'package:tone_snap/data/models/browse_group_model.dart';
|
|
import 'package:tone_snap/data/models/browse_model.dart';
|
|
import 'package:tone_snap/data/models/music_model.dart';
|
|
import 'package:tone_snap/routes/app_routes.dart';
|
|
|
|
class HomeController extends GetxController {
|
|
static HomeController get to => Get.find<HomeController>();
|
|
var viewState = ViewState.loading.obs;
|
|
var groupList = <BrowseGroupModel>[].obs;
|
|
String? visitorData;
|
|
|
|
@override
|
|
void onReady() {
|
|
super.onReady();
|
|
firstBrowse();
|
|
}
|
|
|
|
/// 首次请求
|
|
Future<void> firstBrowse() async {
|
|
Map<String, dynamic> queryParameters = {
|
|
'prettyPrint': false,
|
|
'browseId': 'FEmusic_home'
|
|
};
|
|
BrowseModel? browseModel = await MusicApi.browse<BrowseModel>(queryParameters: queryParameters, formJson: BrowseModel.fromMap);
|
|
if (browseModel != null) {
|
|
_extractAssemblyData(browseModel);
|
|
|
|
// 获取 visitorData
|
|
visitorData = browseModel.responseContext?.visitorData;
|
|
|
|
// 获取 continuation、clickTrackingParams
|
|
var continuations = browseModel.contents?.singleColumnBrowseResultsRenderer?.tabs?[0].tabRenderer?.content?.sectionListRenderer?.continuations;
|
|
String? continuation;
|
|
String? clickTrackingParams;
|
|
if (continuations != null && continuations.isNotEmpty) {
|
|
continuation = continuations[0].nextContinuationData?.continuation;
|
|
clickTrackingParams = continuations[0].nextContinuationData?.clickTrackingParams;
|
|
}
|
|
_reBrowse(continuation: continuation, clickTrackingParams: clickTrackingParams);
|
|
}
|
|
viewState.value = groupList.isNotEmpty ? ViewState.normal : ViewState.empty;
|
|
}
|
|
|
|
/// 复用请求
|
|
Future<void> _reBrowse({String? continuation, String? clickTrackingParams}) async {
|
|
Map<String, dynamic> queryParameters = {
|
|
'ctoken': continuation,
|
|
'continuation': continuation,
|
|
'type': 'next',
|
|
'itct': clickTrackingParams,
|
|
'prettyPrint': false
|
|
};
|
|
BrowseModel? browseModel = await MusicApi.browse<BrowseModel>(visitorData: visitorData, queryParameters: queryParameters, formJson: BrowseModel.fromMap);
|
|
if (browseModel != null) {
|
|
_extractAssemblyData(browseModel);
|
|
|
|
var continuations = browseModel.continuationContents?.sectionListContinuation?.continuations;
|
|
if (continuations != null && continuations.isNotEmpty) {
|
|
// continuation、clickTrackingParams 若不为空,继续请求
|
|
if (continuations[0].nextContinuationData?.continuation != null && continuations[0].nextContinuationData?.clickTrackingParams != null) {
|
|
_reBrowse(continuation: continuations[0].nextContinuationData?.continuation, clickTrackingParams: continuations[0].nextContinuationData?.clickTrackingParams);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 提取首页数据,组装展示数据
|
|
void _extractAssemblyData(BrowseModel browseModel) {
|
|
List<SectionListContinuationContent>? contents;
|
|
if (browseModel.contents?.singleColumnBrowseResultsRenderer?.tabs?[0].tabRenderer?.content != null) {
|
|
contents = browseModel.contents?.singleColumnBrowseResultsRenderer?.tabs?[0].tabRenderer?.content?.sectionListRenderer?.contents;
|
|
} else if (browseModel.continuationContents != null) {
|
|
contents = browseModel.continuationContents?.sectionListContinuation?.contents;
|
|
}
|
|
if (contents != null && contents.isNotEmpty) {
|
|
for (var e1 in contents) {
|
|
var browseGroupModel = BrowseGroupModel();
|
|
|
|
// 获取头部标题
|
|
var runs = e1.musicCarouselShelfRenderer?.header?.musicCarouselShelfBasicHeaderRenderer?.title?.runs;
|
|
if (runs != null && runs.isNotEmpty) {
|
|
browseGroupModel.groupTitle = runs[0].text;
|
|
}
|
|
var contents = e1.musicCarouselShelfRenderer?.contents;
|
|
if (contents != null) {
|
|
browseGroupModel.browseList ??= [];
|
|
for (var e2 in contents) {
|
|
var musicModel = MusicModel();
|
|
|
|
// 获取封面缩略图
|
|
List<ThumbnailElement>? thumbnails;
|
|
if (e2.musicResponsiveListItemRenderer != null) {
|
|
thumbnails = e2.musicResponsiveListItemRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails;
|
|
|
|
var flexColumns = e2.musicResponsiveListItemRenderer?.flexColumns;
|
|
if (flexColumns != null) {
|
|
for (var e3 in flexColumns) {
|
|
var runs = e3.musicResponsiveListItemFlexColumnRenderer?.text?.runs;
|
|
if (flexColumns.indexOf(e3) == 0) {
|
|
if (runs != null && runs.isNotEmpty) {
|
|
// 获取主标题
|
|
musicModel.title = runs[0].text;
|
|
|
|
// 获取数据类型
|
|
if (runs[0].navigationEndpoint?.watchEndpoint != null) {
|
|
browseGroupModel.musicType = runs[0].navigationEndpoint?.watchEndpoint?.watchEndpointMusicSupportedConfigs?.watchEndpointMusicConfig?.musicVideoType;
|
|
musicModel.videoId = runs[0].navigationEndpoint?.watchEndpoint?.videoId;
|
|
musicModel.playlistId = runs[0].navigationEndpoint?.watchEndpoint?.playlistId;
|
|
} else if (runs[0].navigationEndpoint?.browseEndpoint != null) {
|
|
browseGroupModel.musicType = runs[0].navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType;
|
|
musicModel.browseId = runs[0].navigationEndpoint?.browseEndpoint?.browseId;
|
|
musicModel.params = runs[0].navigationEndpoint?.browseEndpoint?.params;
|
|
}
|
|
}
|
|
} else {
|
|
// 获取副标题
|
|
if (runs != null && runs.isNotEmpty) {
|
|
musicModel.subtitle = runs.map((e) => e.text).join(' • ');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (e2.musicTwoRowItemRenderer != null) {
|
|
thumbnails = e2.musicTwoRowItemRenderer?.thumbnailRenderer?.musicThumbnailRenderer?.thumbnail?.thumbnails;
|
|
|
|
// 获取主标题
|
|
var runs = e2.musicTwoRowItemRenderer?.title?.runs;
|
|
if (runs != null && runs.isNotEmpty) {
|
|
musicModel.title = runs[0].text;
|
|
}
|
|
|
|
// 获取副标题
|
|
var subtitleRuns = e2.musicTwoRowItemRenderer?.subtitle?.runs;
|
|
if (subtitleRuns != null && subtitleRuns.isNotEmpty) {
|
|
musicModel.subtitle = subtitleRuns.map((e) => e.text).join();
|
|
}
|
|
|
|
// 获取数据类型
|
|
if (e2.musicTwoRowItemRenderer?.navigationEndpoint != null) {
|
|
browseGroupModel.musicType = e2.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.browseEndpointContextSupportedConfigs?.browseEndpointContextMusicConfig?.pageType;
|
|
musicModel.browseId = e2.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId;
|
|
musicModel.params = e2.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.params;
|
|
}
|
|
}
|
|
if (thumbnails != null && thumbnails.isNotEmpty) {
|
|
musicModel.coverUrl = thumbnails.last.url;
|
|
}
|
|
browseGroupModel.browseList?.add(musicModel);
|
|
}
|
|
}
|
|
// 根据类型判断是否添加
|
|
if (MusicTypeExtension.isThereAny(browseGroupModel.musicType)) {
|
|
groupList.add(browseGroupModel);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void openSearch() {
|
|
Get.toNamed(AppRoutes.searchResult);
|
|
}
|
|
|
|
void openSetting() {
|
|
Get.toNamed(AppRoutes.setting);
|
|
}
|
|
|
|
void openPlayPage(MusicModel musicModel) {
|
|
Get.toNamed(AppRoutes.playPage, arguments: {
|
|
'videoId': musicModel.videoId,
|
|
'playlistId': musicModel.playlistId,
|
|
});
|
|
}
|
|
|
|
void openAlbumSong(MusicModel musicModel) {
|
|
Get.toNamed(AppRoutes.albumSongList, arguments: {
|
|
'browseId': musicModel.browseId,
|
|
'params': musicModel.params,
|
|
'coverUrl': musicModel.coverUrl,
|
|
'title': musicModel.title,
|
|
'subtitle': musicModel.subtitle,
|
|
});
|
|
}
|
|
}
|