Skip to content

Refactor: Creating a separate widget for "Save/Update" floating action button in the add_or_update_alarm_view.dart #654

@amaydixit11

Description

@amaydixit11

Description

Problem

  • A few files (like add_or_update_alarm_view.dart) have grown to over 1000 lines of code
  • As discussed with @MarkisDev, this needs modularization for better code organization
  • The floating action button implementation contains business logic mixed with UI code
  • This leads to
    • Reduced code maintainability
    • Harder to test individual components
    • Difficult to reuse components
    • Increased cognitive load for developers
  • The large file size and mixed concerns make the code harder to maintain and understand

Proposed Solution

  1. Extract the floating action button into a separate widget component
  2. Implement proper separation of concerns
  3. Create a clean, reusable Floating Action Button widget

Benefits of This Refactoring

  1. Separation of Concerns

    • UI logic is separated from business logic
    • Button appearance and behavior are encapsulated
    • Permissions checking is handled cleanly
  2. Improved Maintainability

    • Smaller, focused components
    • Clear responsibilities for each class
    • Easier to test individual components
  3. Better Reusability

    • Floating Action Button widget can be reused across the app
    • Consistent styling and behavior
    • Configurable through parameters
  4. Code Organization

    • Reduced file size in main view
    • Better folder structure
    • Clearer component boundaries

Here's the implementation:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:ultimate_alarm_clock/app/utils/constants.dart';
import 'package:ultimate_alarm_clock/app/utils/utils.dart';
import '../controllers/add_or_update_alarm_controller.dart';
import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart';

class SaveOrUpdateFloatingActionButton extends GetView<AddOrUpdateAlarmController> {
  const SaveOrUpdateFloatingActionButton({
    Key? key,
    required this.onSavePressed,
  }) : super(key: key);

  final Future<void> Function() onSavePressed;

  @override
  Widget build(BuildContext context) {
    final themeController = Get.find<ThemeController>();
    final width = MediaQuery.of(context).size.width;
    final height = MediaQuery.of(context).size.height;

    return Obx(
      () => controller.mutexLock.value
          ? const SizedBox()
          : Padding(
              padding: const EdgeInsets.all(18.0),
              child: SizedBox(
                height: height * 0.06,
                width: width * 0.8,
                child: TextButton(
                  style: ButtonStyle(
                    backgroundColor: MaterialStateProperty.all(kprimaryColor),
                  ),
                  onPressed: () async {
                    Utils.hapticFeedback();
                    await _handleButtonPress();
                  },
                  child: Text(
                    _getButtonText(),
                    style: Theme.of(context).textTheme.displaySmall!.copyWith(
                          color: themeController.secondaryTextColor.value,
                        ),
                  ),
                ),
              ),
            ),
    );
  }

  String _getButtonText() {
    return controller.alarmRecord.value.alarmID.isEmpty 
        ? 'Save'.tr 
        : 'Update'.tr;
  }

  Future<void> _handleButtonPress() async {
    await controller.checkOverlayPermissionAndNavigate();

    if (!await _checkRequiredPermissions()) return;

    await onSavePressed();
  }

  Future<bool> _checkRequiredPermissions() async {
    return await Permission.systemAlertWindow.isGranted &&
        await Permission.ignoreBatteryOptimizations.isGranted;
  }
}

Usage in Original File

Replace the existing Floating Action Button code in add_or_update_alarm_view.dart with:

floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: SaveOrUpdateFloatingActionButton(
  onSavePressed: () async {
    if (!controller.homeController.isProfile.value) {
      await _handleAlarmSave();
    } else if (controller.profileTextEditingController.text.isNotEmpty) {
      controller.createProfile();
    }
  },
),

Screenshots

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions