Majid Hajian
Majid Hajian is a passionate software developer with years of developing and architecting complex web and mobile applications. He is passionate about web platform especially flutter, IoT, PWAs, and performance.
Majid Hajian
mhadaily
Updated - Flutter2
Credit to: JDominik Roszkowski - https://codepen.io/orestesgaolin/pen/ExVboMY
https://chrome-trex-flutter.netlify.app/#/
Credit to: Joshua de Guzman - https://codepen.io/joshuadeguzman/pen/jObrzJB
https://nike-shop-flutter.netlify.app
Credit to: Zoey Fan - https://codepen.io/zoeyfan/pen/ExVaXGK
https://gooey-edge-flutter.netlify.app
mhadaily
mhadaily
import 'package:flutter/material.dart';
MaterialApp(
ThemeData(
name: "Majid Hajian",
location: "Oslo, Norway",
description: '''
Google Developer Expert
Passionate Software engineer,
Community Leader, Author and international Speaker
''',
main: "Flutter/Dart, PWA, Performance",
homepage: "https://www.majidhajian.com",
socials: {
twitter: "https://www.twitter.com/mhadaily",
github: "https://www.github.com/mhadaily"
},
author: {
Pluralsight: "www.pluralsight.com/authors/majid-hajian",
Apress: "Progressive Web App with Angular, Book",
PacktPub: "PWA development",
Udemy: "PWA development",
}
founder: "Softiware As (www.Softiware.com)"
devDependencies: {
tea: "Ginger",
mac: "10.14+",
},
community: {
MobileEraConference: "Orginizer",
FlutterVikings: "Orginizer",
FlutterDartOslo: "Orginizer",
GDGOslo: "Co-Orginizer",
DevFestNorway: "Orginizer",
...more
}));
Find me on the internet by
Mobile / Desktop / Web / Embedded
Expressive & Flexible UI
Fast Development
Native Performance
mhadaily
Expressive & Flexible UI
Fast Development
Native Performance
mhadaily
mhadaily
mhadaily
https://skia.org/
Skia is an open-source 2D graphics library that provides common APIs that work across a variety of hardware and software platforms.
mhadaily
mhadaily
https://dart.dev/tools/dart2js
dart2js -O2 -o test.js test.dart
mhadaily
HTML renderer
Uses a combination of HTML elements, CSS, Canvas elements, and SVG elements. This renderer has a smaller download size.
CanvasKit renderer
This renderer is fully consistent with Flutter mobile and desktop, has faster performance with higher widget density, but adds about 2MB in download size.
mhadaily
A PWA built with Flutter
Single Page Application
Existing Mobile Applications
At this time
mhadaily
mhadaily
class User {
id: number;
constructor(public name: string){id=1};
async fetchInfo() {
return new Promise(
resolve => setTimeout(resolve, 3*1000);
);
}
}
async function main(){
const user = new User('Majid');
await user.fetchInfo();
console.log(`Hello ${user.id}`)
}
main();
class User {
final int id;
final String name;
User(this.name) {id = 1};
fetchInfo() async {
return Future.delayed(const Duraction(seconds: 2));
}
}
main() async {
final user = User('Majid');
await user.fetchInfo();
print('Hello ${user.id}');
}
https://dartpad.dev/
mhadaily
import 'dart:async';
Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
yield i;
}
}
main() async {
final count = await countStream(10).first;
print('first count $count');
countStream(10).listen((v) {
print('Listen to count $v');
});
}
import { fromEvent } from 'rxjs';
import { throttleTime, scan } from 'rxjs/operators';
fromEvent(document, 'click')
.pipe(
throttleTime(1000),
scan(count => count + 1, 0)
)
.subscribe(count => console.log(`Clicked ${count} times`));
https://dartpad.dev/
mhadaily
mhadaily
mhadaily
class HelloWorld extends StatelessWidget {
@override
Widget build(BuildContext context){
return Text('Hello World');
}
}
class HelloWorld extends HTMLElement {
connectedCallback(){
this.innerHTML = '<p>Hello World</p>';
}
}
mhadaily
class HelloWorld extends StatelessWidget {
@override
Widget build(BuildContext context){
return Text('Hello World');
}
}
class HelloWorld extends React.Component {
render() {
return '<p>Hello World</p>';
}
}
mhadaily
mhadaily
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello World!'),
),
body: Center(
child: Text(
'Majid Hajian',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
);
mhadaily
<my-app-header>
<hello-world bold></hello-world>
</my-app-header>
<div style="font-weight:bold; text-align:center;">
Majid Hajian
</div>
mhadaily
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello World!'),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: const Text(
'Majid Hajian',
style: TextStyle(
fontWeight: FontWeight.bold
),
),
),
),
),
);
<style>
.myclass{
font-weight:bold;
text-align:center;
padding: 10rem;
}
</style>
<div class="myclass">
Majid Hajian
</div>
mhadaily
var container = Container(
child: Center(
child: Container(
child: Text(
"Lorem ipsum",
style: bold24Roboto,
),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: const Alignment(0.0, -1.0),
end: const Alignment(0.0, 0.6),
colors: <Color>[
const Color(0xffef5350),
const Color(0x00ef5350)
],
),
),
padding: EdgeInsets.all(16),
),
),
width: 320,
height: 240,
color: Colors.grey[300],
);
<style>
.myclass{
background: linear-gradient(180deg, #ef5350, rgba(0, 0, 0, 0) 80%);
}
</style>
<div class="myclass">
Majid Hajian
</div>
mhadaily
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Hello World!'),
),
body: Center(
child: Text(
'Majid Hajian',
style: TextStyle(
fontWeight: FontWeight.bold
),
),
),
),
);
mhadaily
Widget build(BuildContext context) {
return GestureDetector(
child: AbsorbPointer(child : child),
onTap: () {
print('tap');
onTap();
},
onTapCancel: () {
print('tapCancel');
}
);
}
mhadaily
StoreProvider<int>{
store: store,
child: Text('Flutter Web!'),
}
mhadaily
mhadaily
MaterialApp(
initialRoute: "/login",
routes: {
"/login": (context) => LoginPage(),
"/home": (context) => HomePage()
}
);
mhadaily
Use the LayoutBuilder class
Use the MediaQuery.of() method in your build functions
mhadaily
Design
class ResponsiveWidget {
...
//Large screen is any screen whose width is more than 1200 pixels
static bool isLargeScreen(BuildContext context) {
return MediaQuery.of(context).size.width > 1200;
}
//Small screen is any screen whose width is less than 800 pixels
static bool isSmallScreen(BuildContext context) {
return MediaQuery.of(context).size.width < 800;
}
//Medium screen is any screen whose width is less than 1200 pixels,
//and more than 800 pixels
static bool isMediumScreen(BuildContext context) {
return MediaQuery.of(context).size.width > 800 &&
MediaQuery.of(context).size.width < 1200;
}
}
import 'package:landingpage/utils/responsive_widget.dart';
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ResponsiveWidget(
largeScreen: LargeScreen(),
smallScreen: SmallScreen(),
);
}
...
}
mhadaily
class AnimatedCount extends ImplicitlyAnimatedWidget {
final int count;
AnimatedCount({
Key key,
@required this.count,
@required Duration duration,
Curve curve = Curves.linear
}) : super(duration: duration, curve: curve, key: key);
@override
ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState() => _AnimatedCountState();
}
class _AnimatedCountState extends AnimatedWidgetBaseState<AnimatedCount> {
IntTween _count;
@override
Widget build(BuildContext context) {
return Text(_count.evaluate(animation).toString());
}
@override
void forEachTween(TweenVisitor visitor) {
_count = visitor(_count, widget.count, (dynamic value) => IntTween(begin: value));
}
}
mhadaily
Progressive Web App
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="gooey_edge">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>hello</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('flutter-first-frame', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
mhadaily
inspection
mhadaily
WEB
Web Assembly
WebGL
Layout and Paint API (Worklets)
Service workers
PWAs
and more ...
mhadaily
Ecosystem
How to Start!
mhadaily
mhadaily
// Install Flutter SDK
// flutter.dev/docs/get-started/install
flutter channel stable
flutter upgrade
flutter create myapp
cd myapp
flutter run -d chrome
├── README.md
├── android
├── build
│ └── web
├── ios
├── lib
│ └── main.dart
├── pubspec.lock
├── pubspec.yaml
├── pwa_flutter.iml
├── test
│ └── widget_test.dart
└── web
├── favicon.png
├── icons
├── index.html
└── manifest.json
mhadaily
After production build
static assets
Write you code
Html Entry file
Similar to package.json
Credit: https://github.com/MarcusNg/flutter_facebook_responsive_ui
mhadaily
flutter.gskinner.com
Flutter
Opens a new window for many developers to support several platforms with one single code base without compromising performance.
But one more thing...
Flutter web still needs improvement!
Read more: https://medium.com/flutter/flutter-web-support-hits-the-stable-milestone-d6b84e83b425
Learn more
Majid Hajian
mhadaily
Slides and link to source code
bit.ly/web-flutter
SVG icons credited to undraw.co
By Majid Hajian
The web is the largest application-delivery platform in existence and introducing progressive web applications takes it into the next level. Flutter, a UI toolkit to create beautiful cross-platform applications, supports standard web technologies like HTML, DOM, Canvas, JavaScript, and runs PWA on the browser; Not surprisingly, with only one language, Dart! In this session, I will fly you from a typical Javascript, CSS, HTML web development to Dart side with Flutter through live-coding of a beautiful progressive web app!
Majid Hajian is a passionate software developer with years of developing and architecting complex web and mobile applications. He is passionate about web platform especially flutter, IoT, PWAs, and performance.