Git Merge & Rebase with visual

Git Rebase git rebase yourBranch Git Merge & Rebase Visual You can play on Git School

Clone, PR, Conflicts & Settings

GitHub Clone & Push Changes git clone <repository-url> git push origin <branch-name> Git Pull Request (PR) & Code Review Resolve PR Merge Conflicts Change Default Branch & Repo Settings এই ভিডিওতে GitHub repository-এর default branch পরিবর্তন, visibility (public/private) change এবং repo delete করার option দেখানো হয়েছে। ...

GitHub Issues, Collaborators & Fork

Create Issue, Fix with PR & Delete Branch Add Collaborator / Give Repo Access How to Fork a GitHub Repository Checkout Remote Branch Locally Learn how to fetch remote branches and check them out locally for development. ...

Equatable

Flutter == vs Value Equality code import 'package:equatable/equatable.dart'; class Contact extends Equatable { const Contact({required this.type, required this.value}); final String type; final String value; @override List<Object?> get props => [type, value]; } class Phone with Equatable { const Phone({this.isPrimary = false, this.contact}); final bool isPrimary; final Contact? contact; @override List<Object?> get props => [...contact?.props ?? [], isPrimary]; } void main() { Contact a = Contact(type: "phone", value: "0101"); Contact b = Contact(type: "phone", value: "0101"); if (a == b) { print("same same ...."); } else { print("a: ${a.toString()}"); print("b: ${b.toString()}"); } } equatable on pub.dev↗

Json serilizable

user.dart import 'package:example/models/contact.dart'; import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart'; // the `user` is the fileName @JsonEnum(valueField: "value") enum Gender { male("m"), female("f"); const Gender(this.value); final String value; } @JsonSerializable(fieldRename: FieldRename.screamingSnake) class User { User({ required this.name, required this.dateOfBirth, required this.gender, required this.contact, required this.presentAddress, }); final String name; final Gender gender; @JsonKey(name: "dob") final DateTime? dateOfBirth; final Contact contact; final String presentAddress; factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); } Custom Converter class DateTimeConverter implements JsonConverter<DateTime?, Map<String, dynamic>?> { const DateTimeConverter(); @override DateTime? fromJson(Map<String, dynamic>? json) { if (json == null) return null; final second = json["seconds"]; return DateTime.fromMillisecondsSinceEpoch(second); } @override Map<String, dynamic>? toJson(DateTime? object) { if (object == null) return null; return {'seconds': (object.millisecondsSinceEpoch / 1000).round()}; } } Custom config build.yaml targets: $default: builders: json_serializable: options: # Options configure how source code is generated for every # `@JsonSerializable`-annotated class in the package. # # The default value for each is listed. any_map: false checked: false constructor: "" create_factory: true create_field_map: false create_json_keys: false create_json_schema: true create_per_field_to_json: false create_to_json: true date_time_utc: true disallow_unrecognized_keys: false explicit_to_json: false field_rename: snake generic_argument_factories: false ignore_unannotated: false include_if_null: true json_serializable on pub.dev↗

freezed

Flutter Freezed | Models, copyWith, JSON Serialization, Generics & Union Types Make sure to watch json_seriliazble first. Freezed class address.dart { "success": true, "data": { "street": "123 Main Street", "district": "Dhaka", "country": "Bangladesh" }, "message": "Address fetched" } import 'package:freezed_annotation/freezed_annotation.dart'; part 'address.freezed.dart'; part 'address.g.dart'; @freezed abstract class Address with _$Address { const factory Address({ required String street, required String district, required String country, }) = _Address; factory Address.fromJson(Map<String, Object?> json) => _$AddressFromJson(json); static const Address present = Address( street: "present", district: "addr.dis", country: "BD", ); static const Address permanent = Address( street: "permanent", district: "addr.dis", country: "...", ); } person.dart { "success": true, "data": { "name": "John Doe", "age": 25, "address": "Earth", "skills": ["Dart", "Flutter"], "presentAddress": { "street": "123 Main Street", "district": "Dhaka", "country": "Bangladesh" }, "permanentAddress": { "street": "45 Lake Road", "district": "Chattogram", "country": "Bangladesh" } }, "message": "Person fetched" } import 'package:freezed_annotation/freezed_annotation.dart'; import 'address.dart'; part 'user.freezed.dart'; part 'user.g.dart'; @freezed abstract class Person with _$Person { const factory Person({ required String name, int? age, @Default("Eath") String? address, @Default([]) List<String> skills, required Address presentAddress, Address? permanentAddress, }) = _Person; factory Person.fromJson(Map<String, Object?> json) => _$PersonFromJson(json); static const Person ui = Person( name: "0", age: 0, skills: [], presentAddress: Address.present, permanentAddress: Address.permanent, ); } Generic api_response.dart import 'package:freezed_annotation/freezed_annotation.dart'; part 'api_response.freezed.dart'; part 'api_response.g.dart'; @Freezed(genericArgumentFactories: true) abstract class ApiResponse<T> with _$ApiResponse<T> { const factory ApiResponse({ required bool success, T? data, String? message, }) = _ApiResponse<T>; factory ApiResponse.fromJson( Map<String, dynamic> json, T Function(Object?) fromJsonT, ) => _$ApiResponseFromJson(json, fromJsonT); } Union code-snippet We are using type instead of runtimetype ...

