feat: use image as activity background

- add switch tile in settings to toggle
- if set, remove image from activity summary widget
This commit is contained in:
Ava Shilling 2026-01-23 17:17:05 -05:00
parent 902428f8e6
commit 0aa9e8be58
7 changed files with 80 additions and 14 deletions

View file

@ -145,6 +145,7 @@ abstract class AppConfig {
static bool sendPublicReadReceipts = true;
static bool swipeRightToLeftToReply = true;
static bool? sendOnEnter;
static bool useActivityImageAsChatBackground = true;
static bool showPresences = true;
// #Pangea
// static bool displayNavigationRail = false;

View file

@ -35,6 +35,8 @@ abstract class SettingKeys {
static const String displayNavigationRail =
'chat.fluffy.display_navigation_rail';
// #Pangea
static const String useActivityImageAsChatBackground =
'pangea.use_activity_image_as_chat_background';
static const String volume = 'pangea.volume';
static const String showedActivityMenu =
'pangea.showed_activity_menu_tutorial';

View file

@ -5070,5 +5070,6 @@
},
"findCourse": "Find a course",
"publicInviteDescChat": "Search for users to invite them to this chat.",
"publicInviteDescSpace": "Search for users to invite them to this space."
"publicInviteDescSpace": "Search for users to invite them to this space.",
"useActivityImageAsChatBackground": "Use activity image as chat background"
}

View file

@ -6,6 +6,7 @@ import 'package:badges/badges.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pages/chat/chat.dart';
@ -24,6 +25,7 @@ import 'package:fluffychat/pangea/analytics_misc/level_up/star_rain_widget.dart'
import 'package:fluffychat/pangea/chat/widgets/chat_floating_action_button.dart';
import 'package:fluffychat/pangea/chat/widgets/chat_input_bar.dart';
import 'package:fluffychat/pangea/chat/widgets/chat_view_background.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/navigation/navigation_util.dart';
import 'package:fluffychat/utils/account_config.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
@ -357,7 +359,52 @@ class ChatView extends StatelessWidget {
child: Stack(
// Pangea#
children: <Widget>[
if (accountConfig.wallpaperUrl != null)
// Only use activity image as chat background if enabled in AppConfig
if (controller.room.activityPlan != null &&
controller.room.activityPlan!.imageURL != null &&
AppConfig.useActivityImageAsChatBackground)
Opacity(
opacity: 0.25,
child: ImageFiltered(
imageFilter: ui.ImageFilter.blur(
sigmaX: accountConfig.wallpaperBlur ?? 0.0,
sigmaY: accountConfig.wallpaperBlur ?? 0.0,
),
child: controller.room.activityPlan!.imageURL!
.toString()
.startsWith('mxc')
? MxcImage(
uri: controller.room.activityPlan!.imageURL!,
fit: BoxFit.cover,
height: MediaQuery.sizeOf(context).height,
width: MediaQuery.sizeOf(context).width,
cacheKey: controller
.room.activityPlan!.imageURL
.toString(),
isThumbnail: false,
)
: Image.network(
controller.room.activityPlan!.imageURL
.toString(),
fit: BoxFit.cover,
height: MediaQuery.sizeOf(context).height,
width: MediaQuery.sizeOf(context).width,
headers: controller
.room.activityPlan!.imageURL
.toString()
.contains(Environment.cmsApi)
? {
'Authorization':
'Bearer ${MatrixState.pangeaController.userController.accessToken}',
}
: null,
errorBuilder: (context, error, stackTrace) =>
Container(),
),
),
)
// If not enabled, fall through to default wallpaper logic
else if (accountConfig.wallpaperUrl != null)
Opacity(
opacity: accountConfig.wallpaperOpacity ?? 0.5,
child: ImageFiltered(

View file

@ -144,6 +144,7 @@ class Message extends StatelessWidget {
valueListenable: controller.activityController.showInstructions,
builder: (context, show, __) {
return ActivitySummary(
inChat: true,
activity: event.room.activityPlan!,
room: event.room,
assignedRoles: event.room.hasArchivedActivity

View file

@ -78,6 +78,14 @@ class SettingsChatView extends StatelessWidget {
storeKey: SettingKeys.swipeRightToLeftToReply,
defaultValue: AppConfig.swipeRightToLeftToReply,
),
SettingsSwitchListTile.adaptive(
title: L10n.of(context).useActivityImageAsChatBackground,
onChanged: (b) =>
AppConfig.useActivityImageAsChatBackground = b,
storeKey: SettingKeys.useActivityImageAsChatBackground,
defaultValue: AppConfig.useActivityImageAsChatBackground,
),
// #Pangea
// Divider(color: theme.dividerColor),
// ListTile(

View file

@ -9,6 +9,7 @@ import 'package:material_symbols_icons/symbols.dart';
import 'package:matrix/matrix.dart';
import 'package:matrix/src/utils/markdown.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
@ -35,6 +36,8 @@ class ActivitySummary extends StatelessWidget {
final ValueNotifier<Set<String>>? usedVocab;
final bool inChat;
const ActivitySummary({
super.key,
required this.activity,
@ -49,6 +52,7 @@ class ActivitySummary extends StatelessWidget {
this.getParticipantOpacity,
this.room,
this.course,
this.inChat = false,
});
@override
@ -63,18 +67,20 @@ class ActivitySummary extends StatelessWidget {
child: Column(
spacing: 4.0,
children: [
LayoutBuilder(
builder: (context, constraints) {
return ImageByUrl(
imageUrl: activity.imageURL,
width: min(
constraints.maxWidth,
MediaQuery.sizeOf(context).height * 0.5,
),
borderRadius: BorderRadius.circular(20),
);
},
),
(!inChat || !AppConfig.useActivityImageAsChatBackground)
? LayoutBuilder(
builder: (context, constraints) {
return ImageByUrl(
imageUrl: activity.imageURL,
width: min(
constraints.maxWidth,
MediaQuery.sizeOf(context).height * 0.5,
),
borderRadius: BorderRadius.circular(20),
);
},
)
: const SizedBox.shrink(),
ActivityParticipantList(
activity: activity,
room: room,