Flutter

Flutter

Flutter allows you to build beautiful native apps on iOS and Android from a single codebase.
Fabiola  Auma

Fabiola Auma

1656756000

A Flutter Plugin to Show incoming Call In Your Flutter App!

Flutter_incoming_call

A Flutter plugin to show incoming call in your Flutter app! Alpha version(not ready for production!)

Usage

To use this plugin:

  1. Configure android project: Just add to your manifest activity and receiver.
<activity
    android:name="com.github.alezhka.flutter_incoming_call.IncomingCallActivity"
    android:theme="@style/Theme.AppCompat"
    android:screenOrientation="portrait"
    android:showOnLockScreen="true">
    <intent-filter>
        <action android:name="com.github.alezhka.flutter_incoming_call.activity.ACTION_INCOMING_CALL" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

<receiver android:name="com.github.alezhka.flutter_incoming_call.CallBroadcastReceiver"
    android:enabled="true"
    android:exported="false"/>
  1. Configure Flutter plugin:
FlutterIncomingCall.configure(
    appName: 'example_incoming_call',
    duration: 30000,
    android: ConfigAndroid(
        vibration: true,
        ringtonePath: 'default',
        channelId: 'calls',
        channelName: 'Calls channel name',
        channelDescription: 'Calls channel description',
    ),
    ios: ConfigIOS(
        iconName: 'AppIcon40x40',
        ringtonePath: null,
        includesCallsInRecents: false,
        supportsVideo: true,
        maximumCallGroups: 2,
        maximumCallsPerCallGroup: 1,
    )
)
  1. Listen events:
FlutterIncomingCall.onEvent.listen((event) {
    if(event is CallEvent) { // Android | IOS
    } else if(event is HoldEvent) { // IOS
    } else if(event is MuteEvent) { // IOS
    } else if(event is DmtfEvent) { // IOS
    } else if(event is AudioSessionEvent) { // IOS
    }
});
  1. Call api:
FlutterIncomingCall.displayIncomingCall(String uid, String name, String avatar, String handle, String type, bool isVideo);
FlutterIncomingCall.endCall(String uuid);
FlutterIncomingCall.endAllCalls();

Demo

iosios (Lockscreen)AndroidAndroid (Lockscreen)

Example

Check out the example in the example project folder for a working example.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_incoming_call

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_incoming_call: ^0.1.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_incoming_call/flutter_incoming_call.dart';

example/lib/main.dart

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

import 'package:flutter_incoming_call/flutter_incoming_call.dart';
import 'package:uuid/uuid.dart';

void main() {
  runApp(MyApp());
}

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

class _MyAppState extends State<MyApp> {

  var uuid = Uuid();

  BaseCallEvent? _lastEvent;
  CallEvent? _lastCallEvent;
  HoldEvent? _lastHoldEvent;
  MuteEvent? _lastMuteEvent;
  DmtfEvent? _lastDmtfEvent;
  AudioSessionEvent? _lastAudioSessionEvent;

  void _incomingCall() {
    final uid = uuid.v4();
    final name = 'Daenerys Targaryen';
    final avatar = 'https://scontent.fhel6-1.fna.fbcdn.net/v/t1.0-9/62009611_2487704877929752_6506356917743386624_n.jpg?_nc_cat=102&_nc_sid=09cbfe&_nc_ohc=cIgJjOYlVj0AX_J7pnl&_nc_ht=scontent.fhel6-1.fna&oh=ef2b213b74bd6999cd74e3d5de235cf4&oe=5F6E3331';
    final handle = 'example_incoming_call';
    final type = HandleType.generic;
    final isVideo = true;
    FlutterIncomingCall.displayIncomingCall(uid, name, avatar, handle, type, isVideo);
  }

  void _endCurrentCall() {
    if(_lastEvent != null) {
      FlutterIncomingCall.endCall(_lastCallEvent!.uuid);
    }
  }

  void _endAllCalls() {
    FlutterIncomingCall.endAllCalls();
  }

  @override
  void initState() {
    super.initState();
    FlutterIncomingCall.configure(
      appName: 'example_incoming_call',
      duration: 30000,
      android: ConfigAndroid(
        vibration: true,
        ringtonePath: 'default',
        channelId: 'calls',
        channelName: 'Calls channel name',
        channelDescription: 'Calls channel description',
      ),
      ios: ConfigIOS(
        iconName: 'AppIcon40x40',
        ringtonePath: null,
        includesCallsInRecents: false,
        supportsVideo: true,
        maximumCallGroups: 2,
        maximumCallsPerCallGroup: 1,
      )
    );
    FlutterIncomingCall.onEvent.listen((event) {
      setState(() { _lastEvent = event; });
      if(event is CallEvent) {
        setState(() { _lastCallEvent = event; });
      } else if(event is HoldEvent) {
        setState(() { _lastHoldEvent = event; });
      } else if(event is MuteEvent) {
        setState(() { _lastMuteEvent = event; });
      } else if(event is DmtfEvent) {
        setState(() { _lastDmtfEvent = event; });
      } else if(event is AudioSessionEvent) {
        setState(() { _lastAudioSessionEvent = event; });
      }
    });
  }

  @override
  void dispose() {
    _endAllCalls();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              TextButton(
                child: Text('Incoming call now'),
                onPressed: _incomingCall,
              ),
              SizedBox(height: 16),
              TextButton(
                child: Text('Incoming call delay 5 sec'),
                onPressed: () => Future.delayed(Duration(seconds: 5), _incomingCall),
              ),
              SizedBox(height: 16),
              TextButton(
                child: Text('End current call'),
                onPressed: _endCurrentCall,
              ),
              SizedBox(height: 16),
              TextButton(
                child: Text('End all calls'),
                onPressed: _endAllCalls,
              ),
              SizedBox(height: 16),
              Text(
                'Last event:',
                style: TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
              Text(
                _lastEvent != null ? _lastEvent.toString() : 'Not event',
                style: TextStyle(
                    fontSize: 16
                ),
              ),
              if(_lastCallEvent != null) ...[
                Text(
                  'Last call event:',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  _lastCallEvent.toString(),
                  style: TextStyle(
                      fontSize: 16
                  ),
                )
              ],
              if(_lastHoldEvent != null) ...[
                Text(
                  'Last hold event:',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  _lastHoldEvent.toString(),
                  style: TextStyle(
                      fontSize: 16
                  ),
                )
              ],
              if(_lastMuteEvent != null) ...[
                Text(
                  'Last mute event:',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  _lastMuteEvent.toString(),
                  style: TextStyle(
                      fontSize: 16
                  ),
                )
              ],
              if(_lastDmtfEvent != null) ...[
                Text(
                  'Last dmtf event:',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  _lastDmtfEvent.toString(),
                  style: TextStyle(
                      fontSize: 16
                  ),
                )
              ],
              if(_lastAudioSessionEvent != null) ...[
                Text(
                  'Last audio session event:',
                  style: TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                Text(
                  _lastAudioSessionEvent.toString(),
                  style: TextStyle(
                      fontSize: 16
                  ),
                )
              ]
            ],
          ),
        ),
      ),
    );
  }
}

Author: Alezhka
Source code: https://github.com/Alezhka/flutter_incoming_call
License: GPL-3.0 license

#dart #flutter 

A Flutter Plugin to Show incoming Call In Your Flutter App!
Daniel  Hughes

Daniel Hughes

1656756000

Bidmad Plugin: Flutter Plugin for using BidmadSDK

Introduce

BidmadPlugin is a plugin for using Bidmad, a mobile app advertisement SDK, in Flutter.
You can use the plugin to serve banner/interstitial/reward ads in your flutter mobile app.
 

Flutter Sample Download

Programming Guide

1. Android Setting

*If you are using a version lower than 1.0.0, please check here first before proceeding to the guide below.

1.1 gradle.properties Setting

Add the options below to gradle.properties

...
android.enableDexingArtifactTransform=false

1.2 Proguard Settings

If you are using Proguard, add the rule below.

...
-keep class com.adop.sdk.** { *; }
-keep class ad.helper.openbidding.** { *; }
-keep class com.adop.adapter.fc.** { *; }
-keep class com.adop.adapter.fnc.** { *; }
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}

# Pangle
-keep class com.bytedance.sdk.** { *; }
-keep class com.bykv.vk.openvk.component.video.api.** { *; }

# Tapjoy
-keep class com.tapjoy.** { *; }
-keep class com.moat.** { *; }
-keepattributes JavascriptInterface
-keepattributes *Annotation*
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
-keep class com.google.android.gms.ads.identifier.** { *; }
-dontwarn com.tapjoy.**

2. iOS Setting

2.1 import BidmadSDK-iOS CocoaPods

After fetching our plugin into your app by "flutter pub get", a "Podfile" will be generated in your project's iOS Folder.
 

  1. In Podfile, set the platform requirement to iOS 11.
    Bidmad-Guide-Flutter-1
     
  2. Install our CocoaPods iOS Framework with command "pod install"
    Bidmad-Guide-Flutter-2
     
  3. Now, open the Xcode Workspace file with the name "Runner.xcworkspace" and proceed to guide 2.2 below. Bidmad-Guide-Flutter-3
     

2.2 Xcode Build Setting

Select "No" for Enable Bitcode under your Build Setting.

2.3 Setting SKAdNetwork

To use AdNetworks provided by BidmadSDK, you need to add SKAdNetworkIdentifier to Info.plist. Please add SKAdNetworkItems below to info.plist.

<key>SKAdNetworkItems</key>
<array>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>cstr6suwn9.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>v9wttpbfk9.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>n38lu8286q.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>4dzt52r2t5.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>bvpn9ufa9b.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>2u9pt9hc89.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>4468km3ulz.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>4fzdc2evr5.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>7ug5zh24hu.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>8s468mfl3y.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>9rd848q2bz.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>9t245vhmpl.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>av6w8kgt66.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>f38h382jlk.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>hs6bdukanm.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>kbd757ywx3.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>ludvb6z3bs.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>m8dbw4sv7c.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>mlmmfzh3r3.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>prcb7njmu6.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>t38b2kh725.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>tl55sbb4fm.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>wzmmz9fp6w.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>yclnxrl5pm.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>ydx93a7ass.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>238da6jt44.skadnetwork</string>
    </dict>
    <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>22mmun2rn5.skadnetwork</string>
    </dict>
</array>

Also, please add NSUserTrackingUsageDescription with your own description of why you would like to track user data (e.g. "App would like to access IDFA for tracking purpose") into info.plist

...
<key>NSUserTrackingUsageDescription</key>
<string>App would like to access IDFA for tracking purpose</string>
...

3. Using Plugin

3.1 InitializeSDK

At the starting point of your app, please call initializeSdk(). If initializeSdk method is not called, SDK initializes itself on your first loading, which subsequently may delay your first ad loading.

FlutterBidmadCommon().initializeSdk();

For interstitial and rewarded ads, instead of calling initializeSdk(), load your first ad at the starting point of your app by following the interstitial and rewarded ad loading guide below, and show your ad at the point of your choice.

3.1 Banner AD

The following is an example of requesting a Banner ad.

3.1.1 Banner placement based on position

....//Banner init
    FlutterBidmadCommon common = FlutterBidmadCommon();
    FlutterBaseBanner banner;

    common.initBannerChannel().then((value) {
      String _channelNm = value;

      banner = FlutterBaseBanner(
          channelName: _channelNm
      );

      banner.setAdInfo("Your Zone Id");

      banner.setCallbackListener(
          onLoadAd: (String zoneId){
            print("banner onLoadAd");
          },
          onFailAd: (String zoneId){
            print("banner onFailAd");
          }
      );

      //option 
      //banner.setInterval(120); //banner refresh time(60s~120s)
    });

....//Banner Load
    banner.load(300); //set Position Y(height)

....//Banner Remove
    banner.removeAdView();

3.1.2 Banner Widget

....//Banner Widget init
    Container(
      child: BidmadBannerWidget(
        onBidmadBannerWidgetCreated: _onWidgetTestCreated,
      ),
      height: 50.0, //Banner Height(50, 100, 250)
    ),

....//onBidmadBannerWidgetCreated 
  void _onWidgetTestCreated(FlutterBaseBanner controller){
    controller.setAdInfo("Your Zone Id");

    controller.setCallbackListener(
        onLoadAd: (String zoneId){
          print("banner onLoadAd");
        },
        onFailAd: (String zoneId){
          print("banner onFailAd");
        }
    );

    controller.loadWidget();
  }

3.2 Interstitial AD

The following is an example of requesting a Interstitial ad.

....//Interstitial init
    FlutterBidmadCommon common = FlutterBidmadCommon();
    FlutterBaseInterstitial interstitial;

    common.initInterstitialChannel().then((value) {
      String _channelNm = value;

      interstitial = FlutterBaseInterstitial(
          channelName: _channelNm
      );

      interstitial.setAdInfo("Your Zone Id");

      interstitial.setCallbackListener(
          onLoadAd: (String zoneId){
            print("interstitial onLoadAd");
          },
          onShowAd: (String zoneId){
            print("interstitial onShowAd" );
            interstitial.load(); //Ad Reload
          },
          onCloseAd: (String zoneId){
            print("interstitial onCloseAd");
          },
          onFailAd: (String zoneId){
            print("interstitial onFailAd");
          }
      );
    });

....//Interstitial Load
    interstitial.load();

....//Interstitial Show
    interstitial.isLoaded().then((value){
      if(value){
        interstitial.show();
      }
    });

3.3 Reward AD

The following is an example of requesting a Reward ad.

....//Reward init
    FlutterBidmadCommon common = FlutterBidmadCommon();
    FlutterBaseReward reward;

    common.initRewardChannel().then((value) {
      String _channelNm = value;
      reward = FlutterBaseReward(
          channelName: _channelNm
      );

      reward.setAdInfo("Your Zone Id");

      reward.setCallbackListener(
          onLoadAd: (String zoneId){
            print("reward onLoadAd");
          },
          onShowAd: (String zoneId){
            print("reward onShowAd");

            reward.load();
          },
          onCompleteAd: (String zoneId){
            print("reward onCompleteAd");
          },
          onSkipAd: (String zoneId){
            print("reward onSkippedAd");
          },
          onCloseAd: (String zoneId){
            print("reward onCloseAd");
          },
          onClickAd: (String zoneId){
            print("reward onClickAd");
          },
          onFailAd: (String zoneId){
            print("reward onFailAd");
          }
      );
    });

....//Reward Load
    reward.load();

....//Reward Show
    reward.isLoaded().then((value){
      if(value){
        reward.show();
      }
    });

3.4 ATT Functions

reqAdTrackingAuthorization() displays a popup, requesting for App Tracking Consent from user. And the function will return set of number string values, showing the result.

FlutterBidmadCommon common = FlutterBidmadCommon();
    common.reqAdTrackingAuthorization().then(
      (value) {
        switch (value) {
          case "0":
            print("App Tracking Not Determined");
            break;
          case "1":
            print("App Tracking Restricted Authoriziation Status");
            break;
          case "2":
            print("App Tracking Denied Authorization Status");
            break;
          case "3":
            print("App Tracking Authorized Authorization Status");
            break;
          case "4":
            print("user is on lower version than iOS 14");
            break;
        }
      }
    );

For App Tracking Not Determined, the function will return 0, For App Tracking Restricted Authoriziation Status, the function will return 1, For App Tracking Denied Authorization Status, the function will return 2, For App Tracking Authorized Authorization Status the function will return 3, and Lastly, if the user is on lower version than iOS 14 then it will return 4.

If you wish to obtain app tracking consent through a method other than what's provided by Plugin, If the user agrees, True, and if rejected, pass False to setAdvertiserTrackingEnabled.

    common.setAdvertiserTrackingEnabled(false);
    print(common.getAdvertiserTrackingEnabled());

4. Plugin Interface

4.1 FlutterBaseBanner

*Banner ads are handled through FlutterBaseBanner and this is a list of functions for that.

FunctionDescription
FlutterBaseBanner(@required String channelName)This is the FlutterBaseBanner constructor, Receives the Name for Channel creation as a Param.
Future(void) load(int y)Request a banner ad. When a banner ad is exposed, the banner is exposed at height y (center alignment).
Future(void) loadWidget()Request a banner ad. In order for the function to function properly, FlutterBaseBanner object must be obtained through the BidmadBannerWidget Class.
Future(void) setInterval(int sec)Set the banner refresh cycle.(60s~120s)
Future(void) setAdInfo(String zoneId)Set the issued ZoneId.
Future(void) setCUID(String cuid)Set the CUID property of each ad type. recommend encrypting text using sha256 or higher.
Future(void) hideBanner()Hide the banner View
Future(void) showBanner()Show the banner View.
Future(void) removeBanner()Remove the exposed banner.
void Function(String zoneId) onLoadAdIf a listener is registered, the registered function is called when ad load.
void Function(String zoneId) onFailAdIf a listener is registered, the registered function is called when ad load fail.

4.2 BidmadBannerWidget

*For banner ads in the form of a widget, it must be processed through BidmadBannerWidget, and this is a list of functions for that.

FunctionDescription
BidmadBannerWidget(BidmadBannerWidgetCreatedCallback onBidmadBannerWidgetCreated)This is the BidmadBannerWidget constructor. After creating the widget, it receives a callback for processing.
onBidmadBannerWidgetCreated(FlutterBaseBanner controller)It is a callback that can receive a FlutterBaseBanner and handle banner related processing.

4.3 FlutterBaseInterstitial

*Interstitial ads are handled through FlutterBaseInterstitial and this is a list of functions for that.

