Условное отображение, основанное на значении состояния «Провайдер» - PullRequest
0 голосов
/ 01 мая 2020
  1. Флаттер 1.12.13 + исправление.9
  2. Дарт 2.7.2
  3. Пакет провайдера: ^ 4.0.5

Проблема заключается в домашний экран загружается неправильно. У меня есть AuthProvider класс, который расширен ChangeNotifier

в AuthProvider класс У меня есть логин метод, который получает JSON данных из API и после ответа я обновляю свойство _token и затем вызываю notifyListeners ()

main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import './providers/auth_provider.dart';

import './screens/login_screen.dart';
import './screens/translation_screen.dart';
import './screens/registration_screen.dart';
import './screens/welcome_screen.dart';

void main() => runApp(TranslationApp());

class TranslationApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: AuthProvider(),
        ),
      ],
      child: Consumer<AuthProvider>(
        builder: (context, auth, _) => MaterialApp(
          title: 'Translation App',
          theme: ThemeData(
            primarySwatch: Colors.purple,
            accentColor: Colors.deepOrange,
            fontFamily: 'Lato',
          ),
          home: auth.isAuth ? TranslationScreen() : WelcomeScreen(),
          routes: {
            WelcomeScreen.routeName: (context) => WelcomeScreen(),
            RegistrationScreen.routeName: (context) => RegistrationScreen(),
            LoginScreen.routeName: (context) => LoginScreen(),
            TranslationScreen.routeName: (context) => TranslationScreen(),
          },
        ),
      ),
    );
  }
}

login_screen.dart

import 'package:flutter/material.dart';

import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:provider/provider.dart';

import '../providers/auth_provider.dart';

import '../widgets/rounded_button.dart';

import '../constants.dart';

class LoginScreen extends StatefulWidget {
  static const String routeName = '/login';

  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  bool _showSpinner = false;
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  Map<String, String> _authData = {
    'email': '',
    'password': '',
  };

  TextEditingController _emailController = TextEditingController();
  TextEditingController _passwordController = TextEditingController();

  Future<void> _submitForm() async {
    if (!_formKey.currentState.validate()) {
      return;
    }
    _formKey.currentState.save();

    setState(() {
      _showSpinner = true;
    });

    try {
      await Provider.of<AuthProvider>(
        context,
        listen: false,
      ).login(
        _authData['email'],
        _authData['password'],
      );
    } catch (error) {
      print(error);
    }

    setState(() {
      _showSpinner = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: ModalProgressHUD(
        inAsyncCall: _showSpinner,
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 24.0),
          child: Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                Hero(
                  tag: 'logo',
                  child: Container(
                    child: Image.asset('assets/images/logo.png'),
                    height: 200.0,
                    width: MediaQuery.of(context).size.height * .09,
                  ),
                ),
                SizedBox(
                  height: 48.0,
                ),
                TextFormField(
                  textAlign: TextAlign.center,
                  keyboardType: TextInputType.emailAddress,
                  controller: _emailController,
                  validator: (value) {
                    if (value.isEmpty ||
                        !value.contains('@') ||
                        !value.contains('.')) {
                      return 'Email field is not correct';
                    }
                    return null;
                  },
                  onSaved: (value) {
                    _authData['email'] = value;
                  },
                  decoration: kTextFieldDecoration.copyWith(
                    hintText: 'Enter your email',
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextFormField(
                  textAlign: TextAlign.center,
                  obscureText: true,
                  controller: _passwordController,
                  validator: (value) {
                    if (value.isEmpty || value.length < 6) {
                      return 'Password field is not correct';
                    }
                    return null;
                  },
                  onSaved: (value) {
                    _authData['password'] = value;
                  },
                  decoration: kTextFieldDecoration.copyWith(
                    hintText: 'Enter your password',
                  ),
                ),
                SizedBox(
                  height: 24.0,
                ),
                RoundedButton(
                  text: 'Log In',
                  color: Colors.purple,
                  onPressed: _submitForm,
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

auth_provider.dart

import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';

import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;

class AuthProvider extends ChangeNotifier {
  String _token;
  int _id;
  String _email;
  bool _isAdmin;

  String get token {
    return _token;
  }

  int get id {
    return _id;
  }

  String get email {
    return _email;
  }

  bool get isAdmin {
    return _isAdmin;
  }

  bool get isAuth {
    return _token != null;
  }

  Future<void> login(String email, String password) async {
    final String url = 'http://localhost:8000/api/mobile/auth/login';
    try {
      final http.Response response = await http.post(
        url,
        body: {
          'email': email,
          'password': password,
          'device_name': 'apple',
        },
      );

      if (response.statusCode != 200) {
        throw HttpException('An error occored ${response.statusCode}');
      }

      final user = json.decode(response.body);
      _token = user['data']['token'];
      notifyListeners();

      final prefs = await SharedPreferences.getInstance();
      final userData = json.encode({'token': _token});
      prefs.setString('userData', userData);
    } catch (exception) {
      throw exception;
    }
  }

  Future<void> logout() async {}

  Future<void> register() async {
    final String url = 'http://127.0.0.1:8000/api/mobile/auth/registration';
    try {
      final http.Response response = await http.post(url);

      if (response.statusCode == 200) {
        final data = json.decode(response.body);
        _id = data['id'];
        _email = data['email'];

        final SharedPreferences sharedPreferences =
            await SharedPreferences.getInstance();
        final userData = json.encode({
          'id': _id,
          'email': _email,
        });
        sharedPreferences.setString('userData', userData);
      } else {
        throw HttpException('Auth Provider Post method error!');
      }
    } catch (exception) {
      throw exception;
    }
  }
}

...