style(theme): 客户端切换深色视觉风格

This commit is contained in:
Zhou Weidong committed 2026-10-22 13:49:20 +08:00
1 parent 295c21513c
commit 4bc04fd8ae
75 files changed
+732 -330

No files matched your search

@@ -51,7 +51,7 @@ class _AccountDeactivatePageState extends State<AccountDeactivatePage> {
final signedIn = context.watch<AuthController>().isSignedIn;
final canShow = signedIn || _logic.scheduledAt != null;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('account-deactivate-page'),
backKey: const Key('account-deactivate-back'),
+1 -1
View File
@@ -51,7 +51,7 @@ class _AccountDevicesPageState extends State<AccountDevicesPage> {
final l10n = AppLocalizations.of(context)!;
final signedIn = context.watch<AuthController>().isSignedIn;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('account-devices-page'),
backKey: const Key('account-devices-back'),
+1 -1
View File
@@ -52,7 +52,7 @@ class _AccountExportPageState extends State<AccountExportPage> {
final l10n = AppLocalizations.of(context)!;
final signedIn = context.watch<AuthController>().isSignedIn;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('account-export-page'),
backKey: const Key('account-export-back'),
+2 -1
View File
@@ -70,7 +70,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
final l10n = AppLocalizations.of(context)!;
final signedIn = context.watch<AuthController>().isSignedIn;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('account-profile-page'),
backKey: const Key('account-profile-back'),
@@ -181,6 +181,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> {
Widget _genderField(AppLocalizations l10n) => DropdownButtonFormField<String>(
key: const Key('account-gender'),
isExpanded: true,
initialValue: _gender,
decoration: InputDecoration(labelText: l10n.accountGender),
items: [
+1 -1
View File
@@ -268,7 +268,7 @@ class _ModeSegment extends StatelessWidget {
duration: _segmentDuration,
alignment: Alignment.center,
decoration: BoxDecoration(
color: selected ? AppColors.blue : Colors.transparent,
color: selected ? AppColors.blue : AppColors.transparent,
borderRadius: BorderRadius.circular(18),
),
child: Stack(
+1 -1
View File
@@ -258,7 +258,7 @@ class _AuthPageState extends State<AuthPage> {
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: AppColors.ink,
+1 -1
View File
@@ -141,7 +141,7 @@ class _AuthModeSwitch extends StatelessWidget {
style: TextButton.styleFrom(
minimumSize: const Size(0, _minTapTarget),
padding: EdgeInsets.zero,
overlayColor: Colors.transparent,
overlayColor: AppColors.transparent,
splashFactory: NoSplash.splashFactory,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
),
+2 -2
View File
@@ -28,8 +28,8 @@ Future<bool?> showPhoneAuthSheet(BuildContext context, {bool signUp = false}) {
context: context,
isScrollControlled: true,
useSafeArea: true,
backgroundColor: Colors.transparent,
barrierColor: Colors.black.withValues(alpha: 0.62),
backgroundColor: AppColors.transparent,
barrierColor: AppColors.mediaBlack.withValues(alpha: 0.62),
builder: (_) => PhoneAuthSheet(initialSignUp: signUp),
);
}
+5 -5
View File
@@ -13,8 +13,8 @@ const double _arrowSize = 36;
const double _illustrationWidth = 156;
const double _illustrationHeight = 88;
const double _mottoLineWidth = 96;
const List<Color> _aiGradientStart = [Color(0xFFFFE3D0), Color(0xFFFFC9AC)];
const List<Color> _uploadGradient = [Color(0xFFFFEAD9), Color(0xFFFFD3B3)];
const List<Color> _aiGradientStart = [AppColors.raised, AppColors.goldCard];
const List<Color> _uploadGradient = [AppColors.card, AppColors.raised];
/// 创作页:AI 制作与上传发布两张主卡,底部品牌标语。
class CreatePage extends StatelessWidget {
@@ -24,7 +24,7 @@ class CreatePage extends StatelessWidget {
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: SafeArea(
bottom: false,
child: ListView(
@@ -131,7 +131,7 @@ class _CreateCard extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(_cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
@@ -296,7 +296,7 @@ class _UploadIllustration extends StatelessWidget {
width: 30,
height: 20,
decoration: BoxDecoration(
color: Colors.white.withValues(alpha: 0.55),
color: AppColors.onSurface.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(4),
),
child: const Icon(
+7 -7
View File
@@ -35,8 +35,8 @@ import 'widgets/discover_header.dart';
import 'widgets/discover_search_results.dart';
import 'widgets/drama_grid.dart';
const Color _filterIconColor = Color(0xFF7B61FF);
const Color _newIconColor = Color(0xFF14B8A6);
const Color _filterIconColor = AppColors.blueSoft;
const Color _newIconColor = AppColors.blueSoft;
const double _toolbarHeight = 36;
const double _toolbarGap = 10;
const double _toolbarRadius = 10;
@@ -165,9 +165,9 @@ class _DiscoverPageState extends State<DiscoverPage> {
),
);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
value: SystemUiOverlayStyle.light,
child: Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: embedded
? content
: Scaffold(backgroundColor: AppColors.ink, body: content),
@@ -228,13 +228,13 @@ class _DiscoverPageState extends State<DiscoverPage> {
color: AppColors.ink,
border: Border(
bottom: BorderSide(
color: pinned ? AppColors.border : Colors.transparent,
color: pinned ? AppColors.border : AppColors.transparent,
),
),
boxShadow: pinned
? const [
BoxShadow(
color: Color(0x14000000),
color: AppColors.shadowSubtle,
blurRadius: 8,
offset: Offset(0, 2),
),
@@ -419,7 +419,7 @@ class _DiscoverPageState extends State<DiscoverPage> {
_categoryUnderlineHeight,
),
painter: CategoryUnderlinePainter(
color: selected ? AppColors.blue : Colors.transparent,
color: selected ? AppColors.blue : AppColors.transparent,
),
),
],
@@ -97,7 +97,7 @@ class _DiscoverSearchFieldState extends State<DiscoverSearchField> {
color: AppColors.card,
borderRadius: BorderRadius.circular(_searchRadius),
border: Border.all(
color: _focused ? AppColors.blue : Colors.transparent,
color: _focused ? AppColors.blue : AppColors.transparent,
),
),
child: Row(
+4 -4
View File
@@ -23,8 +23,8 @@ const double _tagChipFontSize = 11;
const double _heatFontSize = 9;
const double _heatIconSize = 11;
const int _maxTags = 3;
const Color _heatBackground = Color(0x99000000);
const Color _tagChipBackground = Color(0xFFF4F1EE);
const Color _heatBackground = AppColors.overlayMedium;
const Color _tagChipBackground = AppColors.raised;
final RegExp _tagSplitter = RegExp(r'[,/、·]');
/// 剧场/分类页共用的双列剧目网格。
@@ -231,11 +231,11 @@ class _DiscoverCoverImage extends StatelessWidget {
Widget _placeholder() {
return const ColoredBox(
color: AppColors.card,
color: AppColors.raised,
child: Center(
child: Icon(
Icons.image_not_supported_outlined,
color: AppColors.muted,
color: AppColors.subtle,
size: 32,
),
),
@@ -183,8 +183,8 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: drama == null
? const [Color(0x00000000), Color(0x8A0B0C10)]
: const [Color(0x00000000), Color(0xE6000000)],
? const [AppColors.transparent, AppColors.bannerScrimMid]
: const [AppColors.transparent, AppColors.bannerScrimEnd],
),
),
),
@@ -232,7 +232,7 @@ class _FeedBannerCarouselState extends State<FeedBannerCarousel> {
child: dramaId == null
? card
: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: borderRadius,
clipBehavior: Clip.antiAlias,
child: InkWell(
+9 -9
View File
@@ -56,7 +56,7 @@ class _DownloadsPageState extends State<DownloadsPage> {
final l10n = AppLocalizations.of(context)!;
final signedIn = context.watch<AuthController>().isSignedIn;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('downloads-page'),
backKey: const Key('downloads-back'),
@@ -105,7 +105,7 @@ class _DownloadsBody extends StatelessWidget {
child: Text(
l10n.downloadedItems,
style: const TextStyle(
color: Colors.white,
color: AppColors.onSurface,
fontSize: 16,
fontWeight: FontWeight.w700,
),
@@ -236,7 +236,7 @@ class _PolicyPanel extends StatelessWidget {
Text(
l10n.downloadQuota(policy.remaining, policy.maxPerDevice),
style: const TextStyle(
color: Colors.white,
color: AppColors.onSurface,
fontSize: 17,
fontWeight: FontWeight.w800,
),
@@ -261,7 +261,7 @@ class _PolicyPanel extends StatelessWidget {
child: Text(
l10n.downloadWifiOnly,
style: const TextStyle(
color: Colors.white,
color: AppColors.onSurface,
fontSize: AppDimens.body,
),
),
@@ -279,7 +279,7 @@ class _PolicyPanel extends StatelessWidget {
child: Text(
l10n.downloadQuality,
style: const TextStyle(
color: Colors.white,
color: AppColors.onSurface,
fontSize: AppDimens.body,
),
),
@@ -375,7 +375,7 @@ class _LicenseTile extends StatelessWidget {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
color: AppColors.onSurface,
fontSize: 15,
fontWeight: FontWeight.w700,
),
@@ -418,12 +418,12 @@ class _LicenseTile extends StatelessWidget {
),
Text(
l10n.downloadProgress(license.progressPercent),
style: const TextStyle(color: Colors.white70, fontSize: 12),
style: const TextStyle(color: AppColors.muted, fontSize: 12),
),
if (license.quality.isNotEmpty)
Text(
license.quality,
style: const TextStyle(color: Colors.white70, fontSize: 12),
style: const TextStyle(color: AppColors.muted, fontSize: 12),
),
],
),
@@ -433,7 +433,7 @@ class _LicenseTile extends StatelessWidget {
child: LinearProgressIndicator(
minHeight: AppDimens.progressHeight,
value: progress.clamp(0.0, 1.0),
backgroundColor: Colors.white24,
backgroundColor: AppColors.border,
valueColor: const AlwaysStoppedAnimation(AppColors.blueSoft),
),
),
@@ -88,15 +88,15 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
Widget build(BuildContext context) {
return AnnotatedRegion<SystemUiOverlayStyle>(
key: const Key('detail-system-overlay'),
value: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: Colors.transparent,
value: SystemUiOverlayStyle.light.copyWith(
statusBarColor: AppColors.transparent,
systemNavigationBarColor: AppColors.ink,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: AppColors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
systemNavigationBarContrastEnforced: false,
),
child: Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: ListenableBuilder(
listenable: logic,
builder: (context, _) => _page(context),
@@ -330,7 +330,7 @@ class DramaEpisodeGrid extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(_chipRadius),
side: BorderSide(
color: selected || locked ? Colors.transparent : AppColors.border,
color: selected || locked ? AppColors.transparent : AppColors.border,
),
),
clipBehavior: Clip.antiAlias,
+2 -2
View File
@@ -75,7 +75,7 @@ class _FavoritesPageState extends State<FavoritesPage> {
final l10n = AppLocalizations.of(context)!;
final signedIn = context.watch<AuthController>().isSignedIn;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: Scaffold(
key: const Key('favorites-page'),
backgroundColor: AppColors.ink,
@@ -264,7 +264,7 @@ class _FavoriteCard extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(_cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
+1 -1
View File
@@ -58,7 +58,7 @@ class _FilterPageState extends State<FilterPage> {
);
final results = _filtered(catalog.dramas);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
value: SystemUiOverlayStyle.light,
child: Scaffold(
key: const Key('filter-page'),
backgroundColor: AppColors.ink,
+9 -9
View File
@@ -100,7 +100,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
final catalog = context.watch<CatalogController>();
final l10n = AppLocalizations.of(context)!;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: _buildHome(context, catalog, l10n),
);
}
@@ -115,7 +115,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
}
if (catalog.error != null) {
return Scaffold(
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
body: HomeFailureView(
error: catalog.debugError ?? catalog.error,
onRetry: () => unawaited(_retryHome(catalog)),
@@ -125,7 +125,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
}
if (catalog.dramas.isEmpty) {
return Scaffold(
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
body: EmptyState(
key: const Key('home-empty'),
icon: Icons.movie_outlined,
@@ -271,14 +271,14 @@ class _HomeTabsState extends State<_HomeTabs> {
},
child: Scaffold(
key: logic.scaffoldKey,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
resizeToAvoidBottomInset: false,
body: _body(context),
bottomNavigationBar: logic.videoImmersive ? null : _nav(context, l10n),
),
);
return AnnotatedRegion<SystemUiOverlayStyle>(
value: feed ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark,
value: SystemUiOverlayStyle.light,
child: feed
? content
: DecoratedBox(
@@ -352,13 +352,13 @@ class _HomeTabsState extends State<_HomeTabs> {
child: IgnorePointer(
key: const Key('home-feed-channel-loading'),
child: ColoredBox(
color: Colors.black26,
color: AppColors.controlSoftScrim,
child: Center(
child: SizedBox.square(
dimension: 24,
child: CircularProgressIndicator(
strokeWidth: 2.4,
color: Colors.white70,
color: AppColors.muted,
),
),
),
@@ -374,7 +374,7 @@ class _HomeTabsState extends State<_HomeTabs> {
return Stack(
fit: StackFit.expand,
children: [
const ColoredBox(color: Colors.black),
const ColoredBox(color: AppColors.mediaBlack),
SafeArea(
bottom: false,
child: Column(
@@ -395,7 +395,7 @@ class _HomeTabsState extends State<_HomeTabs> {
child: CircularProgressIndicator(
key: Key('home-feed-channel-loading'),
strokeWidth: 2.4,
color: Colors.white70,
color: AppColors.muted,
),
),
)
+1 -1
View File
@@ -86,7 +86,7 @@ class HomeDramaCard extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
+2 -2
View File
@@ -91,7 +91,7 @@ class _MyPageState extends State<MyPage> {
),
);
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: embedded
? content
: Scaffold(backgroundColor: AppColors.ink, body: content),
@@ -223,7 +223,7 @@ class _MyPageState extends State<MyPage> {
Future<void> _openLanguage() async {
final selected = await showModalBottomSheet<Locale>(
context: context,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
showDragHandle: false,
builder: (_) =>
_LanguageSheet(selected: context.read<LocaleController>().locale),
+1 -1
View File
@@ -36,7 +36,7 @@ class MineHeader extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
+3 -3
View File
@@ -71,7 +71,7 @@ class _ShortcutTile extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
@@ -198,7 +198,7 @@ class MineVipCard extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(
@@ -287,7 +287,7 @@ class MineMenuList extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.cardRadius),
clipBehavior: Clip.antiAlias,
child: Column(
+10 -7
View File
@@ -102,7 +102,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
final hero = visible.isEmpty ? null : visible.first;
final more = pager.items.skip(1).take(_moreLimit).toList();
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle.dark,
value: SystemUiOverlayStyle.light,
child: Scaffold(
key: const Key('new-releases-page'),
backgroundColor: AppColors.ink,
@@ -259,7 +259,10 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0x00000000), Color(0xB3000000)],
colors: [
AppColors.transparent,
AppColors.playerOverlayPill,
],
),
),
),
@@ -282,7 +285,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
Text(
l10n.premiereToday,
style: const TextStyle(
color: Colors.white70,
color: AppColors.muted,
fontSize: 10,
fontWeight: FontWeight.w600,
),
@@ -293,7 +296,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 20,
fontWeight: FontWeight.w800,
),
@@ -315,7 +318,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white70,
color: AppColors.muted,
fontSize: 11,
),
),
@@ -338,7 +341,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
),
child: const Icon(
Icons.play_arrow_rounded,
color: Colors.white,
color: AppColors.onPrimary,
size: 22,
),
),
@@ -490,7 +493,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
child: Text(
l10n.newBadge,
style: TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: compact ? 9 : 10,
fontWeight: FontWeight.w800,
),
+1 -1
View File
@@ -46,7 +46,7 @@ class _NoticesPageState extends State<NoticesPage> {
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('notices-page'),
backKey: const Key('notices-back'),
+9 -6
View File
@@ -23,6 +23,7 @@ import '../../core/data/services/playback_session.dart';
import '../../core/data/services/video_player_port.dart';
import '../../core/data/services/wallet_controller.dart';
import '../../core/formatting/localized_content.dart';
import '../../core/theme/app_colors.dart';
import '../../core/navigation/fade_page_route.dart';
import '../../l10n/app_localizations.dart';
import '../discover/discover_types.dart';
@@ -937,8 +938,9 @@ class PlayerLogic extends ChangeNotifier {
} catch (_) {
if (context.mounted && session.active == player) {
final l10n = AppLocalizations.of(context)!;
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(l10n.seekFailed)));
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(l10n.seekFailed)));
}
} finally {
if (scrubbingPlayer == player) cancelScrub();
@@ -1017,7 +1019,7 @@ class PlayerLogic extends ChangeNotifier {
try {
await showModalBottomSheet<void>(
context: context,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
isScrollControlled: true,
builder: (_) => EpisodePickerSheet(
drama: drama,
@@ -1079,8 +1081,9 @@ class PlayerLogic extends ChangeNotifier {
await session.playbackSettled;
await saveCurrentProgress();
if (!context.mounted) return;
final action = await Navigator.of(context)
.push<MyPageAction>(MaterialPageRoute(builder: (_) => const MyPage()));
final action = await Navigator.of(
context,
).push<MyPageAction>(MaterialPageRoute(builder: (_) => const MyPage()));
if (!context.mounted) return;
if (action == MyPageAction.discover) {
await showDiscover(context);
@@ -1154,7 +1157,7 @@ class PlayerLogic extends ChangeNotifier {
await showModalBottomSheet<void>(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
showDragHandle: false,
isDismissible: false,
enableDrag: false,
+12 -12
View File
@@ -393,19 +393,19 @@ class _PlayerPageState extends State<PlayerPage>
return AnnotatedRegion<SystemUiOverlayStyle>(
key: const Key('player-system-overlay'),
value: SystemUiOverlayStyle.light.copyWith(
statusBarColor: Colors.transparent,
systemNavigationBarColor: Colors.black,
systemNavigationBarDividerColor: Colors.transparent,
statusBarColor: AppColors.transparent,
systemNavigationBarColor: AppColors.mediaBlack,
systemNavigationBarDividerColor: AppColors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
systemNavigationBarContrastEnforced: false,
),
child: Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: widget.embedded
? body
: Scaffold(
key: const Key('player-scaffold'),
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
resizeToAvoidBottomInset: false,
body: body,
),
@@ -457,7 +457,7 @@ class _PlayerPageState extends State<PlayerPage>
if (widget.homeMode)
const ColoredBox(
key: Key('home-feed-black-background'),
color: Colors.black,
color: AppColors.mediaBlack,
),
PlayerVideoSurface(
controller: videoPort?.controller,
@@ -497,14 +497,14 @@ class _PlayerPageState extends State<PlayerPage>
children: [
const Icon(
Icons.wifi_off_rounded,
color: Colors.white70,
color: AppColors.muted,
size: 36,
),
const SizedBox(height: 12),
Text(
errorText(l10n, logic.ticketError, l10n.playbackError),
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white70),
style: const TextStyle(color: AppColors.muted),
),
const SizedBox(height: 12),
FilledButton(
@@ -524,14 +524,14 @@ class _PlayerPageState extends State<PlayerPage>
children: [
const Icon(
Icons.error_outline_rounded,
color: Colors.white70,
color: AppColors.muted,
size: 36,
),
const SizedBox(height: 12),
Text(
l10n.playbackError,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white70),
style: const TextStyle(color: AppColors.muted),
),
],
),
@@ -551,7 +551,7 @@ class _PlayerPageState extends State<PlayerPage>
children: [
const Icon(
Icons.movie_filter_outlined,
color: Colors.white70,
color: AppColors.muted,
size: 36,
),
const SizedBox(height: 12),
@@ -560,7 +560,7 @@ class _PlayerPageState extends State<PlayerPage>
? l10n.lockedTitle(episode.number)
: l10n.noMediaNotice,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white70),
style: const TextStyle(color: AppColors.muted),
),
],
),
+3 -3
View File
@@ -6,7 +6,7 @@ extension _PlayerViewActions on _PlayerPageState {
Future<void> _openSpeedSheet(BuildContext context) async {
final selected = await showModalBottomSheet<double>(
context: context,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
showDragHandle: false,
builder: (_) => PlayerSpeedSheet(selected: _playbackSpeed),
);
@@ -19,7 +19,7 @@ extension _PlayerViewActions on _PlayerPageState {
final l10n = AppLocalizations.of(context)!;
await showModalBottomSheet<void>(
context: context,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
showDragHandle: false,
isScrollControlled: true,
builder: (_) => PlayerMoreSheet(
@@ -52,7 +52,7 @@ extension _PlayerViewActions on _PlayerPageState {
if (wallet == null) return;
await showModalBottomSheet<bool>(
context: context,
backgroundColor: Colors.transparent,
backgroundColor: AppColors.transparent,
showDragHandle: false,
isScrollControlled: true,
builder: (_) => PlayerUnlockSheet(
@@ -413,13 +413,16 @@ class _CommentPostSuccessOverlay extends StatelessWidget {
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.82),
color: AppColors.mediaBlack.withValues(alpha: 0.82),
borderRadius: BorderRadius.circular(8),
),
child: Text(
message,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white, fontSize: 14),
style: const TextStyle(
color: AppColors.onPrimary,
fontSize: 14,
),
),
),
),
@@ -40,11 +40,11 @@ class EpisodePickerSheet extends StatelessWidget {
final episodes = drama.episodes;
return AnnotatedRegion<SystemUiOverlayStyle>(
key: const Key('player-episodes-system-overlay'),
value: SystemUiOverlayStyle.dark.copyWith(
statusBarColor: Colors.transparent,
value: SystemUiOverlayStyle.light.copyWith(
statusBarColor: AppColors.transparent,
systemNavigationBarColor: AppColors.card,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: AppColors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
systemNavigationBarContrastEnforced: false,
),
child: Container(
@@ -2,6 +2,8 @@
import 'package:flutter/material.dart';
import '../../../core/theme/app_colors.dart';
/// Shared floating action used to leave clear-screen mode.
class ExitClearScreenButton extends StatelessWidget {
const ExitClearScreenButton({
@@ -23,8 +25,8 @@ class ExitClearScreenButton extends StatelessWidget {
onPressed: onPressed,
padding: EdgeInsets.zero,
style: IconButton.styleFrom(
backgroundColor: const Color(0x80000000),
foregroundColor: Colors.white,
backgroundColor: AppColors.controlScrim,
foregroundColor: AppColors.onPrimary,
shape: const CircleBorder(),
),
icon: const Icon(Icons.fullscreen_exit_rounded, size: 18),
+14 -8
View File
@@ -2,6 +2,8 @@
import 'package:flutter/material.dart';
import '../../../core/theme/app_colors.dart';
import '../../home/home_feed_channel.dart';
import '../../../l10n/app_localizations.dart';
@@ -140,8 +142,8 @@ class _TopIconButton extends StatelessWidget {
icon: Icon(
icon,
size: glyphSize,
color: Colors.white,
shadows: const [Shadow(blurRadius: 6, color: Colors.black)],
color: AppColors.onPrimary,
shadows: const [Shadow(blurRadius: 6, color: AppColors.mediaBlack)],
),
),
);
@@ -184,15 +186,17 @@ class _RefreshButton extends StatelessWidget {
child: CircularProgressIndicator(
key: Key('home-feed-refreshing'),
strokeWidth: 2,
color: Colors.white,
color: AppColors.onPrimary,
),
),
)
: Icon(
Icons.refresh_rounded,
size: glyphSize,
color: Colors.white,
shadows: const [Shadow(blurRadius: 6, color: Colors.black)],
color: AppColors.onPrimary,
shadows: const [
Shadow(blurRadius: 6, color: AppColors.mediaBlack),
],
),
),
),
@@ -232,10 +236,12 @@ class _FeedTabItem extends StatelessWidget {
label,
maxLines: 1,
style: TextStyle(
color: selected ? Colors.white : Colors.white70,
color: selected ? AppColors.onPrimary : AppColors.muted,
fontSize: fontSize,
fontWeight: selected ? FontWeight.w800 : FontWeight.w600,
shadows: const [Shadow(blurRadius: 6, color: Colors.black)],
shadows: const [
Shadow(blurRadius: 6, color: AppColors.mediaBlack),
],
),
),
const SizedBox(height: 4),
@@ -243,7 +249,7 @@ class _FeedTabItem extends StatelessWidget {
width: underlineWidth,
height: underlineHeight,
decoration: BoxDecoration(
color: selected ? Colors.white : Colors.transparent,
color: selected ? AppColors.onPrimary : AppColors.transparent,
borderRadius: BorderRadius.circular(1),
),
),
+13 -13
View File
@@ -20,8 +20,8 @@ import 'seek_progress_bar.dart';
part 'home_feed_overlay_parts.dart';
const Color _overlayPill = Color(0x66000000);
const Color _fullBarBackground = Color(0x4D000000);
const Color _overlayPill = AppColors.overlaySoft;
const Color _fullBarBackground = AppColors.overlayBar;
const double _titleFontSize = 17;
const double _metaFontSize = 12;
const double _tagFontSize = 11;
@@ -29,7 +29,7 @@ const double _fullBarHeight = 44;
const double _progressHeight = 2;
const double _progressHitHeight = 24;
const List<Shadow> _boostTextShadows = [
Shadow(color: Colors.black54, blurRadius: 5, offset: Offset(0, 1)),
Shadow(color: AppColors.shadow, blurRadius: 5, offset: Offset(0, 1)),
];
const int _maxTags = 4;
final RegExp _tagSplitter = RegExp(r'[,/、·]');
@@ -236,7 +236,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
key: const Key('home-feed-author-note'),
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(color: Colors.white70, fontSize: 11),
style: const TextStyle(color: AppColors.muted, fontSize: 11),
),
],
],
@@ -260,14 +260,14 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white70,
color: AppColors.muted,
fontSize: _metaFontSize,
),
),
),
const Icon(
Icons.chevron_right_rounded,
color: Colors.white70,
color: AppColors.muted,
size: 16,
),
],
@@ -288,16 +288,16 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontFamily: 'Outfit',
color: Colors.white,
color: AppColors.onPrimary,
fontSize: _titleFontSize,
fontWeight: FontWeight.w800,
shadows: [Shadow(blurRadius: 8, color: Colors.black)],
shadows: [Shadow(blurRadius: 8, color: AppColors.mediaBlack)],
),
),
),
const Icon(
Icons.chevron_right_rounded,
color: Colors.white,
color: AppColors.onPrimary,
size: 20,
),
],
@@ -326,7 +326,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
tag,
maxLines: 1,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: _tagFontSize,
),
),
@@ -369,7 +369,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
children: [
const Icon(
Icons.play_arrow_rounded,
color: Colors.white,
color: AppColors.onPrimary,
size: 14,
),
const SizedBox(width: 6),
@@ -381,7 +381,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 13,
fontWeight: FontWeight.w600,
),
@@ -389,7 +389,7 @@ class _HomeFeedOverlayState extends State<HomeFeedOverlay> {
),
const Icon(
Icons.chevron_right_rounded,
color: Colors.white,
color: AppColors.onPrimary,
size: 18,
),
],
@@ -251,7 +251,10 @@ class _FeedProgressBarState extends State<_FeedProgressBar> {
bottom: bottom,
child: SizedBox(
height: widget.height,
child: ColoredBox(key: _inactiveTrackKey, color: Colors.white24),
child: ColoredBox(
key: _inactiveTrackKey,
color: AppColors.border,
),
),
),
],
@@ -301,7 +304,7 @@ class _FeedProgressBarState extends State<_FeedProgressBar> {
child: Container(
key: const Key('home-feed-progress-track'),
height: trackHeight,
color: Colors.white24,
color: AppColors.border,
),
),
Positioned(
@@ -321,7 +324,7 @@ class _FeedProgressBarState extends State<_FeedProgressBar> {
width: size,
height: size,
decoration: const BoxDecoration(
color: Colors.white,
color: AppColors.onPrimary,
shape: BoxShape.circle,
),
),
@@ -71,7 +71,7 @@ class _RailButton extends StatelessWidget {
width: _iconSize,
height: _iconSize,
fit: BoxFit.contain,
color: item.selected ? AppColors.blue : Colors.white,
color: item.selected ? AppColors.blue : AppColors.onPrimary,
colorBlendMode: BlendMode.srcIn,
),
),
@@ -83,11 +83,11 @@ class _RailButton extends StatelessWidget {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
height: 1,
fontSize: 12,
fontWeight: FontWeight.w600,
shadows: [Shadow(blurRadius: 6, color: Colors.black)],
shadows: [Shadow(blurRadius: 6, color: AppColors.mediaBlack)],
),
),
],
@@ -2,13 +2,15 @@
import 'package:flutter/material.dart';
import '../../../core/theme/app_colors.dart';
/// 播放未就绪时沿进度轨道循环移动的加载高光。
class LoadingProgressTrack extends StatefulWidget {
const LoadingProgressTrack({
super.key = const Key('progress-loading'),
required this.height,
this.trackColor = Colors.white24,
this.highlightColor = Colors.white,
this.trackColor = AppColors.inactiveTrack,
this.highlightColor = AppColors.onPrimary,
});
final double height;
@@ -6,9 +6,9 @@ import '../../../core/theme/app_colors.dart';
const double _toggleSize = 68;
const double _iconSize = 36;
const Color _toggleBackground = Colors.black26;
const Color _toggleBackground = AppColors.controlSoftScrim;
const List<Shadow> _iconShadows = [
Shadow(color: Colors.black54, blurRadius: 12),
Shadow(color: AppColors.shadow, blurRadius: 12),
];
/// 首页沉浸流与全屏播放器共用的播放/暂停按钮。
@@ -271,7 +271,7 @@ class _PlayerMoreSheetState extends State<PlayerMoreSheet> {
}) {
return Material(
key: key,
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(8),
child: InkWell(
borderRadius: BorderRadius.circular(8),
@@ -347,7 +347,7 @@ class _SegmentButton extends StatelessWidget {
? AppColors.muted
: AppColors.subtle;
return Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(_segmentRadius),
child: InkWell(
onTap: onTap,
@@ -357,12 +357,12 @@ class _SegmentButton extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: _segmentPadding),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selected ? AppColors.card : Colors.transparent,
color: selected ? AppColors.card : AppColors.transparent,
borderRadius: BorderRadius.circular(_segmentRadius),
boxShadow: selected
? const [
BoxShadow(
color: Color(0x14000000),
color: AppColors.shadowSubtle,
blurRadius: 4,
offset: Offset(0, 1),
),
+3 -3
View File
@@ -18,7 +18,7 @@ const double _topBarHeight = 58;
const double _boostHintIconSize = 16;
const double _boostHintFontSize = 13;
const List<Shadow> _playerTextShadows = [
Shadow(color: Colors.black54, blurRadius: 5, offset: Offset(0, 1)),
Shadow(color: AppColors.shadow, blurRadius: 5, offset: Offset(0, 1)),
];
/// K29 竖屏播放页浮层。
@@ -270,7 +270,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
thumbnailsUrl: data.episode.thumbnailsUrl,
episodeId: data.episode.id,
posterUrl: data.drama.posterUrl,
inactiveTrackColor: Colors.white24,
inactiveTrackColor: AppColors.inactiveTrack,
onScrubStart: actions.onScrubStart,
onSeek: actions.onSeek,
),
@@ -279,7 +279,7 @@ class PlayerPlaybackOverlay extends StatelessWidget {
Widget _detailRow(String series) {
return Material(
color: Colors.transparent,
color: AppColors.transparent,
child: InkWell(
key: const Key('player-open-detail'),
onTap: actions.onDetail,
@@ -22,7 +22,7 @@ class _TopButton extends StatelessWidget {
tooltip: tooltip,
padding: EdgeInsets.zero,
style: IconButton.styleFrom(
backgroundColor: const Color(0x80000000),
backgroundColor: AppColors.controlScrim,
foregroundColor: AppColors.onPrimary,
),
onPressed: onPressed,
@@ -41,7 +41,7 @@ class _SpeedEntry extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
color: const Color(0x80000000),
color: AppColors.controlScrim,
borderRadius: BorderRadius.circular(999),
child: InkWell(
onTap: onTap,
@@ -4,6 +4,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import '../../../core/theme/app_colors.dart';
const Duration _videoFadeDuration = Duration(milliseconds: 200);
const double _errorHorizontal = 32;
const int _errorMaxLines = 3;
@@ -55,7 +57,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
children: [
const ColoredBox(
key: Key('player-fallback-background'),
color: Colors.black,
color: AppColors.mediaBlack,
),
AnimatedOpacity(
key: const Key('player-video-opacity'),
@@ -81,7 +83,7 @@ class _PlayerVideoSurfaceState extends State<PlayerVideoSurface> {
maxLines: _errorMaxLines,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white70, fontSize: 13),
style: const TextStyle(color: AppColors.muted, fontSize: 13),
),
),
),
@@ -164,7 +164,7 @@ class _ScrubPreviewCardState extends State<ScrubPreviewCard> {
decoration: BoxDecoration(
color: AppColors.card,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.white, width: 1),
border: Border.all(color: AppColors.onPrimary, width: 1),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(7),
@@ -174,7 +174,7 @@ class _ScrubPreviewCardState extends State<ScrubPreviewCard> {
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
color: Colors.black87,
color: AppColors.scrubPreviewScrim,
child: Text(
'${_format(widget.position)} / ${_format(widget.duration)}',
key: const Key('scrub-preview-time'),
@@ -182,7 +182,7 @@ class _ScrubPreviewCardState extends State<ScrubPreviewCard> {
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 11,
fontWeight: FontWeight.w600,
height: 1.2,
@@ -233,7 +233,7 @@ class _SeekProgressBarState extends State<SeekProgressBar> {
'${_format(previewPosition)} / ${_format(video.duration)}',
textAlign: TextAlign.center,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 14,
fontWeight: FontWeight.w600,
height: 1.2,
+6 -6
View File
@@ -27,10 +27,10 @@ const double _rankColumnWidth = 56;
const double _listCoverWidth = 72;
const double _listCoverHeight = 96;
const double _loadMoreThreshold = 200;
const Color _goldStart = Color(0xFFF3B34C);
const Color _goldEnd = Color(0xFFD9A23A);
const Color _bronzeStart = Color(0xFFCD7F32);
const Color _bronzeEnd = Color(0xFFA9713A);
const Color _goldStart = AppColors.gold;
const Color _goldEnd = AppColors.goldDeep;
const Color _bronzeStart = AppColors.bronze;
const Color _bronzeEnd = AppColors.bronzeDeep;
/// 剧场榜单页:前三名横排领奖台,第 4 名起纵向列表。
class RankingPage extends StatefulWidget {
@@ -265,7 +265,7 @@ class _PodiumCard extends StatelessWidget {
l10n.topLabel(rank),
maxLines: 1,
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 11,
fontWeight: FontWeight.w800,
),
@@ -335,7 +335,7 @@ class _RankingRow extends StatelessWidget {
boxShadow: const [AppTheme.cardShadow],
),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(14),
clipBehavior: Clip.antiAlias,
child: InkWell(
+5 -5
View File
@@ -12,7 +12,7 @@ import '../new_releases/new_releases_page.dart';
const double _ticketRadius = 20;
const double _notchSize = 24;
const Color _ticketDash = Color(0x66FF7A1A);
const Color _ticketDash = AppColors.primaryBorder;
/// 预约页:档期周历 + 电影票式空态 + 预约权益说明。
class ReservePage extends StatefulWidget {
@@ -131,7 +131,7 @@ class _ReservePageState extends State<ReservePage> {
Text(
weekdays[date.weekday - 1],
style: TextStyle(
color: selected ? Colors.white : AppColors.muted,
color: selected ? AppColors.onPrimary : AppColors.muted,
fontSize: 11,
fontWeight: FontWeight.w600,
),
@@ -140,7 +140,7 @@ class _ReservePageState extends State<ReservePage> {
Text(
'${date.day}',
style: TextStyle(
color: selected ? Colors.white : AppColors.onSurface,
color: selected ? AppColors.onPrimary : AppColors.onSurface,
fontSize: 15,
fontWeight: FontWeight.w800,
),
@@ -207,7 +207,7 @@ class _ReservePageState extends State<ReservePage> {
),
style: FilledButton.styleFrom(
backgroundColor: AppColors.blue,
foregroundColor: Colors.white,
foregroundColor: AppColors.onPrimary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
@@ -285,7 +285,7 @@ class _ReservePageState extends State<ReservePage> {
child: Text(
'${index + 1}',
style: const TextStyle(
color: Colors.white,
color: AppColors.onPrimary,
fontSize: 12,
fontWeight: FontWeight.w800,
),
+1 -1
View File
@@ -23,7 +23,7 @@ class SettingsPage extends StatelessWidget {
final l10n = AppLocalizations.of(context)!;
final auth = context.watch<AuthController>();
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('settings-page'),
backKey: const Key('settings-back'),
+1 -1
View File
@@ -57,7 +57,7 @@ class _StorePageState extends State<StorePage> {
final l10n = AppLocalizations.of(context)!;
final isVip = widget.type == StoreController.vipType;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('store-page'),
backKey: const Key('store-back'),
+1 -1
View File
@@ -46,7 +46,7 @@ class _WalletPageState extends State<WalletPage> {
final l10n = AppLocalizations.of(context)!;
final wallet = context.watch<WalletController>();
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: PlainPageScaffold(
pageKey: const Key('wallet-page'),
backKey: const Key('wallet-back'),
@@ -38,7 +38,7 @@ class WatchRecordsPage extends StatelessWidget {
final signedIn = context.watch<AuthController>().isSignedIn;
final l10n = AppLocalizations.of(context)!;
return Theme(
data: AppTheme.light(),
data: AppTheme.dark(),
child: Scaffold(
key: const Key('watch-records-page'),
backgroundColor: AppColors.ink,
@@ -170,7 +170,7 @@ class WatchRecordCard extends StatelessWidget {
key: ValueKey('watch-record-${record.dramaId}'),
decoration: _cardDecoration(),
child: Material(
color: Colors.transparent,
color: AppColors.transparent,
borderRadius: BorderRadius.circular(_cardRadius),
clipBehavior: Clip.antiAlias,
child: InkWell(