live first frame

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-03-10 11:35:24 +08:00
parent 98ce99202e
commit 3090cfc6f9
9 changed files with 215 additions and 138 deletions

View File

@@ -4,16 +4,19 @@ import 'package:PiliPlus/models_new/live/live_area_list/area_item.dart';
import 'package:PiliPlus/models_new/live/live_area_list/area_list.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:flutter/material.dart' show TabController;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
class LiveAreaController
extends CommonListController<List<AreaList>?, AreaList> {
class LiveAreaController extends CommonListController<List<AreaList>?, AreaList>
with GetSingleTickerProviderStateMixin {
late final isLogin = Accounts.main.isLogin;
late final isEditing = false.obs;
late final favInfo = {};
TabController? tabController;
@override
void onInit() {
super.onInit();
@@ -31,6 +34,16 @@ class LiveAreaController
return super.onRefresh();
}
@override
bool customHandleResponse(bool isRefresh, Success<List<AreaList>?> response) {
assert(tabController == null);
final length = response.response?.length;
if (length != null && length != 0) {
tabController = TabController(length: length, vsync: this);
}
return super.customHandleResponse(isRefresh, response);
}
Rx<LoadingState<List<AreaItem>>> favState =
LoadingState<List<AreaItem>>.loading().obs;
@@ -65,4 +78,11 @@ class LiveAreaController
isEditing.value = !isEditing.value;
}
}
@override
void onClose() {
tabController?.dispose();
tabController = null;
super.onClose();
}
}

View File

@@ -80,82 +80,78 @@ class _LiveAreaPageState extends State<LiveAreaPage> {
Loading() => const SizedBox.shrink(),
Success(:final response) =>
response != null && response.isNotEmpty
? DefaultTabController(
length: response.length,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TabBar(
isScrollable: true,
tabAlignment: TabAlignment.start,
tabs: response.map((e) => Tab(text: e.name)).toList(),
),
Expanded(
child: tabBarView(
children: response
.map(
(e) => KeepAliveWrapper(
builder: (context) {
if (e.areaList.isNullOrEmpty) {
return const SizedBox.shrink();
}
return GridView.builder(
padding: EdgeInsets.only(
top: 12,
bottom: bottom + 100,
),
gridDelegate:
const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
mainAxisExtent: 80,
),
itemCount: e.areaList!.length,
itemBuilder: (context, index) {
final item = e.areaList![index];
return _tagItem(
theme: theme,
item: item,
onPressed: () {
// success
bool? isFav =
_controller.favInfo[item.id];
if (isFav == true) {
_controller.favInfo[item.id] =
false;
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TabBar(
isScrollable: true,
tabAlignment: TabAlignment.start,
controller: _controller.tabController,
tabs: response.map((e) => Tab(text: e.name)).toList(),
),
Expanded(
child: tabBarView(
controller: _controller.tabController,
children: response
.map(
(e) => KeepAliveWrapper(
builder: (context) {
if (e.areaList.isNullOrEmpty) {
return const SizedBox.shrink();
}
return GridView.builder(
padding: EdgeInsets.only(
top: 12,
bottom: bottom + 100,
),
gridDelegate:
const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
mainAxisExtent: 80,
),
itemCount: e.areaList!.length,
itemBuilder: (context, index) {
final item = e.areaList![index];
return _tagItem(
theme: theme,
item: item,
onPressed: () {
// success
bool? isFav =
_controller.favInfo[item.id];
if (isFav == true) {
_controller.favInfo[item.id] = false;
_controller.favState
..value.data.remove(item)
..refresh();
(context as Element).markNeedsBuild();
} else {
// check
if (_controller
.favState
.value
.isSuccess) {
_controller.favInfo[item.id] = true;
_controller.favState
..value.data.remove(item)
..value.data.add(item)
..refresh();
(context as Element)
.markNeedsBuild();
} else {
// check
if (_controller
.favState
.value
.isSuccess) {
_controller.favInfo[item.id] =
true;
_controller.favState
..value.data.add(item)
..refresh();
(context as Element)
.markNeedsBuild();
}
}
},
);
},
);
},
),
)
.toList(),
),
}
},
);
},
);
},
),
)
.toList(),
),
],
),
),
],
)
: scrollErrorWidget(onReload: _controller.onReload),
Error(:final errMsg) => scrollErrorWidget(
@@ -192,9 +188,7 @@ class _LiveAreaPageState extends State<LiveAreaPage> {
const SizedBox(height: 8),
if (response != null && response.isNotEmpty) ...[
SortableWrap(
onSortStart: (index) {
_controller.isEditing.value = true;
},
onSortStart: (index) => _controller.isEditing.value = true,
onSorted: (int oldIndex, int newIndex) {
response.insert(newIndex, response.removeAt(oldIndex));
},