💄 Shows listening activities are from spotfiy

This commit is contained in:
2025-11-02 16:55:16 +08:00
parent cfbe6e580b
commit a76b97d1d2

View File

@@ -393,9 +393,11 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
], ],
).opacity(0.75).padding(horizontal: 16, bottom: 8), ).opacity(0.75).padding(horizontal: 16, bottom: 8),
...activities.map((activity) { ...activities.map((activity) {
final dcImages = _buildImages(ref, activity); final images = _buildImages(ref, activity);
return Card( return Stack(
children: [
Card(
elevation: 0, elevation: 0,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
side: BorderSide( side: BorderSide(
@@ -409,11 +411,12 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
title: Column( title: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (dcImages.isNotEmpty) if (images.isNotEmpty)
Row( Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment:
CrossAxisAlignment.end,
spacing: 8, spacing: 8,
children: dcImages, children: images,
).padding(vertical: 4), ).padding(vertical: 4),
Row( Row(
spacing: 2, spacing: 2,
@@ -431,7 +434,9 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
onPressed: () { onPressed: () {
launchUrlString(activity.titleUrl!); launchUrlString(activity.titleUrl!);
}, },
icon: const Icon(Symbols.launch_rounded), icon: const Icon(
Symbols.launch_rounded,
),
iconSize: 16, iconSize: 16,
padding: EdgeInsets.all(4), padding: EdgeInsets.all(4),
constraints: const BoxConstraints( constraints: const BoxConstraints(
@@ -468,11 +473,13 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
builder: (context, snapshot) { builder: (context, snapshot) {
final now = DateTime.now(); final now = DateTime.now();
final meta = final meta =
activity.meta as Map<String, dynamic>; activity.meta
as Map<String, dynamic>;
final progressMs = final progressMs =
meta['progress_ms'] as int? ?? 0; meta['progress_ms'] as int? ?? 0;
final durationMs = final durationMs =
meta['track_duration_ms'] as int? ?? 1; meta['track_duration_ms'] as int? ??
1;
final elapsed = final elapsed =
now now
.difference(activity.createdAt) .difference(activity.createdAt)
@@ -488,7 +495,9 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
begin: _startProgress, begin: _startProgress,
end: _endProgress, end: _endProgress,
).animate(_progressController); ).animate(_progressController);
_progressController.forward(from: 0.0); _progressController.forward(
from: 0.0,
);
} }
return AnimatedBuilder( return AnimatedBuilder(
animation: _progressAnimation, animation: _progressAnimation,
@@ -503,7 +512,8 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
final currentSec = final currentSec =
(animatedProgressMs % 60000) ~/ (animatedProgressMs % 60000) ~/
1000; 1000;
final totalMin = durationMs ~/ 60000; final totalMin =
durationMs ~/ 60000;
final totalSec = final totalSec =
(durationMs % 60000) ~/ 1000; (durationMs % 60000) ~/ 1000;
return Column( return Column(
@@ -516,11 +526,12 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
backgroundColor: backgroundColor:
Colors.grey.shade300, Colors.grey.shade300,
trackGap: 0, trackGap: 0,
stopIndicatorColor: Colors.green, stopIndicatorColor:
valueColor:
AlwaysStoppedAnimation<Color>(
Colors.green, Colors.green,
), valueColor:
AlwaysStoppedAnimation<
Color
>(Colors.green),
).padding(top: 3), ).padding(top: 3),
Text( Text(
'${currentMin.toString().padLeft(2, '0')}:${currentSec.toString().padLeft(2, '0')} / ${totalMin.toString().padLeft(2, '0')}:${totalSec.toString().padLeft(2, '0')}', '${currentMin.toString().padLeft(2, '0')}:${currentSec.toString().padLeft(2, '0')} / ${totalMin.toString().padLeft(2, '0')}:${totalSec.toString().padLeft(2, '0')}',
@@ -549,10 +560,12 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
final hours = duration.inHours final hours = duration.inHours
.toString() .toString()
.padLeft(2, '0'); .padLeft(2, '0');
final minutes = (duration.inMinutes % 60) final minutes = (duration.inMinutes %
60)
.toString() .toString()
.padLeft(2, '0'); .padLeft(2, '0');
final seconds = (duration.inSeconds % 60) final seconds = (duration.inSeconds %
60)
.toString() .toString()
.padLeft(2, '0'); .padLeft(2, '0');
return Text( return Text(
@@ -564,12 +577,16 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
Row( Row(
spacing: 2, spacing: 2,
children: [ children: [
Flexible(child: Text(activity.subtitle!)), Flexible(
child: Text(activity.subtitle!),
),
if (activity.titleUrl != null && if (activity.titleUrl != null &&
activity.titleUrl!.isNotEmpty) activity.titleUrl!.isNotEmpty)
IconButton( IconButton(
onPressed: () { onPressed: () {
launchUrlString(activity.titleUrl!); launchUrlString(
activity.titleUrl!,
);
}, },
icon: const Icon( icon: const Icon(
Symbols.launch_rounded, Symbols.launch_rounded,
@@ -588,7 +605,22 @@ class _ActivityPresenceWidgetState extends State<ActivityPresenceWidget>
], ],
), ),
), ),
).padding(horizontal: 8); ).padding(horizontal: 8),
if (activity.manualId == 'spotify')
Positioned(
top: 16,
right: 24,
child: Tooltip(
message: 'Listening on Spotify',
child: Image.asset(
'assets/images/oidc/spotify.png',
width: 24,
height: 24,
),
),
),
],
);
}), }),
], ],
).padding(horizontal: 8, top: 8, bottom: 16), ).padding(horizontal: 8, top: 8, bottom: 16),