AmityCo / Flutter_sample_uikit

ThanakornThanom/-flutter_amity_uikit_beta_service developed by SLE team
Other
1 stars 2 forks source link

Example Not Running #61

Open andrewkimjoseph opened 10 months ago

andrewkimjoseph commented 10 months ago

I'm trying to setup this UI Kit to work, by including it in my pubspec.yaml file like this:

_amity_uikit_betaservice: git: url: https://github.com/AmityCo/Amity-Social-UIKit-Flutter-Opensource

However, the example given does not work, and I get the following error:

Screenshot 2024-01-17 at 15 44 43

Here is a gist showing the main.dart file that I ran: https://gist.github.com/andrewkimjoseph/42274b2186297fdbeac2062b8c710d3d

Kindly address it so that we have a way of integrating your UI Kit.

ThanakornThanom commented 9 months ago

Could you please provide me with your pubspec.yaml file and the relevant code snippet?

andrewkimjoseph commented 9 months ago

Pubspec.yaml:

name: partify_sdk_testing_again
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=3.2.3 <4.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  amity_uikit_beta_service:
    git:
      url: https://github.com/AmityCo/Amity-Social-UIKit-Flutter-Opensource

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^2.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

Main.dart file:

import 'package:amity_uikit_beta_service/amity_sle_uikit.dart';
import 'package:amity_uikit_beta_service/utils/navigation_key.dart';
import 'package:amity_uikit_beta_service/view/chat/chat_friend_tab.dart';
import 'package:amity_uikit_beta_service/view/chat/single_chat_room.dart';
import 'package:amity_uikit_beta_service/view/social/global_feed.dart';
import 'package:flutter/material.dart';

void main() async {
  ///Step 1: Initialize amity SDK with the following function
  WidgetsFlutterBinding.ensureInitialized();
  AmitySLEUIKit().initUIKit(
      apikey: "MY_API_KEY",
      region: AmityRegion.eu);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    ///Step2: Wrap Material App with AmitySLEProvider and Builder
    return AmitySLEProvider(
      child: MaterialApp(
        navigatorKey: NavigationService.navigatorKey,
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const InitialWidget(),
      ),
    );
  }
}

class InitialWidget extends StatelessWidget {
  const InitialWidget({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  ///Step 3: login with Amity
                  AmitySLEUIKit()
                      .registerDevice(context: context, userId: "johnwick2");
                },
                child: const Text("Login to Amity"),
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  ///Step 4: Navigate To channel List page
                  Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) => const AmitySLEChannelScreen(),
                  ));
                },
                child: const Text("Navigate to UIKIT: Channel List page"),
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () async {
                  ///4.1: Navigate To channel chat screen page with ChannelId

                  await Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) => const SingleChatRoom(
                      channelId: "Flutter_Flutter",
                    ),
                  ));
                },
                child: const Text("Navigate to UIKIT: Chat room page"),
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () {
                  ///4.e: Navigate To Global Feed Screen
                  Navigator.of(context).push(MaterialPageRoute(
                    builder: (context) =>
                        const Scaffold(body: GlobalFeedScreen()),
                  ));
                },
                child: const Text("Navigate to UIKIT: Global Feed"),
              ),
            ],
          )
        ],
      ),
    );
  }
}
AuThanakorn commented 9 months ago

I found that removing the line navigatorKey: NavigationService.navigatorKey, resolves the issue. I'm currently investigating the root cause for a more comprehensive understanding.

In the meantime, you can use the following code as an alternative solution:

import 'dart:developer';

import 'package:amity_uikit_beta_service/amity_sle_uikit.dart';
import 'package:amity_uikit_beta_service/components/alert_dialog.dart';
import 'package:amity_uikit_beta_service/view/UIKit/social/create_community_page.dart';
import 'package:amity_uikit_beta_service/view/UIKit/social/explore_page.dart';
import 'package:amity_uikit_beta_service/view/UIKit/social/my_community_feed.dart';
import 'package:amity_uikit_beta_service/view/UIKit/social/post_target_page.dart';
import 'package:amity_uikit_beta_service/view/social/global_feed.dart';
// import 'package:amity_uikit_beta_service_example/firebase_options.dart';
// import 'package:firebase_core/firebase_core.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
  ///Step 1: Initialize amity SDK with the following function
  WidgetsFlutterBinding.ensureInitialized();
  // await Firebase.initializeApp(
  // options: DefaultFirebaseOptions.currentPlatform,
  // );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _apiKey = TextEditingController();
  AmityRegion? _selectedRegion;
  final TextEditingController _customUrl = TextEditingController();
  @override
  void initState() {
    super.initState();
    _loadPreferences();
  }

  Future<void> _loadPreferences() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      _apiKey.text = prefs.getString('apiKey') ?? "";

      String? selectedRegionString = prefs.getString('selectedRegion');
      if (selectedRegionString != null) {
        _selectedRegion = AmityRegion.values.firstWhere(
          (e) => e.toString() == selectedRegionString,
          orElse: () => AmityRegion.sg,
        );
      }
      if (_selectedRegion == AmityRegion.custom) {
        _customUrl.text = prefs.getString('customUrl') ?? "";
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('API Configuration'),
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextFormField(
              controller: _apiKey,
              decoration: const InputDecoration(
                labelText: 'API Key',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 20),
            const Text('Select Region:'),
            ...AmityRegion.values.map((region) {
              return RadioListTile<AmityRegion>(
                title: Text(region.toString().split('.').last.toUpperCase()),
                value: region,
                groupValue: _selectedRegion,
                onChanged: (AmityRegion? value) {
                  setState(() {
                    _selectedRegion = value;
                    if (value != AmityRegion.custom) {
                      _customUrl.text = ""; // Reset custom URL
                    }
                  });
                },
              );
            }).toList(),
            if (_selectedRegion == AmityRegion.custom) ...[
              const SizedBox(height: 20),
              TextFormField(
                decoration: const InputDecoration(
                  labelText: 'Custom URL',
                  border: OutlineInputBorder(),
                ),
                controller: _customUrl,
              ),
            ],
            const SizedBox(height: 40),
            ElevatedButton(
                child: const Text('Initialize'),
                onPressed: () async {
                  if (_selectedRegion != null &&
                      (_selectedRegion != AmityRegion.custom)) {
                    final prefs = await SharedPreferences.getInstance();

                    await prefs.setString('apiKey', _apiKey.text);
                    await prefs.setString(
                        'selectedRegion', _selectedRegion.toString());
                    if (_selectedRegion == AmityRegion.custom) {
                      await prefs.setString('customUrl', _customUrl.text);
                    }
                    log("save pref");

                    await AmitySLEUIKit().initUIKit(
                        apikey: _apiKey.text,
                        region: _selectedRegion!,
                        customEndpoint: _customUrl.text);
                    // Navigate to the nextx page
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) => const AmityApp()),
                    );
                  }
                }),
          ],
        ),
      ),
    );
  }
}

class AmityApp extends StatelessWidget {
  const AmityApp({super.key});
  @override
  Widget build(BuildContext context) {
    return AmitySLEProvider(
      child: Builder(builder: (context2) {
        return const UserListPage();
      }),
    );
  }
}

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

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

class _UserListPageState extends State<UserListPage> {
  List<String> _usernames = [];
  final TextEditingController _controller = TextEditingController();

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

  _loadUsernames() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _usernames = prefs.getStringList('usernames') ?? [];
    });
  }

  _addUsername() async {
    if (_controller.text.isNotEmpty) {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      _usernames.add(_controller.text);
      prefs.setStringList('usernames', _usernames);
      _controller.clear();
      setState(() {});
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('User List'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              controller: _controller,
              decoration: const InputDecoration(
                labelText: 'Username',
                border: OutlineInputBorder(),
              ),
            ),
          ),
          ElevatedButton(
            onPressed: _addUsername,
            child: const Text('Add Username'),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _usernames.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(_usernames[index]),
                  onTap: () async {
                    log("login");

                    ///Step 3: login with Amity
                    await AmitySLEUIKit().registerDevice(
                      context: context,
                      userId: _usernames[index],
                      callback: (isSuccess, error) {
                        log("callback:$isSuccess");
                        if (isSuccess) {
                          log("success");
                          Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (context) =>
                                  SecondPage(username: _usernames[index]),
                            ),
                          );
                        } else {
                          AmityDialog().showAlertErrorDialog(
                              title: "Error", message: error.toString());
                        }
                      },
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({super.key, required this.username});
  final String username;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Welcome, $username'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) => ThirdPage(username: username),
                  ),
                );
              },
              child: const Text('Social'),
            ),
            ElevatedButton(
              onPressed: () {
                // Navigator.of(context).pushNamed('/third',
                //     arguments: {'username': username, 'feature': 'Chat'});
              },
              child: const Text('Chat'),
            ),
          ],
        ),
      ),
    );
  }
}

class ThirdPage extends StatelessWidget {
  const ThirdPage({super.key, required this.username});
  final String username;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Social'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ListTile(
              title: const Text('Register push notification'),
              onTap: () async {
                // FirebaseMessaging messaging = FirebaseMessaging.instance;

                // NotificationSettings settings =
                //     await messaging.requestPermission();

                // if (settings.authorizationStatus ==
                //         AuthorizationStatus.authorized ||
                //     settings.authorizationStatus ==
                //         AuthorizationStatus.provisional) {
                //   String? token;
                //   String tokenType = Platform.isIOS ? "APNS" : "FCM";

                //   if (Platform.isIOS) {
                //     log("getting token");
                //     token =
                //         await messaging.getAPNSToken().catchError((e) async {
                //       await showDialog(
                //         context: context,
                //         builder: (BuildContext context) {
                //           return AlertDialog(
                //             title: const Text('Error'),
                //             content: Text(e),
                //           );
                //         },
                //       );
                //       return e;
                //     });
                //     log("apns Token : $token");
                //   } else {
                //     token = await messaging.getToken();
                //     log("getting 3token");
                //     token =
                //         await messaging.getAPNSToken().catchError((e) async {
                //       await showDialog(
                //         context: context,
                //         builder: (BuildContext context) {
                //           return AlertDialog(
                //             title: const Text('Error'),
                //             content: Text(e),
                //           );
                //         },
                //       );
                //       return e;
                //     });
                //     log("android token Token : $token");
                //   }

                //   log('Firebase Push Token ($tokenType): $token');
                //   await AmitySLEUIKit().registerNotification(token,
                //       (isSuccess, error) async {
                //     await showDialog(
                //       context: context,
                //       builder: (BuildContext context) {
                //         return AlertDialog(
                //           title: isSuccess
                //               ? const Text('Success')
                //               : const Text('Error'),
                //           content: SingleChildScrollView(
                //             child: ListBody(
                //               children: <Widget>[
                //                 Text(isSuccess
                //                     ? 'Push notification registered successfully.\nToken Type: $tokenType\nToken: $token'
                //                     : 'Failed to register push notification.\nError: $error'),
                //                 if (isSuccess)
                //                   ElevatedButton(
                //                     onPressed: () {
                //                       Clipboard.setData(ClipboardData(
                //                           text: token ?? "no token"));
                //                     },
                //                     child: const Text('Copy Token'),
                //                   ),
                //               ],
                //             ),
                //           ),
                //           actions: <Widget>[
                //             TextButton(
                //                 child: const Text('Close'),
                //                 onPressed: () {
                //                   Navigator.of(context).pop();
                //                 }),
                //           ],
                //         );
                //       },
                //     );
                //   });
                // } else {
                //   log('Push notification permission was declined');

                //   // ignore: use_build_context_synchronously
                //   showDialog(
                //     context: context,
                //     builder: (BuildContext context) {
                //       return const AlertDialog(
                //         title: Text('Error'),
                //         content:
                //             Text('Push notification permission was declined'),
                //       );
                //     },
                //   );
                // }
              },
            ),
            ListTile(
              title: const Text('unregister'),
              onTap: () {
                // Navigate or perform action based on 'Global Feed' tap
                AmitySLEUIKit().unRegisterDevice();
              },
            ),
            ListTile(
              title: const Text('Global Feed'),
              onTap: () {
                // Navigate or perform action based on 'Global Feed' tap
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) =>
                      const Scaffold(body: GlobalFeedScreen()),
                ));
              },
            ),
            ListTile(
              title: const Text('User Profile'),
              onTap: () {
                // Navigate or perform action based on 'User Profile' tap
              },
            ),
            ListTile(
              title: const Text('Newsfeed'),
              onTap: () {
                // Navigate or perform action based on 'Newsfeed' tap
              },
            ),
            ListTile(
              title: const Text('Create Community'),
              onTap: () {
                // Navigate or perform action based on 'Newsfeed' tap
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) =>
                      const Scaffold(body: CreateCommunityPage()),
                ));
              },
            ),
            ListTile(
              title: const Text('Create Post'),
              onTap: () {
                // Navigate or perform action based on 'Newsfeed' tap
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) => const Scaffold(body: PostToPage()),
                ));
              },
            ),
            ListTile(
              title: const Text('My Community'),
              onTap: () {
                // Navigate or perform action based on 'Newsfeed' tap
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) => const Scaffold(body: MyCommunityPage()),
                ));
              },
            ),
            ListTile(
              title: const Text('Explore'),
              onTap: () {
                // Navigate or perform action based on 'Newsfeed' tap
                Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) => const Scaffold(body: CommunityPage()),
                ));
              },
            ),
          ],
        ),
      ),
    );
  }
}