FunctionDescription
FlutterBaseInterstitial(@required String channelName)This is the FlutterBaseInterstitial constructor, Receives the Name for Channel creation as a Param.
Future(void) load()Request a interstitial ad
Future(void) show()Display the loaded interstitial ad
Future(bool) isLoaded()Check if the ad is loaded.
Future(void) setAdInfo(String zoneId)Set the issued ZoneId.
Future(void) setCUID(String cuid)Set the CUID property of each ad type. recommend encrypting text using sha256 or higher.
void Function(String zoneId) onLoadAdIf a listener is registered, the registered function is called when ad load.
void Function(String zoneId) onShowAdIf a listener is registered, the registered function is called when ad show.
void Function(String zoneId) onFailAdIf a listener is registered, the registered function is called when ad load fail.
void Function(String zoneId) onCloseAdIf a listener is registered, the registered function is called when ad close.

4.4 FlutterBaseReward

*Reward ads are handled through FlutterBaseReward and this is a list of functions for that.

FunctionDescription
FlutterBaseReward(@required String channelName)This is the FlutterBaseReward constructor, Receives the Name for Channel creation as a Param.
Future(void) load()Request a reward ad.
Future(void) show()Display the loaded reward ad.
Future(bool) isLoaded()Check if the ad is loaded.
Future(void) setAdInfo(String zoneId)Set the issued ZoneId.
Future(void) setCUID(String cuid)Set the CUID property of each ad type. recommend encrypting text using sha256 or higher.
void Function(String zoneId) onLoadAdIf a listener is registered, the registered function is called when ad load.
void Function(String zoneId) onShowAdIf a listener is registered, the registered function is called when ad show.
void Function(String zoneId) onFailAdIf a listener is registered, the registered function is called when ad load fail.
void Function(String zoneId) onCompleteAdIf a listener is registered, the registered function is called when ad complate.
void Function(String zoneId) onCloseAdIf a listener is registered, the registered function is called when ad close.
void Function(String zoneId) onClickAdIf a listener is registered, the registered function is called when ad click.
void Function(String zoneId) onSkipAdIf a listener is registered, the registered function is called when ad skip.

4.5 FlutterBidmadCommon

*This is a list of functions available through BidmadCommon.

FunctionDescription
FlutterBidmadCommon()This is the FlutterBidmadCommon constructor
Future(void) setDebugging(bool isDebug)Debugging log output
Future(void) initializeSdk()Initialize BidmadSDK's supported ad networks
Future(String) initBannerChannel()Creating a channel for controlling banner ad
Future(String) initInterstitialChannel()Creating a channel for controlling interstitial ad
Future(String) initRewardChannel()Creating a channel for controlling reward ad
Future(String) reqAdTrackingAuthorization()Requesting for App Tracking Consent from user
Future(void) setAdvertiserTrackingEnabled(bool enable)Setting ATT Setting manually
Future(bool) getAdvertiserTrackingEnabled()Getting ATT Setting, true if consent and false if not consent

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add bidmad_plugin

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  bidmad_plugin: ^1.3.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:bidmad_plugin/BidmadBannerWidget.dart';
import 'package:bidmad_plugin/BidmadFlutterPlugin.dart';
import 'package:bidmad_plugin/FlutterBaseBanner.dart';
import 'package:bidmad_plugin/FlutterBaseInterstitial.dart';
import 'package:bidmad_plugin/FlutterBaseReward.dart';
import 'package:bidmad_plugin/FlutterBidmadCommon.dart';
import 'package:bidmad_plugin/FlutterBidmadGDPRforGoogle.dart';

Author:
Source code: https://pub.dev/packages/bidmad_plugin/install
License:

#dart #flutter 

Bidmad Plugin: Flutter Plugin for using BidmadSDK
米 萱萱

米 萱萱

1656754874

如何使用 Flutter_bloc 在 Flutter 中添加多风味认证

在本文中,我们将学习如何在 Flutter 应用中为不同风格添加 Google 身份验证。

介绍

在本教程中,我们将了解不同生产阶段的定义及其在开发中的重要性。我们还将介绍如何在各种环境中使用不同的Firebase 配置。此外,我们将了解块小部件以及它们在 Flutter 应用程序中管理状态时的作用。

让我们创建一个 Flutter 项目来实现不同风格的 Google 身份验证,以便我们可以在我们的设备上拥有相同应用程序的不同版本进行测试。

不同阶段

在大型科技公司中,项目通常分三个阶段完成:开发、准备和生产(尽管这些阶段可能因公司而异)。

在这些不同的阶段,对产品进行彻底测试以处理错误,以便将高质量的软件产品交付给消费者。

发展

在这一步中,UI的初始构建以及API和后端的集成都是在开发环境中完成的。您在此环境中使用的数据通常是测试 API 或测试数据库,并且没有任何数据是真实的。如果在发布后向应用程序添加新功能,它们将首先从开发环境中实现。

此阶段涉及大量代码测试,以确保代码功能齐全且应用程序高效运行。在此步骤中执行的测试类型称为unit testing

分期

在测试环境中,可以引入选定的用户来测试应用程序。这可以让您很好地了解应用程序在启动时将如何工作,因为它可以与真实数据进行交互。测试环境试图模拟生产,因此即使出现重大故障并且系统出现故障,也不需要关闭生产。

在此阶段测试所有数据库迁移。添加新功能时,还会发送功能以检查最坏的情况。如果新功能在上传时出现问题,则会发现并修复错误。

如果您曾经使用过 WhatsApp Web,您可能会收到加入试用计划的请求,以便在新功能上线之前对其进行测试。这是所谓的 beta 测试的一个例子。

生产

这是发布应用程序供用户试用的阶段。这是您的公司或客户最重要的阶段。在生产阶段,您不希望用户注意到任何重大错误,因为您最终可能会失去用户。理想情况下,到目前为止,软件中的大多数主要错误已经在早期阶段得到解决。

一般开发提示:您不必一次实现软件的所有功能。在发布新功能之前,优先考虑控制问题并确保当前功能稳定。

构建我们的 Flutter 应用

在 Flutter 应用程序中配置变体需要手动配置,这意味着我们将不得不处理不同目录中的许多文件。这可能会变得非常混乱,但是在very_good_cli的帮助下事情会容易得多。

建立

要创建一个新的 Flutter 项目,我们将使用一个名为very_good_cli的 Dart 包。这个包将帮助我们创建一个标准框架并在我们的 iOS 和 Android 应用程序中配置我们需要的所有环境。

要安装该工具,请在终端中键入以下命令:dart pub global activate very_good_cli

安装并激活very_good_cli后,我们可以使用以下命令创建Flutter项目:very_good create my_app --desc "My new Flutter app" --org "com.custom.org"

将 YAML 文件的内容替换为以下内容:

name: googlesigninwithflavor
description: A Very Good Project created by Very Good CLI.
version: 1.0.0+1
publish_to: none
environment:
  sdk: ">=2.16.0 <3.0.0"
dependencies:
  bloc: ^8.0.3
  flutter:
    sdk: flutter
  flutter_bloc: ^8.0.1
  intl: ^0.17.0
  google_sign_in: ^5.2.4
  equatable: ^2.0.3
  firebase_core: ^1.14.0
  firebase_auth: ^3.3.13
dev_dependencies:
  bloc_test: ^9.0.3
  flutter_test:
    sdk: flutter
  mocktail: ^0.3.0
  very_good_analysis: ^2.4.0
flutter:
  uses-material-design: true
  generate: true
  assets:
    - asset/

文件结构

lib                                   
├─ app                                
│  ├─ bloc                            
│  │  ├─ google_sign_in_bloc.dart     
│  │  ├─ google_sign_in_event.dart    
│  │  └─ google_sign_in_state.dart    
│  ├─ view                            
│  │  ├─ app.dart                     
│  │  └─ google_sign_in_view.dart     
│  └─ app.dart                        
├─ dashboard                          
│  └─ dashboard.dart                  
├─ repository                         
│  └─ authentication_repository.dart  
├─ bootstrap.dart                     
├─ generated_plugin_registrant.dart   
├─ main_development.dart              
├─ main_production.dart               
└─ main_staging.dart                  

当我们创建我们的项目时,我们会看到三个不同的核心文件,它们以生产的三个阶段命名。在生产的特定阶段,这些文件中的每一个都可以根据需要具有不同的设置。

main_development.dart              
main_production.dart               
main_staging.dart  

我们可以通过将以下参数传递到我们的终端来运行任何风格:

# For Development
flutter run --flavor development --t lib/main_development.dart
# For Staging
flutter run --flavor development --t lib/main_staging.dart
# For Production
flutter run --flavor development --t lib/main_production.dart

对于Android,我们通常在配置不同风格时处理的build.gradle文件是我们Android目录中的文件。

对于 iOS,我们将使用的文件是 Xcode 模式。但是,我们不需要这样做,因为very_good_cli 已经为我们生成了它们。

为我们的不同环境配置 Firebase

最近,Firebase推出了 Firebase CLI,它让 Firebase 项目的设置变得简单而无缝。但是,有些功能尚不受支持,例如分析和 Google 登录。由于我们将使用 Google 登录,因此我们需要手动配置 Firebase。因此,我们将手动配置我们的 Firebase 项目。

在我们的 Firebase 控制台中,我们将创建三个不同的项目,如下所示:

  • flavor dev
  • flavor stg
  • flavor prod各种口味的Firebase项目

在 Firebase 上注册 Flutter 项目时,我们必须在Android 包的名称中添加.dev.stg或。.prd

您可以在android/app/build.gradle文件中找到包名称。显示为applicationId,如下图。

 defaultConfig {
        applicationId "com.example.verygoodcore.googlesigninwithflavor"
        minSdkVersion flutter.minSdkVersion
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
    flavorDimensions "default"
    productFlavors { 
        production {
            dimension "default"
            applicationIdSuffix ""
            manifestPlaceholders = [appName: "Googlesigninwithflavor"]
        }
        staging {
            dimension "default"
            applicationIdSuffix ".stg"
            manifestPlaceholders = [appName: "[STG] Googlesigninwithflavor"]
        }        
        development {
            dimension "default"
            applicationIdSuffix ".dev"
            manifestPlaceholders = [appName: "[DEV] Googlesigninwithflavor"]
        }
    }

对于 iOS

在注册 iOS 时,我们还需要输入正确的包 ID。但是,如果您以前没有使用 Xcode 的经验,则可能很难导航。我们可以通过以下步骤找到包 ID:

Abra 或 Xcode当你打开 Xcode 时你看到了什么

单击Open a project or file

转到您的 Flutter 项目并打开 iOS 目录。选择Runner.xcworkspace目录。

然后单击 Runner 下拉菜单。在 General View 选项卡中,选择Build Settings,我们将在那里找到我们的应用程序包。

我们将对所有 Firebase 项目重复这些步骤。注册后,我们可以下载google-services.json适用于Android和GoogleService-Info.plistiOS的文件。

文件将google-services.json移至android/app/src/{respective environment}. 对于 iOS,我们将创建一个新的配置目录,其中包含我们环境的子目录并添加GoogleService-Info.plist到各种环境中。Runner让我们在 Xcode 中添加这个文件。阅读此Firebase 指南以了解更多信息。

实现 Google 身份验证的配置

要在我们的应用中使用 Google 身份验证,我们需要通过以下步骤启用 Google Provider。我们将在我们的开发环境中启用 Google Provider。

访问 Firebase。在本教程中,我们将从开发项目开始。

在主导航栏上,选择身份验证。您应该看到以下内容:启用身份验证

然后单击Set up sign-in method。将显示提供者列表。选择谷歌登录,您将看到:登录做谷歌

为项目激活Enable并添加支持电子邮件,如下图所示。然后保存您的设置。添加项目支持电子邮件

在导航栏上,单击设置图标并Project settings从下拉列表中进行选择。然后滚动到页面底部。我们需要从我们的项目中添加一个SHA-1 key和一个。SHA-256 key

要添加 SHA 密钥或指纹,我们将返回到我们的项目,右键单击 Android 文件夹,然后单击Open in an integrated terminal。这应该会在我们的 VS Code 环境中为我们打开一个新终端。

在您的终端中使用命令./gradlew signingReport获取密钥。运行此命令后,由于环境不同,我们应该会获得多个签名密钥。在终端中使用开发调试 SHA-1 密钥。

替代方案:在代码编辑器的终端中,您可以将目录更改为 Android 文件夹并运行命令。指纹/SHA 密钥

单击保存按钮并下载google-services.json更新的文件。替换google-services.json开发环境中的文件。在我们的例子中,我们会将它添加到开发环境中。

注意: Firebase需要SHA-1 密钥才能使 Google 登录正常工作。

我们刚刚启用了 Google 身份验证!我们将在下一节中实现它。

在我们的 Flutter 项目中实现 Google 身份验证

我们将使用该块进行状态管理。Bloc 是添加的状态管理器very_good_cli

创建存储库

存储库就像一个服务,为我们的块提供我们需要发送到我们的 UI 层的数据。存储库负责根据块的请求进行直接 API 调用。我们将按如下方式实现我们的存储库:

import 'dart:developer';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthenticationRepository {
  Future<bool> signInWithGoogle() async {
    try {
      final user = GoogleSignIn().currentUser ?? await GoogleSignIn().signIn();
      if (user != null) {
        await GoogleSignIn().signOut();
      }
      final googleAuth = await user?.authentication;
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth?.accessToken,
        idToken: googleAuth?.idToken,
      );
      await FirebaseAuth.instance.signInWithCredential(credential);
      return true;
    } catch (e) {
      log('An Error Occurred $e');
      return false;
    }
  }
  
  Future<void> handleSignOut() => GoogleSignIn().disconnect();
  // Future<void> signOut() async {
  //   final _googleSignIn = GoogleSignIn();
  //   _googleSignIn.disconnect();
  // }
}

阻止事件

对于我们的项目,我们将需要两个事件,GoogleSignInRequested并且GoogleSignOutRequested. 我们可以通过以下方式实现:

part of 'google_sign_in_bloc.dart';
abstract class GoogleSignInEvent extends Equatable {
  const GoogleSignInEvent();
  @override
  List<Object> get props => [];
}
class GoogleSignInRequested extends GoogleSignInEvent {}
class GoogleSignOutRequested extends GoogleSignInEvent {}

创建块状态

我们还需要两种状态——一种是当用户是Authenticated时,一种是当用户是时UnAuthenticated

part of 'google_sign_in_bloc.dart';
abstract class GoogleSignInState extends Equatable {
  @override
  List<Object?> get props => [];
}
class UnAuthenticated extends GoogleSignInState {}
class Authenticated extends GoogleSignInState {}

创建我们的块

我们的块将为我们的 UI 公开两种状态:Authenticated用户登录时和UnAuthenticated用户离开仪表板时。

让我们像这样实现它:

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:googlesigninwithflavor/repository/authentication_repository.dart';
part 'google_sign_in_event.dart';
part 'google_sign_in_state.dart';
class GoogleSignInBloc extends Bloc<GoogleSignInEvent, GoogleSignInState> {
  GoogleSignInBloc({required this.authenticationRepository})
      : super(UnAuthenticated()) {
    on<GoogleSignInRequested>(_onGoogleSignInPressed);
    on<GoogleSignOutRequested>(_onGoogleSignOutPressed);
  }
  final AuthenticationRepository authenticationRepository;
  Future<void> _onGoogleSignInPressed(
    GoogleSignInRequested event,
    Emitter<GoogleSignInState> emit,
  ) async {
    final response = await authenticationRepository.signInWithGoogle();
    if (response) {
      emit(Authenticated());
    }
  }
  void _onGoogleSignOutPressed(
    GoogleSignOutRequested event,
    Emitter<GoogleSignInState> emit,
  ) {
    authenticationRepository.handleSignOut();
    emit(UnAuthenticated());
  }
}

构建我们的用户界面

我们的app.dart类将像这样渲染我们的启动屏幕:

import 'package:flutter/material.dart';
import 'package:googlesigninwithflavor/app/view/google_sign_in_view.dart';
class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)),
        colorScheme: ColorScheme.fromSwatch(
          accentColor: const Color(0xFF13B9FF),
        ),
      ),
      home: const GoogleSignInView(),
    );
  }
}

google_sign_in_view.dart将保留我们的启动画面和登录按钮的实现。

class GoogleSignInView extends StatelessWidget {
  const GoogleSignInView({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RepositoryProvider(
      create: (context) => AuthenticationRepository(),
      child: BlocProvider(
        create: (context) => GoogleSignInBloc(
          authenticationRepository: RepositoryProvider.of(context),
        ),
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Sign In With Google'),
          ),
          body: const ShowSignInButton(),
        ),
      ),
    );
  }
}

在上面的代码中,我们使用RepositoryProvider小部件来创建我们的存储库的一个实例和一个孩子,它将使我们能够通过RepositoryProvider.of(context).

我们还使用BlocProvider小部件来创建我们的实例,Bloc以便子树或子小部件可以访问它。

然后我们将在我们的子小部件中使用该块,如下所示:

class ShowSignInButton extends StatelessWidget {
  const ShowSignInButton({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return BlocListener<GoogleSignInBloc, GoogleSignInState>(
      listener: (context, state) {
        if (state is Authenticated) {
          Navigator.push<Type>(
            context,
            MaterialPageRoute(builder: (_) => const DashBoard()),
          );
        }
      },
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Center(
            child: Image.asset(
              'asset/google2.png',
              height: 60,
            ),
          ),
          ElevatedButton(
            onPressed: () {
              context.read<GoogleSignInBloc>().add(GoogleSignInRequested());
            },
            child: const Text('Sign In With Google'),
          ),
        ],
      ),
    );
  }
}

在这里,我们使用BlocListner来根据块发出的状态导航到不同的屏幕。

我们还将GoogleSignInRequested事件传递给我们的ElevatedButton,因此当用户单击按钮以使用 Google 登录时,该事件将传递给块并向GoogleSignInAPI 发出请求。

让我们也实现一个仪表板屏幕来显示经过身份验证的用户的详细信息。为了实现这一点,我们需要调用 Firebase Auth 实例来访问当前用户的详细信息。我们还将创建一个注销按钮,该按钮将使用BlocListner小部件将用户带回登录屏幕:

class DashBoard extends StatelessWidget {
  const DashBoard({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RepositoryProvider(
      create: (context) => AuthenticationRepository(),
      child: BlocProvider(
        create: (context) => GoogleSignInBloc(
          authenticationRepository: RepositoryProvider.of(context),
        ),
        child: DashBoardDetails(),
      ),
    );
  }
}
class DashBoardDetails extends StatelessWidget {
  DashBoardDetails({
    Key? key,
  }) : super(key: key);
  final user = FirebaseAuth.instance.currentUser!;
  @override
  Widget build(BuildContext context) {
    return BlocListener<GoogleSignInBloc, GoogleSignInState>(
      listener: (context, state) {
        if (state is UnAuthenticated) {
          Navigator.of(context).pushAndRemoveUntil<Type>(
            MaterialPageRoute(builder: (context) => const GoogleSignInView()),
            (route) => false,
          );
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Very Good Codemagic'),
        ),
        body: BlocBuilder<GoogleSignInBloc, GoogleSignInState>(
          builder: (context, state) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Center(
                  child: Text('Welcome to your Dashboard'),
                ),
                Text('${user.displayName}'),
                if (user.photoURL != null)
                  Image.network('${user.photoURL}')
                else
                  Container(),
                ElevatedButton(
                  onPressed: () {
                    context
                        .read<GoogleSignInBloc>()
                        .add(GoogleSignOutRequested());
                  },
                  child: const Text('Sign Out'),
                )
              ],
            );
          },
        ),
      ),
    );
  }
}

居住!🎉 我们刚刚为我们的开发、登台和生产环境成功创建了 Google 登录身份验证。


来源:https ://blog.codemagic.io

#flutter

如何使用 Flutter_bloc 在 Flutter 中添加多风味认证

Как добавить многофакторную аутентификацию во Flutter

В этой статье мы узнаем, как добавить аутентификацию Google для разных вариантов вашего приложения Flutter.

Введение

В этом уроке мы узнаем определения различных этапов производства и их важность в разработке. Мы также расскажем, как использовать разные конфигурации Firebase в различных средах. Кроме того, мы узнаем о блочных виджетах и ​​о том, что они делают при управлении нашим состоянием в нашем приложении Flutter.

Давайте создадим проект Flutter для реализации аутентификации Google для разных вариантов, чтобы у нас были разные версии одного и того же приложения на наших устройствах для тестирования.

разные этапы

В крупных технологических компаниях проекты обычно выполняются в три этапа: разработка, подготовка и производство (хотя эти этапы могут варьироваться от компании к компании).

На этих различных этапах продукты тщательно тестируются на наличие ошибок, чтобы высококачественные программные продукты могли быть отправлены потребителю.

Разработка

На этом этапе начальное построение пользовательского интерфейса и интеграция API и серверной части выполняются в среде разработки. Данные, с которыми вы работаете в этой среде, обычно представляют собой тестовый API или тестовую базу данных, и никакие данные не являются реальными. Если новые функции будут добавлены в приложение после выпуска, они будут реализованы сначала из среды разработки.

Этот этап включает в себя много тестов кода, чтобы убедиться, что код полностью функционален, а приложение работает эффективно. Тип теста, выполняемого на этом этапе, называется unit testing.

постановка

В тестовой среде для тестирования приложения можно привлечь выбранных пользователей. Это может дать вам хорошее представление о том, как приложение будет работать при запуске, поскольку оно может взаимодействовать с реальными данными. Среда тестирования пытается имитировать производственную среду, поэтому даже в случае серьезного сбоя и отказа системы производственную среду не нужно останавливать.

На этом этапе тестируются все миграции баз данных. Функции также отправляются для проверки наихудших сценариев при добавлении новых функций. Если новые функции ломаются при загрузке, ошибки будут найдены и исправлены.

Если вы когда-либо использовали WhatsApp Web, вы, вероятно, получали запрос на участие в пробной программе, чтобы протестировать новую функцию, прежде чем она будет запущена. Это пример так называемого бета-тестирования.

Производство

На этом этапе приложение выпускается для опробования пользователями. Это самый важный этап для вашей компании или клиента. На этапе производства вы не хотите, чтобы пользователи замечали какие-либо серьезные ошибки, так как вы можете потерять пользователей. В идеале, к этому моменту большинство основных ошибок в программном обеспечении уже были устранены на более ранних этапах.

Общий совет по разработке: вам не нужно реализовывать все функции программного обеспечения сразу. Расставьте приоритеты, контролируя проблемы и обеспечивая стабильность текущих функций, прежде чем выпускать новые.

Создание нашего приложения Flutter

Для настройки вариантов в нашем приложении Flutter требуется ручная настройка, а это значит, что нам придется работать со многими файлами в разных каталогах. Это может сильно запутать, но с помощью very_good_cli все может быть намного проще .

Установить

Чтобы создать новый проект Flutter, мы будем использовать пакет Dart с именем very_good_cli . Этот пакет поможет нам создать стандартную структуру и настроить все необходимые среды в нашем приложении для iOS и Android.

Чтобы установить инструмент, введите в терминале следующую команду:dart pub global activate very_good_cli

После установки и активации very_good_cli мы можем использовать следующую команду для создания проекта Flutter:very_good create my_app --desc "My new Flutter app" --org "com.custom.org"

Замените содержимое файла YAML следующим:

name: googlesigninwithflavor
description: A Very Good Project created by Very Good CLI.
version: 1.0.0+1
publish_to: none
environment:
  sdk: ">=2.16.0 <3.0.0"
dependencies:
  bloc: ^8.0.3
  flutter:
    sdk: flutter
  flutter_bloc: ^8.0.1
  intl: ^0.17.0
  google_sign_in: ^5.2.4
  equatable: ^2.0.3
  firebase_core: ^1.14.0
  firebase_auth: ^3.3.13
dev_dependencies:
  bloc_test: ^9.0.3
  flutter_test:
    sdk: flutter
  mocktail: ^0.3.0
  very_good_analysis: ^2.4.0
flutter:
  uses-material-design: true
  generate: true
  assets:
    - asset/

файловая структура

lib                                   
├─ app                                
│  ├─ bloc                            
│  │  ├─ google_sign_in_bloc.dart     
│  │  ├─ google_sign_in_event.dart    
│  │  └─ google_sign_in_state.dart    
│  ├─ view                            
│  │  ├─ app.dart                     
│  │  └─ google_sign_in_view.dart     
│  └─ app.dart                        
├─ dashboard                          
│  └─ dashboard.dart                  
├─ repository                         
│  └─ authentication_repository.dart  
├─ bootstrap.dart                     
├─ generated_plugin_registrant.dart   
├─ main_development.dart              
├─ main_production.dart               
└─ main_staging.dart                  

Когда мы создаем наш проект, мы видим три разных основных файла, названных в честь трех этапов производства. Каждый из этих файлов может иметь различные настройки, необходимые на данном этапе производства.

main_development.dart              
main_production.dart               
main_staging.dart  

Мы можем запустить любой вариант, передав в наш терминал следующие аргументы:

# For Development
flutter run --flavor development --t lib/main_development.dart
# For Staging
flutter run --flavor development --t lib/main_staging.dart
# For Production
flutter run --flavor development --t lib/main_production.dart

Для Android файл, с которым мы обычно имеем дело при настройке различных вариантов, — это build.gradleфайл в нашем каталоге Android.

Для iOS файлы, с которыми мы будем работать, представляют собой схемы Xcode. Однако нам не нужно этого делать, так как они уже созданы для нас с помощью very_good_cli.

Настройка Firebase для различных сред

Недавно Firebase представила интерфейс командной строки Firebase, который упростил и упростил настройку проектов Firebase. Однако некоторые функции, такие как аналитика и вход через Google, пока не поддерживаются. Поскольку мы будем использовать Google Sign-in, нам нужно вручную настроить Firebase. Поэтому мы будем вручную настраивать наши проекты Firebase.

В нашей консоли Firebase мы создадим три разных проекта следующим образом:

  • flavor dev
  • flavor stg
  • flavor prodПроект Firebase разных вкусов

При регистрации нашего проекта Flutter в Firebase мы должны добавить .dev, .stgили .prdк имени нашего пакета Android.

Вы можете найти имя пакета в вашем android/app/build.gradleфайле. Он отображается как applicationId, как показано ниже.

 defaultConfig {
        applicationId "com.example.verygoodcore.googlesigninwithflavor"
        minSdkVersion flutter.minSdkVersion
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
    flavorDimensions "default"
    productFlavors { 
        production {
            dimension "default"
            applicationIdSuffix ""
            manifestPlaceholders = [appName: "Googlesigninwithflavor"]
        }
        staging {
            dimension "default"
            applicationIdSuffix ".stg"
            manifestPlaceholders = [appName: "[STG] Googlesigninwithflavor"]
        }        
        development {
            dimension "default"
            applicationIdSuffix ".dev"
            manifestPlaceholders = [appName: "[DEV] Googlesigninwithflavor"]
        }
    }

для iOS

При регистрации для iOS нам также необходимо ввести правильный идентификатор пакета. Однако в Xcode может быть сложно ориентироваться, если у вас нет предыдущего опыта работы с ним. Мы можем найти идентификатор пакета, выполнив следующие действия:

Абра или XcodeЧто вы видите, когда открываете Xcode

Щелкните Open a project or file.

Перейдите в свой проект Flutter и откройте каталог iOS. Выберите Runner.xcworkspaceкаталог.

Затем щелкните раскрывающееся меню Runner. На вкладке «Общий вид» выберите Build Settings, и мы сразу же найдем наш пакет приложений.

Мы повторим эти шаги для всех наших проектов Firebase. После регистрации мы можем скачать google-services.jsonфайл для Android и GoogleService-Info.plistiOS.

Файлы google-services.jsonбудут перемещены в android/app/src/{respective environment}. Для iOS мы создадим новый каталог конфигурации, в котором есть подкаталоги наших сред, и добавим GoogleService-Info.plistих в различные среды. Давайте добавим этот файл Runnerв Xcode. Прочтите это руководство по Firebase для получения дополнительной информации.

Конфигурация для реализации аутентификации Google

Чтобы использовать аутентификацию Google в нашем приложении, нам нужно включить Google Provider, выполнив следующие действия. Мы включим Google Provider в нашей среде разработки.

Получите доступ к Firebase. В этом уроке мы начнем с проекта разработки.

На главной панели навигации выберите Аутентификация. Вы должны увидеть следующее:Включение аутентификации

Затем щелкните Set up sign-in method. Отобразится список поставщиков. Выберите Google Login, и вы увидите это:Войти в Google

Активируйте Enableи добавьте адрес электронной почты поддержки для проекта, как показано на изображении ниже. Затем сохраните настройки.Добавить электронную почту поддержки проекта

На панели навигации щелкните значок настроек и выберите Project settingsиз раскрывающегося списка. Затем прокрутите страницу вниз. Нам нужно добавить a SHA-1 keyи a SHA-256 keyиз нашего проекта.

Чтобы добавить ключи SHA или отпечатки пальцев, мы вернемся к нашему проекту, щелкнем правой кнопкой мыши папку Android и выберем Open in an integrated terminal. Это должно открыть для нас новый терминал в нашей среде VS Code.

В вашем терминале используйте команду ./gradlew signingReportдля получения ключей. После запуска этой команды мы должны получить несколько ключей подписи из-за различных сред. Используйте отладочные ключи SHA-1 для разработки в своем терминале.

Альтернатива: в терминале вашего редактора кода вы можете изменить каталог на папку Android и запустить команду.Отпечатки пальцев/ключи SHA

Нажмите кнопку «Сохранить» и загрузите google-services.jsonобновленный файл. Замените google-services.jsonфайл в вашей среде разработки. В нашем случае мы добавим его в среду разработки.

Примечание. Ключ SHA-1 требуется Firebase для правильной работы входа через Google.

Мы только что включили аутентификацию Google! Мы реализуем это в следующем разделе.

Реализация аутентификации Google в нашем проекте Flutter

Мы будем использовать блок для нашего управления состоянием. Bloc — менеджер состояний, добавленный very_good_cli.

Создание репозитория

Репозиторий похож на службу, которая обслуживает наш блок данными, которые нам нужно отправить на наш уровень пользовательского интерфейса. Репозиторий отвечает за выполнение прямых вызовов API по запросу блока. Мы реализуем наш репозиторий следующим образом:

import 'dart:developer';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthenticationRepository {
  Future<bool> signInWithGoogle() async {
    try {
      final user = GoogleSignIn().currentUser ?? await GoogleSignIn().signIn();
      if (user != null) {
        await GoogleSignIn().signOut();
      }
      final googleAuth = await user?.authentication;
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth?.accessToken,
        idToken: googleAuth?.idToken,
      );
      await FirebaseAuth.instance.signInWithCredential(credential);
      return true;
    } catch (e) {
      log('An Error Occurred $e');
      return false;
    }
  }
  
  Future<void> handleSignOut() => GoogleSignIn().disconnect();
  // Future<void> signOut() async {
  //   final _googleSignIn = GoogleSignIn();
  //   _googleSignIn.disconnect();
  // }
}

блокировать события

Для нашего проекта нам понадобятся два события GoogleSignInRequestedи GoogleSignOutRequested. Мы можем реализовать это следующим образом:

part of 'google_sign_in_bloc.dart';
abstract class GoogleSignInEvent extends Equatable {
  const GoogleSignInEvent();
  @override
  List<Object> get props => [];
}
class GoogleSignInRequested extends GoogleSignInEvent {}
class GoogleSignOutRequested extends GoogleSignInEvent {}

Создание состояния блока

Нам также понадобятся два состояния — одно, когда пользователь есть, Authenticatedи одно, когда пользователь UnAuthenticated:

part of 'google_sign_in_bloc.dart';
abstract class GoogleSignInState extends Equatable {
  @override
  List<Object?> get props => [];
}
class UnAuthenticated extends GoogleSignInState {}
class Authenticated extends GoogleSignInState {}

Создаем наш блок

Наш блок будет отображать два состояния нашего пользовательского интерфейса: Authenticatedкогда пользователь вошел в систему и UnAuthenticatedкогда пользователь покидает панель управления.

Давайте реализуем это так:

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:googlesigninwithflavor/repository/authentication_repository.dart';
part 'google_sign_in_event.dart';
part 'google_sign_in_state.dart';
class GoogleSignInBloc extends Bloc<GoogleSignInEvent, GoogleSignInState> {
  GoogleSignInBloc({required this.authenticationRepository})
      : super(UnAuthenticated()) {
    on<GoogleSignInRequested>(_onGoogleSignInPressed);
    on<GoogleSignOutRequested>(_onGoogleSignOutPressed);
  }
  final AuthenticationRepository authenticationRepository;
  Future<void> _onGoogleSignInPressed(
    GoogleSignInRequested event,
    Emitter<GoogleSignInState> emit,
  ) async {
    final response = await authenticationRepository.signInWithGoogle();
    if (response) {
      emit(Authenticated());
    }
  }
  void _onGoogleSignOutPressed(
    GoogleSignOutRequested event,
    Emitter<GoogleSignInState> emit,
  ) {
    authenticationRepository.handleSignOut();
    emit(UnAuthenticated());
  }
}

Создание нашего пользовательского интерфейса

Наш app.dartкласс будет отображать наш экран-заставку следующим образом:

import 'package:flutter/material.dart';
import 'package:googlesigninwithflavor/app/view/google_sign_in_view.dart';
class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        appBarTheme: const AppBarTheme(color: Color(0xFF13B9FF)),
        colorScheme: ColorScheme.fromSwatch(
          accentColor: const Color(0xFF13B9FF),
        ),
      ),
      home: const GoogleSignInView(),
    );
  }
}

google_sign_in_view.dartсохранит реализацию нашего экрана-заставки и кнопку входа в систему.

class GoogleSignInView extends StatelessWidget {
  const GoogleSignInView({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RepositoryProvider(
      create: (context) => AuthenticationRepository(),
      child: BlocProvider(
        create: (context) => GoogleSignInBloc(
          authenticationRepository: RepositoryProvider.of(context),
        ),
        child: Scaffold(
          appBar: AppBar(
            title: const Text('Sign In With Google'),
          ),
          body: const ShowSignInButton(),
        ),
      ),
    );
  }
}

В приведенном выше коде мы используем RepositoryProviderвиджет для создания экземпляра нашего репозитория и дочернего элемента, который даст нам доступ к репозиторию через файлы RepositoryProvider.of(context).

Мы также используем BlocProviderвиджет для создания своего экземпляра, Blocчтобы к нему можно было получить доступ из поддерева или дочерних виджетов.

Затем мы будем использовать блок в наших дочерних виджетах следующим образом:

class ShowSignInButton extends StatelessWidget {
  const ShowSignInButton({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return BlocListener<GoogleSignInBloc, GoogleSignInState>(
      listener: (context, state) {
        if (state is Authenticated) {
          Navigator.push<Type>(
            context,
            MaterialPageRoute(builder: (_) => const DashBoard()),
          );
        }
      },
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Center(
            child: Image.asset(
              'asset/google2.png',
              height: 60,
            ),
          ),
          ElevatedButton(
            onPressed: () {
              context.read<GoogleSignInBloc>().add(GoogleSignInRequested());
            },
            child: const Text('Sign In With Google'),
          ),
        ],
      ),
    );
  }
}

Здесь мы используем BlocListnerдля перехода к другому экрану в зависимости от состояния, испускаемого блоком.

Мы также передаем GoogleSignInRequestedсобытие в наш ElevatedButton, поэтому, когда пользователь нажимает кнопку для входа в Google, событие передается в блок и делается запрос к GoogleSignInAPI.

Давайте также реализуем экран панели инструментов для отображения сведений о аутентифицированном пользователе. Чтобы реализовать это, нам нужно вызвать экземпляр Firebase Auth, чтобы получить доступ к данным текущего пользователя. Мы также создадим кнопку выхода, которая вернет пользователя на экран входа с помощью BlocListnerвиджета:

