mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-11-03 19:54:12 +00:00 
			
		
		
		
	Start to update general settings
This commit is contained in:
		@@ -1,7 +1,9 @@
 | 
				
			|||||||
import 'dart:io';
 | 
					import 'dart:io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:comunic/enums/user_page_visibility.dart';
 | 
				
			||||||
import 'package:comunic/models/account_image_settings.dart';
 | 
					import 'package:comunic/models/account_image_settings.dart';
 | 
				
			||||||
import 'package:comunic/models/api_request.dart';
 | 
					import 'package:comunic/models/api_request.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/general_settings.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Settings helper
 | 
					/// Settings helper
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
@@ -14,6 +16,54 @@ const _APIAccountImageVisibilityAPILevels = {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SettingsHelper {
 | 
					class SettingsHelper {
 | 
				
			||||||
 | 
					  /// Get & return general user settings
 | 
				
			||||||
 | 
					  static Future<GeneralSettings> getGeneralSettings() async {
 | 
				
			||||||
 | 
					    final response =
 | 
				
			||||||
 | 
					        (await APIRequest(uri: "settings/get_general", needLogin: true).exec())
 | 
				
			||||||
 | 
					            .assertOk()
 | 
				
			||||||
 | 
					            .getObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return GeneralSettings(
 | 
				
			||||||
 | 
					      email: response["email"],
 | 
				
			||||||
 | 
					      firstName: response["firstName"],
 | 
				
			||||||
 | 
					      lastName: response["lastName"],
 | 
				
			||||||
 | 
					      pageVisibility: response["is_open"]
 | 
				
			||||||
 | 
					          ? UserPageVisibility.OPEN
 | 
				
			||||||
 | 
					          : response["is_public"]
 | 
				
			||||||
 | 
					              ? UserPageVisibility.PUBLIC
 | 
				
			||||||
 | 
					              : UserPageVisibility.PRIVATE,
 | 
				
			||||||
 | 
					      allowComments: response["allow_comments"],
 | 
				
			||||||
 | 
					      allowPostsFromFriends: response["allow_posts_from_friends"],
 | 
				
			||||||
 | 
					      allowComunicEmails: response["allow_comunic_mails"],
 | 
				
			||||||
 | 
					      publicFriendsList: response["public_friends_list"],
 | 
				
			||||||
 | 
					      virtualDirectory: response["virtual_directory"],
 | 
				
			||||||
 | 
					      personnalWebsite: response["personnal_website"],
 | 
				
			||||||
 | 
					      publicNote: response["publicNote"],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Apply new general settings
 | 
				
			||||||
 | 
					  static Future<void> updateGeneralSettings(GeneralSettings settings) async {
 | 
				
			||||||
 | 
					    (await APIRequest(uri: "settings/set_general", needLogin: true, args: {
 | 
				
			||||||
 | 
					      "firstName": settings.firstName,
 | 
				
			||||||
 | 
					      "lastName": settings.lastName,
 | 
				
			||||||
 | 
					      "allow_comunic_mails": settings.allowComunicEmails ? "true" : "false",
 | 
				
			||||||
 | 
					      "isPublic": settings.pageVisibility == UserPageVisibility.PUBLIC
 | 
				
			||||||
 | 
					          ? "true"
 | 
				
			||||||
 | 
					          : "false",
 | 
				
			||||||
 | 
					      "isOpen":
 | 
				
			||||||
 | 
					          settings.pageVisibility == UserPageVisibility.OPEN ? "true" : "false",
 | 
				
			||||||
 | 
					      "allowComments": settings.allowComments ? "true" : "false",
 | 
				
			||||||
 | 
					      "allowPostsFromFriends":
 | 
				
			||||||
 | 
					          settings.allowPostsFromFriends ? "true" : "false",
 | 
				
			||||||
 | 
					      "publicFriendsList": settings.publicFriendsList ? "true" : "false",
 | 
				
			||||||
 | 
					      "personnalWebsite": settings.personnalWebsite,
 | 
				
			||||||
 | 
					      "virtualDirectory": settings.virtualDirectory,
 | 
				
			||||||
 | 
					      "publicNote": settings.publicNote,
 | 
				
			||||||
 | 
					    }).exec())
 | 
				
			||||||
 | 
					        .assertOk();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Get & return account image settings
 | 
					  /// Get & return account image settings
 | 
				
			||||||
  static Future<AccountImageSettings> getAccountImageSettings() async {
 | 
					  static Future<AccountImageSettings> getAccountImageSettings() async {
 | 
				
			||||||
    final response =
 | 
					    final response =
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								lib/models/general_settings.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								lib/models/general_settings.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/enums/user_page_visibility.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General settings
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre Hubert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GeneralSettings {
 | 
				
			||||||
 | 
					  final String email;
 | 
				
			||||||
 | 
					  String firstName;
 | 
				
			||||||
 | 
					  String lastName;
 | 
				
			||||||
 | 
					  final UserPageVisibility pageVisibility;
 | 
				
			||||||
 | 
					  final bool allowComments;
 | 
				
			||||||
 | 
					  final bool allowPostsFromFriends;
 | 
				
			||||||
 | 
					  final bool allowComunicEmails;
 | 
				
			||||||
 | 
					  final bool publicFriendsList;
 | 
				
			||||||
 | 
					  final String virtualDirectory;
 | 
				
			||||||
 | 
					  final String personnalWebsite;
 | 
				
			||||||
 | 
					  final String publicNote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GeneralSettings({
 | 
				
			||||||
 | 
					    @required this.email,
 | 
				
			||||||
 | 
					    @required this.firstName,
 | 
				
			||||||
 | 
					    @required this.lastName,
 | 
				
			||||||
 | 
					    @required this.pageVisibility,
 | 
				
			||||||
 | 
					    @required this.allowComments,
 | 
				
			||||||
 | 
					    @required this.allowPostsFromFriends,
 | 
				
			||||||
 | 
					    @required this.allowComunicEmails,
 | 
				
			||||||
 | 
					    @required this.publicFriendsList,
 | 
				
			||||||
 | 
					    @required this.virtualDirectory,
 | 
				
			||||||
 | 
					    @required this.personnalWebsite,
 | 
				
			||||||
 | 
					    @required this.publicNote,
 | 
				
			||||||
 | 
					  })  : assert(email != null),
 | 
				
			||||||
 | 
					        assert(firstName != null),
 | 
				
			||||||
 | 
					        assert(lastName != null),
 | 
				
			||||||
 | 
					        assert(pageVisibility != null),
 | 
				
			||||||
 | 
					        assert(allowComments != null),
 | 
				
			||||||
 | 
					        assert(allowPostsFromFriends != null),
 | 
				
			||||||
 | 
					        assert(allowComunicEmails),
 | 
				
			||||||
 | 
					        assert(publicFriendsList != null),
 | 
				
			||||||
 | 
					        assert(virtualDirectory != null),
 | 
				
			||||||
 | 
					        assert(personnalWebsite != null),
 | 
				
			||||||
 | 
					        assert(publicNote != null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -10,6 +10,7 @@ class SingleInputDialog extends StatefulWidget {
 | 
				
			|||||||
  final String label;
 | 
					  final String label;
 | 
				
			||||||
  final bool Function(String) checkInput;
 | 
					  final bool Function(String) checkInput;
 | 
				
			||||||
  final String errorMessage;
 | 
					  final String errorMessage;
 | 
				
			||||||
 | 
					  final bool canBeEmpty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const SingleInputDialog({
 | 
					  const SingleInputDialog({
 | 
				
			||||||
    Key key,
 | 
					    Key key,
 | 
				
			||||||
@@ -19,8 +20,8 @@ class SingleInputDialog extends StatefulWidget {
 | 
				
			|||||||
    @required this.label,
 | 
					    @required this.label,
 | 
				
			||||||
    @required this.checkInput,
 | 
					    @required this.checkInput,
 | 
				
			||||||
    @required this.errorMessage,
 | 
					    @required this.errorMessage,
 | 
				
			||||||
 | 
					    this.canBeEmpty = false,
 | 
				
			||||||
  })  : assert(title != null),
 | 
					  })  : assert(title != null),
 | 
				
			||||||
        assert(icon != null),
 | 
					 | 
				
			||||||
        assert(label != null),
 | 
					        assert(label != null),
 | 
				
			||||||
        assert(checkInput != null),
 | 
					        assert(checkInput != null),
 | 
				
			||||||
        assert(errorMessage != null),
 | 
					        assert(errorMessage != null),
 | 
				
			||||||
@@ -34,7 +35,8 @@ class __InputURLDialogState extends State<SingleInputDialog> {
 | 
				
			|||||||
  TextEditingController _controller;
 | 
					  TextEditingController _controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool get _isValid =>
 | 
					  bool get _isValid =>
 | 
				
			||||||
      _controller.text.isNotEmpty && widget.checkInput(_controller.text);
 | 
					      (_controller.text.isNotEmpty || widget.canBeEmpty) &&
 | 
				
			||||||
 | 
					      widget.checkInput(_controller.text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
@@ -50,7 +52,7 @@ class __InputURLDialogState extends State<SingleInputDialog> {
 | 
				
			|||||||
        controller: _controller,
 | 
					        controller: _controller,
 | 
				
			||||||
        onChanged: (s) => setState(() {}),
 | 
					        onChanged: (s) => setState(() {}),
 | 
				
			||||||
        decoration: InputDecoration(
 | 
					        decoration: InputDecoration(
 | 
				
			||||||
          icon: Icon(widget.icon),
 | 
					          icon: widget.icon == null ? null : Icon(widget.icon),
 | 
				
			||||||
          alignLabelWithHint: true,
 | 
					          alignLabelWithHint: true,
 | 
				
			||||||
          labelText: widget.label,
 | 
					          labelText: widget.label,
 | 
				
			||||||
          errorText: _controller.text.isNotEmpty && !_isValid
 | 
					          errorText: _controller.text.isNotEmpty && !_isValid
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import 'package:comunic/ui/routes/account_settings/account_image_settings.dart';
 | 
					import 'package:comunic/ui/routes/account_settings/account_image_settings.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/routes/account_settings/general_account_settings.dart';
 | 
				
			||||||
import 'package:comunic/utils/intl_utils.dart';
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:settings_ui/settings_ui.dart';
 | 
					import 'package:settings_ui/settings_ui.dart';
 | 
				
			||||||
@@ -32,6 +33,14 @@ class __AccountSettingsBodyState extends State<_AccountSettingsBody> {
 | 
				
			|||||||
        SettingsSection(
 | 
					        SettingsSection(
 | 
				
			||||||
          title: tr("Account settings"),
 | 
					          title: tr("Account settings"),
 | 
				
			||||||
          tiles: [
 | 
					          tiles: [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SettingsTile(
 | 
				
			||||||
 | 
					              title: tr("General settings"),
 | 
				
			||||||
 | 
					              subtitle: tr("Configure the main settings of your account"),
 | 
				
			||||||
 | 
					              leading: Icon(Icons.settings),
 | 
				
			||||||
 | 
					              onTap: () => _openSection(GeneralAccountSettingsScreen()),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SettingsTile(
 | 
					            SettingsTile(
 | 
				
			||||||
              title: tr("Account image"),
 | 
					              title: tr("Account image"),
 | 
				
			||||||
              subtitle: tr("Customize your account image"),
 | 
					              subtitle: tr("Customize your account image"),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								lib/ui/routes/account_settings/general_account_settings.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								lib/ui/routes/account_settings/general_account_settings.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/helpers/settings_helper.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/models/general_settings.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/async_screen_widget.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/ui/widgets/settings/text_settings_edit_tile.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/account_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/ui_utils.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:settings_ui/settings_ui.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// General account settings
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre HUBERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GeneralAccountSettingsScreen extends StatelessWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Scaffold(
 | 
				
			||||||
 | 
					      appBar: AppBar(
 | 
				
			||||||
 | 
					        title: Text("General settings"),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      body: _GeneralAccountSettingsBody(),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _GeneralAccountSettingsBody extends StatefulWidget {
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  __GeneralAccountSettingsBodyState createState() =>
 | 
				
			||||||
 | 
					      __GeneralAccountSettingsBodyState();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class __GeneralAccountSettingsBodyState
 | 
				
			||||||
 | 
					    extends State<_GeneralAccountSettingsBody> {
 | 
				
			||||||
 | 
					  GeneralSettings _settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final _key = GlobalKey<AsyncScreenWidgetState>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return AsyncScreenWidget(
 | 
				
			||||||
 | 
					        key: _key,
 | 
				
			||||||
 | 
					        onReload: () async =>
 | 
				
			||||||
 | 
					            _settings = await SettingsHelper.getGeneralSettings(),
 | 
				
			||||||
 | 
					        onBuild: _buildSettings,
 | 
				
			||||||
 | 
					        errorMessage: tr("Could not load general settings!"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildSettings() {
 | 
				
			||||||
 | 
					    return SettingsList(
 | 
				
			||||||
 | 
					      sections: [
 | 
				
			||||||
 | 
					        SettingsSection(
 | 
				
			||||||
 | 
					          title: tr("Main account information"),
 | 
				
			||||||
 | 
					          tiles: _mainInformationTiles(),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  List<SettingsTile> _mainInformationTiles() {
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      SettingsTile(
 | 
				
			||||||
 | 
					        title: tr("User ID"),
 | 
				
			||||||
 | 
					        subtitle: "${userID()}",
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      SettingsTile(
 | 
				
			||||||
 | 
					        title: tr("Email address"),
 | 
				
			||||||
 | 
					        subtitle: _settings.email,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // First name
 | 
				
			||||||
 | 
					      TextEditSettingsTile(
 | 
				
			||||||
 | 
					        title: tr("First name"),
 | 
				
			||||||
 | 
					        currValue: _settings.firstName,
 | 
				
			||||||
 | 
					        onChanged: (s) {
 | 
				
			||||||
 | 
					          _settings.firstName = s;
 | 
				
			||||||
 | 
					          _updateSettings();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Last name
 | 
				
			||||||
 | 
					      TextEditSettingsTile(
 | 
				
			||||||
 | 
					        title: tr("Last name"),
 | 
				
			||||||
 | 
					        currValue: _settings.lastName,
 | 
				
			||||||
 | 
					        onChanged: (s) {
 | 
				
			||||||
 | 
					          _settings.lastName = s;
 | 
				
			||||||
 | 
					          _updateSettings();
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Apply new settings
 | 
				
			||||||
 | 
					  Future<void> _updateSettings() async {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      await SettingsHelper.updateGeneralSettings(_settings);
 | 
				
			||||||
 | 
					    } catch (e, stack) {
 | 
				
			||||||
 | 
					      print("Error while updating settings! $e/n$stack");
 | 
				
			||||||
 | 
					      showSimpleSnack(context, tr("Could not update general settings!"));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _key.currentState.refresh();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										60
									
								
								lib/ui/widgets/settings/text_settings_edit_tile.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								lib/ui/widgets/settings/text_settings_edit_tile.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					import 'package:comunic/ui/dialogs/single_input_dialog.dart';
 | 
				
			||||||
 | 
					import 'package:comunic/utils/intl_utils.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:settings_ui/settings_ui.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Text edit settings tile
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @author Pierre HUBERT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool _defaultCheck(String s) => s.isNotEmpty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TextEditSettingsTile extends SettingsTile {
 | 
				
			||||||
 | 
					  final String title;
 | 
				
			||||||
 | 
					  final String currValue;
 | 
				
			||||||
 | 
					  final void Function(String) onChanged;
 | 
				
			||||||
 | 
					  final bool Function(String) checkInput;
 | 
				
			||||||
 | 
					  final bool allowEmptyValues;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool get readOnly => onChanged == null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const TextEditSettingsTile({
 | 
				
			||||||
 | 
					    Key key,
 | 
				
			||||||
 | 
					    @required this.title,
 | 
				
			||||||
 | 
					    @required this.currValue,
 | 
				
			||||||
 | 
					    @required this.onChanged,
 | 
				
			||||||
 | 
					    this.checkInput = _defaultCheck,
 | 
				
			||||||
 | 
					    this.allowEmptyValues = false,
 | 
				
			||||||
 | 
					  })  : assert(title != null),
 | 
				
			||||||
 | 
					        assert(currValue != null),
 | 
				
			||||||
 | 
					        assert(checkInput != null),
 | 
				
			||||||
 | 
					        assert(allowEmptyValues != null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return SettingsTile(
 | 
				
			||||||
 | 
					      title: title,
 | 
				
			||||||
 | 
					      subtitle: currValue,
 | 
				
			||||||
 | 
					      onTap: readOnly ? null : () => _changeValue(context),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void _changeValue(BuildContext context) async {
 | 
				
			||||||
 | 
					    final value = await showDialog<String>(
 | 
				
			||||||
 | 
					      context: context,
 | 
				
			||||||
 | 
					      builder: (b) => SingleInputDialog(
 | 
				
			||||||
 | 
					        title: title,
 | 
				
			||||||
 | 
					        icon: null,
 | 
				
			||||||
 | 
					        initialValue: currValue,
 | 
				
			||||||
 | 
					        label: title,
 | 
				
			||||||
 | 
					        checkInput: checkInput,
 | 
				
			||||||
 | 
					        errorMessage: tr("Invalid value!"),
 | 
				
			||||||
 | 
					        canBeEmpty: allowEmptyValues,
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (value == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    onChanged(value);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user