Skip to content

Settings panel#73

Merged
mateobelanger merged 38 commits intomasterfrom
mobile/app-user-settings
Nov 22, 2020
Merged

Settings panel#73
mateobelanger merged 38 commits intomasterfrom
mobile/app-user-settings

Conversation

@mateobelanger
Copy link
Copy Markdown
Contributor

@mateobelanger mateobelanger commented Nov 10, 2020

  • Added settings tab to navdrawer
  • Persistent settings with streamed_shared_preferences package (previously added by Mourad)
  • Cute UI blocks with settings_ui package
  • Added Age, Sex and AcquisitionBoard settings
  • 'Not Set' values when app is initially launched
  • Settings widget can be added to Record 'Sleep sequence' when a value has not been setted.

Misc

  • Changed sliverbar backgound, I think it's nice
  • Changed the app logo to new dodo

rsz_1124755560_838718470216463_4549644917938712101_n
rsz_124919687_426030165220498_1733611947004864712_n
rsz_124829334_2786706181587668_7741060750976301390_n_1

Comment thread mobile/lib/src/domain/settings/acquisition_board.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/presentation/pages/settings/settings_page.dart
Comment thread mobile/lib/src/presentation/pages/settings/settings_page.dart Outdated
Copy link
Copy Markdown
Contributor

@MouradLachhab MouradLachhab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice. The only other thing is that when I started checking how to dynamically change between Bluetooth and USB repository, I looked into streaming_shared_preferences that extends shared_preferences. So unless we go for the solution where we automatically connect to the device instead of selecting it, we might have to swap for that to do dynamic changes. It allows you to subscribe to preferences and be notified of changes. They are very similar and changes should be minimal.

Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart
Comment thread mobile/lib/src/presentation/pages/settings/settings_page.dart
mateobelanger and others added 8 commits November 10, 2020 13:46
Co-authored-by: Anes Belfodil <abelfodil@users.noreply.github.com>
Co-authored-by: Anes Belfodil <abelfodil@users.noreply.github.com>
Co-authored-by: Anes Belfodil <abelfodil@users.noreply.github.com>
Co-authored-by: Anes Belfodil <abelfodil@users.noreply.github.com>
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/application/settings/settings_cubit.dart
@WilliamHarvey97
Copy link
Copy Markdown
Contributor

such wow! good job!

@mateobelanger
Copy link
Copy Markdown
Contributor Author

Je n'aime pas du tout le widget pour la sélection du board d'acquisition? Qu'est-ce que vous diriez d'utiliser des radio buttons dans un modal? J'ai déjà fait un widget pour ça:

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class RadioButtonItem {
  final Widget title;
  final dynamic value;

  RadioButtonItem({@required this.title, @required this.value});
}

class RadioButtonsDialog<T> extends HookWidget {
  final Widget title;
  final List<RadioButtonItem> radioButtonItems;
  final T initialValue;
  final String cancelLabel;
  final String confirmLabel;
  final void Function(T) onConfirm;

  RadioButtonsDialog({
    Key key,
    this.title,
    @required this.radioButtonItems,
    @required this.initialValue,
    @required this.cancelLabel,
    @required this.confirmLabel,
    @required this.onConfirm,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final selection = useState(initialValue);
    return AlertDialog(
      title: title,
      contentPadding: EdgeInsets.symmetric(vertical: 8),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ...radioButtonItems.map(
            (e) => RadioListTile(
              title: e.title,
              value: e.value,
              groupValue: selection.value,
              onChanged: (value) => selection.value = value,
            ),
          )
        ],
      ),
      actions: <Widget>[
        FlatButton(
          child: Text(cancelLabel.toUpperCase()),
          onPressed: () {
            Navigator.of(context).pop(false);
          },
        ),
        FlatButton(
          child: Text(
            confirmLabel.toUpperCase(),
            style: TextStyle(
              color: Theme.of(context).accentColor,
            ),
          ),
          onPressed: () {
            onConfirm(selection.value);
            Navigator.of(context).pop(true);
          },
        ),
      ],
    );
  }
}

