Skip to content
Snippets Groups Projects
card_name_editable.dart 8.95 KiB
Newer Older
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';

import '../../../g1/api.dart';
import '../../../shared_prefs.dart';
import '../../logger.dart';
import '../../ui_helpers.dart';
import '../connectivity_widget_wrapper_wrapper.dart';
import 'card_text_style.dart';

class CardNameEditable extends StatefulWidget {
  const CardNameEditable({super.key});

  @override
  State<CardNameEditable> createState() => _CardNameEditableState();
}

class _CardNameEditableState extends State<CardNameEditable> {
  bool _isEditingText = false;
vjrj's avatar
vjrj committed
  final TextEditingController _controller = TextEditingController();
  late String currentText;
vjrj's avatar
vjrj committed
  final String defValue = tr('your_name_here');

  final String pubKey = SharedPreferencesHelper().getPubKey();
  String _previousValue = '';
vjrj's avatar
vjrj committed
  bool _isSubmitting = false;

  @override
  void initState() {
    final String localUsername = SharedPreferencesHelper().getName();
    currentText = localUsername.isEmpty ? defValue : localUsername;
vjrj's avatar
vjrj committed
    super.initState();
vjrj's avatar
vjrj committed
  Future<String> _initValue() async {
    final String localUsername = SharedPreferencesHelper().getName();
    final bool isConnected = await ConnectivityWidgetWrapperWrapper.isConnected;
    if (isConnected) {
      try {
        String? name = await getCesiumPlusUser(pubKey);
        logger(
            'currentText: $currentText, localUsername: $localUsername, _previousValue: $_previousValue, retrieved_name: $name');
        if (name != null) {
          name = name.replaceAll(userNameSuffix, '');
          _controller.text = name;
          currentText = name;
          SharedPreferencesHelper().setName(name: name);
        } else {
          _controller.text = '';
          currentText = defValue;
          SharedPreferencesHelper().setName(name: '');
        }
      } catch (e) {
        logger(e);
        _controller.text = localUsername;
        currentText = localUsername;
    } else {
      // not connected, same an on exception
vjrj's avatar
vjrj committed
      _controller.text = localUsername;
      currentText = localUsername;
    }
vjrj's avatar
vjrj committed
    _previousValue = _controller.text;
    _controller.selection = TextSelection.fromPosition(
        TextPosition(offset: _controller.text.length));

    logger(
        'currentText: $currentText, localUsername: $localUsername,  _previousValue: $_previousValue');
vjrj's avatar
vjrj committed
    return currentText;

  @override
  void dispose() {
vjrj's avatar
vjrj committed
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
vjrj's avatar
vjrj committed
    return FutureBuilder<String>(
        future: _initValue(),
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          return _isEditingText
              ? SizedBox(
                  width: 150.0,
                  child: SizedBox(
                      height: 40.0,
                      child: TextField(
                        // focusNode: myFocusNode,
                        decoration: InputDecoration(
                          contentPadding: const EdgeInsets.symmetric(
                              vertical: 5.0, horizontal: 7.0),
                          filled: true,
                          fillColor: Colors.white,
                          enabledBorder: const OutlineInputBorder(
                            borderSide: BorderSide(color: Colors.grey),
vjrj's avatar
vjrj committed
                          focusedBorder: const OutlineInputBorder(
                            borderSide: BorderSide(width: 2.0),
vjrj's avatar
vjrj committed
                          suffix: const Text('$userNameSuffix  '),
                          suffixIcon: _isSubmitting
                              ? const RefreshProgressIndicator()
                              : Row(
                                  mainAxisSize: MainAxisSize.min,
                                  children: <Widget>[
                                    GestureDetector(
                                      onTap: () {
                                        setState(() {
                                          _isEditingText = false;
                                        });
                                      },
                                      child: const Padding(
                                        padding: EdgeInsets.only(right: 8.0),
                                        child: Icon(Icons.cancel_outlined),
                                      ),
                                    ),
                                    GestureDetector(
                                      onTap: () {
                                        _updateValue(_controller.text);
                                      },
                                      child: const Padding(
                                        padding: EdgeInsets.only(right: 8.0),
                                        child: Icon(Icons.check),
                                      ),
                                    ),
                                  ],
                                ),
vjrj's avatar
vjrj committed
                        cursorColor: Colors.black,
                        onSubmitted: _updateValue,
                        enabled: !_isSubmitting,
                        /* onChanged: (String value) {
                          if (value.isEmpty) {
                            _deleteValue();
                          }
                        }, */
                        /*onSubmitted: (String newValue) {
                    updateName(newValue);
                  }, */
vjrj's avatar
vjrj committed
                        // maxLength: 15,
                        autofocus: true,
                        controller: _controller,
                      )))
              : Tooltip(
                  message: tr('your_name_here'),
                  child: InkWell(
                    child: RichText(
                      // softWrap: true,
                      maxLines: 2,
                      overflow: TextOverflow.ellipsis,
                      text: TextSpan(
                        style: DefaultTextStyle.of(context).style,
                        children: <TextSpan>[
                          if (currentText == defValue)
                            TextSpan(
                                text: currentText.toUpperCase(),
                                style: const TextStyle(
                                    fontFamily: 'SourceCodePro',
                                    color: Colors.grey)),
                          if (currentText.isNotEmpty && currentText != defValue)
                            TextSpan(
                                text: currentText,
                                style: cardTextStyle(context, 15)),
                          /*  TextSpan(
              text: ' Lorem ipsum dolor sit amet, consectetur adipiscing elit',
              style: cardTextStyle(context, 15),
            ), */
vjrj's avatar
vjrj committed
                          if (currentText.isNotEmpty && currentText != defValue)
                            TextSpan(
                              text: userNameSuffix,
                              style: cardTextStyle(context, 12),
                            ),
                        ],
vjrj's avatar
vjrj committed
                    ),
                    onTap: () {
                      setState(() {
                        _isEditingText = true;
                      });
                    },
                  ));
        });
  Future<void> _updateValue(String newValue) async {
vjrj's avatar
vjrj committed
    if (newValue.isEmpty) {
      return _deleteValue();
    }
    logger('updating with newValue: $newValue');
    try {
vjrj's avatar
vjrj committed
      setState(() {
        _isSubmitting = true;
      });
      if (_validate(newValue)) {
        await createOrUpdateCesiumPlusUser(newValue);
        setState(() {
          _previousValue = newValue;
vjrj's avatar
vjrj committed
          currentText = newValue;
        });
      } else {
        setState(() {
vjrj's avatar
vjrj committed
          _controller.text = _previousValue;
          currentText = _previousValue.isEmpty ? defValue : _previousValue;
        });
      }
    } catch (e) {
      setState(() {
vjrj's avatar
vjrj committed
        _controller.text = _previousValue;
        currentText = _previousValue.isEmpty ? defValue : _previousValue;
      });
    }
    setState(() {
      _isEditingText = false;
vjrj's avatar
vjrj committed
      _isSubmitting = false;
    });
    logger(
        'currentText: $currentText, newValue: $newValue,  _previousValue: $_previousValue');
  }

  Future<void> _deleteValue() async {
    try {
vjrj's avatar
vjrj committed
      setState(() {
        _isSubmitting = true;
      });
      await deleteCesiumPlusUser();
      SharedPreferencesHelper().setName(name: '');
      setState(() {
vjrj's avatar
vjrj committed
        _controller.text = '';
        currentText = defValue;
      });
    } catch (e) {
      setState(() {
vjrj's avatar
vjrj committed
        _controller.text = _previousValue;
        currentText = _previousValue.isEmpty ? defValue : _previousValue;
      });
    }
    setState(() {
      _isEditingText = false;
vjrj's avatar
vjrj committed
      _isSubmitting = false;
    });
    logger(
        'delete with currentText: $currentText,  _previousValue: $_previousValue');
  }

  bool _validate(String newValue) {
    if (newValue.isEmpty) {
      return false;
    }
    return true;