class DashBoard extends StatelessWidget {
  const DashBoard({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return RepositoryProvider(
      create: (context) => AuthenticationRepository(),
      child: BlocProvider(
        create: (context) => GoogleSignInBloc(
          authenticationRepository: RepositoryProvider.of(context),
        ),
        child: DashBoardDetails(),
      ),
    );
  }
}
class DashBoardDetails extends StatelessWidget {
  DashBoardDetails({
    Key? key,
  }) : super(key: key);
  final user = FirebaseAuth.instance.currentUser!;
  @override
  Widget build(BuildContext context) {
    return BlocListener<GoogleSignInBloc, GoogleSignInState>(
      listener: (context, state) {
        if (state is UnAuthenticated) {
          Navigator.of(context).pushAndRemoveUntil<Type>(
            MaterialPageRoute(builder: (context) => const GoogleSignInView()),
            (route) => false,
          );
        }
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Very Good Codemagic'),
        ),
        body: BlocBuilder<GoogleSignInBloc, GoogleSignInState>(
          builder: (context, state) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Center(
                  child: Text('Welcome to your Dashboard'),
                ),
                Text('${user.displayName}'),
                if (user.photoURL != null)
                  Image.network('${user.photoURL}')
                else
                  Container(),
                ElevatedButton(
                  onPressed: () {
                    context
                        .read<GoogleSignInBloc>()
                        .add(GoogleSignOutRequested());
                  },
                  child: const Text('Sign Out'),
                )
              ],
            );
          },
        ),
      ),
    );
  }
}

Жить! 🎉 Мы только что успешно создали аутентификацию входа через Google для наших сред разработки, промежуточной и производственной среды.


источник: https://blog.codemagic.io

#flutter 

Как добавить многофакторную аутентификацию во Flutter
Mike  Kozey

Mike Kozey

1656750905

Question_wizard: This Library Allows You to Play A Wizard Game

question_wizard

This library allows you to play a wizard game.

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add question_wizard

With Flutter:

 $ flutter pub add question_wizard

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  question_wizard: ^0.0.1

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:question_wizard/question_wizard.dart';

example/main.dart

import 'package:question_wizard/question_wizard.dart';

void main() {
  final List<Option> options = [
    new Option(label: 'choose a blue color', value: '#0000FF'),
    new Option(label: 'choose a green color', value: '#00FF00'),
  ];
  Prompter prompter = Prompter();

  String? colorCode = prompter.askMultiple('select a color:', options);
  bool answer = prompter.askBinary('do you like this package 🥰');

  if (answer) {
    print("thank's a lot buddy 😊");
  } else {
    print("I know that's not a great package. 😔");
  }
}

Original article source at: https://pub.dev/packages/question_wizard 

#flutter #dart #game 

Question_wizard: This Library Allows You to Play A Wizard Game

Flutter Dropdown to Handle Error and Prevent Exception

TODO: Put a short description of the package here that helps potential users know whether this package might be useful for them.

Features

TODO: List what your package can do. Maybe include images, gifs, or videos.

Getting started

TODO: List prerequisites and provide or point to information on how to start using the package.

Usage

TODO: Include short and useful examples for package users. Add longer examples to /example folder.

const like = 'sample';

Additional information

TODO: Tell users more about the package: where to find more information, how to contribute to the package, how to file issues, what response they can expect from the package authors, and more. 

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add smart_dropdown_field

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  smart_dropdown_field: ^0.0.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:smart_dropdown_field/smart_dropdown_field.dart'; 

Download Details:

Author: PhilipPurwoko

Source Code: https://github.com/PhilipPurwoko/smart_dropdown_field

#flutter #dropdown 

Flutter Dropdown to Handle Error and Prevent Exception

Local Storage inspector for Flutter

Plugin providing shared preferences inspector capabilities for local storage inspector.

See https://pub.dev/packages/storage_inspector

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add preferences_local_storage_inspector

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  preferences_local_storage_inspector: ^0.2.3

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:preferences_local_storage_inspector/preferences_local_storage_inspector.dart'; 

example/example.dart

import 'package:flutter/material.dart';
import 'package:preferences_local_storage_inspector/preferences_local_storage_inspector.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:storage_inspector/storage_inspector.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // ignore: avoid_print
  storageInspectorLogger = (e) => print(e);

  final preferences = await SharedPreferences.getInstance();

  final driver = StorageServerDriver(
    bundleId: 'com.example.test',
    icon: '<some icon>',
  );
  final keyValueServer =
      PreferencesKeyValueServer(preferences, 'Preferences', keySuggestions: {
    const ValueWithType(StorageType.string, 'testBool'),
    const ValueWithType(StorageType.string, 'testInt'),
    const ValueWithType(StorageType.string, 'testFloat'),
  });
  driver.addKeyValueServer(keyValueServer);

  // Don't wait for a connection from the instrumentation driver
  await driver.start(paused: false);

  // run app
  await Future<void>.delayed(const Duration(minutes: 15));

  await driver.stop(); //Optional when main ends
} 

Download Details:

Author: NicolaVerbeeck

Source Code: https://github.com/NicolaVerbeeck/flutter_local_storage_inspector

#flutter #android #ios 

Local Storage inspector for Flutter
Hunter  Krajcik

Hunter Krajcik

1656746160

Bungie-api-dart: Dart Definitions for The Bungie.net API

Bungie API Dart support

This project implements Dart definitions and API helpers for the Bungie.net API. It's based on bungie-api-ts that is meant for use in Destiny Item Manager, but should be general enough to use in any project. The code is completely generated from Bungie's documentation - I considered using something like Swagger Codegen, but instead opted for a custom generator so we could make the result as nice as possible.

Install

add this to your dependencies block in pubspec.yaml

dependencies:
  bungie_api: ^12.2.4

Interfaces and Enums

There are definitions for every type defined in the Bungie.net services. See their documentation for a list - the interface names are the last part of the full name (for example, Destiny.Definitions.DestinyVendorActionDefinition becomes DestinyVendorActionDefinition). There are a few exceptions, like SingleComponentResponseOfDestinyInventoryComponent, which have been mapped into nicer forms like SingleComponentResponse<DestinyInventoryComponent>, and the server responses, which are now ServerResponse<T> instead of something like DestinyCharacterResponse.

API Helpers

In addition to the types, there are also simple helper functions for each API endpoint. They define the inputs and outputs to that endpoint, and will call a user-provided function with HTTP request info that you can then use to make an HTTP request. This pattern was used so the API helpers could provide full type information. These helpers are not a full API client - they assist in building one. An example:

import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:bungie_api_dart/destiny2.dart';

class BungieApiService{
  Future<ServerResponse<DestinyManifest>> getManifest(){
    return getDestinyManifest(new Client());
  }
}
class Client implements HttpClient{
  static const API_KEY = "your_key";
  @override
    Future<Object> request(HttpClientConfig config) {
      if(config.method == 'GET'){
        return http.get(config.url, headers: {'X-API-Key': API_KEY});
      }
      return http.post(config.url, headers: {'X-API-Key': API_KEY});
    }
}

Build

./install.sh && ./build.sh

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add bungie_api