(Ici je juge que c'est une bonne chose d'avoir un state local au widget, car c'est uniquement un state de présentation et non pas un state d'application. Par contre, il faudra sauvegarder la carte sélectionnné dans un bloc)

j'ai enlevé l'option du board d'acquisition parce que c'était plus nécessaire

@WilliamHarvey97
Copy link
Copy Markdown
Contributor

WilliamHarvey97 commented Nov 13, 2020

j'ai enlevé l'option du board d'acquisition parce que c'était plus nécessaire

Pour le sexe alors? Aussi, si c'est le genre de widget que tu aimes j'aurais aussi un NumberInputDialog

Comment thread mobile/lib/src/presentation/pages/settings/settings_page.dart Outdated
@mateobelanger
Copy link
Copy Markdown
Contributor Author

Je n'aime pas du tout le widget pour la sélection du board d'acquisition? Qu'est-ce que vous diriez d'utiliser des radio buttons dans un modal? J'ai déjà fait un widget pour ça:

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

class RadioButtonItem {
  final Widget title;
  final dynamic value;

  RadioButtonItem({@required this.title, @required this.value});
}

class RadioButtonsDialog<T> extends HookWidget {
  final Widget title;
  final List<RadioButtonItem> radioButtonItems;
  final T initialValue;
  final String cancelLabel;
  final String confirmLabel;
  final void Function(T) onConfirm;

  RadioButtonsDialog({
    Key key,
    this.title,
    @required this.radioButtonItems,
    @required this.initialValue,
    @required this.cancelLabel,
    @required this.confirmLabel,
    @required this.onConfirm,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final selection = useState(initialValue);
    return AlertDialog(
      title: title,
      contentPadding: EdgeInsets.symmetric(vertical: 8),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ...radioButtonItems.map(
            (e) => RadioListTile(
              title: e.title,
              value: e.value,
              groupValue: selection.value,
              onChanged: (value) => selection.value = value,
            ),
          )
        ],
      ),
      actions: <Widget>[
        FlatButton(
          child: Text(cancelLabel.toUpperCase()),
          onPressed: () {
            Navigator.of(context).pop(false);
          },
        ),
        FlatButton(
          child: Text(
            confirmLabel.toUpperCase(),
            style: TextStyle(
              color: Theme.of(context).accentColor,
            ),
          ),
          onPressed: () {
            onConfirm(selection.value);
            Navigator.of(context).pop(true);
          },
        ),
      ],
    );
  }
}

(Ici je juge que c'est une bonne chose d'avoir un state local au widget, car c'est uniquement un state de présentation et non pas un state d'application. Par contre, il faudra sauvegarder la carte sélectionnné dans un bloc)

j'ai enlevé l'option du board d'acquisition parce que c'était plus nécessaire

j'ai enlevé l'option du board d'acquisition parce que c'était plus nécessaire
pour le widget de sélection dropdown. J'me suis inspiré des settings de Spotify. C'est purement une préférence subjective d'ergonomie. J'trouve ça moins intrusif.

Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated
Comment thread mobile/lib/src/domain/settings/settings.dart Outdated
@mateobelanger mateobelanger force-pushed the mobile/app-user-settings branch from 1e213f2 to 3f665f9 Compare November 21, 2020 09:09
Comment thread mobile/lib/src/domain/settings/i_settings_repository.dart Outdated
Comment thread mobile/lib/src/infrastructure/settings_repository/settings_repository.dart Outdated
Comment thread mobile/lib/src/domain/settings/settings.dart Outdated
Comment thread mobile/lib/src/locator.dart
Comment thread mobile/lib/src/application/settings/settings_cubit.dart Outdated

Settings(
{this.age = 30, this.serverAddress = '0.0.0.0', this.sex = Sex.NotSet})
: assert(age != null || (age == null && age > 12 && age < 125)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use contants like MAX_AGE, MIN_AGE.

Maybe use a factory constructor so you can throw custom exceptions that you could handle in the future, in place of assert statements.

@mateobelanger mateobelanger merged commit 8b0036b into master Nov 22, 2020
@mateobelanger mateobelanger deleted the mobile/app-user-settings branch November 22, 2020 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants