Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/src/widgets/solid_scaffold.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'package:solidui/src/constants/navigation.dart';
import 'package:solidui/src/handlers/solid_auth_handler.dart';
import 'package:solidui/src/services/solid_security_key_notifier.dart';
import 'package:solidui/src/services/solid_security_key_service.dart';
import 'package:solidui/src/utils/solid_notifications.dart';
Expand Down Expand Up @@ -124,10 +125,18 @@ class SolidScaffold extends StatefulWidget {

final SolidNavUserInfo? userInfo;

/// Optional logout callback.
/// Optional custom logout callback.
/// If null and [showLogout] is true, the built-in
/// [SolidAuthHandler.instance.handleLogout] will be used.

final void Function(BuildContext)? onLogout;

/// Whether to show the logout button.
/// Defaults to true. When true and [onLogout] is null, the built-in
/// [SolidAuthHandler.instance.handleLogout] will be used automatically.

final bool showLogout;

/// Optional alert dialogue callback.

final void Function(BuildContext, String, String?)? onShowAlert;
Expand Down Expand Up @@ -239,6 +248,7 @@ class SolidScaffold extends StatefulWidget {
this.statusBar,
this.userInfo,
this.onLogout,
this.showLogout = true,
this.onShowAlert,
this.narrowScreenThreshold = NavigationConstants.narrowScreenThreshold,
this.backgroundColor,
Expand Down
51 changes: 31 additions & 20 deletions lib/src/widgets/solid_scaffold_appbar_actions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,22 @@ class SolidAppBarActionsManager {
/// Initialises AppBar actions in preferences notifier if empty or missing
/// items. Dynamically handles all buttons from config.actions and
/// config.overflowItems in addition to standard buttons.
///
/// The [hasLogout] parameter indicates whether the application has provided
/// a logout callback. If false, the logout button will not be added to the
/// preferences list.

static void initializeIfNeeded(
SolidAppBarConfig config,
SolidThemeToggleConfig? themeToggle,
) {
SolidThemeToggleConfig? themeToggle, {
bool hasLogout = false,
}) {
// Check if we need to add missing buttons (standard or custom).

final existingActions = solidPreferencesNotifier.appBarActions;
final needsInit = existingActions.isEmpty;
final needsMerge =
!needsInit && _hasMissingButtons(existingActions, config, themeToggle);
final needsMerge = !needsInit &&
_hasMissingButtons(existingActions, config, themeToggle, hasLogout);

if (!needsInit && !needsMerge) return;

Expand Down Expand Up @@ -119,20 +124,22 @@ class SolidAppBarActionsManager {
);
}

// Add Logout button.
// Add Logout button if the application has provided a logout callback.
// Default: show in AppBar.

actionEntries.add(
_ActionEntry(
item: const SolidAppBarActionItem(
id: SolidAppBarActionIds.logout,
label: 'Logout',
icon: Icons.logout,
showInOverflow: false, // Show in AppBar by default.
if (hasLogout) {
actionEntries.add(
_ActionEntry(
item: const SolidAppBarActionItem(
id: SolidAppBarActionIds.logout,
label: 'Logout',
icon: Icons.logout,
showInOverflow: false, // Show in AppBar by default.
),
initialIndex: 300, // Logout button after custom/overflow actions.
),
initialIndex: 300, // Logout button after custom/overflow actions.
),
);
);
}

// Add About button.
// Default: show in AppBar, rightmost position.
Expand Down Expand Up @@ -174,6 +181,7 @@ class SolidAppBarActionsManager {
List<SolidAppBarActionItem> actions,
SolidAppBarConfig config,
SolidThemeToggleConfig? themeToggle,
bool hasLogout,
) {
final existingIds = actions.map((a) => a.id).toSet();

Expand All @@ -200,12 +208,15 @@ class SolidAppBarActionsManager {
expectedIds.add(item.id);
}

// Standard buttons that should always exist.
// Logout button (only if application has provided a logout callback).

if (hasLogout) {
expectedIds.add(SolidAppBarActionIds.logout);
}

// About button should always exist.

expectedIds.addAll([
SolidAppBarActionIds.logout,
SolidAppBarActionIds.about,
]);
expectedIds.add(SolidAppBarActionIds.about);

// Check if any expected ID is missing.

Expand Down
6 changes: 5 additions & 1 deletion lib/src/widgets/solid_scaffold_appbar_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ class SolidScaffoldAppBarBuilder {
bool hideNavRail = false,
void Function(BuildContext)? onLogout,
}) {
SolidAppBarActionsManager.initializeIfNeeded(config, themeToggle);
SolidAppBarActionsManager.initializeIfNeeded(
config,
themeToggle,
hasLogout: onLogout != null,
);

final isWideScreen = !hideNavRail &&
SolidScaffoldHelpers.isWideScreen(
Expand Down
23 changes: 20 additions & 3 deletions lib/src/widgets/solid_scaffold_widget_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ library;

import 'package:flutter/material.dart';

import 'package:solidui/src/handlers/solid_auth_handler.dart';
import 'package:solidui/src/widgets/solid_about_models.dart';
import 'package:solidui/src/widgets/solid_nav_drawer.dart';
import 'package:solidui/src/widgets/solid_nav_models.dart';
Expand All @@ -42,6 +43,18 @@ import 'package:solidui/src/widgets/solid_theme_notifier.dart';
/// Widget builder specifically for SolidScaffold.

class SolidScaffoldWidgetBuilder {
/// Returns the effective logout callback.
/// If [showLogout] is true and [onLogout] is null, returns the built-in
/// [SolidAuthHandler.instance.handleLogout]. Otherwise returns [onLogout].

static void Function(BuildContext)? _getEffectiveLogout(
SolidScaffold widget,
) {
if (!widget.showLogout) return null;
return widget.onLogout ??
(context) => SolidAuthHandler.instance.handleLogout(context);
}

/// Builds a default SolidNavUserInfo from available scaffold configuration.

static SolidNavUserInfo? _buildDefaultUserInfo(
Expand Down Expand Up @@ -82,6 +95,10 @@ class SolidScaffoldWidgetBuilder {
required String Function() getVersionToDisplay,
String? currentWebId,
}) {
// Get the effective logout callback (built-in or custom).

final effectiveLogout = _getEffectiveLogout(widget);

return SolidScaffoldBuildHelper.buildScaffold(
context: context,
scaffoldKey: scaffoldKey,
Expand Down Expand Up @@ -114,7 +131,7 @@ class SolidScaffoldWidgetBuilder {
shouldShowVersion,
getVersionToDisplay,
hideNavRail: widget.hideNavRail,
onLogout: widget.onLogout,
onLogout: effectiveLogout,
),
),
buildDrawer: () {
Expand All @@ -128,8 +145,8 @@ class SolidScaffoldWidgetBuilder {
tabs: SolidScaffoldHelpers.convertToNavTabs(widget.menu),
selectedIndex: currentSelectedIndex,
onTabSelected: onMenuSelected,
onLogout: widget.onLogout,
showLogout: widget.onLogout != null,
onLogout: effectiveLogout,
showLogout: effectiveLogout != null,
);
},
endDrawer: widget.endDrawer,
Expand Down