With Flutter:

 $ flutter pub add bungie_api

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  bungie_api: ^13.14.0

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:bungie_api/api/app.dart';
import 'package:bungie_api/api/community_content.dart';
import 'package:bungie_api/api/content.dart';
import 'package:bungie_api/api/destiny2.dart';
import 'package:bungie_api/api/fireteam.dart';
import 'package:bungie_api/api/forum.dart';
import 'package:bungie_api/api/get_available_locales.dart';
import 'package:bungie_api/api/global_alerts.dart';
import 'package:bungie_api/api/group_v2.dart';
import 'package:bungie_api/api/settings.dart';
import 'package:bungie_api/api/social.dart';
import 'package:bungie_api/api/tokens.dart';
import 'package:bungie_api/api/trending.dart';
import 'package:bungie_api/api/user.dart';
import 'package:bungie_api/api/user_system_overrides.dart';
import 'package:bungie_api/app.dart';
import 'package:bungie_api/applications.dart';
import 'package:bungie_api/common.dart';
import 'package:bungie_api/communitycontent.dart';
import 'package:bungie_api/components.dart';
import 'package:bungie_api/config.dart';
import 'package:bungie_api/content.dart';
import 'package:bungie_api/core.dart';
import 'package:bungie_api/dates.dart';
import 'package:bungie_api/destiny2.dart';
import 'package:bungie_api/entities.dart';
import 'package:bungie_api/enums/activity_graph_node_highlight_type.dart';
import 'package:bungie_api/enums/application_scopes.dart';
import 'package:bungie_api/enums/application_status.dart';
import 'package:bungie_api/enums/awa_response_reason.dart';
import 'package:bungie_api/enums/awa_type.dart';
import 'package:bungie_api/enums/awa_user_selection.dart';
import 'package:bungie_api/enums/bucket_category.dart';
import 'package:bungie_api/enums/bucket_scope.dart';
import 'package:bungie_api/enums/bungie_credential_type.dart';
import 'package:bungie_api/enums/bungie_membership_type.dart';
import 'package:bungie_api/enums/capabilities.dart';
import 'package:bungie_api/enums/chat_security_setting.dart';
import 'package:bungie_api/enums/community_content_sort_mode.dart';
import 'package:bungie_api/enums/component_privacy_setting.dart';
import 'package:bungie_api/enums/content_property_data_type_enum.dart';
import 'package:bungie_api/enums/damage_type.dart';
import 'package:bungie_api/enums/destiny_activity_difficulty_tier.dart';
import 'package:bungie_api/enums/destiny_activity_mode_category.dart';
import 'package:bungie_api/enums/destiny_activity_mode_type.dart';
import 'package:bungie_api/enums/destiny_activity_nav_point_type.dart';
import 'package:bungie_api/enums/destiny_ammunition_type.dart';
import 'package:bungie_api/enums/destiny_breaker_type.dart';
import 'package:bungie_api/enums/destiny_class.dart';
import 'package:bungie_api/enums/destiny_collectible_state.dart';
import 'package:bungie_api/enums/destiny_component_type.dart';
import 'package:bungie_api/enums/destiny_energy_type.dart';
import 'package:bungie_api/enums/destiny_game_privacy_setting.dart';
import 'package:bungie_api/enums/destiny_game_versions.dart';
import 'package:bungie_api/enums/destiny_gating_scope.dart';
import 'package:bungie_api/enums/destiny_gender.dart';
import 'package:bungie_api/enums/destiny_graph_node_state.dart';
import 'package:bungie_api/enums/destiny_item_sort_type.dart';
import 'package:bungie_api/enums/destiny_item_sub_type.dart';
import 'package:bungie_api/enums/destiny_item_type.dart';
import 'package:bungie_api/enums/destiny_join_closed_reasons.dart';
import 'package:bungie_api/enums/destiny_milestone_display_preference.dart';
import 'package:bungie_api/enums/destiny_milestone_type.dart';
import 'package:bungie_api/enums/destiny_objective_grant_style.dart';
import 'package:bungie_api/enums/destiny_objective_ui_style.dart';
import 'package:bungie_api/enums/destiny_party_member_states.dart';
import 'package:bungie_api/enums/destiny_presentation_display_style.dart';
import 'package:bungie_api/enums/destiny_presentation_node_state.dart';
import 'package:bungie_api/enums/destiny_presentation_node_type.dart';
import 'package:bungie_api/enums/destiny_presentation_screen_style.dart';
import 'package:bungie_api/enums/destiny_progression_reward_item_acquisition_behavior.dart';
import 'package:bungie_api/enums/destiny_progression_reward_item_state.dart';
import 'package:bungie_api/enums/destiny_progression_scope.dart';
import 'package:bungie_api/enums/destiny_progression_step_display_effect.dart';
import 'package:bungie_api/enums/destiny_race.dart';
import 'package:bungie_api/enums/destiny_record_state.dart';
import 'package:bungie_api/enums/destiny_record_toast_style.dart';
import 'package:bungie_api/enums/destiny_record_value_style.dart';
import 'package:bungie_api/enums/destiny_reward_source_category.dart';
import 'package:bungie_api/enums/destiny_scope.dart';
import 'package:bungie_api/enums/destiny_socket_array_type.dart';
import 'package:bungie_api/enums/destiny_socket_category_style.dart';
import 'package:bungie_api/enums/destiny_socket_visibility.dart';
import 'package:bungie_api/enums/destiny_stat_aggregation_type.dart';
import 'package:bungie_api/enums/destiny_stat_category.dart';
import 'package:bungie_api/enums/destiny_stats_category_type.dart';
import 'package:bungie_api/enums/destiny_stats_group_type.dart';
import 'package:bungie_api/enums/destiny_stats_merge_method.dart';
import 'package:bungie_api/enums/destiny_talent_node_state.dart';
import 'package:bungie_api/enums/destiny_talent_node_step_damage_types.dart';
import 'package:bungie_api/enums/destiny_talent_node_step_guardian_attributes.dart';
import 'package:bungie_api/enums/destiny_talent_node_step_impact_effects.dart';
import 'package:bungie_api/enums/destiny_talent_node_step_light_abilities.dart';
import 'package:bungie_api/enums/destiny_talent_node_step_weapon_performances.dart';
import 'package:bungie_api/enums/destiny_unlock_value_uistyle.dart';
import 'package:bungie_api/enums/destiny_vendor_filter.dart';
import 'package:bungie_api/enums/destiny_vendor_interaction_reward_selection.dart';
import 'package:bungie_api/enums/destiny_vendor_item_refund_policy.dart';
import 'package:bungie_api/enums/destiny_vendor_item_state.dart';
import 'package:bungie_api/enums/destiny_vendor_progression_type.dart';
import 'package:bungie_api/enums/destiny_vendor_reply_type.dart';
import 'package:bungie_api/enums/developer_role.dart';
import 'package:bungie_api/enums/equip_failure_reason.dart';
import 'package:bungie_api/enums/equipping_item_block_attributes.dart';
import 'package:bungie_api/enums/fireteam_date_range.dart';
import 'package:bungie_api/enums/fireteam_platform.dart';
import 'package:bungie_api/enums/fireteam_platform_invite_result.dart';
import 'package:bungie_api/enums/fireteam_public_search_option.dart';
import 'package:bungie_api/enums/fireteam_slot_search.dart';
import 'package:bungie_api/enums/forum_flags_enum.dart';
import 'package:bungie_api/enums/forum_media_type.dart';
import 'package:bungie_api/enums/forum_post_category_enums.dart';
import 'package:bungie_api/enums/forum_post_popularity.dart';
import 'package:bungie_api/enums/forum_post_sort_enum.dart';
import 'package:bungie_api/enums/forum_recruitment_intensity_label.dart';
import 'package:bungie_api/enums/forum_recruitment_tone_label.dart';
import 'package:bungie_api/enums/forum_topics_category_filters_enum.dart';
import 'package:bungie_api/enums/forum_topics_quick_date_enum.dart';
import 'package:bungie_api/enums/forum_topics_sort_enum.dart';
import 'package:bungie_api/enums/friend_relationship_state.dart';
import 'package:bungie_api/enums/global_alert_level.dart';
import 'package:bungie_api/enums/global_alert_type.dart';
import 'package:bungie_api/enums/group_alliance_status.dart';
import 'package:bungie_api/enums/group_application_resolve_state.dart';
import 'package:bungie_api/enums/group_date_range.dart';
import 'package:bungie_api/enums/group_homepage.dart';
import 'package:bungie_api/enums/group_member_count_filter.dart';
import 'package:bungie_api/enums/group_post_publicity.dart';
import 'package:bungie_api/enums/group_potential_member_status.dart';
import 'package:bungie_api/enums/group_sort_by.dart';
import 'package:bungie_api/enums/group_type.dart';
import 'package:bungie_api/enums/groups_for_member_filter.dart';
import 'package:bungie_api/enums/host_guided_games_permission_level.dart';
import 'package:bungie_api/enums/ignore_length.dart';
import 'package:bungie_api/enums/ignore_status.dart';
import 'package:bungie_api/enums/item_bind_status.dart';
import 'package:bungie_api/enums/item_location.dart';
import 'package:bungie_api/enums/item_perk_visibility.dart';
import 'package:bungie_api/enums/item_state.dart';
import 'package:bungie_api/enums/membership_option.dart';
import 'package:bungie_api/enums/opt_in_flags.dart';
import 'package:bungie_api/enums/period_type.dart';
import 'package:bungie_api/enums/platform_error_codes.dart';
import 'package:bungie_api/enums/platform_friend_type.dart';
import 'package:bungie_api/enums/plug_availability_mode.dart';
import 'package:bungie_api/enums/plug_ui_styles.dart';
import 'package:bungie_api/enums/presence_online_state_flags.dart';
import 'package:bungie_api/enums/presence_status.dart';
import 'package:bungie_api/enums/runtime_group_member_type.dart';
import 'package:bungie_api/enums/socket_plug_sources.dart';
import 'package:bungie_api/enums/socket_type_action_type.dart';
import 'package:bungie_api/enums/special_item_type.dart';
import 'package:bungie_api/enums/tier_type.dart';
import 'package:bungie_api/enums/transfer_statuses.dart';
import 'package:bungie_api/enums/trending_entry_type.dart';
import 'package:bungie_api/enums/unit_type.dart';
import 'package:bungie_api/enums/vendor_display_category_sort_order.dart';
import 'package:bungie_api/enums/vendor_interaction_type.dart';
import 'package:bungie_api/enums/vendor_item_status.dart';
import 'package:bungie_api/exceptions.dart';
import 'package:bungie_api/fireteam.dart';
import 'package:bungie_api/forum.dart';
import 'package:bungie_api/forums.dart';
import 'package:bungie_api/getavailablelocales.dart';
import 'package:bungie_api/globalalerts.dart';
import 'package:bungie_api/groupsv2.dart';
import 'package:bungie_api/groupv2.dart';
import 'package:bungie_api/helpers/base_bungie_net_response.dart';
import 'package:bungie_api/helpers/bungie_net_token.dart';
import 'package:bungie_api/helpers/http.dart';
import 'package:bungie_api/helpers/oauth.dart';
import 'package:bungie_api/ignores.dart';
import 'package:bungie_api/interpolation.dart';
import 'package:bungie_api/links.dart';
import 'package:bungie_api/models/api_usage.dart';
import 'package:bungie_api/models/application.dart';
import 'package:bungie_api/models/application_developer.dart';
import 'package:bungie_api/models/awa_authorization_result.dart';
import 'package:bungie_api/models/awa_initialize_response.dart';
import 'package:bungie_api/models/awa_permission_requested.dart';
import 'package:bungie_api/models/awa_user_response.dart';
import 'package:bungie_api/models/bungie_friend.dart';
import 'package:bungie_api/models/bungie_friend_list_response.dart';
import 'package:bungie_api/models/bungie_friend_request_list_response.dart';
import 'package:bungie_api/models/clan_banner.dart';
import 'package:bungie_api/models/clan_banner_decal.dart';
import 'package:bungie_api/models/clan_banner_source.dart';
import 'package:bungie_api/models/comment_summary.dart';
import 'package:bungie_api/models/component_response.dart';
import 'package:bungie_api/models/content_item_public_contract.dart';
import 'package:bungie_api/models/content_preview.dart';
import 'package:bungie_api/models/content_representation.dart';
import 'package:bungie_api/models/content_type_default_value.dart';
import 'package:bungie_api/models/content_type_description.dart';
import 'package:bungie_api/models/content_type_property.dart';
import 'package:bungie_api/models/content_type_property_section.dart';
import 'package:bungie_api/models/core_setting.dart';
import 'package:bungie_api/models/core_settings_configuration.dart';
import 'package:bungie_api/models/core_system.dart';
import 'package:bungie_api/models/cross_save_user_membership.dart';
import 'package:bungie_api/models/datapoint.dart';
import 'package:bungie_api/models/date_range.dart';
import 'package:bungie_api/models/destiny2_core_settings.dart';
import 'package:bungie_api/models/destiny_action_request.dart';
import 'package:bungie_api/models/destiny_activity.dart';
import 'package:bungie_api/models/destiny_activity_challenge_definition.dart';
import 'package:bungie_api/models/destiny_activity_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_art_element_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_connection_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_display_objective_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_display_progression_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_list_entry_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_node_activity_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_node_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_node_featuring_state_definition.dart';
import 'package:bungie_api/models/destiny_activity_graph_node_state_entry.dart';
import 'package:bungie_api/models/destiny_activity_guided_block_definition.dart';
import 'package:bungie_api/models/destiny_activity_history_results.dart';
import 'package:bungie_api/models/destiny_activity_insertion_point_definition.dart';
import 'package:bungie_api/models/destiny_activity_loadout_requirement.dart';
import 'package:bungie_api/models/destiny_activity_loadout_requirement_set.dart';
import 'package:bungie_api/models/destiny_activity_matchmaking_block_definition.dart';
import 'package:bungie_api/models/destiny_activity_mode_definition.dart';
import 'package:bungie_api/models/destiny_activity_modifier_definition.dart';
import 'package:bungie_api/models/destiny_activity_modifier_reference_definition.dart';
import 'package:bungie_api/models/destiny_activity_playlist_item_definition.dart';
import 'package:bungie_api/models/destiny_activity_reward_definition.dart';
import 'package:bungie_api/models/destiny_activity_type_definition.dart';
import 'package:bungie_api/models/destiny_activity_unlock_string_definition.dart';
import 'package:bungie_api/models/destiny_aggregate_activity_results.dart';
import 'package:bungie_api/models/destiny_aggregate_activity_stats.dart';
import 'package:bungie_api/models/destiny_animation_reference.dart';
import 'package:bungie_api/models/destiny_art_dye_reference.dart';
import 'package:bungie_api/models/destiny_artifact_character_scoped.dart';
import 'package:bungie_api/models/destiny_artifact_definition.dart';
import 'package:bungie_api/models/destiny_artifact_profile_scoped.dart';
import 'package:bungie_api/models/destiny_artifact_tier.dart';
import 'package:bungie_api/models/destiny_artifact_tier_definition.dart';
import 'package:bungie_api/models/destiny_artifact_tier_item.dart';
import 'package:bungie_api/models/destiny_artifact_tier_item_definition.dart';
import 'package:bungie_api/models/destiny_base_item_component_set_ofint32.dart';
import 'package:bungie_api/models/destiny_base_item_component_set_ofint64.dart';
import 'package:bungie_api/models/destiny_base_item_component_set_ofuint32.dart';
import 'package:bungie_api/models/destiny_breaker_type_definition.dart';
import 'package:bungie_api/models/destiny_bubble_definition.dart';
import 'package:bungie_api/models/destiny_challenge_status.dart';
import 'package:bungie_api/models/destiny_character_action_request.dart';
import 'package:bungie_api/models/destiny_character_activities_component.dart';
import 'package:bungie_api/models/destiny_character_component.dart';
import 'package:bungie_api/models/destiny_character_customization.dart';
import 'package:bungie_api/models/destiny_character_peer_view.dart';
import 'package:bungie_api/models/destiny_character_progression_component.dart';
import 'package:bungie_api/models/destiny_character_records_component.dart';
import 'package:bungie_api/models/destiny_character_render_component.dart';
import 'package:bungie_api/models/destiny_character_response.dart';
import 'package:bungie_api/models/destiny_checklist_definition.dart';
import 'package:bungie_api/models/destiny_checklist_entry_definition.dart';
import 'package:bungie_api/models/destiny_clan_aggregate_stat.dart';
import 'package:bungie_api/models/destiny_class_definition.dart';
import 'package:bungie_api/models/destiny_collectible_acquisition_block.dart';
import 'package:bungie_api/models/destiny_collectible_component.dart';
import 'package:bungie_api/models/destiny_collectible_definition.dart';
import 'package:bungie_api/models/destiny_collectible_node_detail_response.dart';
import 'package:bungie_api/models/destiny_collectible_state_block.dart';
import 'package:bungie_api/models/destiny_collectibles_component.dart';
import 'package:bungie_api/models/destiny_color.dart';
import 'package:bungie_api/models/destiny_craftable_component.dart';
import 'package:bungie_api/models/destiny_craftable_socket_component.dart';
import 'package:bungie_api/models/destiny_craftable_socket_plug_component.dart';
import 'package:bungie_api/models/destiny_craftables_component.dart';
import 'package:bungie_api/models/destiny_currencies_component.dart';
import 'package:bungie_api/models/destiny_damage_type_definition.dart';
import 'package:bungie_api/models/destiny_definition.dart';
import 'package:bungie_api/models/destiny_derived_item_category_definition.dart';
import 'package:bungie_api/models/destiny_derived_item_definition.dart';
import 'package:bungie_api/models/destiny_destination_bubble_setting_definition.dart';
import 'package:bungie_api/models/destiny_destination_definition.dart';
import 'package:bungie_api/models/destiny_display_category_definition.dart';
import 'package:bungie_api/models/destiny_display_properties_definition.dart';
import 'package:bungie_api/models/destiny_energy_capacity_entry.dart';
import 'package:bungie_api/models/destiny_energy_cost_entry.dart';
import 'package:bungie_api/models/destiny_energy_type_definition.dart';
import 'package:bungie_api/models/destiny_entity_search_result.dart';
import 'package:bungie_api/models/destiny_entity_search_result_item.dart';
import 'package:bungie_api/models/destiny_environment_location_mapping.dart';
import 'package:bungie_api/models/destiny_equip_item_result.dart';
import 'package:bungie_api/models/destiny_equip_item_results.dart';
import 'package:bungie_api/models/destiny_equipment_slot_definition.dart';
import 'package:bungie_api/models/destiny_equipping_block_definition.dart';
import 'package:bungie_api/models/destiny_error_profile.dart';
import 'package:bungie_api/models/destiny_faction_definition.dart';
import 'package:bungie_api/models/destiny_faction_progression.dart';
import 'package:bungie_api/models/destiny_faction_vendor_definition.dart';
import 'package:bungie_api/models/destiny_gear_art_arrangement_reference.dart';
import 'package:bungie_api/models/destiny_gender_definition.dart';
import 'package:bungie_api/models/destiny_historical_stats_account_result.dart';
import 'package:bungie_api/models/destiny_historical_stats_activity.dart';
import 'package:bungie_api/models/destiny_historical_stats_by_period.dart';
import 'package:bungie_api/models/destiny_historical_stats_definition.dart';
import 'package:bungie_api/models/destiny_historical_stats_per_character.dart';
import 'package:bungie_api/models/destiny_historical_stats_period_group.dart';
import 'package:bungie_api/models/destiny_historical_stats_results.dart';
import 'package:bungie_api/models/destiny_historical_stats_value.dart';
import 'package:bungie_api/models/destiny_historical_stats_value_pair.dart';
import 'package:bungie_api/models/destiny_historical_stats_with_merged.dart';
import 'package:bungie_api/models/destiny_historical_weapon_stats.dart';
import 'package:bungie_api/models/destiny_historical_weapon_stats_data.dart';
import 'package:bungie_api/models/destiny_icon_sequence_definition.dart';
import 'package:bungie_api/models/destiny_insert_plug_action_definition.dart';
import 'package:bungie_api/models/destiny_insert_plugs_action_request.dart';
import 'package:bungie_api/models/destiny_insert_plugs_free_action_request.dart';
import 'package:bungie_api/models/destiny_insert_plugs_request_entry.dart';
import 'package:bungie_api/models/destiny_inventory_bucket_definition.dart';
import 'package:bungie_api/models/destiny_inventory_component.dart';
import 'package:bungie_api/models/destiny_inventory_item_definition.dart';
import 'package:bungie_api/models/destiny_inventory_item_stat_definition.dart';
import 'package:bungie_api/models/destiny_item_action_block_definition.dart';
import 'package:bungie_api/models/destiny_item_action_request.dart';
import 'package:bungie_api/models/destiny_item_action_required_item_definition.dart';
import 'package:bungie_api/models/destiny_item_category_definition.dart';
import 'package:bungie_api/models/destiny_item_change_response.dart';
import 'package:bungie_api/models/destiny_item_component.dart';
import 'package:bungie_api/models/destiny_item_component_set_ofint32.dart';
import 'package:bungie_api/models/destiny_item_component_set_ofint64.dart';
import 'package:bungie_api/models/destiny_item_component_set_ofuint32.dart';
import 'package:bungie_api/models/destiny_item_crafting_block_bonus_plug_definition.dart';
import 'package:bungie_api/models/destiny_item_crafting_block_definition.dart';
import 'package:bungie_api/models/destiny_item_creation_entry_level_definition.dart';
import 'package:bungie_api/models/destiny_item_gearset_block_definition.dart';
import 'package:bungie_api/models/destiny_item_instance_component.dart';
import 'package:bungie_api/models/destiny_item_instance_energy.dart';
import 'package:bungie_api/models/destiny_item_intrinsic_socket_entry_definition.dart';
import 'package:bungie_api/models/destiny_item_inventory_block_definition.dart';
import 'package:bungie_api/models/destiny_item_investment_stat_definition.dart';
import 'package:bungie_api/models/destiny_item_metric_block_definition.dart';
import 'package:bungie_api/models/destiny_item_objective_block_definition.dart';
import 'package:bungie_api/models/destiny_item_objectives_component.dart';
import 'package:bungie_api/models/destiny_item_peer_view.dart';
import 'package:bungie_api/models/destiny_item_perk_entry_definition.dart';
import 'package:bungie_api/models/destiny_item_perks_component.dart';
import 'package:bungie_api/models/destiny_item_plug.dart';
import 'package:bungie_api/models/destiny_item_plug_base.dart';
import 'package:bungie_api/models/destiny_item_plug_component.dart';
import 'package:bungie_api/models/destiny_item_plug_definition.dart';
import 'package:bungie_api/models/destiny_item_plug_objectives_component.dart';
import 'package:bungie_api/models/destiny_item_preview_block_definition.dart';
import 'package:bungie_api/models/destiny_item_quality_block_definition.dart';
import 'package:bungie_api/models/destiny_item_quantity.dart';
import 'package:bungie_api/models/destiny_item_render_component.dart';
import 'package:bungie_api/models/destiny_item_response.dart';
import 'package:bungie_api/models/destiny_item_reusable_plugs_component.dart';
import 'package:bungie_api/models/destiny_item_sack_block_definition.dart';
import 'package:bungie_api/models/destiny_item_set_action_request.dart';
import 'package:bungie_api/models/destiny_item_set_block_definition.dart';
import 'package:bungie_api/models/destiny_item_set_block_entry_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_block_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_category_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_entry_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_entry_plug_item_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_entry_plug_item_randomized_definition.dart';
import 'package:bungie_api/models/destiny_item_socket_state.dart';
import 'package:bungie_api/models/destiny_item_sockets_component.dart';
import 'package:bungie_api/models/destiny_item_source_block_definition.dart';
import 'package:bungie_api/models/destiny_item_source_definition.dart';
import 'package:bungie_api/models/destiny_item_stat_block_definition.dart';
import 'package:bungie_api/models/destiny_item_state_request.dart';
import 'package:bungie_api/models/destiny_item_stats_component.dart';
import 'package:bungie_api/models/destiny_item_summary_block_definition.dart';
import 'package:bungie_api/models/destiny_item_talent_grid_block_definition.dart';
import 'package:bungie_api/models/destiny_item_talent_grid_component.dart';
import 'package:bungie_api/models/destiny_item_tier_type_definition.dart';
import 'package:bungie_api/models/destiny_item_tier_type_infusion_block.dart';
import 'package:bungie_api/models/destiny_item_tooltip_notification.dart';
import 'package:bungie_api/models/destiny_item_transfer_request.dart';
import 'package:bungie_api/models/destiny_item_translation_block_definition.dart';
import 'package:bungie_api/models/destiny_item_value_block_definition.dart';
import 'package:bungie_api/models/destiny_item_vendor_source_reference.dart';
import 'package:bungie_api/models/destiny_item_version_definition.dart';
import 'package:bungie_api/models/destiny_kiosk_item.dart';
import 'package:bungie_api/models/destiny_kiosks_component.dart';
import 'package:bungie_api/models/destiny_leaderboard.dart';
import 'package:bungie_api/models/destiny_leaderboard_entry.dart';
import 'package:bungie_api/models/destiny_leaderboard_results.dart';
import 'package:bungie_api/models/destiny_linked_graph_definition.dart';
import 'package:bungie_api/models/destiny_linked_graph_entry_definition.dart';
import 'package:bungie_api/models/destiny_linked_profiles_response.dart';
import 'package:bungie_api/models/destiny_location_definition.dart';
import 'package:bungie_api/models/destiny_location_release_definition.dart';
import 'package:bungie_api/models/destiny_lore_definition.dart';
import 'package:bungie_api/models/destiny_manifest.dart';
import 'package:bungie_api/models/destiny_material_requirement.dart';
import 'package:bungie_api/models/destiny_material_requirement_set_definition.dart';
import 'package:bungie_api/models/destiny_medal_tier_definition.dart';
import 'package:bungie_api/models/destiny_metric_component.dart';
import 'package:bungie_api/models/destiny_metric_definition.dart';
import 'package:bungie_api/models/destiny_metrics_component.dart';
import 'package:bungie_api/models/destiny_milestone.dart';
import 'package:bungie_api/models/destiny_milestone_activity.dart';
import 'package:bungie_api/models/destiny_milestone_activity_completion_status.dart';
import 'package:bungie_api/models/destiny_milestone_activity_definition.dart';
import 'package:bungie_api/models/destiny_milestone_activity_phase.dart';
import 'package:bungie_api/models/destiny_milestone_activity_variant.dart';
import 'package:bungie_api/models/destiny_milestone_activity_variant_definition.dart';
import 'package:bungie_api/models/destiny_milestone_challenge_activity.dart';
import 'package:bungie_api/models/destiny_milestone_challenge_activity_definition.dart';
import 'package:bungie_api/models/destiny_milestone_challenge_activity_graph_node_entry.dart';
import 'package:bungie_api/models/destiny_milestone_challenge_activity_phase.dart';
import 'package:bungie_api/models/destiny_milestone_challenge_definition.dart';
import 'package:bungie_api/models/destiny_milestone_content.dart';
import 'package:bungie_api/models/destiny_milestone_content_item_category.dart';
import 'package:bungie_api/models/destiny_milestone_definition.dart';
import 'package:bungie_api/models/destiny_milestone_quest.dart';
import 'package:bungie_api/models/destiny_milestone_quest_definition.dart';
import 'package:bungie_api/models/destiny_milestone_quest_reward_item.dart';
import 'package:bungie_api/models/destiny_milestone_quest_rewards_definition.dart';
import 'package:bungie_api/models/destiny_milestone_reward_category.dart';
import 'package:bungie_api/models/destiny_milestone_reward_category_definition.dart';
import 'package:bungie_api/models/destiny_milestone_reward_entry.dart';
import 'package:bungie_api/models/destiny_milestone_reward_entry_definition.dart';
import 'package:bungie_api/models/destiny_milestone_value_definition.dart';
import 'package:bungie_api/models/destiny_milestone_vendor.dart';
import 'package:bungie_api/models/destiny_milestone_vendor_definition.dart';
import 'package:bungie_api/models/destiny_node_activation_requirement.dart';
import 'package:bungie_api/models/destiny_node_socket_replace_response.dart';
import 'package:bungie_api/models/destiny_node_step_definition.dart';
import 'package:bungie_api/models/destiny_objective_definition.dart';
import 'package:bungie_api/models/destiny_objective_display_properties.dart';
import 'package:bungie_api/models/destiny_objective_perk_entry_definition.dart';
import 'package:bungie_api/models/destiny_objective_progress.dart';
import 'package:bungie_api/models/destiny_objective_stat_entry_definition.dart';
import 'package:bungie_api/models/destiny_parent_item_override.dart';
import 'package:bungie_api/models/destiny_perk_reference.dart';
import 'package:bungie_api/models/destiny_place_definition.dart';
import 'package:bungie_api/models/destiny_platform_silver_component.dart';
import 'package:bungie_api/models/destiny_player.dart';
import 'package:bungie_api/models/destiny_plug_item_crafting_requirements.dart';
import 'package:bungie_api/models/destiny_plug_item_crafting_unlock_requirement.dart';
import 'package:bungie_api/models/destiny_plug_rule_definition.dart';
import 'package:bungie_api/models/destiny_plug_set_definition.dart';
import 'package:bungie_api/models/destiny_plug_sets_component.dart';
import 'package:bungie_api/models/destiny_plug_whitelist_entry_definition.dart';
import 'package:bungie_api/models/destiny_position_definition.dart';
import 'package:bungie_api/models/destiny_post_game_carnage_report_data.dart';
import 'package:bungie_api/models/destiny_post_game_carnage_report_entry.dart';
import 'package:bungie_api/models/destiny_post_game_carnage_report_extended_data.dart';
import 'package:bungie_api/models/destiny_post_game_carnage_report_team_entry.dart';
import 'package:bungie_api/models/destiny_postmaster_transfer_request.dart';
import 'package:bungie_api/models/destiny_power_cap_definition.dart';
import 'package:bungie_api/models/destiny_presentation_child_block.dart';
import 'package:bungie_api/models/destiny_presentation_node_base_definition.dart';
import 'package:bungie_api/models/destiny_presentation_node_child_entry.dart';
import 'package:bungie_api/models/destiny_presentation_node_child_entry_base.dart';
import 'package:bungie_api/models/destiny_presentation_node_children_block.dart';
import 'package:bungie_api/models/destiny_presentation_node_collectible_child_entry.dart';
import 'package:bungie_api/models/destiny_presentation_node_component.dart';
import 'package:bungie_api/models/destiny_presentation_node_craftable_child_entry.dart';
import 'package:bungie_api/models/destiny_presentation_node_definition.dart';
import 'package:bungie_api/models/destiny_presentation_node_metric_child_entry.dart';
import 'package:bungie_api/models/destiny_presentation_node_record_child_entry.dart';
import 'package:bungie_api/models/destiny_presentation_node_requirements_block.dart';
import 'package:bungie_api/models/destiny_presentation_nodes_component.dart';
import 'package:bungie_api/models/destiny_profile_collectibles_component.dart';
import 'package:bungie_api/models/destiny_profile_component.dart';
import 'package:bungie_api/models/destiny_profile_progression_component.dart';
import 'package:bungie_api/models/destiny_profile_records_component.dart';
import 'package:bungie_api/models/destiny_profile_response.dart';
import 'package:bungie_api/models/destiny_profile_transitory_component.dart';
import 'package:bungie_api/models/destiny_profile_transitory_current_activity.dart';
import 'package:bungie_api/models/destiny_profile_transitory_joinability.dart';
import 'package:bungie_api/models/destiny_profile_transitory_party_member.dart';
import 'package:bungie_api/models/destiny_profile_transitory_tracking_entry.dart';
import 'package:bungie_api/models/destiny_profile_user_info_card.dart';
import 'package:bungie_api/models/destiny_progression.dart';
import 'package:bungie_api/models/destiny_progression_definition.dart';
import 'package:bungie_api/models/destiny_progression_display_properties_definition.dart';
import 'package:bungie_api/models/destiny_progression_level_requirement_definition.dart';
import 'package:bungie_api/models/destiny_progression_mapping_definition.dart';
import 'package:bungie_api/models/destiny_progression_reset_entry.dart';
import 'package:bungie_api/models/destiny_progression_reward_definition.dart';
import 'package:bungie_api/models/destiny_progression_reward_item_quantity.dart';
import 'package:bungie_api/models/destiny_progression_step_definition.dart';
import 'package:bungie_api/models/destiny_public_activity_status.dart';
import 'package:bungie_api/models/destiny_public_milestone.dart';
import 'package:bungie_api/models/destiny_public_milestone_activity.dart';
import 'package:bungie_api/models/destiny_public_milestone_activity_variant.dart';
import 'package:bungie_api/models/destiny_public_milestone_challenge.dart';
import 'package:bungie_api/models/destiny_public_milestone_challenge_activity.dart';
import 'package:bungie_api/models/destiny_public_milestone_quest.dart';
import 'package:bungie_api/models/destiny_public_milestone_vendor.dart';
import 'package:bungie_api/models/destiny_public_vendor_component.dart';
import 'package:bungie_api/models/destiny_public_vendor_sale_item_component.dart';
import 'package:bungie_api/models/destiny_public_vendors_response.dart';
import 'package:bungie_api/models/destiny_quest_status.dart';
import 'package:bungie_api/models/destiny_race_definition.dart';
import 'package:bungie_api/models/destiny_record_completion_block.dart';
import 'package:bungie_api/models/destiny_record_component.dart';
import 'package:bungie_api/models/destiny_record_definition.dart';
import 'package:bungie_api/models/destiny_record_expiration_block.dart';
import 'package:bungie_api/models/destiny_record_interval_block.dart';
import 'package:bungie_api/models/destiny_record_interval_objective.dart';
import 'package:bungie_api/models/destiny_record_interval_rewards.dart';
import 'package:bungie_api/models/destiny_record_title_block.dart';
import 'package:bungie_api/models/destiny_records_component.dart';
import 'package:bungie_api/models/destiny_report_offense_pgcr_request.dart';
import 'package:bungie_api/models/destiny_report_reason_category_definition.dart';
import 'package:bungie_api/models/destiny_report_reason_definition.dart';
import 'package:bungie_api/models/destiny_reward_source_definition.dart';
import 'package:bungie_api/models/destiny_sandbox_perk_definition.dart';
import 'package:bungie_api/models/destiny_scored_presentation_node_base_definition.dart';
import 'package:bungie_api/models/destiny_season_definition.dart';
import 'package:bungie_api/models/destiny_season_pass_definition.dart';
import 'package:bungie_api/models/destiny_season_preview_definition.dart';
import 'package:bungie_api/models/destiny_season_preview_image_definition.dart';
import 'package:bungie_api/models/destiny_socket_category_definition.dart';
import 'package:bungie_api/models/destiny_socket_type_definition.dart';
import 'package:bungie_api/models/destiny_socket_type_scalar_material_requirement_entry.dart';
import 'package:bungie_api/models/destiny_stat.dart';
import 'package:bungie_api/models/destiny_stat_definition.dart';
import 'package:bungie_api/models/destiny_stat_display_definition.dart';
import 'package:bungie_api/models/destiny_stat_group_definition.dart';
import 'package:bungie_api/models/destiny_stat_override_definition.dart';
import 'package:bungie_api/models/destiny_string_variables_component.dart';
import 'package:bungie_api/models/destiny_talent_exclusive_group.dart';
import 'package:bungie_api/models/destiny_talent_grid_definition.dart';
import 'package:bungie_api/models/destiny_talent_node.dart';
import 'package:bungie_api/models/destiny_talent_node_category.dart';
import 'package:bungie_api/models/destiny_talent_node_definition.dart';
import 'package:bungie_api/models/destiny_talent_node_exclusive_set_definition.dart';
import 'package:bungie_api/models/destiny_talent_node_stat_block.dart';
import 'package:bungie_api/models/destiny_talent_node_step_groups.dart';
import 'package:bungie_api/models/destiny_trait_category_definition.dart';
import 'package:bungie_api/models/destiny_trait_definition.dart';
import 'package:bungie_api/models/destiny_unlock_definition.dart';
import 'package:bungie_api/models/destiny_unlock_expression_definition.dart';
import 'package:bungie_api/models/destiny_unlock_status.dart';
import 'package:bungie_api/models/destiny_unlock_value_definition.dart';
import 'package:bungie_api/models/destiny_vendor_accepted_item_definition.dart';
import 'package:bungie_api/models/destiny_vendor_action_definition.dart';
import 'package:bungie_api/models/destiny_vendor_base_component.dart';
import 'package:bungie_api/models/destiny_vendor_categories_component.dart';
import 'package:bungie_api/models/destiny_vendor_category.dart';
import 'package:bungie_api/models/destiny_vendor_category_entry_definition.dart';
import 'package:bungie_api/models/destiny_vendor_category_overlay_definition.dart';
import 'package:bungie_api/models/destiny_vendor_component.dart';
import 'package:bungie_api/models/destiny_vendor_definition.dart';
import 'package:bungie_api/models/destiny_vendor_display_properties_definition.dart';
import 'package:bungie_api/models/destiny_vendor_group.dart';
import 'package:bungie_api/models/destiny_vendor_group_component.dart';
import 'package:bungie_api/models/destiny_vendor_group_definition.dart';
import 'package:bungie_api/models/destiny_vendor_group_reference.dart';
import 'package:bungie_api/models/destiny_vendor_interaction_definition.dart';
import 'package:bungie_api/models/destiny_vendor_interaction_reply_definition.dart';
import 'package:bungie_api/models/destiny_vendor_interaction_sack_entry_definition.dart';
import 'package:bungie_api/models/destiny_vendor_inventory_flyout_bucket_definition.dart';
import 'package:bungie_api/models/destiny_vendor_inventory_flyout_definition.dart';
import 'package:bungie_api/models/destiny_vendor_item_definition.dart';
import 'package:bungie_api/models/destiny_vendor_item_quantity.dart';
import 'package:bungie_api/models/destiny_vendor_item_socket_override.dart';
import 'package:bungie_api/models/destiny_vendor_location_definition.dart';
import 'package:bungie_api/models/destiny_vendor_receipt.dart';
import 'package:bungie_api/models/destiny_vendor_receipts_component.dart';
import 'package:bungie_api/models/destiny_vendor_requirement_display_entry_definition.dart';
import 'package:bungie_api/models/destiny_vendor_response.dart';
import 'package:bungie_api/models/destiny_vendor_sale_item_action_block_definition.dart';
import 'package:bungie_api/models/destiny_vendor_sale_item_base_component.dart';
import 'package:bungie_api/models/destiny_vendor_sale_item_component.dart';
import 'package:bungie_api/models/destiny_vendor_sale_item_set_component_of_destiny_public_vendor_sale_item_component.dart';
import 'package:bungie_api/models/destiny_vendor_sale_item_set_component_of_destiny_vendor_sale_item_component.dart';
import 'package:bungie_api/models/destiny_vendor_service_definition.dart';
import 'package:bungie_api/models/destiny_vendors_response.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_instance_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_perks_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_plug_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_render_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_reusable_plugs_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_sockets_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_stats_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_item_talent_grid_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint32_and_destiny_vendor_sale_item_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_character_activities_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_character_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_character_progression_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_character_records_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_character_render_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_collectibles_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_craftables_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_currencies_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_inventory_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_instance_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_perks_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_plug_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_render_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_reusable_plugs_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_sockets_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_stats_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_item_talent_grid_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_kiosks_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_plug_sets_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_presentation_nodes_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofint64_and_destiny_string_variables_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_instance_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_perks_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_plug_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_plug_objectives_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_render_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_reusable_plugs_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_sockets_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_stats_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_item_talent_grid_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_public_vendor_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_vendor_categories_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_destiny_vendor_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_personal_destiny_vendor_sale_item_set_component.dart';
import 'package:bungie_api/models/dictionary_component_response_ofuint32_and_public_destiny_vendor_sale_item_set_component.dart';
import 'package:bungie_api/models/dye_reference.dart';
import 'package:bungie_api/models/email_opt_in_definition.dart';
import 'package:bungie_api/models/email_setting_localization.dart';
import 'package:bungie_api/models/email_setting_subscription_localization.dart';
import 'package:bungie_api/models/email_settings.dart';
import 'package:bungie_api/models/email_subscription_definition.dart';
import 'package:bungie_api/models/email_view_definition.dart';
import 'package:bungie_api/models/email_view_definition_setting.dart';
import 'package:bungie_api/models/entity_action_result.dart';
import 'package:bungie_api/models/exact_search_request.dart';
import 'package:bungie_api/models/fireteam_member.dart';
import 'package:bungie_api/models/fireteam_response.dart';
import 'package:bungie_api/models/fireteam_summary.dart';
import 'package:bungie_api/models/fireteam_user_info_card.dart';
import 'package:bungie_api/models/forum_recruitment_detail.dart';
import 'package:bungie_api/models/gear_asset_data_base_definition.dart';
import 'package:bungie_api/models/general_user.dart';
import 'package:bungie_api/models/get_credential_types_for_account_response.dart';
import 'package:bungie_api/models/get_groups_for_member_response.dart';
import 'package:bungie_api/models/global_alert.dart';
import 'package:bungie_api/models/group_application_list_request.dart';
import 'package:bungie_api/models/group_application_request.dart';
import 'package:bungie_api/models/group_application_response.dart';
import 'package:bungie_api/models/group_ban.dart';
import 'package:bungie_api/models/group_ban_request.dart';
import 'package:bungie_api/models/group_edit_action.dart';
import 'package:bungie_api/models/group_features.dart';
import 'package:bungie_api/models/group_member.dart';
import 'package:bungie_api/models/group_member_application.dart';
import 'package:bungie_api/models/group_member_leave_result.dart';
import 'package:bungie_api/models/group_membership.dart';
import 'package:bungie_api/models/group_membership_base.dart';
import 'package:bungie_api/models/group_membership_search_response.dart';
import 'package:bungie_api/models/group_name_search_request.dart';
import 'package:bungie_api/models/group_optional_conversation.dart';
import 'package:bungie_api/models/group_optional_conversation_add_request.dart';
import 'package:bungie_api/models/group_optional_conversation_edit_request.dart';
import 'package:bungie_api/models/group_options_edit_action.dart';
import 'package:bungie_api/models/group_potential_member.dart';
import 'package:bungie_api/models/group_potential_membership.dart';
import 'package:bungie_api/models/group_potential_membership_search_response.dart';
import 'package:bungie_api/models/group_query.dart';
import 'package:bungie_api/models/group_response.dart';
import 'package:bungie_api/models/group_search_response.dart';
import 'package:bungie_api/models/group_theme.dart';
import 'package:bungie_api/models/group_user_base.dart';
import 'package:bungie_api/models/group_user_info_card.dart';
import 'package:bungie_api/models/group_v2.dart';
import 'package:bungie_api/models/group_v2_card.dart';
import 'package:bungie_api/models/group_v2_clan_info.dart';
import 'package:bungie_api/models/group_v2_clan_info_and_investment.dart';
import 'package:bungie_api/models/hard_linked_user_membership.dart';
import 'package:bungie_api/models/hyperlink_reference.dart';
import 'package:bungie_api/models/ignore_response.dart';
import 'package:bungie_api/models/image_pyramid_entry.dart';
import 'package:bungie_api/models/interpolation_point.dart';
import 'package:bungie_api/models/interpolation_point_float.dart';
import 'package:bungie_api/models/inventory_changed_response.dart';
import 'package:bungie_api/models/paged_query.dart';
import 'package:bungie_api/models/partner_offer_claim_request.dart';
import 'package:bungie_api/models/partner_offer_history_response.dart';
import 'package:bungie_api/models/partner_offer_sku_history_response.dart';
import 'package:bungie_api/models/personal_destiny_vendor_sale_item_set_component.dart';
import 'package:bungie_api/models/platform_friend.dart';
import 'package:bungie_api/models/platform_friend_response.dart';
import 'package:bungie_api/models/poll_response.dart';
import 'package:bungie_api/models/poll_result.dart';
import 'package:bungie_api/models/post_response.dart';
import 'package:bungie_api/models/post_search_response.dart';
import 'package:bungie_api/models/public_destiny_vendor_sale_item_set_component.dart';
import 'package:bungie_api/models/schema_record_state_block.dart';
import 'package:bungie_api/models/search_result.dart';
import 'package:bungie_api/models/search_result_of_content_item_public_contract.dart';
import 'package:bungie_api/models/search_result_of_destiny_entity_search_result_item.dart';
import 'package:bungie_api/models/search_result_of_fireteam_response.dart';
import 'package:bungie_api/models/search_result_of_fireteam_summary.dart';
import 'package:bungie_api/models/search_result_of_group_ban.dart';
import 'package:bungie_api/models/search_result_of_group_member.dart';
import 'package:bungie_api/models/search_result_of_group_member_application.dart';
import 'package:bungie_api/models/search_result_of_group_membership.dart';
import 'package:bungie_api/models/search_result_of_group_potential_membership.dart';
import 'package:bungie_api/models/search_result_of_group_v2_card.dart';
import 'package:bungie_api/models/search_result_of_post_response.dart';
import 'package:bungie_api/models/search_result_of_trending_entry.dart';
import 'package:bungie_api/models/series.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_character_activities_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_character_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_character_progression_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_character_records_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_character_render_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_collectibles_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_currencies_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_inventory_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_instance_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_objectives_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_perks_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_plug_objectives_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_render_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_reusable_plugs_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_sockets_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_stats_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_item_talent_grid_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_kiosks_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_metrics_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_platform_silver_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_plug_sets_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_presentation_nodes_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_profile_collectibles_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_profile_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_profile_progression_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_profile_records_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_profile_transitory_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_string_variables_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_vendor_categories_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_vendor_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_vendor_group_component.dart';
import 'package:bungie_api/models/single_component_response_of_destiny_vendor_receipts_component.dart';
import 'package:bungie_api/models/stream_info.dart';
import 'package:bungie_api/models/tag_metadata_definition.dart';
import 'package:bungie_api/models/tag_metadata_item.dart';
import 'package:bungie_api/models/tag_response.dart';
import 'package:bungie_api/models/trending_categories.dart';
import 'package:bungie_api/models/trending_category.dart';
import 'package:bungie_api/models/trending_detail.dart';
import 'package:bungie_api/models/trending_entry.dart';
import 'package:bungie_api/models/trending_entry_community_creation.dart';
import 'package:bungie_api/models/trending_entry_destiny_activity.dart';
import 'package:bungie_api/models/trending_entry_destiny_item.dart';
import 'package:bungie_api/models/trending_entry_destiny_ritual.dart';
import 'package:bungie_api/models/trending_entry_news.dart';
import 'package:bungie_api/models/trending_entry_support_article.dart';
import 'package:bungie_api/models/user_info_card.dart';
import 'package:bungie_api/models/user_membership.dart';
import 'package:bungie_api/models/user_membership_data.dart';
import 'package:bungie_api/models/user_search_prefix_request.dart';
import 'package:bungie_api/models/user_search_response.dart';
import 'package:bungie_api/models/user_search_response_detail.dart';
import 'package:bungie_api/models/user_theme.dart';
import 'package:bungie_api/models/user_to_user_context.dart';
import 'package:bungie_api/queries.dart';
import 'package:bungie_api/responses/api_usage_response.dart';
import 'package:bungie_api/responses/awa_authorization_result_response.dart';
import 'package:bungie_api/responses/awa_initialize_response_response.dart';
import 'package:bungie_api/responses/boolean_response.dart';
import 'package:bungie_api/responses/bungie_friend_list_response_response.dart';
import 'package:bungie_api/responses/bungie_friend_request_list_response_response.dart';
import 'package:bungie_api/responses/cedictionary_ofstring_andstring_response.dart';
import 'package:bungie_api/responses/celist_of_forum_recruitment_detail_response.dart';
import 'package:bungie_api/responses/celist_of_global_alert_response.dart';
import 'package:bungie_api/responses/celist_of_group_optional_conversation_response.dart';
import 'package:bungie_api/responses/celist_of_partner_offer_sku_history_response_response.dart';
import 'package:bungie_api/responses/clan_banner_source_response.dart';
import 'package:bungie_api/responses/content_item_public_contract_response.dart';
import 'package:bungie_api/responses/content_type_description_response.dart';
import 'package:bungie_api/responses/core_settings_configuration_response.dart';
import 'package:bungie_api/responses/destiny_activity_history_results_response.dart';
import 'package:bungie_api/responses/destiny_aggregate_activity_results_response.dart';
import 'package:bungie_api/responses/destiny_character_response_response.dart';
import 'package:bungie_api/responses/destiny_collectible_node_detail_response_response.dart';
import 'package:bungie_api/responses/destiny_definition_response.dart';
import 'package:bungie_api/responses/destiny_entity_search_result_response.dart';
import 'package:bungie_api/responses/destiny_equip_item_results_response.dart';
import 'package:bungie_api/responses/destiny_historical_stats_account_result_response.dart';
import 'package:bungie_api/responses/destiny_historical_stats_results_response.dart';
import 'package:bungie_api/responses/destiny_historical_weapon_stats_data_response.dart';
import 'package:bungie_api/responses/destiny_item_change_response_response.dart';
import 'package:bungie_api/responses/destiny_item_response_response.dart';
import 'package:bungie_api/responses/destiny_leaderboard_results_response.dart';
import 'package:bungie_api/responses/destiny_linked_profiles_response_response.dart';
import 'package:bungie_api/responses/destiny_manifest_response.dart';
import 'package:bungie_api/responses/destiny_milestone_content_response.dart';
import 'package:bungie_api/responses/destiny_milestone_response.dart';
import 'package:bungie_api/responses/destiny_post_game_carnage_report_data_response.dart';
import 'package:bungie_api/responses/destiny_profile_response_response.dart';
import 'package:bungie_api/responses/destiny_public_vendors_response_response.dart';
import 'package:bungie_api/responses/destiny_vendor_response_response.dart';
import 'package:bungie_api/responses/destiny_vendors_response_response.dart';
import 'package:bungie_api/responses/dictionary_ofint32_andstring_response.dart';
import 'package:bungie_api/responses/dictionary_ofstring_and_core_system_response.dart';
import 'package:bungie_api/responses/dictionary_ofuint32_and_destiny_public_milestone_response.dart';
import 'package:bungie_api/responses/fireteam_response_response.dart';
import 'package:bungie_api/responses/general_user_response.dart';
import 'package:bungie_api/responses/get_groups_for_member_response_response.dart';
import 'package:bungie_api/responses/group_application_response_response.dart';
import 'package:bungie_api/responses/group_member_leave_result_response.dart';
import 'package:bungie_api/responses/group_membership_search_response_response.dart';
import 'package:bungie_api/responses/group_potential_membership_search_response_response.dart';
import 'package:bungie_api/responses/group_response_response.dart';
import 'package:bungie_api/responses/group_search_response_response.dart';
import 'package:bungie_api/responses/hard_linked_user_membership_response.dart';
import 'package:bungie_api/responses/ienumerable_of_application_response.dart';
import 'package:bungie_api/responses/ienumerable_of_user_info_card_response.dart';
import 'package:bungie_api/responses/int32_response.dart';
import 'package:bungie_api/responses/int64_response.dart';
import 'package:bungie_api/responses/iread_only_collection_of_content_item_public_contract_response.dart';
import 'package:bungie_api/responses/list_of_destiny_clan_aggregate_stat_response.dart';
import 'package:bungie_api/responses/list_of_entity_action_result_response.dart';
import 'package:bungie_api/responses/list_of_get_credential_types_for_account_response_response.dart';
import 'package:bungie_api/responses/list_of_group_theme_response.dart';
import 'package:bungie_api/responses/list_of_group_v2_card_response.dart';
import 'package:bungie_api/responses/list_of_tag_response_response.dart';
import 'package:bungie_api/responses/list_of_user_theme_response.dart';
import 'package:bungie_api/responses/platform_friend_response_response.dart';
import 'package:bungie_api/responses/post_search_response_response.dart';
import 'package:bungie_api/responses/read_only_dictionary_ofstring_and_destiny_historical_stats_definition_response.dart';
import 'package:bungie_api/responses/search_result_of_content_item_public_contract_response.dart';
import 'package:bungie_api/responses/search_result_of_fireteam_response_response.dart';
import 'package:bungie_api/responses/search_result_of_fireteam_summary_response.dart';
import 'package:bungie_api/responses/search_result_of_group_ban_response.dart';
import 'package:bungie_api/responses/search_result_of_group_member_application_response.dart';
import 'package:bungie_api/responses/search_result_of_group_member_response.dart';
import 'package:bungie_api/responses/search_result_of_trending_entry_response.dart';
import 'package:bungie_api/responses/trending_categories_response.dart';
import 'package:bungie_api/responses/trending_detail_response.dart';
import 'package:bungie_api/responses/user_membership_data_response.dart';
import 'package:bungie_api/responses/user_search_response_response.dart';
import 'package:bungie_api/settings.dart';
import 'package:bungie_api/social.dart';
import 'package:bungie_api/tags.dart';
import 'package:bungie_api/tokens.dart';
import 'package:bungie_api/trending.dart';
import 'package:bungie_api/user.dart';
import 'package:bungie_api/usersystemoverrides.dart';

Author: LittleLightForDestiny
Source Code: https://github.com/LittleLightForDestiny/bungie-api-dart 
License: MIT license

#flutter #dart #api 

Bungie-api-dart: Dart Definitions for The Bungie.net API

Flutter Plugin for KARTE Notification, Provides A Simple API

KARTE Notification for Flutter

A Flutter plugin to use the KARTE Notification API, for both Android & iOS. KARTE Notification package provides a simple API for push notification.

Documentation

The developer guide is located at

License

Flutter KARTE Notification package is published under the Apache 2.0 License.

Your use of KARTE is governed by the KARTE Terms of Use.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add karte_notification

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  karte_notification: ^1.1.0

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:karte_notification/karte_notification.dart'; 

example/lib/main.dart

import 'dart:async';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:karte_core/karte_core.dart';
import 'package:karte_notification/karte_notification.dart' as krt;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

Future<dynamic> myBackgroundMessageHandler(RemoteMessage message) async {
  // Called when received notification on background only Android
  print('myBackgroundMessageHandler $message');
  var karteNotification = await krt.Notification.create(message);
  print("karte notification: $karteNotification");
  if (karteNotification != null) {
    karteNotification.handleForAndroid();
  }
}

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

class _MyAppState extends State<MyApp> {
  String _homeScreenText = "Waiting for token...";
  String _logText = "";
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;

