Merge branch 'main' into fix

This commit is contained in:
guozhigq
2024-11-16 15:34:40 +08:00
74 changed files with 229 additions and 379 deletions

View File

@ -12,7 +12,6 @@
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" /> <data android:scheme="https" />
</intent> </intent>
</queries> </queries>
<queries> <queries>
<intent> <intent>
@ -20,7 +19,6 @@
"android.support.customtabs.action.CustomTabsService" /> "android.support.customtabs.action.CustomTabsService" />
</intent> </intent>
</queries> </queries>
<queries> <queries>
<!-- If your app checks for http support --> <!-- If your app checks for http support -->
<intent> <intent>
@ -34,7 +32,6 @@
<data android:scheme="https" /> <data android:scheme="https" />
</intent> </intent>
</queries> </queries>
<application <application
android:label="PiliPala" android:label="PiliPala"
android:name="${applicationName}" android:name="${applicationName}"
@ -144,102 +141,55 @@
<data android:scheme="bilibili" android:host="assistant" /> <data android:scheme="bilibili" android:host="assistant" />
<data android:scheme="bilibili" android:host="feedback" /> <data android:scheme="bilibili" android:host="feedback" />
<data android:scheme="bilibili" android:host="auth" android:path="/launch" /> <data android:scheme="bilibili" android:host="auth" android:path="/launch" />
<data android:scheme="http" android:host="live.bilibili.com"
android:pathPattern="/live/.*" />
<data android:scheme="https" android:host="live.bilibili.com" <data android:scheme="https" android:host="live.bilibili.com"
android:pathPattern="/live/.*" /> android:pathPattern="/live/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.tv"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="www.bilibili.tv" <data android:scheme="https" android:host="www.bilibili.tv"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.cn"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="www.bilibili.cn" <data android:scheme="https" android:host="www.bilibili.cn"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/mobile/video/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/mobile/video/.*" /> android:pathPattern="/mobile/video/.*" />
<data android:scheme="http" android:host="m.bilibili.com"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="m.bilibili.com" <data android:scheme="https" android:host="m.bilibili.com"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/story/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/story/.*" /> android:pathPattern="/story/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/bangumi/i/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/bangumi/i/.*" /> android:pathPattern="/bangumi/i/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/mobile/bangumi/i/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/mobile/bangumi/i/.*" /> android:pathPattern="/mobile/bangumi/i/.*" />
<data android:scheme="http" android:host="bangumi.bilibili.com"
android:pathPattern="/.*" />
<data android:scheme="https" android:host="bangumi.bilibili.com" <data android:scheme="https" android:host="bangumi.bilibili.com"
android:pathPattern="/.*" /> android:pathPattern="/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/bangumi/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/bangumi/.*" /> android:pathPattern="/bangumi/.*" />
<data android:scheme="http" android:host="m.bilibili.com"
android:pathPattern="/bangumi/.*" />
<data android:scheme="https" android:host="m.bilibili.com" <data android:scheme="https" android:host="m.bilibili.com"
android:pathPattern="/bangumi/.*" /> android:pathPattern="/bangumi/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/cheese/play/ss.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/cheese/play/ss.*" /> android:pathPattern="/cheese/play/ss.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/cheese/play/ep.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/cheese/play/ep.*" /> android:pathPattern="/cheese/play/ep.*" />
<data android:scheme="http" android:host="m.bilibili.com"
android:pathPattern="/bangumi/play/ss.*" />
<data android:scheme="https" android:host="m.bilibili.com" <data android:scheme="https" android:host="m.bilibili.com"
android:pathPattern="/cheese/play/ss.*" /> android:pathPattern="/cheese/play/ss.*" />
<data android:scheme="http" android:host="m.bilibili.com"
android:pathPattern="/cheese/play/ep.*" />
<data android:scheme="https" android:host="m.bilibili.com" <data android:scheme="https" android:host="m.bilibili.com"
android:pathPattern="/cheese/play/ep.*" /> android:pathPattern="/cheese/play/ep.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/read/cv.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/read/cv.*" /> android:pathPattern="/read/cv.*" />
<data android:scheme="http" android:host="www.bilibili.com" android:path="/review/" />
<data android:scheme="https" android:host="www.bilibili.com" android:path="/review/" /> <data android:scheme="https" android:host="www.bilibili.com" android:path="/review/" />
<data android:scheme="http" android:host="bilibili.cn"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="bilibili.cn" <data android:scheme="https" android:host="bilibili.cn"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="bilibili.com"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="bilibili.com" <data android:scheme="https" android:host="bilibili.com"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.cn"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="www.bilibili.cn" <data android:scheme="https" android:host="www.bilibili.cn"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/video/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/video/.*" /> android:pathPattern="/video/.*" />
<data android:scheme="http" android:host="www.bilibili.com"
android:pathPattern="/mobile/video/.*" />
<data android:scheme="https" android:host="www.bilibili.com" <data android:scheme="https" android:host="www.bilibili.com"
android:pathPattern="/mobile/video/.*" /> android:pathPattern="/mobile/video/.*" />
<data android:scheme="https" android:host="b23.tv" <data android:scheme="https" android:host="b23.tv"
android:pathPattern="/*" /> android:pathPattern="/*" />
<data android:scheme="https" android:host="space.bilibili.com" <data android:scheme="https" android:host="space.bilibili.com"
android:pathPattern="/*" /> android:pathPattern="/*" />
</intent-filter> </intent-filter>
</activity> </activity>
<service <service
@ -251,7 +201,6 @@
<action android:name="android.media.browse.MediaBrowserService" /> <action android:name="android.media.browse.MediaBrowserService" />
</intent-filter> </intent-filter>
</service> </service>
<receiver <receiver
android:name="com.ryanheise.audioservice.MediaButtonReceiver" android:name="com.ryanheise.audioservice.MediaButtonReceiver"
android:exported="true" android:exported="true"
@ -259,7 +208,7 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" /> <action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data <meta-data
@ -281,4 +230,4 @@
--> -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
</manifest> </manifest>

View File