Understaing State & Updating UI

Who Owns the State? Callbacks & typedef Parent ↔ Child Communication code snippet import 'dart:math'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(colorScheme: .fromSeed(seedColor: Colors.deepPurple)), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; @override Widget build(BuildContext context) { return Scaffold( body: Column( crossAxisAlignment: .stretch, children: [ SectionView( onTap: (v) async { _counter = v; setState(() {}); return "Something went wrong"; }, ), Text( _counter.toString(), style: TextStyle(fontSize: 55), textAlign: .center, ), SectionView( increment: false, onTap: (n) async { _counter = n; await Future.delayed(Duration(seconds: 2)); setState(() {}); return ""; }, ), ], ), ); } } typedef OnSectionViewChange = Future<String> Function(int); class SectionView extends StatefulWidget { const SectionView({super.key, this.increment = true, required this.onTap}); final bool increment; final OnSectionViewChange onTap; @override State<SectionView> createState() => _SectionViewState(); } class _SectionViewState extends State<SectionView> { bool isLoading = false; String errMsg = ""; Future<void> onTap() async { isLoading = true; setState(() {}); Random random = Random(); final number = random.nextInt(4444); errMsg = await widget.onTap(widget.increment ? number : number * -1); isLoading = false; setState(() {}); } @override Widget build(BuildContext context) { return Expanded( child: Material( color: widget.increment ? Colors.blueAccent : Colors.redAccent, child: Center( child: Column( mainAxisSize: .min, children: [ Text(errMsg), InkWell( onTap: isLoading ? null : onTap, child: isLoading ? Center(child: CircularProgressIndicator()) : Icon( widget.increment ? Icons.add : Icons.remove, size: 55, ), ), ], ), ), ), ); } } Why AlertDialog/BottomSheet UI doesn’t update even with setState Widget state 03 ...

FutureBuilder & StreamBuilder

FutureBuilder Learn Async Data & avoid common mistakes. future codeSnippet import 'dart:math'; import 'package:flutter/material.dart'; void main() => runApp( const MaterialApp(debugShowCheckedModeBanner: false, home: MyHomePage()), ); class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { //... Future<int> fetchData() async { await Future.delayed(Duration(seconds: 4)); final number = Random().nextInt(100); return number; } late Future<int> future = fetchData(); @override Widget build(BuildContext context) { return Scaffold( body: Center( child: FutureBuilder<int>( future: future, initialData: 100, builder: (context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return Text(snapshot.error?.toString() ?? ""); } return Column( mainAxisSize: .min, children: [ if (snapshot.connectionState == ConnectionState.waiting) CircularProgressIndicator(), Text(snapshot.data.toString()), ], ); }, ), ), ); } } StreamBuilder Flutter’s Stream and StreamBuilder in detail. It also shows StreamController, StreamSubscription, stream error handling, single-subscription issue and event management with practical examples. ...

Navigation with Navigator 1

Learn Flutter’s Navigator API with practical examples of push, pop, pushReplacement, pushAndRemoveUntil, popUntil, canPop, and passing data between routes. main.dart import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; void main() { runApp( const MaterialApp(home: HomePage(), debugShowCheckedModeBanner: false), ); } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Home")), body: Center( child: ElevatedButton( onPressed: () async { final route = DetailsPage.route(); final result = await Navigator.push(context, route); print(result); }, child: const Text("Go to Details"), ), ), ); } } class DetailsPage extends StatelessWidget { const DetailsPage({super.key, required this.value}); final int value; static MaterialPageRoute route() => MaterialPageRoute( builder: (context) => DetailsPage(value: 123), settings: RouteSettings(arguments: 12312), ); @override Widget build(BuildContext context) { final canPop = ModalRoute.of(context)?.canPop ?? false; return Scaffold( appBar: AppBar(title: const Text("Details")), body: Center( child: Column( spacing: 16, mainAxisSize: .min, children: [ if (canPop) CloseButtonIcon(), ElevatedButton( onPressed: () { Navigator.of(context).pop("hello"); }, child: const Text("pop(result)"), ), ElevatedButton( onPressed: () { Navigator.of(context).pushReplacement(SettingsPage.route()); }, child: const Text("Settings with pushReplacement"), ), ElevatedButton( onPressed: () { Navigator.of(context).push(SettingsPage.route()); }, child: const Text("Settings with push"), ), ElevatedButton( onPressed: () { Navigator.of(context).pushAndRemoveUntil(SettingsPage.route(), ( route, ) { return false; }); }, child: const Text("pushAndRemoveUntil"), ), ], ), ), ); } } class SettingsPage extends StatelessWidget { const SettingsPage({super.key}); static MaterialPageRoute route() => MaterialPageRoute(builder: (_) => SettingsPage()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Settings")), body: Center( child: Column( mainAxisSize: .min, children: [ ElevatedButton( onPressed: () { Navigator.of(context).popUntil((route) { return route.isFirst; }); }, child: const Text("popUntil(Home)"), ), ElevatedButton( onPressed: () { debugPrint("canPop: ${Navigator.canPop(context)}"); Navigator.maybePop(context); }, child: const Text("canPop / maybePop"), ), ], ), ), ); } }

Saving key-value pair

Shared_preferences Persistent theme with Shared_preference. this is part of flutter_workshop provider shared_preferences on pub.dev↗