  void updateState({String? log, String? token}) {
    if (!mounted) return;
    setState(() {
      if (log != null) _logText += log;
      if (token != null) _homeScreenText = "Push Messaging token: $token";
    });
  }

  void checkInitialMessage() async {
    RemoteMessage? message =
        await FirebaseMessaging.instance.getInitialMessage();
    // Called when app launch by tap notification on iOS
    print("checkInitialMessage: $message");
    updateState(log: "\nonLaunch");
    if (message == null) return;
    var karteNotification = await krt.Notification.create(message);
    print("karte notification: $karteNotification");
    if (karteNotification != null) {
      karteNotification.handleForIOS();
    }
  }

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

    checkInitialMessage();
    FirebaseMessaging.onBackgroundMessage(myBackgroundMessageHandler);
    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      // Called when received notification on foreground
      print("onMessage: $message");
      updateState(log: "\nonMessage");
      var karteNotification = await krt.Notification.create(message);
      print("karte notification: $karteNotification");
      if (karteNotification != null) {
        karteNotification.handleForAndroid();
      }
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
      // Called when app resume by tap notification on iOS
      print("onMessageOpenedApp: $message");
      updateState(log: "\nonMessageOpenedApp");
      var karteNotification = await krt.Notification.create(message);
      print("karte notification: $karteNotification");
      if (karteNotification != null) {
        karteNotification.handleForIOS();
      }
    });
    _firebaseMessaging
        .requestPermission(
            alert: true, badge: true, provisional: true, sound: true)
        .then((NotificationSettings value) {
      print("Settings registered: $value");
    });
    _firebaseMessaging.onTokenRefresh.listen((String token) {
      print("onTokenRefreshed: $token");
      krt.Notification.registerFCMToken(token);
      updateState(token: token);
    });
    _firebaseMessaging.getToken().then((String? token) {
      if (token == null) return;
      krt.Notification.registerFCMToken(token);
      updateState(token: token);
      print(_homeScreenText);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('KARTE Notification example app'),
        ),
        body: Center(
          child: Column(
              // mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(_homeScreenText),
                ElevatedButton(
                  onPressed: () {
                    Tracker.view("push_text");
                  },
                  child: Text("View"),
                ),
                Text(_logText),
              ]),
        ),
      ),
    );
  }
} 

Download Details:

Author: plaidev

Source Code: https://github.com/plaidev/karte-flutter

#flutter #android #ios 

Flutter Plugin for KARTE Notification, Provides A Simple API
Fabiola  Auma

Fabiola Auma

1656745200

Flutter Plugin: Accessing information About The Battery State on Tizen

plugins

This repo contains Flutter plugins maintained by the flutter-tizen team. We're in process of adding Tizen platform support to existing first and third-party plugins on pub.dev based on their popularity. If the plugin you're looking for isn't implemented for Tizen yet, consider filing an issue or creating a package by yourself. (We welcome your pull requests!)

To build Flutter applications with plugins, use the flutter-tizen tool.

For how to extend existing plugins for Tizen, see Writing custom platform-specific code and Federated plugins from the Flutter docs. If the original plugin uses the federated plugins approach, you can implement its platform interface either in Dart (inheriting directly) or C++ (using a fallback method channel).

List of packages

The "non-endorsed" status means that the plugin is not endorsed by the original author. In such case, you must set both foobar and foobar_tizen package dependencies in pubspec.yaml file to achieve full functionality.

Tizen packageFrontend packagePubEndorsed
audioplayers_tizenaudioplayers (3rd-party)pub packageNo
battery_plus_tizenbattery_plus (1st-party)pub packageNo
camera_tizencamera (1st-party)pub packageNo
connectivity_plus_tizenconnectivity_plus (1st-party)pub packageNo
device_info_plus_tizendevice_info_plus (1st-party)pub packageNo
flutter_tts_tizenflutter_tts (3rd-party)pub packageNo
geolocator_tizengeolocator (3rd-party)pub packageNo
google_maps_flutter_tizengoogle_maps_flutter (1st-party)pub packageNo
image_picker_tizenimage_picker (1st-party)pub packageNo
integration_test_tizenintegration_test (1st-party)pub packageNo
messageport_tizen(Tizen-only)pub packageN/A
network_info_plus_tizennetwork_info_plus (1st-party)pub packageNo
package_info_plus_tizenpackage_info_plus (1st-party)pub packageNo
path_provider_tizenpath_provider (1st-party)pub packageNo
permission_handler_tizenpermission_handler (3rd-party)pub packageNo
sensors_plus_tizensensors_plus (1st-party)pub packageNo
share_plus_tizenshare_plus (1st-party)pub packageNo
shared_preferences_tizenshared_preferences (1st-party)pub packageNo
sqflite_tizensqflite (3rd-party)pub packageNo
tizen_app_control(Tizen-only)pub packageN/A
tizen_app_manager(Tizen-only)pub packageN/A
tizen_audio_manager(Tizen-only)pub packageN/A
tizen_log(Tizen-only)pub packageN/A
tizen_notification(Tizen-only)pub packageN/A
tizen_package_manager(Tizen-only)pub packageN/A
url_launcher_tizenurl_launcher (1st-party)pub packageNo
video_player_tizenvideo_player (1st-party)pub packageNo
wakelock_tizenwakelock (3rd-party)pub packageNo
wearable_rotary(Tizen-only)pub packageN/A
webview_flutter_tizenwebview_flutter (1st-party)pub packageNo

Device limitations

Package nameWatchWatch
emulator
TVTV
emulator
Remarks
audioplayers_tizen✔️✔️⚠️⚠️Functional limitations (see README)
battery_plus_tizen✔️✔️No battery
camera_tizenNo camera
connectivity_plus_tizen✔️⚠️✔️✔️Returns incorrect connection status
device_info_plus_tizen✔️✔️✔️✔️ 
flutter_tts_tizen✔️✔️✔️✔️ 
geolocator_tizen✔️✔️Not applicable for TV
google_maps_flutter_tizen✔️Dependent library unavailable
image_picker_tizen⚠️No camera
No file manager app
integration_test_tizen✔️✔️✔️✔️ 
messageport_tizen✔️✔️✔️✔️ 
network_info_plus_tizen✔️✔️API not supported on emulator
package_info_plus_tizen✔️✔️✔️✔️ 
path_provider_tizen✔️✔️✔️✔️ 
permission_handler_tizen✔️✔️⚠️⚠️Not applicable for TV
sensors_plus_tizen✔️✔️No sensor hardware
share_plus_tizen⚠️⚠️No SMS or e-mail app
shared_preferences_tizen✔️✔️✔️✔️ 
sqflite_tizen✔️✔️✔️✔️ 
tizen_app_control✔️✔️✔️✔️ 
tizen_app_manager✔️✔️✔️✔️ 
tizen_audio_manager✔️✔️✔️✔️ 
tizen_log✔️✔️Not applicable for TV
tizen_notification✔️✔️✔️API not supported
tizen_package_manager✔️✔️✔️✔️ 
url_launcher_tizen✔️✔️No browser app
video_player_tizen✔️✔️⚠️Functional limitations (see README)
TV emulator issue
wakelock_tizen✔️✔️Cannot override system display setting
wearable_rotary✔️✔️Not applicable for TV
webview_flutter_tizen✔️Dependent library unavailable

battery_tizen


Deprecation Notice

The battery plugin has been replaced by the Flutter Community Plus Plugins version, battery_plus. Consider migrating to battery_plus and its Tizen implementation battery_plus_tizen.


The Tizen implementation of battery.

Usage

This package is not an endorsed implementation of battery. Therefore, you have to include battery_tizen alongside battery as dependencies in your pubspec.yaml file.

dependencies:
  battery: ^2.0.1
  battery_tizen: ^2.0.2

Then you can import battery in your Dart code:

import 'package:battery/battery.dart';

For detailed usage, see https://pub.dev/packages/battery#usage.

Supported devices

  • Galaxy Watch series (running Tizen 4.0 or later)

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add battery_tizen

With Flutter:

 $ flutter pub add battery_tizen

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  battery_tizen: ^2.0.2

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

example/lib/main.dart

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// ignore_for_file: public_member_api_docs