@ -1,8 +1,6 @@
PODS: PODS:
- app_links (0.0.2): - app_links (0.0.2):
- Flutter - Flutter
- appscheme (1.0.4):
- Flutter
- audio_service (0.0.1): - audio_service (0.0.1):
- Flutter - Flutter
- audio_session (0.0.1): - audio_session (0.0.1):
@ -71,7 +69,6 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- app_links (from `.symlinks/plugins/app_links/ios`) - app_links (from `.symlinks/plugins/app_links/ios`)
- appscheme (from `.symlinks/plugins/appscheme/ios`)
- audio_service (from `.symlinks/plugins/audio_service/ios`) - audio_service (from `.symlinks/plugins/audio_service/ios`)
- audio_session (from `.symlinks/plugins/audio_session/ios`) - audio_session (from `.symlinks/plugins/audio_session/ios`)
- auto_orientation (from `.symlinks/plugins/auto_orientation/ios`) - auto_orientation (from `.symlinks/plugins/auto_orientation/ios`)
@ -110,8 +107,6 @@ SPEC REPOS:
EXTERNAL SOURCES: EXTERNAL SOURCES:
app_links: app_links:
:path: ".symlinks/plugins/app_links/ios" :path: ".symlinks/plugins/app_links/ios"
appscheme:
:path: ".symlinks/plugins/appscheme/ios"
audio_service: audio_service:
:path: ".symlinks/plugins/audio_service/ios" :path: ".symlinks/plugins/audio_service/ios"
audio_session: audio_session:
@ -171,7 +166,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0 app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0
appscheme: b1c3f8862331cb20430cf9e0e4af85dbc1572ad8
audio_service: f509d65da41b9521a61f1c404dd58651f265a567 audio_service: f509d65da41b9521a61f1c404dd58651f265a567
audio_session: 4f3e461722055d21515cf3261b64c973c062f345 audio_session: 4f3e461722055d21515cf3261b64c973c062f345
auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d auto_orientation: 102ed811a5938d52c86520ddd7ecd3a126b5d39d

View File

@ -408,17 +408,29 @@ class TitleBar extends StatelessWidget {
toolbarHeight: 45, toolbarHeight: 45,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
centerTitle: false, centerTitle: false,
title: Text( elevation: 1,
title, scrolledUnderElevation: 1,
style: Theme.of(context).textTheme.titleMedium, title: Padding(
padding: const EdgeInsets.only(left: 12),
child: Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
), ),
actions: !isFullScreen actions: !isFullScreen
? [ ? [
IconButton( SizedBox(
icon: const Icon(Icons.close, size: 20), width: 35,
onPressed: () => Navigator.pop(context), height: 35,
child: IconButton(
icon: const Icon(Icons.close, size: 20),
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () => Navigator.pop(context),
),
), ),
const SizedBox(width: 14), const SizedBox(width: 8),
] ]
: null, : null,
); );
@ -479,7 +491,7 @@ class EpisodeListItem extends StatelessWidget {
dense: false, dense: false,
leading: isCurrentIndex leading: isCurrentIndex
? Image.asset( ? Image.asset(
'assets/images/live.gif', 'assets/images/live.png',
color: primary, color: primary,
height: 12, height: 12,
) )

View File

@ -17,7 +17,9 @@ class DanmakaHttp {
var response = await Request().get( var response = await Request().get(
Api.webDanmaku, Api.webDanmaku,
data: params, data: params,
extra: {'resType': ResponseType.bytes}, options: Options(
responseType: ResponseType.bytes,
),
); );
return DmSegMobileReply.fromBuffer(response.data); return DmSegMobileReply.fromBuffer(response.data);
} }

View File

