mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-14 13:20:17 +08:00
Compare commits
5 Commits
2.0.3.1
...
cbc4f58323
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbc4f58323 | ||
|
|
b553e7554d | ||
|
|
68724c8a9e | ||
|
|
85baf8e0e6 | ||
|
|
222c9d01a0 |
@@ -1004,4 +1004,6 @@ abstract final class Api {
|
|||||||
|
|
||||||
static const String memberGuard =
|
static const String memberGuard =
|
||||||
'${HttpString.liveBaseUrl}/xlive/app-ucenter/v1/guard/MainGuardCardAll';
|
'${HttpString.liveBaseUrl}/xlive/app-ucenter/v1/guard/MainGuardCardAll';
|
||||||
|
|
||||||
|
static const String bubble = '/x/tribee/v1/dyn/all';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import 'package:PiliPlus/models/dynamics/vote_model.dart';
|
|||||||
import 'package:PiliPlus/models_new/article/article_info/data.dart';
|
import 'package:PiliPlus/models_new/article/article_info/data.dart';
|
||||||
import 'package:PiliPlus/models_new/article/article_list/data.dart';
|
import 'package:PiliPlus/models_new/article/article_list/data.dart';
|
||||||
import 'package:PiliPlus/models_new/article/article_view/data.dart';
|
import 'package:PiliPlus/models_new/article/article_view/data.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/data.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_mention/data.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_mention/data.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_mention/group.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_mention/group.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_reserve/data.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_reserve/data.dart';
|
||||||
@@ -777,4 +778,30 @@ abstract final class DynamicsHttp {
|
|||||||
return Error(res.data['message']);
|
return Error(res.data['message']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<LoadingState<BubbleData>> bubble({
|
||||||
|
required Object tribeId,
|
||||||
|
Object? categoryId,
|
||||||
|
int? sortType,
|
||||||
|
required int page,
|
||||||
|
}) async {
|
||||||
|
final res = await Request().get(
|
||||||
|
Api.bubble,
|
||||||
|
queryParameters: {
|
||||||
|
'tribee_id': tribeId,
|
||||||
|
'category_id': ?categoryId,
|
||||||
|
'sort_type': ?sortType,
|
||||||
|
'page_size': 20,
|
||||||
|
'page_num': page,
|
||||||
|
'web_location': 333.40165,
|
||||||
|
'x-bili-device-req-json':
|
||||||
|
'{"platform":"web","device":"pc","spmid":"333.40165"}',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return Success(BubbleData.fromJson(res.data['data']));
|
||||||
|
} else {
|
||||||
|
return Error(res.data['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
lib/models_new/bubble/base_info.dart
Normal file
15
lib/models_new/bubble/base_info.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/tribee_info.dart';
|
||||||
|
|
||||||
|
class BaseInfo {
|
||||||
|
TribeInfo? tribeInfo;
|
||||||
|
bool? isJoined;
|
||||||
|
|
||||||
|
BaseInfo({this.tribeInfo, this.isJoined});
|
||||||
|
|
||||||
|
factory BaseInfo.fromJson(Map<String, dynamic> json) => BaseInfo(
|
||||||
|
tribeInfo: json['tribee_info'] == null
|
||||||
|
? null
|
||||||
|
: TribeInfo.fromJson(json['tribee_info'] as Map<String, dynamic>),
|
||||||
|
isJoined: json['is_joined'] as bool?,
|
||||||
|
);
|
||||||
|
}
|
||||||
13
lib/models_new/bubble/basic_info.dart
Normal file
13
lib/models_new/bubble/basic_info.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class BasicInfo {
|
||||||
|
String? icon;
|
||||||
|
String? title;
|
||||||
|
String? jumpUri;
|
||||||
|
|
||||||
|
BasicInfo({this.icon, this.title, this.jumpUri});
|
||||||
|
|
||||||
|
factory BasicInfo.fromJson(Map<String, dynamic> json) => BasicInfo(
|
||||||
|
icon: json['icon'] as String?,
|
||||||
|
title: json['title'] as String?,
|
||||||
|
jumpUri: json['jump_uri'] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
13
lib/models_new/bubble/category.dart
Normal file
13
lib/models_new/bubble/category.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/category_list.dart';
|
||||||
|
|
||||||
|
class Category {
|
||||||
|
List<CategoryList>? categoryList;
|
||||||
|
|
||||||
|
Category({this.categoryList});
|
||||||
|
|
||||||
|
factory Category.fromJson(Map<String, dynamic> json) => Category(
|
||||||
|
categoryList: (json['category_list'] as List<dynamic>?)
|
||||||
|
?.map((e) => CategoryList.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
13
lib/models_new/bubble/category_list.dart
Normal file
13
lib/models_new/bubble/category_list.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class CategoryList {
|
||||||
|
String? id;
|
||||||
|
String? name;
|
||||||
|
int? type;
|
||||||
|
|
||||||
|
CategoryList({this.id, this.name, this.type});
|
||||||
|
|
||||||
|
factory CategoryList.fromJson(Map<String, dynamic> json) => CategoryList(
|
||||||
|
id: json['id'] as String?,
|
||||||
|
name: json['name'] as String?,
|
||||||
|
type: json['type'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
15
lib/models_new/bubble/content.dart
Normal file
15
lib/models_new/bubble/content.dart
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/dyn_list.dart';
|
||||||
|
|
||||||
|
class Content {
|
||||||
|
String? count;
|
||||||
|
List<DynList>? dynList;
|
||||||
|
|
||||||
|
Content({this.count, this.dynList});
|
||||||
|
|
||||||
|
factory Content.fromJson(Map<String, dynamic> json) => Content(
|
||||||
|
count: json['count'] as String?,
|
||||||
|
dynList: (json['dyn_list'] as List<dynamic>?)
|
||||||
|
?.map((e) => DynList.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
33
lib/models_new/bubble/data.dart
Normal file
33
lib/models_new/bubble/data.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/base_info.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/category.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/content.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/sort_info.dart';
|
||||||
|
|
||||||
|
class BubbleData {
|
||||||
|
BaseInfo? baseInfo;
|
||||||
|
Content? content;
|
||||||
|
Category? category;
|
||||||
|
SortInfo? sortInfo;
|
||||||
|
|
||||||
|
BubbleData({
|
||||||
|
this.baseInfo,
|
||||||
|
this.content,
|
||||||
|
this.category,
|
||||||
|
this.sortInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory BubbleData.fromJson(Map<String, dynamic> json) => BubbleData(
|
||||||
|
baseInfo: json['base_info'] == null
|
||||||
|
? null
|
||||||
|
: BaseInfo.fromJson(json['base_info'] as Map<String, dynamic>),
|
||||||
|
content: json['content'] == null
|
||||||
|
? null
|
||||||
|
: Content.fromJson(json['content'] as Map<String, dynamic>),
|
||||||
|
category: json['category'] == null
|
||||||
|
? null
|
||||||
|
: Category.fromJson(json['category'] as Map<String, dynamic>),
|
||||||
|
sortInfo: json['sort_info'] == null
|
||||||
|
? null
|
||||||
|
: SortInfo.fromJson(json['sort_info'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
21
lib/models_new/bubble/dyn_list.dart
Normal file
21
lib/models_new/bubble/dyn_list.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/meta.dart';
|
||||||
|
|
||||||
|
class DynList {
|
||||||
|
String? dynId;
|
||||||
|
String? title;
|
||||||
|
Meta? meta;
|
||||||
|
|
||||||
|
DynList({
|
||||||
|
this.dynId,
|
||||||
|
this.title,
|
||||||
|
this.meta,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory DynList.fromJson(Map<String, dynamic> json) => DynList(
|
||||||
|
dynId: json['dyn_id'] as String?,
|
||||||
|
title: json['title'] as String?,
|
||||||
|
meta: json['meta'] == null
|
||||||
|
? null
|
||||||
|
: Meta.fromJson(json['meta'] as Map<String, dynamic>),
|
||||||
|
);
|
||||||
|
}
|
||||||
20
lib/models_new/bubble/meta.dart
Normal file
20
lib/models_new/bubble/meta.dart
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
class Meta {
|
||||||
|
String? author;
|
||||||
|
String? timeText;
|
||||||
|
String? replyCount;
|
||||||
|
String? viewStat;
|
||||||
|
|
||||||
|
Meta({
|
||||||
|
this.author,
|
||||||
|
this.timeText,
|
||||||
|
this.replyCount,
|
||||||
|
this.viewStat,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Meta.fromJson(Map<String, dynamic> json) => Meta(
|
||||||
|
author: json['author'] as String?,
|
||||||
|
timeText: json['time_text'] as String?,
|
||||||
|
replyCount: json['reply_count'] as String?,
|
||||||
|
viewStat: json['view_stat'] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
21
lib/models_new/bubble/sort_info.dart
Normal file
21
lib/models_new/bubble/sort_info.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:PiliPlus/models_new/bubble/sort_item.dart';
|
||||||
|
|
||||||
|
class SortInfo {
|
||||||
|
bool? showSort;
|
||||||
|
List<SortItem>? sortItems;
|
||||||
|
int? curSortType;
|
||||||
|
|
||||||
|
SortInfo({
|
||||||
|
this.showSort,
|
||||||
|
this.sortItems,
|
||||||
|
this.curSortType,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory SortInfo.fromJson(Map<String, dynamic> json) => SortInfo(
|
||||||
|
showSort: json['show_sort'] as bool?,
|
||||||
|
sortItems: (json['sort_items'] as List<dynamic>?)
|
||||||
|
?.map((e) => SortItem.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList(),
|
||||||
|
curSortType: json['cur_sort_type'] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
11
lib/models_new/bubble/sort_item.dart
Normal file
11
lib/models_new/bubble/sort_item.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class SortItem {
|
||||||
|
int? sortType;
|
||||||
|
String? text;
|
||||||
|
|
||||||
|
SortItem({this.sortType, this.text});
|
||||||
|
|
||||||
|
factory SortItem.fromJson(Map<String, dynamic> json) => SortItem(
|
||||||
|
sortType: json['sort_type'] as int?,
|
||||||
|
text: json['text'] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
26
lib/models_new/bubble/tribee_info.dart
Normal file
26
lib/models_new/bubble/tribee_info.dart
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class TribeInfo {
|
||||||
|
String? id;
|
||||||
|
String? title;
|
||||||
|
String? subTitle;
|
||||||
|
String? faceUrl;
|
||||||
|
String? jumpUri;
|
||||||
|
String? summary;
|
||||||
|
|
||||||
|
TribeInfo({
|
||||||
|
this.id,
|
||||||
|
this.title,
|
||||||
|
this.subTitle,
|
||||||
|
this.faceUrl,
|
||||||
|
this.jumpUri,
|
||||||
|
this.summary,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory TribeInfo.fromJson(Map<String, dynamic> json) => TribeInfo(
|
||||||
|
id: json['id'] as String?,
|
||||||
|
title: json['title'] as String?,
|
||||||
|
subTitle: json['sub_title'] as String?,
|
||||||
|
faceUrl: json['face_url'] as String?,
|
||||||
|
jumpUri: json['jump_uri'] as String?,
|
||||||
|
summary: json['summary'] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
77
lib/pages/bubble/controller.dart
Normal file
77
lib/pages/bubble/controller.dart
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import 'package:PiliPlus/http/dynamics.dart';
|
||||||
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/category_list.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/data.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/dyn_list.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/sort_info.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
|
import 'package:flutter/material.dart' show TabController;
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BubbleController extends CommonListController<BubbleData, DynList>
|
||||||
|
with GetSingleTickerProviderStateMixin {
|
||||||
|
BubbleController(this.categoryId);
|
||||||
|
final Object? categoryId;
|
||||||
|
|
||||||
|
late final Object tribeId;
|
||||||
|
int? sortType;
|
||||||
|
|
||||||
|
final Rxn<SortInfo> sortInfo = Rxn<SortInfo>();
|
||||||
|
TabController? tabController;
|
||||||
|
final RxnString tribeName = RxnString();
|
||||||
|
final Rxn<List<CategoryList>> tabs = Rxn<List<CategoryList>>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
tribeId = Get.arguments['id'];
|
||||||
|
queryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<DynList>? getDataList(BubbleData response) {
|
||||||
|
return response.content?.dynList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool customHandleResponse(bool isRefresh, Success<BubbleData> response) {
|
||||||
|
if (isRefresh) {
|
||||||
|
final data = response.response;
|
||||||
|
sortInfo.value = data.sortInfo;
|
||||||
|
if (categoryId == null) {
|
||||||
|
tribeName.value = data.baseInfo?.tribeInfo?.title;
|
||||||
|
if (tabController == null) {
|
||||||
|
if (data.category?.categoryList case final categories?
|
||||||
|
when categories.isNotEmpty) {
|
||||||
|
tabController = TabController(
|
||||||
|
length: categories.length,
|
||||||
|
vsync: this,
|
||||||
|
);
|
||||||
|
tabs.value = categories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<LoadingState<BubbleData>> customGetData() => DynamicsHttp.bubble(
|
||||||
|
tribeId: tribeId,
|
||||||
|
categoryId: categoryId,
|
||||||
|
sortType: sortType,
|
||||||
|
page: page,
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onClose() {
|
||||||
|
tabController?.dispose();
|
||||||
|
tabController = null;
|
||||||
|
super.onClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void onSort(int? sortType) {
|
||||||
|
this.sortType = sortType;
|
||||||
|
onReload();
|
||||||
|
}
|
||||||
|
}
|
||||||
244
lib/pages/bubble/view.dart
Normal file
244
lib/pages/bubble/view.dart
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
import 'package:PiliPlus/common/widgets/flutter/list_tile.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||||
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models_new/bubble/dyn_list.dart';
|
||||||
|
import 'package:PiliPlus/pages/bubble/controller.dart';
|
||||||
|
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
|
||||||
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart'
|
||||||
|
hide ListTile, SliverGridDelegateWithMaxCrossAxisExtent;
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class BubblePage extends StatefulWidget {
|
||||||
|
const BubblePage({super.key, this.categoryId});
|
||||||
|
|
||||||
|
final String? categoryId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BubblePage> createState() => _BubblePageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BubblePageState extends State<BubblePage>
|
||||||
|
with AutomaticKeepAliveClientMixin {
|
||||||
|
late final BubbleController _controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller = Get.put(
|
||||||
|
BubbleController(widget.categoryId),
|
||||||
|
tag: widget.categoryId ?? 'all',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BubbleController currCtr([int? index]) {
|
||||||
|
try {
|
||||||
|
index ??= _controller.tabController!.index;
|
||||||
|
if (index != 0) {
|
||||||
|
return Get.find<BubbleController>(
|
||||||
|
tag: _controller.tabs.value![index].id.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (_) {}
|
||||||
|
return _controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
super.build(context);
|
||||||
|
final padding = MediaQuery.viewPaddingOf(context);
|
||||||
|
Widget child = refreshIndicator(
|
||||||
|
onRefresh: _controller.onRefresh,
|
||||||
|
child: CustomScrollView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
controller: _controller.scrollController,
|
||||||
|
slivers: [
|
||||||
|
SliverPadding(
|
||||||
|
padding: EdgeInsets.only(bottom: padding.bottom + 100),
|
||||||
|
sliver: Obx(
|
||||||
|
() => _buildBody(_controller.loadingState.value),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (widget.categoryId != null) {
|
||||||
|
return child;
|
||||||
|
} else {
|
||||||
|
child = Stack(
|
||||||
|
clipBehavior: .none,
|
||||||
|
children: [
|
||||||
|
child,
|
||||||
|
Positioned(
|
||||||
|
right: kFloatingActionButtonMargin,
|
||||||
|
bottom: kFloatingActionButtonMargin + padding.bottom,
|
||||||
|
child: Obx(
|
||||||
|
() {
|
||||||
|
final sortInfo = _controller.sortInfo.value;
|
||||||
|
if (sortInfo == null || sortInfo.showSort != true) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
final item = sortInfo.sortItems?.firstWhereOrNull(
|
||||||
|
(e) => e.sortType == sortInfo.curSortType,
|
||||||
|
);
|
||||||
|
if (item != null) {
|
||||||
|
return FloatingActionButton.extended(
|
||||||
|
tooltip: '排序',
|
||||||
|
onPressed: () => showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
clipBehavior: .hardEdge,
|
||||||
|
contentPadding: const .symmetric(vertical: 12),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: .min,
|
||||||
|
children: sortInfo.sortItems!.map(
|
||||||
|
(e) {
|
||||||
|
final isSelected = item.sortType == e.sortType;
|
||||||
|
return ListTile(
|
||||||
|
dense: true,
|
||||||
|
enabled: !isSelected,
|
||||||
|
onTap: () {
|
||||||
|
Get.back();
|
||||||
|
if (!isSelected) {
|
||||||
|
_controller.onSort(e.sortType);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: Text(
|
||||||
|
e.text!,
|
||||||
|
style: const TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
trailing: isSelected
|
||||||
|
? const Icon(size: 22, Icons.check)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
icon: const Icon(Icons.sort, size: 20),
|
||||||
|
label: Text(item.text!),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Obx(() {
|
||||||
|
final tribeName = _controller.tribeName.value;
|
||||||
|
if (tribeName == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return Text('$tribeName小站');
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.only(left: padding.left, right: padding.right),
|
||||||
|
child: Obx(() {
|
||||||
|
final tabs = _controller.tabs.value;
|
||||||
|
if (tabs == null || tabs.isEmpty) {
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TabBar(
|
||||||
|
isScrollable: true,
|
||||||
|
tabAlignment: .start,
|
||||||
|
controller: _controller.tabController,
|
||||||
|
onTap: (index) {
|
||||||
|
if (!_controller.tabController!.indexIsChanging) {
|
||||||
|
currCtr().scrollController.animToTop();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tabs: tabs.map((item) => Tab(text: item.name!)).toList(),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: tabBarView(
|
||||||
|
controller: _controller.tabController,
|
||||||
|
children: [
|
||||||
|
KeepAliveWrapper(child: child),
|
||||||
|
...tabs
|
||||||
|
.skip(1)
|
||||||
|
.map((item) => BubblePage(categoryId: item.id)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
|
mainAxisExtent: 56,
|
||||||
|
maxCrossAxisExtent: 2 * Grid.smallCardWidth,
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget _buildBody(LoadingState<List<DynList>?> loadingState) {
|
||||||
|
switch (loadingState) {
|
||||||
|
case Loading():
|
||||||
|
return const SliverFillRemaining(child: m3eLoading);
|
||||||
|
case Success(:final response):
|
||||||
|
if (response != null && response.isNotEmpty) {
|
||||||
|
return SliverGrid.builder(
|
||||||
|
gridDelegate: gridDelegate,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == response.length - 1) {
|
||||||
|
_controller.onLoadMore();
|
||||||
|
}
|
||||||
|
final item = response[index];
|
||||||
|
return Material(
|
||||||
|
type: .transparency,
|
||||||
|
child: ListTile(
|
||||||
|
safeArea: false,
|
||||||
|
visualDensity: .standard,
|
||||||
|
// PageUtils.pushDynFromId(id: item.dynId);
|
||||||
|
onTap: () => Get.toNamed(
|
||||||
|
'/articlePage',
|
||||||
|
parameters: {
|
||||||
|
'id': item.dynId!,
|
||||||
|
'type': 'opus',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
item.title!,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: .ellipsis,
|
||||||
|
),
|
||||||
|
trailing: item.meta?.timeText == null
|
||||||
|
? null
|
||||||
|
: Text(
|
||||||
|
item.meta!.timeText!,
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: response.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return HttpError(onReload: _controller.onReload);
|
||||||
|
case Error(:final errMsg):
|
||||||
|
return HttpError(
|
||||||
|
errMsg: errMsg,
|
||||||
|
onReload: _controller.onReload,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get wantKeepAlive => widget.categoryId != null;
|
||||||
|
}
|
||||||
@@ -105,7 +105,8 @@ class _HistoryPageState extends State<HistoryPage>
|
|||||||
right: padding.right,
|
right: padding.right,
|
||||||
),
|
),
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
if (_historyController.tabs.isEmpty) {
|
final tabs = _historyController.tabs;
|
||||||
|
if (tabs.isEmpty) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
return Column(
|
return Column(
|
||||||
@@ -128,9 +129,7 @@ class _HistoryPageState extends State<HistoryPage>
|
|||||||
},
|
},
|
||||||
tabs: [
|
tabs: [
|
||||||
const Tab(text: '全部'),
|
const Tab(text: '全部'),
|
||||||
..._historyController.tabs.map(
|
...tabs.map((item) => Tab(text: item.name)),
|
||||||
(item) => Tab(text: item.name),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -143,9 +142,7 @@ class _HistoryPageState extends State<HistoryPage>
|
|||||||
CustomHorizontalDragGestureRecognizer.new,
|
CustomHorizontalDragGestureRecognizer.new,
|
||||||
children: [
|
children: [
|
||||||
KeepAliveWrapper(child: child),
|
KeepAliveWrapper(child: child),
|
||||||
..._historyController.tabs.map(
|
...tabs.map((item) => HistoryPage(type: item.type)),
|
||||||
(item) => HistoryPage(type: item.type),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
|
|||||||
image: item.backgroundImage == null
|
image: item.backgroundImage == null
|
||||||
? null
|
? null
|
||||||
: DecorationImage(
|
: DecorationImage(
|
||||||
|
alignment: .topRight,
|
||||||
image: CachedNetworkImageProvider(
|
image: CachedNetworkImageProvider(
|
||||||
ImageUtils.safeThumbnailUrl(item.backgroundImage),
|
ImageUtils.safeThumbnailUrl(item.backgroundImage),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ class _MemberGuardState extends State<MemberGuard> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('$_userName的舰队${_count == null ? '' : '($_count)'}'),
|
title: Text('$_userName的舰队${_count == null ? '' : '($_count)'}'),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ abstract class BaseVideoWebState<
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final colorScheme = ColorScheme.of(context);
|
final colorScheme = ColorScheme.of(context);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(name),
|
title: Text(name),
|
||||||
actions: [
|
actions: [
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class _MyReplyState extends State<MyReply> with DynMixin {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('我的评论'),
|
title: const Text('我的评论'),
|
||||||
actions: [
|
actions: [
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ class _PopularSeriesPageState extends State<PopularSeriesPage> with GridMixin {
|
|||||||
return ListTile(
|
return ListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
minTileHeight: 44,
|
minTileHeight: 44,
|
||||||
tileColor: isCurr ? Theme.of(context).highlightColor : null,
|
enabled: !isCurr,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Get.back();
|
Get.back();
|
||||||
if (!isCurr) {
|
if (!isCurr) {
|
||||||
@@ -156,7 +156,7 @@ class _PopularSeriesPageState extends State<PopularSeriesPage> with GridMixin {
|
|||||||
item.name!,
|
item.name!,
|
||||||
style: const TextStyle(fontSize: 14),
|
style: const TextStyle(fontSize: 14),
|
||||||
),
|
),
|
||||||
trailing: isCurr ? const Icon(Icons.check, size: 18) : null,
|
trailing: isCurr ? const Icon(Icons.check, size: 20) : null,
|
||||||
contentPadding: const EdgeInsetsGeometry.symmetric(
|
contentPadding: const EdgeInsetsGeometry.symmetric(
|
||||||
horizontal: 16,
|
horizontal: 16,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -520,41 +520,26 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
child: Obx(
|
child: Obx(
|
||||||
() {
|
() {
|
||||||
final scrollRatio = videoDetailController.scrollRatio.value;
|
final scrollRatio = videoDetailController.scrollRatio.value;
|
||||||
bool shouldShow =
|
final flag =
|
||||||
scrollRatio != 0 &&
|
isPortrait && videoDetailController.scrollCtr.offset != 0;
|
||||||
videoDetailController.scrollCtr.offset != 0 &&
|
return AppBar(
|
||||||
isPortrait;
|
backgroundColor: flag && scrollRatio > 0
|
||||||
return Stack(
|
? Color.lerp(
|
||||||
clipBehavior: Clip.none,
|
Colors.black,
|
||||||
children: [
|
themeData.colorScheme.surface,
|
||||||
AppBar(
|
scrollRatio,
|
||||||
backgroundColor: Colors.black,
|
)
|
||||||
toolbarHeight: 0,
|
: Colors.black,
|
||||||
systemOverlayStyle: Platform.isAndroid
|
toolbarHeight: 0,
|
||||||
? shouldShow
|
systemOverlayStyle: Platform.isAndroid
|
||||||
? null
|
? SystemUiOverlayStyle(
|
||||||
: SystemUiOverlayStyle(
|
statusBarIconBrightness: flag && scrollRatio >= 0.5
|
||||||
statusBarIconBrightness: Brightness.light,
|
? themeData.brightness.reverse
|
||||||
systemNavigationBarIconBrightness:
|
: Brightness.light,
|
||||||
themeData.brightness.reverse,
|
systemNavigationBarIconBrightness:
|
||||||
)
|
themeData.brightness.reverse,
|
||||||
: null,
|
)
|
||||||
),
|
: null,
|
||||||
if (shouldShow)
|
|
||||||
AppBar(
|
|
||||||
backgroundColor: themeData.colorScheme.surface
|
|
||||||
.withValues(alpha: scrollRatio),
|
|
||||||
toolbarHeight: 0,
|
|
||||||
systemOverlayStyle: Platform.isAndroid
|
|
||||||
? SystemUiOverlayStyle(
|
|
||||||
statusBarIconBrightness:
|
|
||||||
themeData.brightness.reverse,
|
|
||||||
systemNavigationBarIconBrightness:
|
|
||||||
themeData.brightness.reverse,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import 'package:easy_debounce/easy_throttle.dart';
|
|||||||
import 'package:floating/floating.dart';
|
import 'package:floating/floating.dart';
|
||||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart' show HapticFeedback;
|
import 'package:flutter/services.dart' show HapticFeedback, DeviceOrientation;
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
|
import 'package:flutter_volume_controller/flutter_volume_controller.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -516,32 +516,41 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
|
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
|
||||||
StreamSubscription<NativeDeviceOrientation>? _orientationListener;
|
DeviceOrientation? _orientation;
|
||||||
|
late final checkIsAutoRotate = Platform.isAndroid && mode != .gravity;
|
||||||
|
StreamSubscription<OrientationParams>? _orientationListener;
|
||||||
|
|
||||||
void _stopOrientationListener() {
|
void _stopOrientationListener() {
|
||||||
_orientationListener?.cancel();
|
_orientationListener?.cancel();
|
||||||
_orientationListener = null;
|
_orientationListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onOrientationChanged(NativeDeviceOrientation value) {
|
void _onOrientationChanged(OrientationParams param) {
|
||||||
if (!visible) return;
|
if (!visible) return;
|
||||||
switch (value) {
|
final orientation = _orientation = param.orientation;
|
||||||
|
final isFullScreen = this.isFullScreen.value;
|
||||||
|
if (checkIsAutoRotate &&
|
||||||
|
param.isAutoRotate != true &&
|
||||||
|
(!isFullScreen || _isVertical || orientation == .portraitUp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (orientation) {
|
||||||
case .portraitUp:
|
case .portraitUp:
|
||||||
if (!_isVertical && controlsLock.value) return;
|
if (!_isVertical && controlsLock.value) return;
|
||||||
if (!horizontalScreen && !_isVertical && isFullScreen.value) {
|
if (!horizontalScreen && !_isVertical && isFullScreen) {
|
||||||
triggerFullScreen(status: false, orientation: value);
|
triggerFullScreen(status: false, orientation: orientation);
|
||||||
} else {
|
} else {
|
||||||
portraitUpMode();
|
portraitUpMode();
|
||||||
}
|
}
|
||||||
case .landscapeLeft:
|
case .landscapeLeft:
|
||||||
if (!horizontalScreen && !isFullScreen.value) {
|
if (!horizontalScreen && !isFullScreen) {
|
||||||
triggerFullScreen(orientation: value);
|
triggerFullScreen(orientation: orientation);
|
||||||
} else {
|
} else {
|
||||||
landscapeLeftMode();
|
landscapeLeftMode();
|
||||||
}
|
}
|
||||||
case .landscapeRight:
|
case .landscapeRight:
|
||||||
if (!horizontalScreen && !isFullScreen.value) {
|
if (!horizontalScreen && !isFullScreen) {
|
||||||
triggerFullScreen(orientation: value);
|
triggerFullScreen(orientation: orientation);
|
||||||
} else {
|
} else {
|
||||||
landscapeRightMode();
|
landscapeRightMode();
|
||||||
}
|
}
|
||||||
@@ -551,11 +560,11 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
|
|
||||||
// 添加一个私有构造函数
|
// 添加一个私有构造函数
|
||||||
PlPlayerController._() {
|
PlPlayerController._() {
|
||||||
if (PlatformUtils.isMobile) {
|
if (PlatformUtils.isMobile && !horizontalScreen) {
|
||||||
_orientationListener = NativeDeviceOrientationPlatform.instance
|
_orientationListener = NativeDeviceOrientationPlatform.instance
|
||||||
.onOrientationChanged(
|
.onOrientationChanged(
|
||||||
useSensor: Platform.isAndroid,
|
useSensor: Platform.isAndroid,
|
||||||
checkIsAutoRotate: mode != .gravity,
|
checkIsAutoRotate: checkIsAutoRotate,
|
||||||
)
|
)
|
||||||
.listen(_onOrientationChanged);
|
.listen(_onOrientationChanged);
|
||||||
}
|
}
|
||||||
@@ -1412,7 +1421,7 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
Future<void> triggerFullScreen({
|
Future<void> triggerFullScreen({
|
||||||
bool status = true,
|
bool status = true,
|
||||||
bool inAppFullScreen = false,
|
bool inAppFullScreen = false,
|
||||||
NativeDeviceOrientation? orientation,
|
DeviceOrientation? orientation,
|
||||||
}) async {
|
}) async {
|
||||||
if (isDesktopPip) return;
|
if (isDesktopPip) return;
|
||||||
if (isFullScreen.value == status) return;
|
if (isFullScreen.value == status) return;
|
||||||
@@ -1424,6 +1433,7 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
if (status) {
|
if (status) {
|
||||||
if (PlatformUtils.isMobile) {
|
if (PlatformUtils.isMobile) {
|
||||||
hideStatusBar();
|
hideStatusBar();
|
||||||
|
if (horizontalScreen) return;
|
||||||
if (orientation == null && mode == .none) {
|
if (orientation == null && mode == .none) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1437,7 +1447,7 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
// https://github.com/flutter/flutter/issues/73651
|
// https://github.com/flutter/flutter/issues/73651
|
||||||
// https://github.com/flutter/flutter/issues/183708
|
// https://github.com/flutter/flutter/issues/183708
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
if (orientation == .landscapeRight) {
|
if ((orientation ?? _orientation) == .landscapeRight) {
|
||||||
await landscapeRightMode();
|
await landscapeRightMode();
|
||||||
} else {
|
} else {
|
||||||
await landscapeLeftMode();
|
await landscapeLeftMode();
|
||||||
@@ -1569,9 +1579,7 @@ class PlPlayerController with BlockConfigMixin {
|
|||||||
bool get isCloseAll => _isCloseAll;
|
bool get isCloseAll => _isCloseAll;
|
||||||
|
|
||||||
void resetScreenRotation() {
|
void resetScreenRotation() {
|
||||||
if (horizontalScreen) {
|
if (!horizontalScreen) {
|
||||||
fullMode();
|
|
||||||
} else {
|
|
||||||
portraitUpMode();
|
portraitUpMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ Future<void>? portraitUpMode() {
|
|||||||
return _setPreferredOrientations(const [.portraitUp]);
|
return _setPreferredOrientations(const [.portraitUp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void>? portraitDownMode() {
|
||||||
|
return _setPreferredOrientations(const [.portraitDown]);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void>? landscapeLeftMode() {
|
Future<void>? landscapeLeftMode() {
|
||||||
return _setPreferredOrientations(const [.landscapeLeft]);
|
return _setPreferredOrientations(const [.landscapeLeft]);
|
||||||
}
|
}
|
||||||
@@ -54,7 +58,7 @@ Future<void>? landscapeRightMode() {
|
|||||||
|
|
||||||
Future<void>? fullMode() {
|
Future<void>? fullMode() {
|
||||||
return _setPreferredOrientations(
|
return _setPreferredOrientations(
|
||||||
const [.portraitUp, .landscapeLeft, .landscapeRight],
|
const [.portraitUp, .portraitDown, .landscapeLeft, .landscapeRight],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:PiliPlus/pages/article/view.dart';
|
|||||||
import 'package:PiliPlus/pages/article_list/view.dart';
|
import 'package:PiliPlus/pages/article_list/view.dart';
|
||||||
import 'package:PiliPlus/pages/audio/view.dart';
|
import 'package:PiliPlus/pages/audio/view.dart';
|
||||||
import 'package:PiliPlus/pages/blacklist/view.dart';
|
import 'package:PiliPlus/pages/blacklist/view.dart';
|
||||||
|
import 'package:PiliPlus/pages/bubble/view.dart';
|
||||||
import 'package:PiliPlus/pages/danmaku_block/view.dart';
|
import 'package:PiliPlus/pages/danmaku_block/view.dart';
|
||||||
import 'package:PiliPlus/pages/dlna/view.dart';
|
import 'package:PiliPlus/pages/dlna/view.dart';
|
||||||
import 'package:PiliPlus/pages/download/view.dart';
|
import 'package:PiliPlus/pages/download/view.dart';
|
||||||
@@ -198,5 +199,6 @@ class Routes {
|
|||||||
GetPage(name: '/videoWeb', page: () => const MemberVideoWeb()),
|
GetPage(name: '/videoWeb', page: () => const MemberVideoWeb()),
|
||||||
GetPage(name: '/ssWeb', page: () => const MemberSSWeb()),
|
GetPage(name: '/ssWeb', page: () => const MemberSSWeb()),
|
||||||
GetPage(name: '/memberGuard', page: () => const MemberGuard()),
|
GetPage(name: '/memberGuard', page: () => const MemberGuard()),
|
||||||
|
GetPage(name: '/bubble', page: () => const BubblePage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -809,6 +809,15 @@ abstract final class PiliScheme {
|
|||||||
}
|
}
|
||||||
launchURL();
|
launchURL();
|
||||||
return false;
|
return false;
|
||||||
|
case 'bubble':
|
||||||
|
// https://www.bilibili.com/bubble/home/1
|
||||||
|
final id = uriDigitRegExp.firstMatch(path)?.group(1);
|
||||||
|
if (id != null) {
|
||||||
|
Get.toNamed('/bubble', arguments: {'id': id});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
launchURL();
|
||||||
|
return false;
|
||||||
default:
|
default:
|
||||||
final res = IdUtils.matchAvorBv(input: area?.split('?').first);
|
final res = IdUtils.matchAvorBv(input: area?.split('?').first);
|
||||||
if (res.isNotEmpty) {
|
if (res.isNotEmpty) {
|
||||||
|
|||||||
28
pubspec.lock
28
pubspec.lock
@@ -311,10 +311,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: connectivity_plus
|
name: connectivity_plus
|
||||||
sha256: b8fe52979ff12432ecf8f0abf6ff70410b1bb734be1c9e4f2f86807ad7166c79
|
sha256: "62ffa266d9a23b79fb3fcbc206afc00bb979417ba57b1324c546b5aab95ba057"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.1.0"
|
version: "7.1.1"
|
||||||
connectivity_plus_platform_interface:
|
connectivity_plus_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1005,6 +1005,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.1"
|
version: "0.6.1"
|
||||||
|
jni:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni
|
||||||
|
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
|
jni_flutter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: jni_flutter
|
||||||
|
sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1235,7 +1251,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: master
|
ref: master
|
||||||
resolved-ref: "42454199133e83a9a31f0fb0107d14af1f96f959"
|
resolved-ref: "64cbc7886f5a5a5ecb09a34aab0d8b9ee48d03d2"
|
||||||
url: "https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git"
|
url: "https://github.com/bggRGjQaUbCoE/flutter_native_device_orientation.git"
|
||||||
source: git
|
source: git
|
||||||
version: "2.0.5"
|
version: "2.0.5"
|
||||||
@@ -1320,13 +1336,13 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.5"
|
||||||
path_provider_android:
|
path_provider_android:
|
||||||
dependency: "direct overridden"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: "149441ca6e4f38193b2e004c0ca6376a3d11f51fa5a77552d8bd4d2b0c0912ba"
|
sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.23"
|
version: "2.3.1"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -296,9 +296,6 @@ dependency_overrides:
|
|||||||
path: libs/macos/media_kit_libs_macos_video
|
path: libs/macos/media_kit_libs_macos_video
|
||||||
ref: dev
|
ref: dev
|
||||||
font_awesome_flutter: 10.9.0
|
font_awesome_flutter: 10.9.0
|
||||||
# TODO: remove
|
|
||||||
# https://github.com/flutter/flutter/issues/184750
|
|
||||||
path_provider_android: 2.2.23
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user