Why is my LoginPage not working and stuck on the loading screen?

44 Views Asked by At

So i wrote this code for Dart, and it's not working, it is stuck on the loading screen while trying to load the LoginPage. everything else seems to work if not for that loginpage, and it's really annying me cause its been over a month since i've started learning flutter and can't diagnose the problem.

i've now edited the code to add a pin function, and it's still stuck on the loading screen

import 'dart:convert';
import 'dart:io';
import 'package:vault/login_page.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class PasswordData {
  final String website;
  final String username;
  final String password;

  PasswordData(this.website, this.username, this.password);

  Map<String, dynamic> toJson() {
    return {
      'website': website,
      'username': username,
      'password': password,
    };
  }

  factory PasswordData.fromJson(Map<String, dynamic> json) {
    return PasswordData(
      json['website'],
      json['username'],
      json['password'],
    );
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isLoggedIn = false;
  bool _hasPin = false;
  String _pin = '';

  void _handleLogin(String pin) {
    setState(() {
      _isLoggedIn = true;
      _hasPin = true;
      _pin = pin;
    });
  }

  @override
  void initState() {
    super.initState();
    _loadPin();
  }

  Future<void> _loadPin() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      _hasPin = prefs.getBool('hasPin') ?? false;
      _pin = prefs.getString('pin') ?? '';
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ... (Theme and other configurations)
      home: DefaultTabController(
        length: 4,
        child: Scaffold(
          appBar: AppBar(
            // ... (AppBar configuration)
          ),
          body: TabBarView(
            children: [
              Tab1Content(
                isLoggedIn: _isLoggedIn,
                onLogin: _handleLogin,
                hasPin: _hasPin,
                pin: _pin,
              ),
              Tab2Content(),
              Tab3Content(),
              Tab4Content(),
            ],
          ),
        ),
      ),
    );
  }
}

class Tab1Content extends StatefulWidget {
  final bool isLoggedIn;
  final void Function(String) onLogin;
  final bool hasPin;
  final String pin;

  Tab1Content({
    required this.isLoggedIn,
    required this.onLogin,
    required this.hasPin,
    required this.pin,
  });

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

class _Tab1ContentState extends State<Tab1Content> {
  final _formKey = GlobalKey<FormState>();
  final _websiteController = TextEditingController();
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  List<PasswordData> _passwords = [];

  Future<void> _addPassword() async {
    if (_formKey.currentState!.validate()) {
      final passwordData = PasswordData(
        _websiteController.text,
        _usernameController.text,
        _passwordController.text,
      );
      await _savePassword(passwordData);
      setState(() {
        _passwords.add(passwordData);
        _websiteController.clear();
        _usernameController.clear();
        _passwordController.clear();
      });
    }
  }

  Future<void> _deletePassword(int index) async {
    setState(() {
      _passwords.removeAt(index);
    });
    await _savePasswordsToSharedPreferences();
  }

  Future<void> _savePasswordsToSharedPreferences() async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsList =
    _passwords.map((password) => password.toJson()).toList();
    await prefs.setString('passwords', json.encode(passwordsList));
  }

  Future<void> _savePassword(PasswordData passwordData) async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsJson = prefs.getString('passwords') ?? '[]';
    final passwordsList =
    List<Map<String, dynamic>>.from(json.decode(passwordsJson));
    passwordsList.add(passwordData.toJson());
    await prefs.setString('passwords', json.encode(passwordsList));
  }

  @override
  Widget build(BuildContext context) {
    if (!widget.isLoggedIn) {
      return Center(
        child: CircularProgressIndicator(),
      );
    } else {
      return Column(
        children: [
          Form(
            key: _formKey,
            child: Column(
              children: [
                TextFormField(
                  controller: _websiteController,
                  decoration: InputDecoration(labelText: 'Website/Platform'),
                  validator: (value) {
                    if (value?.isEmpty ?? true) {
                      return 'Please enter the website/platform';
                    }
                    return null;
                  },
                ),
                // ... (similar input fields for username and password)
                ElevatedButton(
                  onPressed: _addPassword,
                  child: Text('Save Password'),
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _passwords.length,
              itemBuilder: (context, index) {
                final password = _passwords[index];
                return ListTile(
                  title: Text(password.website),
                  subtitle: Text('Username: ${password.username}'),
                  trailing: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      IconButton(
                        onPressed: () {},
                        icon: Icon(Icons.copy),
                      ),
                      IconButton(
                        onPressed: () {
                          _deletePassword(index);
                        },
                        icon: Icon(Icons.delete),
                      ),
                    ],
                  ),
                );
              },
            ),
          ),
        ],
      );
    }
  }

// ... (other methods, such as _deletePassword, _savePasswordsToSharedPreferences, etc.)
}


  Future<void> _savePassword(PasswordData passwordData) async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsJson = prefs.getString('passwords') ?? '[]';
    final passwordsList =
    List<Map<String, dynamic>>.from(json.decode(passwordsJson));
    passwordsList.add(passwordData.toJson());
    await prefs.setString('passwords', json.encode(passwordsList));
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }



class Tab2Content extends StatefulWidget {
  @override
  _Tab2ContentState createState() => _Tab2ContentState();
}

class _Tab2ContentState extends State<Tab2Content> {
  List<File> _images = [];

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }

// ... (rest of the code remains the same)
}

class Tab3Content extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Tab 3');
  }
}

class Tab4Content extends StatefulWidget {
  @override
  State<Tab4Content> createState() => _Tab4ContentState();
}

class _Tab4ContentState extends State<Tab4Content> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

(https://i.stack.imgur.com/srJUR.png)

1

There are 1 best solutions below

3
Sagar Acharya On

From the code that you have pasted, I see you have a My App class that has parameter and the function _handleLogin now the thing is you have 4 tab controllers in which you are passing the data to the Tab1Content.

 Tab1Content(_isLoggedIn, _handleLogin),

But the reason for your Tab1content to be in loading state is because the _isLoggedIn never became true it is always false. I see you have a function that makes it true but it was never called. I have made some modifications in the code which you provided.

I have checked in the initState function if logged in then moving to login page.

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

import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class PasswordData {
  final String website;
  final String username;
  final String password;

  PasswordData(this.website, this.username, this.password);

  Map<String, dynamic> toJson() {
    return {
      'website': website,
      'username': username,
      'password': password,
    };
  }

  factory PasswordData.fromJson(Map<String, dynamic> json) {
    return PasswordData(
      json['website'],
      json['username'],
      json['password'],
    );
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isLoggedIn = false;

  void _handleLogin() {
    setState(() {
      _isLoggedIn = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ... (Theme and other configurations)
      home: DefaultTabController(
        length: 4,
        child: Scaffold(
          appBar: AppBar(
              // ... (AppBar configuration)
              ),
          body: TabBarView(
            children: [
              Tab1Content(_isLoggedIn, _handleLogin),
              Tab2Content(),
              Tab3Content(),
              Tab4Content(),
            ],
          ),
        ),
      ),
    );
  }
}

class Tab1Content extends StatefulWidget {
  final bool isLoggedIn;
  final VoidCallback onLogin;

  Tab1Content(this.isLoggedIn, this.onLogin);

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

class _Tab1ContentState extends State<Tab1Content> {
  final _formKey = GlobalKey<FormState>();
  final _websiteController = TextEditingController();
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  List<PasswordData> _passwords = [];

  Future<void> _addPassword() async {
    if (_formKey.currentState!.validate()) {
      final passwordData = PasswordData(
        _websiteController.text,
        _usernameController.text,
        _passwordController.text,
      );
      await _savePassword(passwordData);
      setState(() {
        _passwords.add(passwordData);
        _websiteController.clear();
        _usernameController.clear();
        _passwordController.clear();
      });
    }
  }

  Future<void> _savePassword(PasswordData passwordData) async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsJson = prefs.getString('passwords') ?? '[]';
    final passwordsList =
        List<Map<String, dynamic>>.from(json.decode(passwordsJson));
    passwordsList.add(passwordData.toJson());
    await prefs.setString('passwords', json.encode(passwordsList));
  }

  Future<void> _loadPasswords() async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsJson = prefs.getString('passwords') ?? '[]';
    final passwordsList =
        List<Map<String, dynamic>>.from(json.decode(passwordsJson));

    final loadedPasswords = passwordsList
        .map((password) => PasswordData.fromJson(password))
        .toList();

    setState(() {
      _passwords = loadedPasswords;
    });
  }

  Future<void> _deletePassword(int index) async {
    setState(() {
      _passwords.removeAt(index);
    });
    await _savePasswordsToSharedPreferences();
  }

  Future<void> _savePasswordsToSharedPreferences() async {
    final prefs = await SharedPreferences.getInstance();
    final passwordsList =
        _passwords.map((password) => password.toJson()).toList();
    await prefs.setString('passwords', json.encode(passwordsList));
  }

  @override
  void initState() {
    super.initState();
    /// New changes made
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!widget.isLoggedIn) {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => LoginPage(onLogin: widget.onLogin)));
      }
    });

    _loadPasswords();
  }

  @override
  Widget build(BuildContext context) {
    if (!widget.isLoggedIn) {
      return Center(
        child: CircularProgressIndicator(),
      );
    }
    return Column(
      children: [
        Form(
          key: _formKey,
          child: Column(
            children: [
              TextFormField(
                controller: _websiteController,
                decoration: InputDecoration(labelText: 'Website/Platform'),
                validator: (value) {
                  if (value?.isEmpty ?? true) {
                    return 'Please enter the website/platform';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: _usernameController,
                decoration: InputDecoration(labelText: 'Username'),
                validator: (value) {
                  if (value?.isEmpty ?? true) {
                    return 'Please enter the username';
                  }
                  return null;
                },
              ),
              TextFormField(
                controller: _passwordController,
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
                validator: (value) {
                  if (value?.isEmpty ?? true) {
                    return 'Please enter the password';
                  }
                  return null;
                },
              ),
              ElevatedButton(
                onPressed: _addPassword,
                child: Text('Save Password'),
              ),
            ],
          ),
        ),
        Expanded(
          child: ListView.builder(
            itemCount: _passwords.length,
            itemBuilder: (context, index) {
              final password = _passwords[index];
              return ListTile(
                title: Text(password.website),
                subtitle: Text('Username: ${password.username}'),
                trailing: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    IconButton(
                      onPressed: () {},
                      icon: Icon(Icons.copy),
                    ),
                    IconButton(
                      onPressed: () {
                        _deletePassword(index);
                      },
                      icon: Icon(Icons.delete),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

class Tab2Content extends StatefulWidget {
  @override
  _Tab2ContentState createState() => _Tab2ContentState();
}

class _Tab2ContentState extends State<Tab2Content> {
  List<File> _images = [];

  Future<void> _pickImages() async {
    final List<XFile> selectedImages = await ImagePicker().pickMultiImage();
    if (selectedImages != null && selectedImages.isNotEmpty) {
      setState(() {
        _images
            .addAll(selectedImages.map((pickedFile) => File(pickedFile.path)));
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: _pickImages,
          child: Text('Pick Images'),
        ),
        Expanded(
          child: GridView.builder(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
            ),
            itemCount: _images.length,
            itemBuilder: (BuildContext context, int index) {
              return Image.file(
                _images[index],
                fit: BoxFit.cover,
              );
            },
          ),
        ),
      ],
    );
  }
}

class Tab3Content extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Tab 3');
  }
}

class Tab4Content extends StatefulWidget {
  @override
  State<Tab4Content> createState() => _Tab4ContentState();
}

class _Tab4ContentState extends State<Tab4Content> {
  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

class LoginPage extends StatelessWidget {
  final VoidCallback onLogin;

  LoginPage({required this.onLogin});

  void _handleLoginButtonPressed() {
    onLogin();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: ElevatedButton(
          child: Text('login'),
          onPressed: () {
            _handleLoginButtonPressed();
          },
        ),
      ),
    );
  }
}