@ -209,24 +209,12 @@ class Request {
*/ */
get(url, {data, Options? options, cancelToken, extra}) async { get(url, {data, Options? options, cancelToken, extra}) async {
Response response; Response response;
options ??= Options(); // 如果 options 为 null则初始化一个新的 Options 对象
ResponseType resType = ResponseType.json;
if (extra != null) { if (extra != null) {
resType = extra['resType'] ?? ResponseType.json;
if (extra['ua'] != null) { if (extra['ua'] != null) {
options.headers = {'user-agent': headerUa(type: extra['ua'])}; options ??= Options();
} options.headers!['user-agent'] = headerUa(type: extra['ua']);
if (extra['opus-goback'] != null) {
if (extra['opus-goback'] != null) {
String cookieHeader = dio.options.headers['cookie'];
options.headers!['cookie'] =
'$cookieHeader; opus-goback = ${extra['opus-goback']}';
}
} }
} }
options.responseType = resType;
try { try {
response = await dio.get( response = await dio.get(
url, url,

View File

@ -65,7 +65,12 @@ class ReadHttp {
static Future parseArticleCv({required String id}) async { static Future parseArticleCv({required String id}) async {
var res = await Request().get( var res = await Request().get(
'https://www.bilibili.com/read/cv$id', 'https://www.bilibili.com/read/cv$id',
extra: {'ua': 'pc', 'opus-goback': '1'}, extra: {'ua': 'pc'},
options: Options(
headers: {
'cookie': 'opus-goback=1',
},
),
); );
String scriptContent = String scriptContent =
extractScriptContents(parse(res.data).body!.outerHtml)[0]; extractScriptContents(parse(res.data).body!.outerHtml)[0];

View File

@ -222,13 +222,27 @@ class BuildMainApp extends StatelessWidget {
elevation: 20, elevation: 20,
); );
return GetMaterialApp( AppBarTheme appBarTheme(ColorScheme colorScheme) {
title: 'PiliPala', return AppBarTheme(
theme: ThemeData( backgroundColor: currentThemeValue == ThemeType.dark
colorScheme: currentThemeValue == ThemeType.dark ? darkColorScheme.surface
? darkColorScheme : lightColorScheme.surface,
: lightColorScheme, foregroundColor: currentThemeValue == ThemeType.dark
? darkColorScheme.onSurface
: lightColorScheme.onSurface,
elevation: 0,
titleSpacing: 0,
scrolledUnderElevation: 0,
// titleTextStyle: TextStyle(
// fontSize: Theme.of(context).textTheme.titleLarge!.fontSize),
);
}
ThemeData buildThemeData(ColorScheme colorScheme) {
return ThemeData(
colorScheme: colorScheme,
snackBarTheme: snackBarTheme, snackBarTheme: snackBarTheme,
appBarTheme: appBarTheme(colorScheme),
pageTransitionsTheme: const PageTransitionsTheme( pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{ builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder( TargetPlatform.android: ZoomPageTransitionsBuilder(
@ -236,12 +250,20 @@ class BuildMainApp extends StatelessWidget {
), ),
}, },
), ),
);
}
return GetMaterialApp(
title: 'PiliPala',
theme: buildThemeData(
currentThemeValue == ThemeType.dark
? darkColorScheme
: lightColorScheme,
), ),
darkTheme: ThemeData( darkTheme: buildThemeData(
colorScheme: currentThemeValue == ThemeType.light currentThemeValue == ThemeType.light
? lightColorScheme ? lightColorScheme
: darkColorScheme, : darkColorScheme,
snackBarTheme: snackBarTheme,
), ),
localizationsDelegates: const [ localizationsDelegates: const [
GlobalCupertinoLocalizations.delegate, GlobalCupertinoLocalizations.delegate,

View File

@ -125,6 +125,7 @@ class ReplyControl {
this.upLike, this.upLike,
this.isShow, this.isShow,
this.entryText, this.entryText,
this.entryTextNum,
this.titleText, this.titleText,
this.time, this.time,
this.location, this.location,
@ -135,6 +136,7 @@ class ReplyControl {
bool? upLike; bool? upLike;
bool? isShow; bool? isShow;
String? entryText; String? entryText;
int? entryTextNum;
String? titleText; String? titleText;
String? time; String? time;
String? location; String? location;
@ -155,6 +157,10 @@ class ReplyControl {
} }
entryText = json['sub_reply_entry_text']; entryText = json['sub_reply_entry_text'];
// 正则匹配
entryTextNum = json['sub_reply_entry_text'] != null
? int.parse(RegExp(r"\d+").stringMatch(json['sub_reply_entry_text']!)!)
: 0;
titleText = json['sub_reply_title_text']; titleText = json['sub_reply_title_text'];
time = json['time_desc']; time = json['time_desc'];
location = json['location'] != null ? json['location'].split('')[1] : ''; location = json['location'] != null ? json['location'].split('')[1] : '';

View File

@ -39,9 +39,7 @@ class _AboutPageState extends State<AboutPage> {
TextStyle subTitleStyle = TextStyle subTitleStyle =
TextStyle(fontSize: 13, color: Theme.of(context).colorScheme.outline); TextStyle(fontSize: 13, color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('关于')),
title: Text('关于', style: Theme.of(context).textTheme.titleMedium),
),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [

View File

@ -55,14 +55,9 @@ class _BlackListPageState extends State<BlackListPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Obx( title: Obx(
() => Text( () => Text(
'黑名单管理 ${_blackListController.total.value == 0 ? '' : '- ${_blackListController.total.value}'}', '黑名单管理 ${_blackListController.total.value == 0 ? '' : '- ${_blackListController.total.value}'}',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
), ),

View File

@ -123,4 +123,15 @@ class DynamicDetailController extends GetxController {
Future onLoad() async { Future onLoad() async {
queryReplyList(reqType: 'onLoad'); queryReplyList(reqType: 'onLoad');
} }
Future removeReply(int? rpid, int? frpid) async {
// 移除一楼评论
if (rpid != null) {
replyList.removeWhere((item) {
return item.rpid == rpid;
});
}
/// TODO 移除二楼评论
}
} }

View File

@ -111,14 +111,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
int rpid = replyItem.rpid!; int rpid = replyItem.rpid!;
Get.to( Get.to(
() => Scaffold( () => Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('评论详情')),
titleSpacing: 0,
centerTitle: false,
title: Text(
'评论详情',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: VideoReplyReplyPanel( body: VideoReplyReplyPanel(
oid: oid, oid: oid,
rpid: rpid, rpid: rpid,
@ -192,10 +185,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 1, scrolledUnderElevation: 1,
centerTitle: false,
titleSpacing: 0,
title: StreamBuilder( title: StreamBuilder(
stream: titleStreamC.stream, stream: titleStreamC.stream,
initialData: false, initialData: false,
@ -335,6 +325,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
.replies! .replies!
.add(replyItem); .add(replyItem);
}, },
onDelete:
_dynamicDetailController.removeReply,
); );
} }
}, },

View File

@ -78,8 +78,6 @@ class _DynamicsPageState extends State<DynamicsPage>
super.build(context); super.build(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
title: SizedBox( title: SizedBox(
height: 34, height: 34,
child: Stack( child: Stack(

View File

@ -49,13 +49,8 @@ class _FansPageState extends State<FansPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: false,
titleSpacing: 0,
title: Text( title: Text(
_fansController.isOwner.value ? '我的粉丝' : '${_fansController.name}的粉丝', _fansController.isOwner.value ? '我的粉丝' : '${_fansController.name}的粉丝',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
body: RefreshIndicator( body: RefreshIndicator(

View File

@ -40,11 +40,8 @@ class _FavPageState extends State<FavPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false,
titleSpacing: 0,
title: Obx(() => Text( title: Obx(() => Text(
'${_favController.isOwner.value ? '' : 'Ta'}的收藏', '${_favController.isOwner.value ? '' : 'Ta'}的收藏',
style: Theme.of(context).textTheme.titleMedium,
)), )),
actions: [ actions: [
Obx(() => !_favController.isOwner.value Obx(() => !_favController.isOwner.value

View File

@ -19,8 +19,6 @@ class _FavEditPageState extends State<FavEditPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
title: Obx( title: Obx(
() => _favEditController.type.value == 'add' () => _favEditController.type.value == 'add'
? Text( ? Text(
@ -32,7 +30,6 @@ class _FavEditPageState extends State<FavEditPage> {
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
centerTitle: false,
actions: [ actions: [
Obx( Obx(
() => _favEditController.privacy.value == 0 () => _favEditController.privacy.value == 0

View File

@ -47,7 +47,6 @@ class _FavSearchPageState extends State<FavSearchPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
actions: [ actions: [
IconButton( IconButton(
onPressed: () => _favSearchCtr.submit(), onPressed: () => _favSearchCtr.submit(),

View File

@ -27,15 +27,10 @@ class _FollowPageState extends State<FollowPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text( title: Text(
_followController.isOwner.value _followController.isOwner.value
? '我的关注' ? '我的关注'
: '${_followController.name}的关注', : '${_followController.name}的关注',
style: Theme.of(context).textTheme.titleMedium,
), ),
actions: [ actions: [
IconButton( IconButton(

View File

@ -47,7 +47,6 @@ class _FollowSearchPageState extends State<FollowSearchPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
actions: [ actions: [
IconButton( IconButton(
onPressed: reRequest, onPressed: reRequest,

View File

@ -69,12 +69,7 @@ class _HistoryPageState extends State<HistoryPage> {
appBar: AppBarWidget( appBar: AppBarWidget(
visible: _historyController.enableMultiple.value, visible: _historyController.enableMultiple.value,
child1: AppBar( child1: AppBar(
titleSpacing: 0, title: const Text('观看记录'),
centerTitle: false,
title: Text(
'观看记录',
style: Theme.of(context).textTheme.titleMedium,
),
actions: [ actions: [
IconButton( IconButton(
onPressed: () => Get.toNamed('/historySearch'), onPressed: () => Get.toNamed('/historySearch'),
@ -127,8 +122,6 @@ class _HistoryPageState extends State<HistoryPage> {
], ],
), ),
child2: AppBar( child2: AppBar(
titleSpacing: 0,
centerTitle: false,
leading: IconButton( leading: IconButton(
onPressed: () { onPressed: () {
_historyController.enableMultiple.value = false; _historyController.enableMultiple.value = false;
@ -143,7 +136,6 @@ class _HistoryPageState extends State<HistoryPage> {
title: Obx( title: Obx(
() => Text( () => Text(
'已选择${_historyController.checkedCount.value}', '已选择${_historyController.checkedCount.value}',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
actions: [ actions: [

View File

@ -45,7 +45,6 @@ class _HistorySearchPageState extends State<HistorySearchPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
actions: [ actions: [
IconButton( IconButton(
onPressed: () => _hisCtr.submit(), onPressed: () => _hisCtr.submit(),

View File

@ -54,7 +54,6 @@ class _HomePageState extends State<HomePage>
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
appBar: AppBar( appBar: AppBar(
toolbarHeight: 0, toolbarHeight: 0,
elevation: 0,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
systemOverlayStyle: Platform.isAndroid systemOverlayStyle: Platform.isAndroid
? SystemUiOverlayStyle( ? SystemUiOverlayStyle(

View File

@ -28,7 +28,6 @@ class HomeAppBar extends StatelessWidget {
background: Column( background: Column(
children: [ children: [
AppBar( AppBar(
centerTitle: false,
title: const Text( title: const Text(
'PiLiPaLa', 'PiLiPaLa',
style: TextStyle( style: TextStyle(
@ -73,8 +72,6 @@ class HomeAppBar extends StatelessWidget {
const SizedBox(width: 10) const SizedBox(width: 10)
], ],
elevation: 0,
scrolledUnderElevation: 0,
), ),
], ],
), ),

View File

@ -104,14 +104,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
int rpid = replyItem.rpid!; int rpid = replyItem.rpid!;
Get.to( Get.to(
() => Scaffold( () => Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('评论详情')),
titleSpacing: 0,
centerTitle: false,
title: Text(
'评论详情',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: VideoReplyReplyPanel( body: VideoReplyReplyPanel(
oid: oid, oid: oid,
rpid: rpid, rpid: rpid,
@ -127,12 +120,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false, title: Text(title),
titleSpacing: 0,
title: Text(
title,
style: Theme.of(context).textTheme.titleMedium,
),
actions: [ actions: [
const SizedBox(width: 4), const SizedBox(width: 4),
IconButton( IconButton(

View File

@ -28,18 +28,12 @@ class _LaterPageState extends State<LaterPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
centerTitle: false,
title: Obx( title: Obx(
() => _laterController.laterList.isNotEmpty () => _laterController.laterList.isNotEmpty
? Text( ? Text(
'稍后再看 (${_laterController.laterList.length})', '稍后再看 (${_laterController.laterList.length})',
style: Theme.of(context).textTheme.titleMedium,
) )
: Text( : const Text('稍后再看'),
'稍后再看',
style: Theme.of(context).textTheme.titleMedium,
),
), ),
actions: [ actions: [
Obx( Obx(

View File

@ -42,13 +42,8 @@ class _LiveFollowPageState extends State<LiveFollowPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Obx(() => Text( title: Obx(() => Text(
'${_liveFollowController.liveFollowingCount}人正在直播中', '${_liveFollowController.liveFollowingCount}人正在直播中',
style: Theme.of(context).textTheme.titleMedium,
)), )),
), ),
body: Container( body: Container(

View File

@ -259,8 +259,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
left: 0, left: 0,
right: 0, right: 0,
child: AppBar( child: AppBar(
centerTitle: false,
titleSpacing: 0,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
foregroundColor: Colors.white, foregroundColor: Colors.white,
toolbarHeight: isPortrait ? 56 : 0, toolbarHeight: isPortrait ? 56 : 0,

View File

@ -47,10 +47,7 @@ class _BottomControlState extends State<BottomControl> {
return AppBar( return AppBar(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
foregroundColor: Colors.white, foregroundColor: Colors.white,
elevation: 0,
scrolledUnderElevation: 0,
primary: false, primary: false,
centerTitle: false,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
titleSpacing: 14, titleSpacing: 14,
title: Row( title: Row(

View File

@ -122,7 +122,7 @@ class ProfilePanel extends StatelessWidget {
), ),
child: Row(children: [ child: Row(children: [
Image.asset( Image.asset(
'assets/images/live.gif', 'assets/images/live.png',
height: 10, height: 10,
), ),
Text( Text(

View File

@ -47,12 +47,9 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
centerTitle: false,
title: Obx( title: Obx(
() => Text( () => Text(
'${_memberArchivesController.isOwner.value ? '' : 'Ta'}的投稿 - ${_memberArchivesController.currentOrder['label']}', '${_memberArchivesController.isOwner.value ? '' : 'Ta'}的投稿 - ${_memberArchivesController.currentOrder['label']}',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
actions: [ actions: [

View File

@ -48,12 +48,9 @@ class _MemberArticlePageState extends State<MemberArticlePage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
centerTitle: false,
title: Obx( title: Obx(
() => Text( () => Text(
'${_memberArticleController.isOwner.value ? '' : 'Ta'}的图文', '${_memberArticleController.isOwner.value ? '' : 'Ta'}的图文',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
), ),

View File

@ -20,7 +20,6 @@ class MemberCoinsItem extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
String heroTag = Utils.makeHeroTag(coinItem.aid); String heroTag = Utils.makeHeroTag(coinItem.aid);
return Card( return Card(
elevation: 0,
clipBehavior: Clip.hardEdge, clipBehavior: Clip.hardEdge,
margin: EdgeInsets.zero, margin: EdgeInsets.zero,
child: InkWell( child: InkWell(

View File

@ -54,12 +54,9 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
centerTitle: false,
title: Obx( title: Obx(
() => Text( () => Text(
'${_memberDynamicController.isOwner.value ? '' : 'Ta'}的动态', '${_memberDynamicController.isOwner.value ? '' : 'Ta'}的动态',
style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
), ),

View File

@ -49,7 +49,6 @@ class _MemberSearchPageState extends State<MemberSearchPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 0,
actions: [ actions: [
IconButton( IconButton(
onPressed: () => _memberSearchCtr.submit(), onPressed: () => _memberSearchCtr.submit(),

View File

@ -41,12 +41,7 @@ class _MemberSeasonsPageState extends State<MemberSeasonsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: Text(Get.parameters['seasonName']!)),
titleSpacing: 0,
centerTitle: false,
title: Text(Get.parameters['seasonName']!,
style: Theme.of(context).textTheme.titleMedium),
),
body: Padding( body: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: StyleString.safeSpace, left: StyleString.safeSpace,

View File

@ -47,9 +47,7 @@ class _MessageAtPageState extends State<MessageAtPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('@我的')),
title: const Text('@我的'),
),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
await _messageAtCtr.queryMessageAt(type: 'init'); await _messageAtCtr.queryMessageAt(type: 'init');
@ -129,7 +127,7 @@ class AtItem extends StatelessWidget {
return InkWell( return InkWell(
onTap: () async { onTap: () async {
MessageUtils.onClickMessage(context, uri, nativeUri, type); MessageUtils.onClickMessage(context, uri, nativeUri, type, null);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(14),

View File

@ -47,9 +47,7 @@ class _MessageLikePageState extends State<MessageLikePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('收到的赞')),
title: const Text('收到的赞'),
),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
await _messageLikeCtr.queryMessageLike(type: 'init'); await _messageLikeCtr.queryMessageLike(type: 'init');
@ -127,7 +125,7 @@ class LikeItem extends StatelessWidget {
final String type = item.item!.type!; final String type = item.item!.type!;
return InkWell( return InkWell(
onTap: () async { onTap: () async {
MessageUtils.onClickMessage(context, uri, nativeUri, type); MessageUtils.onClickMessage(context, uri, nativeUri, type, null);
}, },
child: Stack( child: Stack(
children: [ children: [

View File

@ -48,9 +48,7 @@ class _MessageReplyPageState extends State<MessageReplyPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('回复我的')),
title: const Text('回复我的'),
),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
await _messageReplyCtr.queryMessageReply(type: 'init'); await _messageReplyCtr.queryMessageReply(type: 'init');
@ -119,7 +117,7 @@ class ReplyItem extends StatelessWidget {
final String type = item.item!.type!; final String type = item.item!.type!;
return InkWell( return InkWell(
onTap: () async { onTap: () async {
MessageUtils.onClickMessage(context, uri, nativeUri, type); MessageUtils.onClickMessage(context, uri, nativeUri, type, item.item!);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(14),
@ -157,6 +155,9 @@ class ReplyItem extends StatelessWidget {
text: '回复了我的评论', text: '回复了我的评论',
style: TextStyle(color: outline), style: TextStyle(color: outline),
), ),
if (item.item!.type! == 'dynamic')
TextSpan(
text: '对我的动态发表了评论', style: TextStyle(color: outline)),
])), ])),
const SizedBox(height: 6), const SizedBox(height: 6),
Text.rich( Text.rich(
@ -199,11 +200,32 @@ class ReplyItem extends StatelessWidget {
), ),
), ),
if (item.item!.type! == 'video') if (item.item!.type! == 'video')
NetworkImgLayer( // NetworkImgLayer(
// width: 60,
// height: 60,
// src: item.item!.image,
// radius: 6,
// ),
Container(
width: 60, width: 60,
height: 60, height: 60,
src: item.item!.image, clipBehavior: Clip.hardEdge,
radius: 6, decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6)),
),
child: Image.network(item.item!.image!, fit: BoxFit.cover),
),
if (item.item!.type! == 'dynamic')
Container(
width: 60,
height: 80,
padding: const EdgeInsets.all(4),
child: Text(
item.item!.title!,
maxLines: 4,
style: const TextStyle(fontSize: 12, letterSpacing: 0.3),
overflow: TextOverflow.ellipsis,
),
), ),
], ],
), ),

View File

@ -29,9 +29,7 @@ class _MessageSystemPageState extends State<MessageSystemPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('系统通知')),
title: const Text('系统通知'),
),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
await _messageSystemCtr.queryAndProcessMessages(); await _messageSystemCtr.queryAndProcessMessages();

View File

@ -3,6 +3,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/http/search.dart'; import 'package:pilipala/http/search.dart';
import 'package:pilipala/models/common/reply_type.dart'; import 'package:pilipala/models/common/reply_type.dart';
import 'package:pilipala/models/msg/reply.dart';
import 'package:pilipala/pages/video/detail/reply_reply/index.dart'; import 'package:pilipala/pages/video/detail/reply_reply/index.dart';
import 'package:pilipala/utils/app_scheme.dart'; import 'package:pilipala/utils/app_scheme.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
@ -10,7 +11,12 @@ import 'package:pilipala/utils/utils.dart';
class MessageUtils { class MessageUtils {
// 回复我的、收到的赞点击 // 回复我的、收到的赞点击
static void onClickMessage( static void onClickMessage(
BuildContext context, Uri uri, Uri nativeUri, String type) async { BuildContext context,
Uri uri,
Uri nativeUri,
String type,
ReplyContentItem? item,
) async {
final String path = uri.path; final String path = uri.path;
final String bvid = path.split('/').last; final String bvid = path.split('/').last;
String? sourceType; String? sourceType;
@ -24,8 +30,8 @@ class MessageUtils {
if (nativePath.contains('detail')) { if (nativePath.contains('detail')) {
// 动态详情 // 动态详情
sourceType = 'opus'; sourceType = 'opus';
oid = nativePath.split('/')[3]; oid = item?.subjectId!.toString() ?? nativePath.split('/')[3];
commentRootId = nativePath.split('/')[4]; commentRootId = item?.sourceId!.toString() ?? nativePath.split('/')[4];
} }
switch (type) { switch (type) {
case 'video': case 'video':
@ -47,6 +53,7 @@ class MessageUtils {
} }
break; break;
case 'reply': case 'reply':
case 'dynamic':
debugPrint('commentRootId: $oid, $commentRootId'); debugPrint('commentRootId: $oid, $commentRootId');
navigateToComment( navigateToComment(
context, context,

View File

@ -44,8 +44,6 @@ class _MinePageState extends State<MinePage>
super.build(context); super.build(context);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
scrolledUnderElevation: 0,
elevation: 0,
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.search_outlined), icon: const Icon(Icons.search_outlined),
@ -355,7 +353,8 @@ class _MinePageState extends State<MinePage>
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (flag && index == favFolderList.length) { if (flag && index == favFolderList.length) {
return Padding( return Padding(
padding: const EdgeInsets.only(right: 14), padding:
const EdgeInsets.only(right: 14, bottom: 70),
child: Center( child: Center(
child: IconButton( child: IconButton(
style: ButtonStyle( style: ButtonStyle(
@ -488,7 +487,7 @@ class FavFolderItem extends StatelessWidget {
child: NetworkImgLayer( child: NetworkImgLayer(
src: item!.cover, src: item!.cover,
width: 180, width: 180,
height: 110, height: MediaQuery.textScalerOf(context).scale(110),
), ),
), ),
), ),

View File

@ -23,9 +23,7 @@ class _MineEditPageState extends State<MineEditPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('编辑资料')),
title: const Text('编辑资料'),
),
body: SingleChildScrollView( body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: FutureBuilder( child: FutureBuilder(

View File

@ -38,7 +38,6 @@ class _RankPageState extends State<RankPage>
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
appBar: AppBar( appBar: AppBar(
toolbarHeight: 0, toolbarHeight: 0,
elevation: 0,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
systemOverlayStyle: Platform.isAndroid systemOverlayStyle: Platform.isAndroid
? SystemUiOverlayStyle( ? SystemUiOverlayStyle(

View File

@ -49,7 +49,6 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
width: 1, width: 1,
), ),
), ),
titleSpacing: 0,
actions: [ actions: [
IconButton( IconButton(
onPressed: () => _searchController.submit(), onPressed: () => _searchController.submit(),

View File

@ -51,8 +51,6 @@ class _SearchResultPageState extends State<SearchResultPage>
width: 1, width: 1,
), ),
), ),
titleSpacing: 0,
centerTitle: false,
title: GestureDetector( title: GestureDetector(
onTap: () => Get.back(), onTap: () => Get.back(),
child: SizedBox( child: SizedBox(

View File

@ -131,14 +131,7 @@ class _ExtraSettingState extends State<ExtraSetting> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('其他设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'其他设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView( body: ListView(
children: [ children: [
const SetSwitchItem( const SetSwitchItem(

View File

@ -38,10 +38,7 @@ class _ColorSelectPageState extends State<ColorSelectPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('选择应用主题')),
centerTitle: false,
title: const Text('选择应用主题'),
),
body: ListView( body: ListView(
children: [ children: [
Obx( Obx(

View File

@ -100,9 +100,7 @@ class _LogsPageState extends State<LogsPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false, title: const Text('日志'),
titleSpacing: 0,
title: Text('日志', style: Theme.of(context).textTheme.titleMedium),
actions: [ actions: [
PopupMenuButton<String>( PopupMenuButton<String>(
onSelected: (String type) { onSelected: (String type) {

View File

@ -34,14 +34,7 @@ class _PlayGesturePageState extends State<PlayGesturePage> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('手势设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'手势设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView( body: ListView(
children: [ children: [
ListTile( ListTile(

View File

@ -204,16 +204,7 @@ class _PlaySpeedPageState extends State<PlaySpeedPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('倍速设置')),
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text(
'倍速设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -67,14 +67,7 @@ class _PlaySettingState extends State<PlaySetting> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('播放设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'播放设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView( body: ListView(
children: [ children: [
ListTile( ListTile(

View File

@ -32,14 +32,7 @@ class _PrivacySettingState extends State<PrivacySetting> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('隐私设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'隐私设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: Column( body: Column(
children: [ children: [
ListTile( ListTile(

View File

@ -53,14 +53,7 @@ class _RecommendSettingState extends State<RecommendSetting> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('推荐设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'推荐设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView( body: ListView(
children: [ children: [
ListTile( ListTile(

View File

@ -49,14 +49,7 @@ class _StyleSettingState extends State<StyleSetting> {
.labelMedium! .labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline); .copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('外观设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'外观设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: ListView( body: ListView(
children: [ children: [
Obx( Obx(

View File

@ -9,14 +9,7 @@ class SettingPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final SettingController settingController = Get.put(SettingController()); final SettingController settingController = Get.put(SettingController());
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('设置')),
centerTitle: false,
titleSpacing: 0,
title: Text(
'设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: Column( body: Column(
children: [ children: [
ListTile( ListTile(

View File

@ -40,12 +40,8 @@ class _SubPageState extends State<SubPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false, title:
titleSpacing: 0, Obx(() => Text('${_subController.isOwner.value ? '' : 'Ta'}的订阅')),
title: Obx(() => Text(
'${_subController.isOwner.value ? '' : 'Ta'}的订阅',
style: Theme.of(context).textTheme.titleMedium,
)),
), ),
body: FutureBuilder( body: FutureBuilder(
future: _futureBuilderFuture, future: _futureBuilderFuture,

View File

@ -30,8 +30,6 @@ class _FavPanelState extends State<FavPanel> {
return Column( return Column(
children: [ children: [
AppBar( AppBar(
centerTitle: false,
elevation: 0,
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical( borderRadius: BorderRadius.vertical(
top: Radius.circular(20), top: Radius.circular(20),

View File

@ -57,8 +57,6 @@ class _GroupPanelState extends State<GroupPanel> {
return Column( return Column(
children: <Widget>[ children: <Widget>[
AppBar( AppBar(
centerTitle: false,
elevation: 0,
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical( borderRadius: BorderRadius.vertical(
top: Radius.circular(20), top: Radius.circular(20),

View File

@ -156,7 +156,7 @@ class _PagesPanelState extends State<PagesPanel> {
children: <Widget>[ children: <Widget>[
if (isCurrentIndex) ...<Widget>[ if (isCurrentIndex) ...<Widget>[
Image.asset( Image.asset(
'assets/images/live.gif', 'assets/images/live.png',
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
height: 12, height: 12,
), ),

View File

@ -101,7 +101,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
dense: false, dense: false,
leading: isCurrentIndex leading: isCurrentIndex
? Image.asset( ? Image.asset(
'assets/images/live.gif', 'assets/images/live.png',
color: primary, color: primary,
height: 12, height: 12,
) )
@ -159,7 +159,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
), ),
const SizedBox(width: 15), const SizedBox(width: 15),
Image.asset( Image.asset(
'assets/images/live.gif', 'assets/images/live.png',
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
height: 12, height: 12,
), ),

View File

@ -132,4 +132,32 @@ class VideoReplyController extends GetxController {
queryReplyList(type: 'init'); queryReplyList(type: 'init');
}); });
} }
// 移除评论
Future removeReply(int? rpid, int? frpid) async {
// 移除一楼评论
if (rpid != null) {
replyList.removeWhere((item) {
return item.rpid == rpid;
});
}
// 移除二楼评论
if (frpid != 0 && frpid != null) {
replyList.value = replyList.map((item) {
if (item.rpid! == frpid) {
item.replies!.removeWhere((reply) => reply.rpid == rpid);
// 【共xx条回复】
if (item.replyControl != null &&
item.replyControl!.entryTextNum! >= 1) {
item.replyControl!.entryTextNum =
item.replyControl!.entryTextNum! - 1;
item.rcount = item.replyControl!.entryTextNum;
}
return item;
} else {
return item;
}
}).toList();
}
}
} }

View File

@ -242,10 +242,9 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
.replyList[index], .replyList[index],
showReplyRow: true, showReplyRow: true,
replyLevel: replyLevel, replyLevel: replyLevel,
replyReply: (replyItem, currentReply, replyReply: replyReply,
loadMore) => onDelete:
replyReply(replyItem, currentReply, _videoReplyController.removeReply,
loadMore),
replyType: ReplyType.video, replyType: ReplyType.video,
); );
} }

View File

@ -37,6 +37,7 @@ class ReplyItem extends StatelessWidget {
this.replyReply, this.replyReply,
this.replyType, this.replyType,
this.replySave = false, this.replySave = false,
this.onDelete,
super.key, super.key,
}); });
final ReplyItemModel? replyItem; final ReplyItemModel? replyItem;
@ -46,6 +47,7 @@ class ReplyItem extends StatelessWidget {
final Function? replyReply; final Function? replyReply;
final ReplyType? replyType; final ReplyType? replyType;
final bool replySave; final bool replySave;
final Function(int? rpid, int? frpid)? onDelete;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -75,6 +77,7 @@ class ReplyItem extends StatelessWidget {
item: replyItem, item: replyItem,
mainFloor: true, mainFloor: true,
isOwner: isOwner, isOwner: isOwner,
onDelete: onDelete,
); );
}, },
); );
@ -275,6 +278,7 @@ class ReplyItem extends StatelessWidget {
// f_rpid: replyItem!.rpid, // f_rpid: replyItem!.rpid,
replyItem: replyItem, replyItem: replyItem,
replyReply: replyReply, replyReply: replyReply,
onDelete: onDelete,
), ),
), ),
], ],
@ -371,15 +375,15 @@ class ReplyItemRow extends StatelessWidget {
super.key, super.key,
this.replies, this.replies,
this.replyControl, this.replyControl,
// this.f_rpid,
this.replyItem, this.replyItem,
this.replyReply, this.replyReply,
this.onDelete,
}); });
final List? replies; final List? replies;
ReplyControl? replyControl; ReplyControl? replyControl;
// int? f_rpid;
ReplyItemModel? replyItem; ReplyItemModel? replyItem;
Function? replyReply; Function? replyReply;
final Function(int? rpid, int? frpid)? onDelete;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -410,12 +414,18 @@ class ReplyItemRow extends StatelessWidget {
}, },
onLongPress: () { onLongPress: () {
feedBack(); feedBack();
final bool isOwner = int.parse(replyItem!.member!.mid!) ==
(GlobalDataCache().userInfo?.mid ?? -1);
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
useRootNavigator: true, useRootNavigator: true,
isScrollControlled: true, isScrollControlled: true,
builder: (context) { builder: (context) {
return MorePanel(item: replies![i]); return MorePanel(
item: replies![i],
isOwner: isOwner,
onDelete: onDelete,
);
}, },
); );
}, },
@ -493,7 +503,7 @@ class ReplyItemRow extends StatelessWidget {
if (replyControl!.upReply!) if (replyControl!.upReply!)
const TextSpan(text: 'up主等人 '), const TextSpan(text: 'up主等人 '),
TextSpan( TextSpan(
text: replyControl!.entryText!, text: '查看${replyControl!.entryTextNum}条回复',
style: TextStyle( style: TextStyle(
color: colorScheme.primary, color: colorScheme.primary,
), ),
@ -1019,11 +1029,13 @@ class MorePanel extends StatelessWidget {
final dynamic item; final dynamic item;
final bool mainFloor; final bool mainFloor;
final bool isOwner; final bool isOwner;
final Function(int? rpid, int? frpid)? onDelete;
const MorePanel({ const MorePanel({
super.key, super.key,
required this.item, required this.item,
this.mainFloor = false, this.mainFloor = false,
this.isOwner = false, this.isOwner = false,
this.onDelete,
}); });
Future<dynamic> menuActionHandler(String type) async { Future<dynamic> menuActionHandler(String type) async {
@ -1083,7 +1095,7 @@ class MorePanel extends StatelessWidget {
rpid: item.rpid!, rpid: item.rpid!,
); );
if (result['status']) { if (result['status']) {
SmartDialog.showToast('评论删除成功,需手动刷新'); onDelete?.call(item.rpid!, item.root);
Get.back(); Get.back();
} else { } else {
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);

View File

@ -84,6 +84,16 @@ class VideoReplyReplyController extends GetxController {
return res; return res;
} }
// 移除评论
Future removeReply(int? rpid, int? frpid) async {
// 移除一楼评论
if (rpid != null) {
replyList.removeWhere((item) {
return item.rpid == rpid;
});
}
}
@override @override
void onClose() { void onClose() {
currentPage = 0; currentPage = 0;

View File

@ -89,7 +89,6 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
return AppBar( return AppBar(
toolbarHeight: 45, toolbarHeight: 45,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
centerTitle: false,
title: Text( title: Text(
'评论详情', '评论详情',
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
@ -118,6 +117,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
}, },
replyType: widget.replyType, replyType: widget.replyType,
replyReply: (replyItem) => replyReply(replyItem), replyReply: (replyItem) => replyReply(replyItem),
onDelete: _videoReplyReplyController.removeReply,
); );
} }

View File

@ -614,8 +614,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
builder: ((context, snapshot) { builder: ((context, snapshot) {
return AppBar( return AppBar(
backgroundColor: Colors.black, backgroundColor: Colors.black,
elevation: 0,
scrolledUnderElevation: 0,
); );
}), }),
), ),
@ -861,12 +859,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
return AppBar( return AppBar(
backgroundColor: Colors.transparent, // 使背景透明 backgroundColor: Colors.transparent, // 使背景透明
foregroundColor: Colors.white, foregroundColor: Colors.white,
elevation: 0,
scrolledUnderElevation: 0,
primary: false, primary: false,
centerTitle: false,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
titleSpacing: 0,
title: Container( title: Container(
height: kToolbarHeight, height: kToolbarHeight,
padding: const EdgeInsets.symmetric(horizontal: 14), padding: const EdgeInsets.symmetric(horizontal: 14),

View File

@ -33,8 +33,6 @@ class ScrollAppBar extends StatelessWidget {
padding: EdgeInsets.only(top: statusBarHeight), padding: EdgeInsets.only(top: statusBarHeight),
child: AppBar( child: AppBar(
primary: false, primary: false,
elevation: 0,
scrolledUnderElevation: 0,
centerTitle: true, centerTitle: true,
title: TextButton( title: TextButton(
onPressed: () => callback(), onPressed: () => callback(),

View File

@ -1155,10 +1155,7 @@ class _HeaderControlState extends State<HeaderControl> {
return AppBar( return AppBar(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
foregroundColor: Colors.white, foregroundColor: Colors.white,
elevation: 0,
scrolledUnderElevation: 0,
primary: false, primary: false,
centerTitle: false,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
titleSpacing: 14, titleSpacing: 14,
title: Row( title: Row(

View File

@ -85,7 +85,6 @@ class _MediaListPanelState extends State<MediaListPanel> {
AppBar( AppBar(
toolbarHeight: 45, toolbarHeight: 45,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
centerTitle: false,
title: Text( title: Text(
widget.panelTitle ?? '稍后再看', widget.panelTitle ?? '稍后再看',
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,

View File

@ -19,12 +19,7 @@ class _WebviewPageState extends State<WebviewPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: false, title: Text(_webviewController.pageTitle),
titleSpacing: 0,
title: Text(
_webviewController.pageTitle,
style: Theme.of(context).textTheme.titleMedium,
),
actions: [ actions: [
const SizedBox(width: 4), const SizedBox(width: 4),
IconButton( IconButton(

View File

@ -1,6 +1,5 @@
import 'package:easy_debounce/easy_throttle.dart'; import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/skeleton/skeleton.dart'; import 'package:pilipala/common/skeleton/skeleton.dart';
@ -45,9 +44,7 @@ class _WhisperPageState extends State<WhisperPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(title: const Text('消息')),
title: const Text('消息'),
),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
_whisperController.unread(); _whisperController.unread();

View File

@ -1,5 +1,4 @@
import 'package:app_links/app_links.dart'; import 'package:app_links/app_links.dart';
import 'package:appscheme/appscheme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@ -12,37 +11,20 @@ import 'utils.dart';
class PiliSchame { class PiliSchame {
static late AppLinks appLinks; static late AppLinks appLinks;
static AppScheme appScheme = AppSchemeImpl.getInstance()!;
static Future<void> init() async { static Future<void> init() async {
appLinks = AppLinks(); appLinks = AppLinks();
appLinks.uriLinkStream.listen((Uri uri) { appLinks.uriLinkStream.listen((Uri uri) {
final String scheme = uri.scheme; final String scheme = uri.scheme;
if (RegExp(r'^pili', caseSensitive: false).hasMatch(scheme)) { if (RegExp(r'^pili', caseSensitive: false).hasMatch(scheme)) {
piliScheme(uri); piliScheme(uri);
} } else {
}); routePush(uri);
appScheme.getInitScheme().then((SchemeEntity? value) {
if (value != null) {
routePush(value);
}
});
appScheme.getLatestScheme().then((SchemeEntity? value) {
if (value != null) {
routePush(value);
}
});
appScheme.registerSchemeListener().listen((SchemeEntity? event) {
if (event != null) {
routePush(event);
} }
}); });
} }
/// 路由跳转 /// 路由跳转
static void routePush(value) async { static void routePush(Uri value) async {
final String scheme = value.scheme; final String scheme = value.scheme;
if (scheme == 'bilibili') { if (scheme == 'bilibili') {
biliScheme(value); biliScheme(value);
@ -212,9 +194,9 @@ class PiliSchame {
} }
} }
static Future<void> biliScheme(SchemeEntity value) async { static Future<void> biliScheme(Uri value) async {
final String host = value.host!; final String host = value.host;
final String path = value.path!; final String path = value.path;
switch (host) { switch (host) {
case 'root': case 'root':
Navigator.popUntil( Navigator.popUntil(
@ -300,8 +282,14 @@ class PiliSchame {
} }
break; break;
default: default:
SmartDialog.showToast('未匹配地址,请联系开发者'); final Map<String, String> queryParameters = value.queryParameters;
Clipboard.setData(ClipboardData(text: value.toString())); final String? enterUri = queryParameters['enterUri'];
if (enterUri != null && enterUri.startsWith('bilibili://')) {
biliScheme(Uri.parse(enterUri));
} else {
SmartDialog.showToast('未匹配地址,请联系开发者');
Clipboard.setData(ClipboardData(text: value.toString()));
}
break; break;
} }
} }

View File

@ -49,14 +49,6 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
appscheme:
dependency: "direct main"
description:
name: appscheme
sha256: b885b65219f3839ebafc937024a1bc5ce5a75b0e458fd249ef15e80e81235b6f
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.8"
archive: archive:
dependency: transitive dependency: transitive
description: description:

View File

@ -111,7 +111,6 @@ dependencies:
# 高帧率 # 高帧率
flutter_displaymode: ^0.6.0 flutter_displaymode: ^0.6.0
# scheme跳转 # scheme跳转
appscheme: ^1.0.8
app_links: ^6.3.2 app_links: ^6.3.2
# 弹幕 # 弹幕
ns_danmaku: ns_danmaku: