💄 Optimize the pfc and show the activities
This commit is contained in:
		@@ -68,8 +68,15 @@ const kPresenseActivityIcons = <IconData>[
 | 
			
		||||
 | 
			
		||||
class ActivityPresenceWidget extends ConsumerWidget {
 | 
			
		||||
  final String uname;
 | 
			
		||||
  final bool isCompact;
 | 
			
		||||
  final EdgeInsets compactPadding;
 | 
			
		||||
 | 
			
		||||
  const ActivityPresenceWidget({super.key, required this.uname});
 | 
			
		||||
  const ActivityPresenceWidget({
 | 
			
		||||
    super.key,
 | 
			
		||||
    required this.uname,
 | 
			
		||||
    this.isCompact = false,
 | 
			
		||||
    this.compactPadding = EdgeInsets.zero,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  List<Widget> _buildDiscordImages(WidgetRef ref, SnPresenceActivity activity) {
 | 
			
		||||
    final List<Widget> images = [];
 | 
			
		||||
@@ -139,6 +146,106 @@ class ActivityPresenceWidget extends ConsumerWidget {
 | 
			
		||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
			
		||||
    final activitiesAsync = ref.watch(presenceActivitiesProvider(uname));
 | 
			
		||||
 | 
			
		||||
    if (isCompact) {
 | 
			
		||||
      return activitiesAsync.when(
 | 
			
		||||
        data: (activities) {
 | 
			
		||||
          if (activities.isEmpty) return const SizedBox.shrink();
 | 
			
		||||
          final activity = activities.first;
 | 
			
		||||
          return Padding(
 | 
			
		||||
            padding: compactPadding,
 | 
			
		||||
            child: Row(
 | 
			
		||||
              spacing: 8,
 | 
			
		||||
              children: [
 | 
			
		||||
                if (activity.largeImage != null &&
 | 
			
		||||
                    activity.largeImage!.startsWith('discord:'))
 | 
			
		||||
                  ref
 | 
			
		||||
                      .watch(
 | 
			
		||||
                        discordAssetsUrlProvider(
 | 
			
		||||
                          activity,
 | 
			
		||||
                          activity.largeImage!.substring('discord:'.length),
 | 
			
		||||
                        ),
 | 
			
		||||
                      )
 | 
			
		||||
                      .when(
 | 
			
		||||
                        data:
 | 
			
		||||
                            (url) =>
 | 
			
		||||
                                url != null
 | 
			
		||||
                                    ? ClipRRect(
 | 
			
		||||
                                      borderRadius: BorderRadius.circular(4),
 | 
			
		||||
                                      child: CachedNetworkImage(
 | 
			
		||||
                                        imageUrl: url,
 | 
			
		||||
                                        width: 32,
 | 
			
		||||
                                        height: 32,
 | 
			
		||||
                                      ),
 | 
			
		||||
                                    )
 | 
			
		||||
                                    : const SizedBox.shrink(),
 | 
			
		||||
                        loading:
 | 
			
		||||
                            () => const SizedBox(
 | 
			
		||||
                              width: 32,
 | 
			
		||||
                              height: 32,
 | 
			
		||||
                              child: CircularProgressIndicator(strokeWidth: 1),
 | 
			
		||||
                            ),
 | 
			
		||||
                        error: (error, stack) => const SizedBox.shrink(),
 | 
			
		||||
                      ),
 | 
			
		||||
                Expanded(
 | 
			
		||||
                  child: Column(
 | 
			
		||||
                    crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                    children: [
 | 
			
		||||
                      Text(
 | 
			
		||||
                        (activity.title?.isEmpty ?? true)
 | 
			
		||||
                            ? 'unknown'.tr()
 | 
			
		||||
                            : activity.title!,
 | 
			
		||||
                        maxLines: 1,
 | 
			
		||||
                        overflow: TextOverflow.ellipsis,
 | 
			
		||||
                      ).fontSize(13),
 | 
			
		||||
                      Row(
 | 
			
		||||
                        children: [
 | 
			
		||||
                          Text(
 | 
			
		||||
                            kPresenseActivityTypes[activity.type],
 | 
			
		||||
                          ).tr().fontSize(11),
 | 
			
		||||
                          Icon(
 | 
			
		||||
                            kPresenseActivityIcons[activity.type],
 | 
			
		||||
                            size: 15,
 | 
			
		||||
                            fill: 1,
 | 
			
		||||
                          ),
 | 
			
		||||
                        ],
 | 
			
		||||
                      ),
 | 
			
		||||
                    ],
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                StreamBuilder(
 | 
			
		||||
                  stream: Stream.periodic(const Duration(seconds: 1)),
 | 
			
		||||
                  builder: (context, snapshot) {
 | 
			
		||||
                    final now = DateTime.now();
 | 
			
		||||
 | 
			
		||||
                    // Check if lease has expired and refresh if needed
 | 
			
		||||
                    if (now.isAfter(activity.leaseExpiresAt)) {
 | 
			
		||||
                      WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
			
		||||
                        ref.invalidate(presenceActivitiesProvider(uname));
 | 
			
		||||
                      });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    final duration = now.difference(activity.createdAt);
 | 
			
		||||
                    final hours = duration.inHours.toString().padLeft(2, '0');
 | 
			
		||||
                    final minutes = (duration.inMinutes % 60)
 | 
			
		||||
                        .toString()
 | 
			
		||||
                        .padLeft(2, '0');
 | 
			
		||||
                    final seconds = (duration.inSeconds % 60)
 | 
			
		||||
                        .toString()
 | 
			
		||||
                        .padLeft(2, '0');
 | 
			
		||||
                    return Text(
 | 
			
		||||
                      '$hours:$minutes:$seconds',
 | 
			
		||||
                    ).textColor(Colors.green).fontSize(12);
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          );
 | 
			
		||||
        },
 | 
			
		||||
        loading: () => const SizedBox.shrink(),
 | 
			
		||||
        error: (error, stack) => const SizedBox.shrink(),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return activitiesAsync.when(
 | 
			
		||||
      data:
 | 
			
		||||
          (activities) => Card(
 | 
			
		||||
@@ -206,8 +313,12 @@ class ActivityPresenceWidget extends ConsumerWidget {
 | 
			
		||||
 | 
			
		||||
                              // Check if lease has expired and refresh if needed
 | 
			
		||||
                              if (now.isAfter(activity.leaseExpiresAt)) {
 | 
			
		||||
                                WidgetsBinding.instance.addPostFrameCallback((_) {
 | 
			
		||||
                                  ref.invalidate(presenceActivitiesProvider(uname));
 | 
			
		||||
                                WidgetsBinding.instance.addPostFrameCallback((
 | 
			
		||||
                                  _,
 | 
			
		||||
                                ) {
 | 
			
		||||
                                  ref.invalidate(
 | 
			
		||||
                                    presenceActivitiesProvider(uname),
 | 
			
		||||
                                  );
 | 
			
		||||
                                });
 | 
			
		||||
                              }
 | 
			
		||||
 | 
			
		||||
@@ -238,23 +349,36 @@ class ActivityPresenceWidget extends ConsumerWidget {
 | 
			
		||||
                            Row(
 | 
			
		||||
                              spacing: 8,
 | 
			
		||||
                              children: [
 | 
			
		||||
                                if (activity.titleUrl != null && activity.titleUrl!.isNotEmpty)
 | 
			
		||||
                                if (activity.titleUrl != null &&
 | 
			
		||||
                                    activity.titleUrl!.isNotEmpty)
 | 
			
		||||
                                  ElevatedButton.icon(
 | 
			
		||||
                                    onPressed: () => launchUrlString(activity.titleUrl!),
 | 
			
		||||
                                    onPressed:
 | 
			
		||||
                                        () =>
 | 
			
		||||
                                            launchUrlString(activity.titleUrl!),
 | 
			
		||||
                                    icon: const Icon(Symbols.link, size: 16),
 | 
			
		||||
                                    label: const Text('Open Title Link'),
 | 
			
		||||
                                    style: ElevatedButton.styleFrom(
 | 
			
		||||
                                      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
 | 
			
		||||
                                      padding: const EdgeInsets.symmetric(
 | 
			
		||||
                                        horizontal: 12,
 | 
			
		||||
                                        vertical: 6,
 | 
			
		||||
                                      ),
 | 
			
		||||
                                      textStyle: const TextStyle(fontSize: 12),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
                                if (activity.subtitleUrl != null && activity.subtitleUrl!.isNotEmpty)
 | 
			
		||||
                                if (activity.subtitleUrl != null &&
 | 
			
		||||
                                    activity.subtitleUrl!.isNotEmpty)
 | 
			
		||||
                                  ElevatedButton.icon(
 | 
			
		||||
                                    onPressed: () => launchUrlString(activity.subtitleUrl!),
 | 
			
		||||
                                    onPressed:
 | 
			
		||||
                                        () => launchUrlString(
 | 
			
		||||
                                          activity.subtitleUrl!,
 | 
			
		||||
                                        ),
 | 
			
		||||
                                    icon: const Icon(Symbols.link, size: 16),
 | 
			
		||||
                                    label: const Text('Open Subtitle Link'),
 | 
			
		||||
                                    style: ElevatedButton.styleFrom(
 | 
			
		||||
                                      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
 | 
			
		||||
                                      padding: const EdgeInsets.symmetric(
 | 
			
		||||
                                        horizontal: 12,
 | 
			
		||||
                                        vertical: 6,
 | 
			
		||||
                                      ),
 | 
			
		||||
                                      textStyle: const TextStyle(fontSize: 12),
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user