import 'dart:async';

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final Battery _battery = Battery();

  BatteryState? _batteryState;
  late StreamSubscription<BatteryState> _batteryStateSubscription;

  @override
  void initState() {
    super.initState();
    _batteryStateSubscription =
        _battery.onBatteryStateChanged.listen((BatteryState state) {
      setState(() {
        _batteryState = state;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      body: Center(
        child: Text('$_batteryState'),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.battery_unknown),
        onPressed: () async {
          final int batteryLevel = await _battery.batteryLevel;
          // ignore: unawaited_futures
          showDialog<void>(
            context: context,
            builder: (_) => AlertDialog(
              content: Text('Battery: $batteryLevel%'),
              actions: <Widget>[
                TextButton(
                  child: const Text('OK'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                )
              ],
            ),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    if (_batteryStateSubscription != null) {
      _batteryStateSubscription.cancel();
    }
  }
}

Author: flutter-tizen
Source code: https://github.com/flutter-tizen/plugins
License:

#dart #flutter 

Flutter Plugin: Accessing information About The Battery State on Tizen
Daniel  Hughes

Daniel Hughes

1656745200

AWS API Client for Amazon Machine Learning

High-level APIs for Amazon Web Services (AWS) in Dart

Development

Generate Dart APIs

Generated sources are checked into the repository. To generate the sources, run the following command at the root of the generator folder:

dart bin/generate.dart generate

All commands in generate.dart has the --help command available for more information on usage.

Published generated packages

TODO

  • Implement EC2 protocol

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add aws_machinelearning_api

With Flutter:

 $ flutter pub add aws_machinelearning_api

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  aws_machinelearning_api: ^1.2.0

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:aws_machinelearning_api/machinelearning-2014-12-12.dart';

example/README.md

import 'package:aws_machinelearning_api/machinelearning-2014-12-12.dart';

void main() {
  final service = MachineLearning(region: 'eu-west-1');
  // See documentation on how to use MachineLearning
}

Author: agilord
Source code:  https://github.com/agilord/aws_client
License:

#flutter #dart 

AWS API Client for Amazon Machine Learning
fd MOMIN

fd MOMIN

1656744485

How to Run a Flutter Web App with Node.js and API

 

Flutter at a glance

Flutter is one of Google’s solutions to cross-platform development. While it is fairly new on the scene, its feature set makes it an instant competitor in this space.

It compiles your app down to native code that runs on iOS or Android, resulting in incredible end-user performance and frame rates. It supports stateful hot reloading during development, meaning you can make changes to your code and watch them get applied on your emulator or physical device with no need to restart your app or lose your app state.

Flutter’s primary focus has been iOS and Android. With the 1.9 release, web support has been added as a technical preview. It is still in its early days, and it may not be production-ready just yet, but it is certainly exciting and promising. Minimal changes are required to take an existing Flutter app and compile it into an HTML, CSS, and JS bundle, as you will soon see.

Why run a Flutter web app on Node.js?

Flutter web apps can run on any web server. So why would you want to host your Flutter web app on a Node.js server? Well, to be honest, for many of the same reasons that you’d choose Node.js for your other web apps and APIs: it is incredibly good at servicing large volumes of simple requests, you can code your front end and back end in JavaScript, and so on.

You might already have a Node.js API that serves data to your Flutter iOS or Android apps. Compiling your Flutter app as a web app and hosting it on your existing Node.js server might be a logical extension to your current solution, with no need to add additional hosting costs to the equation.

Demonstration

It’s time to dive into the code and see Flutter web in action. In order to follow along with the example, you will need the following tools:

  • Android Studio (Android SDK manager and emulator)
  • Visual Studio Code + Flutter extension (or Android Studio)
  • Node.js 12

Flutter has fantastic developer documentation. If this is your first time developing a Flutter app.

You will have the opportunity to choose which editor you want to develop in. The examples and instructions in this article are based on Visual Studio Code, but you should still be able to follow along if you choose to use Android Studio instead.

A Node.js 12 server is required to run the web version of the Flutter weather app as well as the back-end weather API.

Step 1: Explore the sample code

In order to demonstrate how to add web support to an existing Flutter app, we will start with a simple weather app that has been tested on Android 10 (API level 29).

Flutter Weather App On Mobile

The weather app allows the user to view the current weather for a predefined list of cities. Weather data is retrieved from a back-end server running on Node.js.

Clone the source code for the weather app and server from GitHub:

Tip: The weather-app-nodejs-server repository has a flutter-web-support branch that contains the completed version of the app copied to the server with Flutter web support enabled.

It is best to clone both repositories beside each other in the same parent folder. The contents of the weather_app_flutter repository will be built and copied to a folder within the weather-app-nodejs-server repository.

Explore the Flutter weather app

Open the weather_app_flutter repository in your editor. Let’s take a closer look at the main.dart file. It contains the scaffolding and widgets that make up the app’s user interface. The Home widget class has a fetchWeatherData function that calls the back-end weather API to retrieve data and update the widget’s state:

fetchWeatherData({String location}) async {
    var url = WEATHER_API_URL + location;
    final response = await http.get(url);
    if (response.statusCode == 200) {
      var jsonResponse = convert.jsonDecode(response.body);
      setState(() {
        this._weatherData = WeatherData(
          jsonResponse\['weather'\]['location'],
          jsonResponse\['weather'\]['temperature'],
          jsonResponse\['weather'\]['weatherDescription'],
        );
        this._apiError = null;
      });
    } else {
      setState(() {
        this._apiError =
            'Unable to retrieve weather data from API (HTTP ${response.statusCode})';
      });
    }
  }

The fetchWeatherData function uses Dart’s http package to connect to the server over HTTP. There are other Dart packages that you could use, but this is the officially recommended package if you plan on adding web support to your Flutter app.

Also make note of the WEATHER_API_URL constant. Update the value of this constant before running the app so that it can connect to the API running on your local Node.js server. The URL must contain your machine’s hostname. A localhost URL will not be accessible to the Android emulator or physical device.

Explore the Node.js server and weather API

Open up the weather-app-nodejs-server repository in your editor.

Node.js Server Repository In Our Code Editor

There are a few important files and folders to review:

  • The public/api-test.html file can be used to quickly test that your server is working as expected after startup (e.g., http://localhost:3000/api-test.html)
  • The routes/weather.js file contains a simple GET API that accepts a path parameter and returns weather data (e.g., http://localhost:3000/api/weather/londonon)
  • The public-flutter folder is where you will copy the compiled web version of the weather app. The Node.js server is set up to serve files from this directory to the root context (e.g., http://localhost:3000)

Step 2: Add web support to the Flutter app

Since web support is still a technical preview, you need the latest in-development version of Flutter, also referred to as the master channel. In the root folder of the weather_app_flutter repository, run the following commands:

flutter channel master
flutter upgrade

Tip : You may encounter an “Unknown operating system. Cannot install Dart SDK.” error on Windows when running Flutter commands in a bash shell in Visual Studio Code. Try running the commands in a normal Windows command shell.

The upgrade process may take a few minutes. Next, you will need to enable web support in your Flutter installation so that it is available to this and other apps you develop on this workstation:

flutter config --enable-web
flutter devices

Once web support is enabled, you will see a new Chrome device in the device list. Restart Visual Studio Code after running these commands to refresh the device list menu if you don’t see Chrome in that list yet.

To add web support to the weather app, you need to run this command in the top-level folder of the weather_flutter_app repository:

flutter create .

The create command will make a few modifications to the app, which you can see in this commit. The most notable change is the addition of a web subfolder that contains an index.html:

Index.html File In Our Code Editor

Start the Node.js server by running this command in the root of the weather-app-nodejs-server repository:

npm start

Select Chrome from the device list in Visual Studio Code and then start the debugging. Alternatively, you can run the following flutter command:

flutter run -d chrome

The first time you start the app in Chrome may take a little longer while Flutter downloads additional dependencies on the fly. Chrome will eventually open, and you will see the weather app running in the browser. Some of the styling will be slightly different than what you saw on the emulator or physical device.

App Preview In Chrome

At this point, you will notice that the app is not displaying any data from the weather API. If you open Chrome DevTools, you will see a cross-origin resource sharing error.

The browser is not allowing the request to be made from the Flutter web server to the Node.js server since they are running on different ports. You could solve this problem by enabling cross-origin resource sharing on the server or installing a Chrome plugin to disable CORS.

We are going to ignore the error for now since in the next step we will run the pre-compiled Flutter web code directly on the Node.js server, thus eliminating the cross-origin requests altogether.

Try making a change to some of the code in the main.dart file and let Flutter recompile your app. You will notice that your changes do not immediately appear in the browser. This is because Flutter web does not yet support hot stateful reloading. Hopefully support for this awesome capability will come soon.

Step 3: Run the Flutter web app on Node.js

Now that you can run the weather app in the browser using Flutter, the next step is to build and copy it to the Node.js server to run alongside the API.

To build a Flutter web app bundle, run this command:

flutter build web

The build command will produce the build/web folder containing all the static files that make up the weather app.

Contents Of The build/web Folder In Our Editor

Copy the contents of weather_app_flutter/build/web to weather-app-nodejs-server/public-flutter. If your Node.js server in is still running, stop it and restart it to pick up the new files.

Access your Node.js server in the browser at http://localhost:3000 to see your app running on Node.js. This time, your app will display weather data retrieved from the weather API without the cross-origin resource sharing error.

Final App Running In The Browser

Final thoughts

It is incredible how simple it was to take an existing Flutter app and compile it into a web app ready to be deployed to a web server. The user interface rendered in the browser looks nearly identical to the user interface in Android.

Tread lightly if you are considering Flutter as your cross-platform app framework solely because of its web support. The Flutter team is very clear that web support is missing features, has known performance issues, and is not quite ready for production yet.

Thank for reading!

#node.js #flutter #javascript #wevdev #api

How to Run a Flutter Web App with Node.js and API
Mike  Kozey

Mike Kozey

1656743400

Flutter Kurdish Localization

Flutter Kurdish Localization 🌍

This package provides unofficial localization support for Central Kurdish Branch Sorani (Kurdish: سۆرانی ,Soranî‎).


Getting Started

import 'package:flutter_kurdish_localization/flutter_kurdish_localization.dart';

Add these two delegates to localizationsDelegates array

KurdishMaterialLocalizations.delegate For text and dates localization KurdishWidgetLocalizations.delegate For text and UI directionality

return MaterialApp(
    localizationsDelegates: [
        ..
        KurdishMaterialLocalizations.delegate,
        KurdishWidgetLocalizations.delegate,
        ...
    ],
    supportedLocales: [ Locale('ku') ]
    ocale: Locale('ku')
 )

Installing

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add flutter_kurdish_localization

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  flutter_kurdish_localization: ^0.0.9

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flutter_kurdish_localization/flutter_kurdish_localization.dart';

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_kurdish_localization/flutter_kurdish_localization.dart';
import 'package:flutter_kurdish_localization_example/util/constants.dart';
import 'package:flutter_kurdish_localization_example/localization/demo_localization.dart';
import 'package:flutter_kurdish_localization_example/router/custom_router.dart';
import 'package:flutter_kurdish_localization_example/router/route_constants.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'localization/language_constants.dart';

bool? landingScreen;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences _prefs = await SharedPreferences.getInstance();
  landingScreen = (_prefs.getBool('landing') ?? false);

  if (landingScreen == true) {
    debugPrint("Landing : $landingScreen");
  } else {
    debugPrint("Landing : $landingScreen");
  }

  runApp(const MyApp());
}

const List<Locale> supportedLocales = [
  Locale('en'),
  Locale('ku'),
  Locale('ar'),
];

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);
  static void setLocale(BuildContext context, Locale newLocale) {
    _MyAppState state = context.findAncestorStateOfType<_MyAppState>()!;
    state.setLocale(newLocale);
  }

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

class _MyAppState extends State<MyApp> {
  Locale? _locale;
  setLocale(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

  @override
  void didChangeDependencies() {
    getLocale().then((locale) {
      setState(() {
        _locale = locale;
      });
    });
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
        systemNavigationBarColor: Colors.transparent, // navigation bar color
        statusBarColor: primaryColor, // status bar color
        statusBarIconBrightness: Brightness.light));
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Flutter Multi Localization Demo",
      theme: ThemeData(primarySwatch: Colors.deepOrange),
      locale: _locale,
      supportedLocales: supportedLocales,
      localizationsDelegates: const [
        DemoLocalization.delegate,
        KurdishMaterialLocalizations.delegate,
        KurdishWidgetLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate
      ],
      localeResolutionCallback: (locale, supportedLocales) {
        for (var supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale!.languageCode &&
              supportedLocale.countryCode == locale.countryCode) {
            return supportedLocale;
          }
        }
        return supportedLocales.first;
      },
      onGenerateRoute: CustomRouter.generatedRoute,
      initialRoute: landingScreen! ? homeRoute : landingRoute,
    );
  }
}

Demo App


Translations are available now!

Links


Author: Aminsamad
Source Code: https://github.com/aminsamad/flutter_kurdish_localization 
License: GPL-3.0 license

#flutter #dart #localization 

Flutter Kurdish Localization
佐藤  桃子

佐藤 桃子

1656740040

Lifecycle_lite: You Can Monitor Page Lifecycle By This Lib

lifecycle_lite

通过简单几步,就可以让你使用whenShow()/whenHide()方法来监听页面的生命周期(退回到了该页面/打开其他页面挡着了该页面)了

Principle

这个库的实现很简单,你完全可以通过阅读代码后自己扩展实现。主要就是在MaterialApp中添加一个对路由的监听,也就是MaterialApp#navigatorObservers,之后通过对路由的监听来记录一个路由的栈。再在对应的State#initState方法或StatelessWidget#createElement中绑定两个生命周期方法的实现到最上层路由。 这样在每次监听到路由变化时,去调用顶层路由对应的绑定方法就OK了。 记得在路由被移出的时候对应的方法也要移出哦~

Getting Started

import 'package:lifecycle/lifecycle_mixin.dart';

1.首先在你的根布局MaterialApp中绑定一个路由监听LifeNavigatorObserver().

    MaterialApp(
        navigatorObservers: [
            LifeNavigatorObserver(),
        ],
    );

2.在你需要添加监听的State中混入LifecycleMixin,并在initState中调用bindImplIntoRoute()方法。

2.StatefulWidget的话,需要混入LifecycleStatefulMixin,对应的StatelessWidget,使用的是LifecycleStatelessMixin

3.实现whenShow()/whenHide()方法,代码看起来是下面的样子。

///Statefule page
class WorksDetailState extends State with LifecycleStatefulMixin{

    @override
    whenShow() {
        super.whenShow();
        print("LifeNavigatorObserver---Show了");
    }

    @override
    whenHide() {
        super.whenHide();
        print("LifeNavigatorObserver---Hide了");
    }
}
///Stateless page
class StatelessPage extends StatelessWidget with LifecycleStatelessMixin{

    @override
    whenShow() {
        super.whenShow();
        print("LifeNavigatorObserver---Show了");
    }

    @override
    whenHide() {
        super.whenHide();
        print("LifeNavigatorObserver---Hide了");
    }
}

尽情享用吧 :P;

Installing

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add lifecycle_lite

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  lifecycle_lite: ^0.0.3

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:lifecycle_lite/life_navigator_observer.dart';
import 'package:lifecycle_lite/lifecycle.dart';
import 'package:lifecycle_lite/lifecycle_export.dart';
import 'package:lifecycle_lite/lifecycle_mixin.dart';
import 'package:lifecycle_lite/utils.dart';

原文来源: https://pub.dev/packages/lifecycle_lite 

#flutter #dart 

Lifecycle_lite: You Can Monitor Page Lifecycle By This Lib
Hunter  Krajcik

Hunter Krajcik

1656738420

Conventional: A Light-weight Conventional Commit Parser and tools

Conventional  

A light-weight library for working with commits that follow the Conventional Commits specification.

Features

  • Commit.parseCommits() for parsing commits from a git --no-pager log --no-decorate command output.
  • hasReleasableCommits() for checking if a list Commit items has releasable commits following the convention.
  • writeChangelog() for automated authoring of CHANGELOGs based on commits that follow the conventional commits spec.
  • lintCommit() for checking whether commit messages follow the conventional commit spec. Useful when used alongside git_hooks.
  • nextVersion() for bumping to a next version based on releasable commits.

Usage

A simple usage example:

import 'package:conventional/conventional.dart';

main() {
  final List<Commit> commits = Commit.parseCommits(testLog);
  if (hasReleasableCommits(commits)) {
    writeChangelog(
      commits: commits,
      changelogFilePath: 'CHANGELOG.md',
      version: '1.2.0',
      now: DateTime.now(),
    );
  }
}

Installing

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add conventional

With Flutter:

 $ flutter pub add conventional

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  conventional: ^0.3.0

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:conventional/conventional.dart';

example/conventional_example.dart

import 'package:conventional/conventional.dart';

// ignore_for_file: avoid_print

const testLog = '''
commit fc9d8117b1074c3c965c5c1ccf845d784c026ac7
Author: Jane Doe <jane.doe@example.com>
Date:   Mon Feb 8 15:26:49 2021 +0800

    ci: fix release workflow

commit cf6080079cd96cb4ccc2edca2ba9cacbcfd64704
Author: Jane Doe <jane.doe@example.com>
Date:   Sun Feb 7 12:58:06 2021 +0800

    ci: try fixing problem with release

commit 925fcd38fe8bd2653ea70d67155b8e31082cf4b2
Author: Jane Doe <jane.doe@example.com>
Date:   Fri Feb 5 16:24:38 2021 +0800

    chore: fix analysis errors

    - disabled checking for non null-safe libraries (temporary)
    - annotation for DatabaseLogWrapper

commit 43cf9b78f77a0180ad408cb87e8a774a530619ce
Author: Jane Doe <jane.doe@example.com>
Date:   Fri Feb 5 11:56:26 2021 +0800

    feat: null-safety and piechart cache

    BREAKING CHANGE: uses null-safety

commit e86efaced15f875ae9e11fd0d79b72d85578f79a
Author: Jane Doe <jane.doe@example.com>
Date:   Wed Jan 27 18:20:41 2021 +0800

    chore: wip to null-safety

commit 18bf98f5cddfecc69b26285b6edca063f1a8b1ec
Merge: b457270 dc60e12
Author: Jane Doe <jane.doe@example.com>
Date:   Sat Dec 19 13:28:47 2020 +0800

    ci: Merge pull request #3 from asartalo/semantic-release

    ci: fixing semantic-release config
''';

void main() {
  // Parse commits
  final List<Commit> commits = Commit.parseCommits(testLog);
  final firstCommit = commits.first;
  print(firstCommit.author.name); // "Jane Doe"
  print(firstCommit.author.email); // "jane.doe@example.com"
  print(firstCommit.breaking); // false
  print(firstCommit.type); // "ci"
  print(firstCommit.description); // "fix release workflow"

  // Check if we have releasable commits
  final shouldRelease = hasReleasableCommits(commits);
  print(shouldRelease); // true

  if (shouldRelease) {
    // Write to a changelog file
    writeChangelog(
      commits: commits,
      changelogFilePath: 'CHANGELOG.md',
      version: '1.2.0',
      now: DateTime.now(),
    );
  }
}

Feature Requests and Bugs

Please file feature requests and bugs at the issue tracker. PR's are welcome and appreciated!

Other Solutions

Author: Asartalo
Source Code: https://github.com/asartalo/conventional 
License: MIT license

#flutter #dart 

Conventional: A Light-weight Conventional Commit Parser and tools