├── .github
└── workflows
│ └── flutter_web.yaml
├── .gitignore
├── .metadata
├── .vscode
└── launch.json
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── br
│ │ │ │ └── com
│ │ │ │ └── toshiossada
│ │ │ │ └── homepage
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── experiences.json
├── experiences_enUs.json
├── images
│ ├── awards
│ │ ├── dart.png
│ │ ├── flutter.png
│ │ ├── gde.png
│ │ └── mvp.png
│ ├── favicon.png
│ ├── flutterbrasil
│ │ ├── dash.png
│ │ └── flutter_br.png
│ ├── icons
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ └── logo.png
│ ├── logo_toshi.png
│ ├── meia_entrada.png
│ └── toshi.png
└── lang
│ ├── en_US.json
│ └── pt_BR.json
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── app
│ └── modules
│ │ └── home
│ │ ├── data
│ │ ├── datasource
│ │ │ └── experience_datasource_impl.dart
│ │ ├── mappers
│ │ │ └── experience_mapper.dart
│ │ └── repositories
│ │ │ ├── datasources
│ │ │ └── experience_datasource.dart
│ │ │ ├── experience_repository_impl.dart
│ │ │ └── models
│ │ │ └── experience_model.dart
│ │ ├── domain
│ │ ├── entities
│ │ │ └── experience_entity.dart
│ │ ├── interfaces
│ │ │ └── experience_repository.dart
│ │ └── usecases
│ │ │ └── get_experiences_usecase.dart
│ │ ├── home_module.dart
│ │ └── pages
│ │ ├── about
│ │ ├── about_page.dart
│ │ └── widget
│ │ │ ├── avatar_widget.dart
│ │ │ ├── awards_widget.dart
│ │ │ └── info_widget.dart
│ │ ├── carrer
│ │ ├── carrer_controller.dart
│ │ ├── carrer_page.dart
│ │ └── carrer_store.dart
│ │ ├── contacts
│ │ ├── contact_page.dart
│ │ └── widgets
│ │ │ └── contact_tile_widget.dart
│ │ ├── dne
│ │ ├── dne_module.dart
│ │ └── pages
│ │ │ ├── dne_page.dart
│ │ │ └── widegets
│ │ │ ├── app_bar_widget.dart
│ │ │ ├── certificate.dart
│ │ │ ├── detail_row_widget.dart
│ │ │ ├── info_widget.dart
│ │ │ ├── link_widget.dart
│ │ │ └── valid_widget.dart
│ │ ├── generator
│ │ └── experiences_pages.dart
│ │ ├── initial
│ │ ├── initial_page.dart
│ │ └── initial_page_controller.dart
│ │ └── widgets
│ │ ├── contact_widget.dart
│ │ └── social_button_widget.dart
├── app_module.dart
├── app_store.dart
├── app_widget.dart
├── core_module.dart
└── main.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
├── web
├── favicon.ico
├── favicon.png
├── icons
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── android-icon-144x144.png
│ ├── android-icon-192x192.png
│ ├── android-icon-36x36.png
│ ├── android-icon-48x48.png
│ ├── android-icon-72x72.png
│ ├── android-icon-96x96.png
│ ├── apple-icon-114x114.png
│ ├── apple-icon-120x120.png
│ ├── apple-icon-144x144.png
│ ├── apple-icon-152x152.png
│ ├── apple-icon-180x180.png
│ ├── apple-icon-57x57.png
│ ├── apple-icon-60x60.png
│ ├── apple-icon-72x72.png
│ ├── apple-icon-76x76.png
│ ├── apple-icon-precomposed.png
│ ├── apple-icon.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon-96x96.png
│ ├── favicon.ico
│ ├── manifest.json
│ ├── ms-icon-144x144.png
│ ├── ms-icon-150x150.png
│ ├── ms-icon-310x310.png
│ └── ms-icon-70x70.png
├── index.html
├── logo.png
├── manifest.json
└── style.css
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.github/workflows/flutter_web.yaml:
--------------------------------------------------------------------------------
1 | name: Flutter Web
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | env:
11 | TESTE3: "21"
12 | CNAME: ${{ vars.CNAME }}
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v1
18 |
19 | - name: Setup Flutter
20 | uses: subosito/flutter-action@v1
21 | with:
22 | channel: "stable"
23 |
24 | - name: Install dependencies
25 | run: flutter pub get
26 |
27 | - name: Build Web
28 | run: flutter build web --release
29 |
30 | - name: Deploy
31 | run: |
32 | cd build/web
33 | echo '${{ env.CNAME }}' > CNAME
34 | git init
35 | git config --global user.email toshiossada@gmail.com
36 | git config --global user.name toshiossada
37 | git status
38 | git remote add origin https://${{secrets.token}}@github.com/toshiossada/toshiossada.github.io.git
39 | git checkout -b gh-pages
40 | git add --all
41 | git commit -m "update"
42 | git push origin gh-pages -f
43 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | **/ios/Flutter/.last_build_id
26 | .dart_tool/
27 | .flutter-plugins
28 | .flutter-plugins-dependencies
29 | .packages
30 | .pub-cache/
31 | .pub/
32 | /build/
33 |
34 | # Web related
35 | lib/generated_plugin_registrant.dart
36 |
37 | # Symbolication related
38 | app.*.symbols
39 |
40 | # Obfuscation related
41 | app.*.map.json
42 |
43 | # Android Studio will place build artifacts here
44 | /android/app/debug
45 | /android/app/profile
46 | /android/app/release
47 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 18116933e77adc82f80866c928266a5b4f1ed645
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 |
8 | {
9 | "name": "flutter_web_site",
10 | "request": "launch",
11 | "type": "dart"
12 | },
13 | {
14 | "name": "flutter_web_site (profile mode)",
15 | "request": "launch",
16 | "type": "dart",
17 | "flutterMode": "profile"
18 | },
19 | {
20 | "name": "flutter_web_site (release mode)",
21 | "request": "launch",
22 | "type": "dart",
23 | "flutterMode": "release"
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # homepage
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 | # flutter_web_site
18 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 30
30 |
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlinOptions {
37 | jvmTarget = '1.8'
38 | }
39 |
40 | sourceSets {
41 | main.java.srcDirs += 'src/main/kotlin'
42 | }
43 |
44 | defaultConfig {
45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
46 | applicationId "br.com.toshiossada.homepage"
47 | minSdkVersion flutter.minSdkVersion
48 | targetSdkVersion 30
49 | versionCode flutterVersionCode.toInteger()
50 | versionName flutterVersionName
51 | }
52 |
53 | buildTypes {
54 | release {
55 | // TODO: Add your own signing config for the release build.
56 | // Signing with the debug keys for now, so `flutter run --release` works.
57 | signingConfig signingConfigs.debug
58 | }
59 | }
60 | }
61 |
62 | flutter {
63 | source '../..'
64 | }
65 |
66 | dependencies {
67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
68 | }
69 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
13 |
17 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/br/com/toshiossada/homepage/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package br.com.toshiossada.homepage
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | tasks.register("clean", Delete) {
28 | delete rootProject.layout.buildDirectory
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/experiences.json:
--------------------------------------------------------------------------------
1 | {
2 | "experiences": [
3 | {
4 | "company": "FARMÁCIAS APP By GrupoSC",
5 | "start": "03/2024",
6 | "end": null,
7 | "role": "Líder Técnico Mobile ",
8 | "description": [
9 | "Liderança da equipe de desenvolvimento no projeto de aplicativo da Farmácias APP, atuando na distribuição e definição de tarefas e prioridades de desenvolvimento, acompanhando o progresso da equipe e garantindo a entrega dos prazos acordados, realizando reuniões de alinhamento e planejamento junto a equipe e atuando na resolução de conflitos.",
10 | "Definição da visão técnica do aplicativo, garantindo escalabilidade e boas práticas, aplicando proatividade para antecipar desafios e propor melhorias contínuas.",
11 | "Desenvolvimento e implementação de novas funcionalidades para o projeto.",
12 | "Revisão de código e garantia da qualidade por meio de code reviews e testes.",
13 | "Atuação na linha de frente de tomada de decisões estratégicas para a evolução do aplicativo, aplicando pensamento crítico para avaliar soluções e direcionar o desenvolvimento de forma eficaz.",
14 | "Acompanhamento e suporte técnico à equipe, promovendo boas práticas de desenvolvimento."
15 | ]
16 | },
17 | {
18 | "company": "GRANTER",
19 | "start": "06/2022",
20 | "end": "10/2024",
21 | "role": "Consultor Especialista Flutter",
22 | "description": [
23 | "Desenvolvimento e arquitetura de aplicativos móveis multiplataforma de alto desempenho.",
24 | "Colaboração com stakeholders para traduzir requisitos de negócio em funcionalidades intuitivas e eficientes para o usuário.",
25 | "Implementação de código limpo, escalável, seguindo as melhores práticas de desenvolvimento.",
26 | "Integração de APIs e serviços externos para funcionalidades avançadas.",
27 | "Suporte contínuo e otimização do desempenho dos aplicativos.",
28 | "Mentoria e compartilhamento de conhecimento em Flutter, contribuindo para o crescimento da equipe."
29 | ]
30 | },
31 | {
32 | "company": "BEES (via Avantti)",
33 | "start": "05/2022",
34 | "end": "02/2024",
35 | "role": "Líder Técnico Mobile",
36 | "description": [
37 | "Curadoria de projetos e identificação de novas oportunidades alinhadas às necessidades dos clientes.",
38 | "Comunicação clara e objetiva sobre soluções técnicas e progresso dos projetos para stakeholders.",
39 | "Desenvolvimento de aplicativos multiplataforma e Design Systems para grandes empresas, como TADA e Zé Delivery.",
40 | "Implementação de Server Driven UI (SDUI) para proporcionar uma experiência de usuário mais dinâmica e personalizada.",
41 | "Projeto e implementação de um Design System reutilizável, garantindo consistência e agilidade no desenvolvimento.",
42 | "Colaboração com designers, engenheiros de back-end e gerentes de produto para otimizar processos e entregas.",
43 | "Mentoria e suporte a desenvolvedores juniores, promovendo a troca de conhecimento dentro da equipe, aplicando empatia para compreender desafios e facilitar o aprendizado."
44 | ]
45 | },
46 | {
47 | "company": "CVC Corp (via ioasys)",
48 | "start": "04/2021",
49 | "end": "04/2022",
50 | "role": "Flutter Specialist",
51 | "description": [
52 | "Desenvolvimento e manutenção de um aplicativo B2B e B2C completo utilizando Flutter, garantindo uma experiência eficiente e centrada no usuário.",
53 | "Mentoria e orientação de desenvolvedores juniores por meio de revisões de código, sessões de compartilhamento de conhecimento e suporte técnico, aplicando comunicação eficaz para transmitir ideias de forma clara e construtiva.",
54 | "Liderança na reformulação da arquitetura do aplicativo com princípios de arquitetura limpa, aumentando a manutenibilidade, escalabilidade e testabilidade do código.",
55 | "Otimização do desempenho do aplicativo e uso eficiente dos recursos, garantindo uma experiência fluida e responsiva."
56 | ]
57 | },
58 | {
59 | "company": "MATERIALIZE",
60 | "start": "11/2020",
61 | "end": "12/2021",
62 | "role": "Especialista Flutter ",
63 | "description": [
64 | "Desenvolvimento e implementação de aplicativos móveis multiplataforma de alta qualidade para diversos clientes.",
65 | "Tradução de requisitos do cliente em soluções eficientes e centradas na experiência do usuário.",
66 | "Forte experiência na construção de aplicativos Flutter com funcionamento otimizado para iOS e Android.",
67 | "Superação de desafios técnicos por meio da implementação de soluções eficazes e escaláveis, aplicando resiliência para lidar com obstáculos e aprimorar continuamente o desenvolvimento.",
68 | "Colaboração estreita com clientes e equipes multidisciplinares para garantir a entrega de produtos alinhados às necessidades do mercado, aplicando trabalho em equipe para integrar diferentes perspectivas e alcançar melhores resultados.",
69 | "Utilização de widgets e bibliotecas Flutter para criar aplicativos interativos e ricos em funcionalidades. "
70 | ]
71 | },
72 | {
73 | "company": "IOB/AO3",
74 | "start": "07/2019",
75 | "end": "04/2021",
76 | "role": "Analista Desenvolvedor de Sistemas Sênior",
77 | "description": [
78 | "Desenvolvimento e implementação de um sistema de auditoria eletrônica (SPED) para validação e certificação de arquivos digitais, otimizando processos e garantindo conformidade regulatória.",
79 | "Liderança no desenvolvimento de aplicativos móveis multiplataforma com IA do IBM Watson, proporcionando soluções inovadoras e melhorando a experiência do usuário.",
80 | "Expertise técnica em .NET 4.5, .NET Core, SQL Server, Angular, Flutter, JavaScript, CSS e HTML5, contribuindo para diversos projetos e superando desafios complexos.",
81 | "Mentoria e orientação de desenvolvedores juniores, promovendo um ambiente colaborativo e incentivando o compartilhamento de conhecimento."
82 | ]
83 | },
84 | {
85 | "company": "FRIENDSBEE",
86 | "start": "03/2019",
87 | "end": "11/2020",
88 | "role": "Analista Desenvolvedor de Sistemas Sênior",
89 | "description": [
90 | "Desenvolvimento e lançamento de um aplicativo de rede social para auxiliar usuários na resolução de desafios diários.",
91 | "Implementação full-stack utilizando angular 6 (front-end), .NET Core (back-end) e MySQL (banco de dados).",
92 | "Colaboração e acompanhamento de 100% das equipes multifuncionais para garantir alinhamento entre desenvolvimento, design e produto.",
93 | "Otimização do desempenho do aplicativo, garantindo escalabilidade e uma experiência de usuário aprimorada."
94 | ]
95 | },
96 | {
97 | "company": "RAÍZEN",
98 | "start": "01/2018",
99 | "end": "07/2019",
100 | "role": "Analista Desenvolvedor de Sistemas Sênior",
101 | "description": [
102 | "Garantia da confiabilidade e sustentabilidade de sistemas através da identificação e resolução de bugs.",
103 | "Manutenção e otimização de sistemas desenvolvidos em .NET (MVC, WebForms e Core), jQuery e SQL Server.",
104 | "Colaboração com equipes multifuncionais para resolução de problemas e implementação de melhorias.",
105 | "Desenvolvimento full-stack, atuando na análise, testes e prevenção de falhas para reduzir interrupções nos sistemas, aplicando resolução de problemas para identificar e corrigir erros de forma eficiente."
106 | ]
107 | },
108 | {
109 | "company": "SAGE",
110 | "start": "12/2016",
111 | "end": "01/2018",
112 | "role": "Analista Desenvolvedor de Sistemas Pleno",
113 | "description": [
114 | "Liderança no desenvolvimento e implementação do SPED, sistema de auditoria eletrônica para validação de arquivos contábeis e fiscais, garantindo conformidade regulatória e maior eficiência nos processos.",
115 | "Atualização e implementação de módulos fiscais e contábeis (ECF, eSocial, Reinf) para manter o sistema alinhado às regulamentações vigentes.",
116 | "Modernização da experiência do usuário, migrando aplicações de Silverlight para HTML5, utilizando Bootstrap, CSS3 e jQuery.",
117 | "Desenvolvimento e manutenção de sistemas complexos com .NET 4.5, SQL Server, JavaScript, CSS e HTML5.",
118 | "Colaboração com equipes multifuncionais para garantir a implementação eficiente do sistema de auditoria."
119 | ]
120 | },
121 | {
122 | "company": "Ci&T",
123 | "start": "02/2012",
124 | "end": "12/2013",
125 | "role": "Engenheiro de Software Jr.)",
126 | "description": [
127 | "Integração de aplicações legadas com SAP na DPaschoal, utilizando VB3, .NET, PL/SQL e SQL Server, facilitando a troca de dados e melhorando a eficiência do sistema.",
128 | "Desenvolvimento de melhorias no sistema de cotação de preços da Coca-Cola e no sistema de avaliação de funcionários da Makro, aplicando .NET e SQL Server.",
129 | "Adaptação a múltiplas linguagens de programação e bancos de dados, garantindo flexibilidade e eficiência no desenvolvimento de soluções.",
130 | "Contribuição ativa para o ambiente Scrum, participando de reuniões e colaborando com a equipe para otimizar entregas e processos."
131 | ]
132 | },
133 | {
134 | "company": "Gerencial Informática",
135 | "start": "07/2011",
136 | "end": "01/2012",
137 | "role": "Desenvolvedor de Software",
138 | "description": [
139 | "Desenvolvimento e manutenção de aplicações em Delphi 5 e 7.",
140 | "Utilização do banco de dados Firebird para armazenamento e recuperação de informações.",
141 | "Conhecimento básico em PHP, com interesse em aprendizado e aprimoramento contínuo."
142 | ]
143 | },
144 | {
145 | "company": "PC TECH",
146 | "start": "01/2006",
147 | "end": "01/2008",
148 | "role": "Programador",
149 | "description": [
150 | "Desenvolvimento e implementação de aplicações web utilizando PHP e MySQL.",
151 | "Criação e manutenção de sites e aplicações com Joomla! CMS, garantindo um gerenciamento de conteúdo eficiente.",
152 | "Participação em todas as etapas do ciclo de desenvolvimento, da análise de requisitos à implantação.",
153 | "Colaboração com designers, gerentes de projeto e desenvolvedores para o sucesso dos projetos.",
154 | "Desenvolvimento de fortes habilidades analíticas e de resolução de problemas."
155 | ]
156 | }
157 | ]
158 | }
--------------------------------------------------------------------------------
/assets/experiences_enUs.json:
--------------------------------------------------------------------------------
1 | {
2 | "experiences": [
3 | {
4 | "company": "FARMÁCIAS APP By GrupoSC",
5 | "end": null,
6 | "start": "03/2024",
7 | "role": "Technical Lead Mobile ",
8 | "description": [
9 | "Led the development team for the Farmácias APP application project, distributing and defining tasks and development priorities, monitoring team progress, and ensuring delivery within agreed deadlines, conducting alignment and planning meetings with the team and resolving conflicts.",
10 | "Defined the technical vision for the application, ensuring scalability and best practices, proactively anticipating challenges and proposing continuous improvements.",
11 | "Developed and executed new features for the project.",
12 | "Conducted code reviews and ensured quality through code reviews and testing.",
13 | "Played a frontline role in strategic decision-making for application evolution, applying critical thinking to evaluate solutions and direct development effectively.",
14 | "Provided technical guidance and support to the team, promoting development best practices."
15 | ]
16 | },
17 | {
18 | "company": "GRANTER",
19 | "end": "10/2024",
20 | "start": "06/2022",
21 | "role": "Consultant Flutter Specialist",
22 | "description": [
23 | "Developed and architected high-performance, cross-platform mobile applications.",
24 | "Worked together with stakeholders to translate business requirements into user-friendly features.",
25 | "Applied clean, scalable code following best practices.",
26 | "Integrated APIs and external services for advanced functionality.",
27 | "Provided ongoing support and optimized app performance.",
28 | "Mentored and shared knowledge in Flutter with the team."
29 | ]
30 | },
31 | {
32 | "company": "BEES (via Avantti)",
33 | "end": "02/2024",
34 | "start": "05/2022",
35 | "role": "Technical Lead Mobile",
36 | "description": [
37 | "Curated projects and identified new opportunities aligned with client needs. ",
38 | "Communicated technical solutions and project progress clearly to stakeholders.",
39 | "Developed cross-platform applications and design systems for major companies like TADA and Zé Delivery.",
40 | "Implemented Server-Driven UI (SDUI) for a dynamic and personalized user experience.",
41 | "Designed and carried a reusable design system, ensuring consistency and development agility.",
42 | "Cooperated with designers, back-end engineers, and product managers to optimize processes and deliveries.",
43 | "Mentored and supported junior developers, promoting knowledge sharing within the team."
44 | ]
45 | },
46 | {
47 | "company": "CVC Corp (via ioasys)",
48 | "start": "04/2021",
49 | "end": "04/2022",
50 | "role": "Flutter Specialist",
51 | "description": [
52 | "Optimized application performance and resource utilization, ensuring a smooth and responsive experience.",
53 | "Led the redesign of the application's architecture using clean architecture principles, increasing maintainability, scalability, and testability.",
54 | "Mentored junior developers through code reviews, knowledge-sharing sessions, and technical support.",
55 | "Developed and maintained a comprehensive B2B and B2C application using Flutter, ensuring an efficient and user-centric experience.Key Tools: Flutter, Dart, Server Driven UI, Jira, AWS e Adobe XD"
56 | ]
57 | },
58 | {
59 | "company": "MATERIALIZE",
60 | "start": "11/2020",
61 | "end": "12/2021",
62 | "role": "Flutter Specialist ",
63 | "description": [
64 | "Developed and performed high-quality, cross-platform mobile applications for various clients.",
65 | "Translated client requirements into efficient, user-centric solutions.",
66 | "Built Flutter applications optimized for iOS and Android.",
67 | "Effected effective and scalable solutions to technical challenges.",
68 | "Effected with clients and multidisciplinary teams to deliver market-aligned products.",
69 | "Utilized Flutter widgets and libraries to create interactive, feature-rich applications. "
70 | ]
71 | },
72 | {
73 | "company": "IOB/AO3",
74 | "start": "07/2019",
75 | "end": "04/2021",
76 | "role": "Senior Systems Analyst Developer",
77 | "description": [
78 | "Developed and orchestrated an electronic audit system (SPED) for validating and certifying digital files, optimizing processes, and ensuring regulatory compliance.",
79 | "Led the development of cross-platform mobile applications with IBM Watson AI, providing innovative solutions and improving user experience.",
80 | "Applied technical expertise in .NET 4.5, .NET Core, SQL Server, Angular, Flutter, JavaScript, CSS, and HTML5 to various projects.",
81 | "Mentored junior developers, fostering a collaborative environment and encouraging knowledge sharing."
82 | ]
83 | },
84 | {
85 | "company": "FRIENDSBEE",
86 | "start": "03/2019",
87 | "end": "11/2020",
88 | "role": "Senior Systems Analyst Develope",
89 | "description": [
90 | "Developed and builded a social network application to help users solve daily challenges.",
91 | "Conducted full-stack development using Angular 6 (front-end), .NET Core (back-end), and MySQL (database).",
92 | "Collaboration and monitoring of 100% of multifunctional teams to ensure alignment between development, design and product.",
93 | "Optimized application performance, ensuring scalability and an enhanced user experience."
94 | ]
95 | },
96 | {
97 | "company": "RAÍZEN",
98 | "start": "01/2018",
99 | "end": "07/2019",
100 | "role": "Senior Systems Analyst Developer",
101 | "description": [
102 | "Ensured system reliability and sustainability by identifying and resolving bugs.",
103 | "Upheld and optimized systems developed in .NET (MVC, WebForms, and Core), jQuery, and SQL Server.",
104 | "Cooperated with cross-functional teams to resolve problems and implement improvements.",
105 | "Performed full-stack development, including analysis, testing, and failure prevention to reduce system interruptions."
106 | ]
107 | },
108 | {
109 | "company": "SAGE",
110 | "start": "12/2016",
111 | "end": "01/2018",
112 | "role": "Systems Analyst Developer",
113 | "description": [
114 | "Led the development and implementation of SPED, an electronic audit system for validating accounting and tax files, ensuring regulatory compliance and greater process efficiency.",
115 | "Updated and integrated fiscal and accounting modules (ECF, eSocial, Reinf) to keep the system aligned with current regulations.",
116 | "Modernized the user experience by migrating applications from Silverlight to HTML5 using Bootstrap, CSS3, and jQuery.",
117 | "Kept up complex systems with .NET 4.5, SQL Server, JavaScript, CSS, and HTML5.",
118 | "Partnered with cross-functional teams to ensure efficient implementation of the audit system."
119 | ]
120 | },
121 | {
122 | "company": "Ci&T",
123 | "start": "02/2012",
124 | "end": "12/2013",
125 | "role": "Software Engineer Jr.",
126 | "description": [
127 | "Integrated legacy applications with SAP at DPaschoal using VB3, .NET, PL/SQL, and SQL Server, facilitating data exchange and improving system efficiency.",
128 | "Developed improvements in Coca-Cola's price quote system and Makro's employee evaluation system using .NET and SQL Server.",
129 | "Adapted to multiple programming languages and databases, ensuring flexibility and efficiency in solution development.",
130 | "Contributed actively to the Scrum environment, participating in meetings and collaborating with the team to optimize deliveries and processes."
131 | ]
132 | },
133 | {
134 | "company": "Gerencial Informática",
135 | "start": "07/2011",
136 | "end": "01/2012",
137 | "role": "Software Developer",
138 | "description": [
139 | "Developed and preserved applications in Delphi 5 and 7.",
140 | "Used the Firebird database for information storage and retrieval.",
141 | "Gained basic knowledge in PHP, with an interest in continuous learning and improvement."
142 | ]
143 | },
144 | {
145 | "company": "PC TECH",
146 | "start": "01/2006",
147 | "end": "01/2008",
148 | "role": "Programmer",
149 | "description": [
150 | "Developed and Engineered web applications using PHP and MySQL.",
151 | "Created and serviced websites and applications with Joomla! CMS, ensuring efficient content management.",
152 | "Participated in all stages of the development cycle, from requirement analysis to deployment.",
153 | "Collaborated with designers, project managers, and developers for project success.",
154 | "Developed strong analytical and problem-solving skills."
155 | ]
156 | }
157 | ]
158 | }
--------------------------------------------------------------------------------
/assets/images/awards/dart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/awards/dart.png
--------------------------------------------------------------------------------
/assets/images/awards/flutter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/awards/flutter.png
--------------------------------------------------------------------------------
/assets/images/awards/gde.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/awards/gde.png
--------------------------------------------------------------------------------
/assets/images/awards/mvp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/awards/mvp.png
--------------------------------------------------------------------------------
/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/favicon.png
--------------------------------------------------------------------------------
/assets/images/flutterbrasil/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/flutterbrasil/dash.png
--------------------------------------------------------------------------------
/assets/images/flutterbrasil/flutter_br.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/flutterbrasil/flutter_br.png
--------------------------------------------------------------------------------
/assets/images/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/assets/images/icons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/assets/images/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/assets/images/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/assets/images/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/assets/images/icons/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/icons/logo.png
--------------------------------------------------------------------------------
/assets/images/logo_toshi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/logo_toshi.png
--------------------------------------------------------------------------------
/assets/images/meia_entrada.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/meia_entrada.png
--------------------------------------------------------------------------------
/assets/images/toshi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/assets/images/toshi.png
--------------------------------------------------------------------------------
/assets/lang/en_US.json:
--------------------------------------------------------------------------------
1 | {
2 | "about": "About",
3 | "carrer": "Carrer",
4 | "contact": "Contact",
5 | "main_description": "A Microsoft Most Valuable Professional (MVP) and Google Developer Expert (GDE) in Flutter and Dart, with over 18 years of experience in software development. A postgraduate degree in Software Engineering complements a strong background in building high-quality mobile applications using Flutter. Expertise in team leadership, project management, and stakeholder communication, along with a passion for community building and knowledge sharing as demonstrated by founding Flutter Brasil.",
6 | "details": "Details",
7 | "get_in_touch": "Get in Touch",
8 | "change_language": "Change Language",
9 | "to": "to",
10 | "follow": "Follow",
11 | "phone": "Phone",
12 | "address": "Address",
13 | "current": "Current",
14 | "send_email": "Send Email",
15 | "experience": "Experience"
16 | }
--------------------------------------------------------------------------------
/assets/lang/pt_BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "about": "Sobre",
3 | "carrer": "Carreira",
4 | "contact": "Contato",
5 | "main_description": "Profissional reconhecido pelo programa da Microsoft como Most Value Professional e do Google Developer Expert em Flutter e Dart, pós graduado em Engenharia de Software, com formação tecnológica em Jogos Digitais e técnica em Informática com mais de 18 anos de experiência na área, atuando em empresas nacionais e multinacionais de grande porte de tecnologia. Profissional com ampla experiência em desenvolvimento de aplicações mobile utilizando Flutter. Possui conhecimento em programação de software em diversas ferramentas da área. Vivência com gestão de equipes, condução de projeto com equipes multidisciplinares e troca com stakeholders. Como fundador da Flutter Brasil, encontra-se na linha de frente na organização de eventos e atividades, visando expandir e fortalecer a comunidade.",
6 | "details": "Detalhes",
7 | "change_language": "Trocar Idioma",
8 | "get_in_touch": "Entre em Contato",
9 | "to": "até",
10 | "follow": "Siga",
11 | "phone": "Telefone",
12 | "address": "Endereço",
13 | "send_email": "Enviar Email",
14 | "current": "Atual",
15 | "experience": "Expêriencia"
16 | }
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | homepage
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/app/modules/home/data/datasource/experience_datasource_impl.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:dio/dio.dart';
4 |
5 | import '../repositories/datasources/experience_datasource.dart';
6 | import '../repositories/models/experience_model.dart';
7 |
8 | class ExperienceDatasourceImpl implements ExperienceDatasource {
9 | final String _assetPath =
10 | 'https://raw.githubusercontent.com/toshiossada/toshiossada/refs/heads/main/experiences.json';
11 | final String _assetPathEnUs =
12 | 'https://raw.githubusercontent.com/toshiossada/toshiossada/refs/heads/main/experiences_enUs.json';
13 |
14 | @override
15 | Future> getExperiences(bool isPtBr) async {
16 | final urlString = isPtBr ? _assetPath : _assetPathEnUs;
17 | final http = Dio();
18 | try {
19 | final response = await http.get(urlString);
20 |
21 | if (response.statusCode == 200) {
22 | final jsonString = response.data;
23 | final decodedJson = jsonDecode(jsonString) as Map;
24 |
25 | if (decodedJson.containsKey('experiences') &&
26 | decodedJson['experiences'] is List) {
27 | final List experienceListJson =
28 | decodedJson['experiences'] as List;
29 |
30 | final List experiences =
31 | experienceListJson.map((jsonItem) {
32 | if (jsonItem is Map) {
33 | return ExperienceModel.fromJson(jsonItem);
34 | } else {
35 | throw FormatException(
36 | "Invalid item type found in 'experiences' list: ${jsonItem.runtimeType}");
37 | }
38 | }).toList();
39 |
40 | return experiences;
41 | } else {
42 | throw FormatException(
43 | "Invalid JSON structure: 'experiences' key not found or is not a list in $urlString");
44 | }
45 | } else {
46 | throw Exception(
47 | 'Failed to load experiences from $urlString. Status code: ${response.statusCode}');
48 | }
49 | } catch (e) {
50 | throw Exception('Error fetching experiences from $urlString: $e');
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/app/modules/home/data/mappers/experience_mapper.dart:
--------------------------------------------------------------------------------
1 | import '../../domain/entities/experience_entity.dart';
2 | import '../repositories/models/experience_model.dart';
3 |
4 | class ExperienceMapper {
5 | ExperienceEntity toEntity(ExperienceModel model) {
6 | return ExperienceEntity(
7 | company: model.company,
8 | start: model.start,
9 | end: model.end,
10 | role: model.role,
11 | description: model.description,
12 | );
13 | }
14 |
15 | ExperienceModel toModel(ExperienceEntity entity) {
16 | return ExperienceModel(
17 | company: entity.company,
18 | start: entity.start,
19 | end: entity.end,
20 | role: entity.role,
21 | description: entity.description,
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/app/modules/home/data/repositories/datasources/experience_datasource.dart:
--------------------------------------------------------------------------------
1 | import '../models/experience_model.dart';
2 |
3 | abstract interface class ExperienceDatasource {
4 | Future> getExperiences(bool isPtBr);
5 | }
6 |
--------------------------------------------------------------------------------
/lib/app/modules/home/data/repositories/experience_repository_impl.dart:
--------------------------------------------------------------------------------
1 | import '../../domain/entities/experience_entity.dart';
2 | import '../../domain/interfaces/experience_repository.dart';
3 | import '../mappers/experience_mapper.dart';
4 | import 'datasources/experience_datasource.dart';
5 |
6 | class ExperienceRepositoryImpl implements ExperienceRepository {
7 | final ExperienceDatasource datasource;
8 | final ExperienceMapper mapper;
9 |
10 | ExperienceRepositoryImpl({required this.datasource, required this.mapper});
11 |
12 | @override
13 | Future> getExperiences(bool isPtBr) async {
14 | final experiences = await datasource.getExperiences(isPtBr);
15 |
16 | return experiences.map(mapper.toEntity).toList();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/app/modules/home/data/repositories/models/experience_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart'; // Import the intl package for date formatting
2 |
3 | class ExperienceModel {
4 | final String company;
5 | final DateTime start;
6 | final DateTime? end;
7 | final String role;
8 | final List description;
9 |
10 | ExperienceModel({
11 | required this.company,
12 | required this.start,
13 | this.end,
14 | required this.role,
15 | required this.description,
16 | });
17 |
18 |
19 | static DateTime? _parseDate(String? dateString) {
20 | if (dateString == null || dateString.isEmpty) {
21 | return null;
22 | }
23 | return DateFormat('MM/yyyy').parseStrict(dateString);
24 | }
25 |
26 | static String? _formatDate(DateTime? date) {
27 | if (date == null) {
28 | return null;
29 | }
30 | return DateFormat('MM/yyyy').format(date);
31 | }
32 |
33 | /// Creates an ExperienceModel instance from a JSON map.
34 | factory ExperienceModel.fromJson(Map json) {
35 | List descriptionList = [];
36 | if (json['description'] is List) {
37 | descriptionList =
38 | List.from(json['description'].map((item) => item.toString()));
39 | }
40 | DateTime? startDate = _parseDate(json['start'] as String?);
41 | DateTime? endDate =
42 | _parseDate(json['end'] as String?); // end can be null in JSON
43 |
44 | // Validate required fields
45 | if (json['company'] == null || startDate == null || json['role'] == null) {
46 | throw FormatException(
47 | "Missing required fields (company, start, role) in Experience JSON: $json");
48 | }
49 |
50 | return ExperienceModel(
51 | company: json['company'] as String,
52 | start: startDate,
53 | end: endDate,
54 | role: json['role'] as String,
55 | description: descriptionList,
56 | );
57 | }
58 |
59 | /// Converts an ExperienceModel instance to a JSON map.
60 | Map toJson() {
61 | return {
62 | 'company': company,
63 | 'start': _formatDate(start),
64 | 'end': _formatDate(end),
65 | 'role': role,
66 | 'description': description,
67 | };
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/app/modules/home/domain/entities/experience_entity.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 | import 'package:localization/localization.dart';
3 |
4 | class ExperienceEntity {
5 | final String company;
6 | final DateTime start;
7 | final DateTime? end;
8 | final String role;
9 | final List description;
10 |
11 | ExperienceEntity({
12 | required this.company,
13 | required this.start,
14 | this.end,
15 | required this.role,
16 | required this.description,
17 | });
18 | String get formattedStart => DateFormat('MM/yyyy').format(start);
19 |
20 | String get formattedEnd {
21 | if (end == null) {
22 | return "current".i18n();
23 | } else {
24 | return DateFormat('MM/yyyy').format(end!);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/app/modules/home/domain/interfaces/experience_repository.dart:
--------------------------------------------------------------------------------
1 | import '../entities/experience_entity.dart'; // Adjust path if needed
2 |
3 | abstract class ExperienceRepository {
4 | Future> getExperiences(bool isPtBr);
5 | }
6 |
--------------------------------------------------------------------------------
/lib/app/modules/home/domain/usecases/get_experiences_usecase.dart:
--------------------------------------------------------------------------------
1 | import '../entities/experience_entity.dart';
2 | import '../interfaces/experience_repository.dart';
3 |
4 |
5 | class GetExperiencesUsecase {
6 | final ExperienceRepository repository;
7 |
8 | GetExperiencesUsecase({required this.repository});
9 |
10 | Future> call(bool isPtBr) {
11 | return repository.getExperiences(isPtBr);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/app/modules/home/home_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_modular/flutter_modular.dart';
2 | import 'package:homepage/app/modules/home/data/repositories/datasources/experience_datasource.dart';
3 | import 'package:homepage/app/modules/home/pages/initial/initial_page.dart';
4 | import 'package:homepage/app/modules/home/pages/initial/initial_page_controller.dart';
5 |
6 | import '../../../core_module.dart';
7 | import 'data/datasource/experience_datasource_impl.dart';
8 | import 'data/mappers/experience_mapper.dart';
9 | import 'data/repositories/experience_repository_impl.dart';
10 | import 'domain/interfaces/experience_repository.dart';
11 | import 'domain/usecases/get_experiences_usecase.dart';
12 | import 'pages/about/about_page.dart';
13 | import 'pages/carrer/carrer_controller.dart';
14 | import 'pages/carrer/carrer_page.dart';
15 | import 'pages/carrer/carrer_store.dart';
16 | import 'pages/contacts/contact_page.dart';
17 | import 'pages/generator/experiences_pages.dart';
18 |
19 | class HomeModule extends Module {
20 | @override
21 | List get imports => [CoreModule()];
22 | @override
23 | void binds(Injector i) {
24 | i
25 | ..add(InitialPageController.new)
26 | ..add(CarrerStore.new)
27 | ..add(CarrerController.new)
28 | ..add(GetExperiencesUsecase.new)
29 | ..add(ExperienceRepositoryImpl.new)
30 | ..add(ExperienceMapper.new)
31 | ..add(ExperienceDatasourceImpl.new);
32 | }
33 |
34 | @override
35 | void routes(RouteManager r) {
36 | r
37 | ..child('/',
38 | child: (_) => InitialPage(
39 | controller: Modular.get(),
40 | ),
41 | children: [
42 | ChildRoute('/about', child: (_) => AboutPage()),
43 | ChildRoute('/contact', child: (_) => ContactPage()),
44 | ChildRoute('/carrer',
45 | child: (_) => CarrerPage(
46 | controller: Modular.get(),
47 | )),
48 | ])
49 | ..child('/experiences-generator', child: (_) => ExperiencesPage());
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/about/about_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:homepage/app/modules/home/pages/about/widget/avatar_widget.dart';
3 | import 'package:localization/localization.dart';
4 | import 'package:url_launcher/url_launcher.dart';
5 |
6 | import '../widgets/contact_widget.dart';
7 | import 'widget/info_widget.dart';
8 |
9 | class AboutPage extends StatefulWidget {
10 | const AboutPage({super.key});
11 |
12 | @override
13 | State createState() => _AboutPageState();
14 | }
15 |
16 | class _AboutPageState extends State {
17 | static const double _breakpoint = 700.0;
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | final screenWidth = MediaQuery.of(context).size.width;
22 | final bool isSmallScreen = screenWidth < _breakpoint;
23 |
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: Text('about'.i18n()),
27 | backgroundColor: Colors.transparent,
28 | elevation: 0,
29 | ),
30 | body: SingleChildScrollView(
31 | padding: const EdgeInsets.all(16.0),
32 | child: Column(
33 | crossAxisAlignment: CrossAxisAlignment.center,
34 | children: [
35 | isSmallScreen
36 | ? _buildSmallLayout(context)
37 | : _buildLargeLayout(context),
38 | const SizedBox(height: 32),
39 | ContactWidget(
40 | onPressed: _launchUrl,
41 | ),
42 | const SizedBox(height: 16),
43 | ],
44 | ),
45 | ),
46 | );
47 | }
48 |
49 | Widget _buildSmallLayout(BuildContext context) {
50 | return Column(
51 | mainAxisAlignment: MainAxisAlignment.center,
52 | children: [
53 | AvatarWidget(),
54 | const SizedBox(height: 24),
55 | InfoWidget(),
56 | ],
57 | );
58 | }
59 |
60 | Widget _buildLargeLayout(BuildContext context) {
61 | return Row(
62 | crossAxisAlignment: CrossAxisAlignment.start,
63 | mainAxisAlignment: MainAxisAlignment.center,
64 | children: [
65 | AvatarWidget(),
66 | const SizedBox(width: 32),
67 | Expanded(child: InfoWidget()),
68 | ],
69 | );
70 | }
71 |
72 | Future _launchUrl(String urlString) async {
73 | final Uri url = Uri.parse(urlString);
74 | if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
75 | if (mounted) {
76 | ScaffoldMessenger.of(context).showSnackBar(
77 | SnackBar(content: Text('Não foi possível abrir $urlString')),
78 | );
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/about/widget/avatar_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:homepage/app/modules/home/pages/about/widget/awards_widget.dart';
3 | import 'package:seo_renderer/renderers/image_renderer/image_renderer_web.dart';
4 |
5 | class AvatarWidget extends StatelessWidget {
6 | const AvatarWidget({super.key});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Column(
11 | children: [
12 | ImageRenderer(
13 | alt: 'Toshi Ossada Logo',
14 | child: Image.asset(
15 | 'assets/images/toshi.png',
16 | ),
17 | ),
18 | AwardsWidget(),
19 | ],
20 | );
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/about/widget/awards_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:seo_renderer/renderers/image_renderer/image_renderer_web.dart';
3 | import 'package:url_launcher/url_launcher.dart';
4 |
5 | class AwardsWidget extends StatelessWidget {
6 | const AwardsWidget({super.key});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Wrap(
11 |
12 | children: [
13 | GestureDetector(
14 | onTap: () {
15 | launchUrl(
16 | Uri.parse(
17 | 'https://developers.google.com/profile/u/toshiossada'),
18 | mode: LaunchMode.externalApplication);
19 | },
20 | child: ImageRenderer(
21 | alt: 'Google Developer Expert',
22 | child: Image.asset(
23 | 'assets/images/awards/gde.png',
24 | height: 62,
25 | ),
26 | ),
27 | ),
28 | SizedBox.square(
29 | dimension: 8,
30 | ),
31 | GestureDetector(
32 | onTap: () {
33 | launchUrl(
34 | Uri.parse(
35 | 'https://mvp.microsoft.com/pt-BR/MVP/profile/670f6b6b-0adf-498c-bb2d-d80b193d4e5d'),
36 | mode: LaunchMode.externalApplication);
37 | },
38 | child: ImageRenderer(
39 | alt: 'Microsoft Most Value Professional',
40 | child: Image.asset(
41 | 'assets/images/awards/mvp.png',
42 | height: 62,
43 | ),
44 | ),
45 | ),
46 | ],
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/about/widget/info_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:localization/localization.dart';
3 | import 'package:seo_renderer/seo_renderer.dart';
4 | import 'package:url_launcher/url_launcher.dart';
5 |
6 | class InfoWidget extends StatelessWidget {
7 | const InfoWidget({super.key});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Column(
12 | crossAxisAlignment: CrossAxisAlignment.start,
13 | children: [
14 | TextRenderer(
15 | style: TextRendererStyle.header1,
16 | child: Text(
17 | 'TOSHI OSSADA',
18 | style: TextStyle(
19 | fontSize: 42,
20 | ),
21 | ),
22 | ),
23 | SizedBox.square(
24 | dimension: 32,
25 | ),
26 | Wrap(
27 | children: [
28 | ImageRenderer(
29 | alt: 'Dart',
30 | child: Image.asset(
31 | 'assets/images/awards/dart.png',
32 | height: 52,
33 | ),
34 | ),
35 | SizedBox.square(
36 | dimension: 32,
37 | ),
38 | ImageRenderer(
39 | alt: 'Flutter',
40 | child: Image.asset(
41 | 'assets/images/awards/flutter.png',
42 | height: 52,
43 | ),
44 | ),
45 | ],
46 | ),
47 | SizedBox.square(
48 | dimension: 32,
49 | ),
50 | TextRenderer(
51 | child: SelectableText(
52 | 'main_description'.i18n(),
53 | ),
54 | ),
55 | GestureDetector(
56 | onTap: () {
57 | launchUrl(Uri.parse('https://flutterbrasil.com.br/'),
58 | mode: LaunchMode.externalApplication);
59 | },
60 | child: Padding(
61 | padding: const EdgeInsets.all(8.0),
62 | child: Wrap(
63 | children: [
64 | ImageRenderer(
65 | alt: 'Flutter',
66 | child: Image.asset(
67 | 'assets/images/flutterbrasil/dash.png',
68 | height: 52,
69 | ),
70 | ),
71 | ImageRenderer(
72 | alt: 'Flutter',
73 | child: Image.asset(
74 | 'assets/images/flutterbrasil/flutter_br.png',
75 | height: 52,
76 | ),
77 | ),
78 | ],
79 | ),
80 | ),
81 | )
82 | ],
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/carrer/carrer_controller.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import '../../../../../app_store.dart';
4 | import '../../domain/entities/experience_entity.dart';
5 | import '../../domain/usecases/get_experiences_usecase.dart';
6 | import 'carrer_store.dart';
7 |
8 | class CarrerController {
9 | final GetExperiencesUsecase getExperiencesUsecase;
10 | final CarrerStore store;
11 | final AppStore appStore;
12 |
13 | CarrerController({
14 | required this.getExperiencesUsecase,
15 | required this.store,
16 | required this.appStore,
17 | });
18 |
19 | init() async {
20 | await getExperiences();
21 | }
22 |
23 | Future> getExperiences() async {
24 | try {
25 | store.loading = true;
26 |
27 | var experiences =
28 | await getExperiencesUsecase.call(appStore.locale == Locale('pt', 'BR'));
29 | store.experience = experiences;
30 |
31 | return experiences;
32 | } catch (e) {
33 | return [];
34 | } finally {
35 | store.loading = false;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/carrer/carrer_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:localization/localization.dart';
3 | import 'package:timeline_tile/timeline_tile.dart';
4 |
5 | import 'carrer_controller.dart';
6 |
7 | class CarrerPage extends StatefulWidget {
8 | final CarrerController controller;
9 | const CarrerPage({
10 | super.key,
11 | required this.controller,
12 | });
13 |
14 | @override
15 | State createState() => _CarrerPageState();
16 | }
17 |
18 | class _CarrerPageState extends State {
19 | CarrerController get controller => widget.controller;
20 |
21 | @override
22 | void initState() {
23 | super.initState();
24 | controller.init();
25 | }
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | final theme = Theme.of(context);
30 |
31 | return Scaffold(
32 | appBar: AppBar(
33 | title: Text("experience".i18n()),
34 | backgroundColor: Colors.transparent,
35 | elevation: 0,
36 | ),
37 | body: ListenableBuilder(
38 | listenable: controller.store,
39 | builder: (context, child) {
40 | if (controller.store.loading) {
41 | return const Center(child: CircularProgressIndicator());
42 | }
43 |
44 | if (controller.store.experience.isEmpty) {
45 | return const Center(child: Text("Nenhuma experiência encontrada."));
46 | }
47 |
48 | return ListView.builder(
49 | padding:
50 | const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
51 | itemCount: controller.store.experience.length,
52 | itemBuilder: (context, index) {
53 | final experience = controller.store.experience[index];
54 | final isFirst = index == 0;
55 | final isLast = index == controller.store.experience.length - 1;
56 |
57 | return TimelineTile(
58 | alignment: TimelineAlign.manual,
59 | lineXY: 0.15,
60 | isFirst: isFirst,
61 | isLast: isLast,
62 | indicatorStyle: IndicatorStyle(
63 | width: 20,
64 | height: 20,
65 | indicatorXY: 0.5,
66 | indicator: Container(
67 | decoration: BoxDecoration(
68 | color: theme.colorScheme.primary,
69 | shape: BoxShape.circle,
70 | ),
71 | ),
72 | padding: const EdgeInsets.all(6),
73 | ),
74 | beforeLineStyle: LineStyle(
75 | color: theme.colorScheme.primary.withValues(alpha: (255 / 2)),
76 | thickness: 2,
77 | ),
78 | afterLineStyle: LineStyle(
79 | color: theme.colorScheme.primary.withValues(alpha: (255 / 2)),
80 | thickness: 2,
81 | ),
82 | endChild: Container(
83 | constraints: const BoxConstraints(
84 | minHeight: 120,
85 | ),
86 | padding: const EdgeInsets.only(
87 | left: 16.0, top: 8.0, bottom: 16.0, right: 8.0),
88 | child: Column(
89 | crossAxisAlignment: CrossAxisAlignment.start,
90 | mainAxisAlignment: MainAxisAlignment.center,
91 | children: [
92 | Text(
93 | '${experience.formattedStart} - ${experience.formattedEnd}',
94 | style: theme.textTheme.bodySmall?.copyWith(
95 | color: theme.colorScheme.onSurface
96 | .withValues(alpha: (255 * 0.7)),
97 | fontWeight: FontWeight.w500,
98 | ),
99 | ),
100 | const SizedBox(height: 4),
101 | Text(
102 | experience.company,
103 | style: theme.textTheme.titleMedium?.copyWith(
104 | fontWeight: FontWeight.bold,
105 | ),
106 | ),
107 | const SizedBox(height: 4),
108 | Text(
109 | experience.role,
110 | style: theme.textTheme.titleSmall?.copyWith(
111 | fontStyle: FontStyle.italic,
112 | color: theme.colorScheme.onSurface
113 | .withValues(alpha: (255 * 0.8)),
114 | ),
115 | ),
116 | const SizedBox(height: 8),
117 | ExpansionTile(
118 | tilePadding: EdgeInsets.zero,
119 | title: Text(
120 | 'details'.i18n(),
121 | style: theme.textTheme.bodySmall?.copyWith(
122 | color: theme.colorScheme.primary,
123 | ),
124 | ),
125 | childrenPadding:
126 | const EdgeInsets.only(top: 4.0, bottom: 8.0),
127 | children: experience.description
128 | .map((desc) => Padding(
129 | padding: const EdgeInsets.only(bottom: 4.0),
130 | child: Row(
131 | crossAxisAlignment:
132 | CrossAxisAlignment.start,
133 | children: [
134 | const Text("• ",
135 | style: TextStyle(
136 | fontWeight: FontWeight.bold)),
137 | Expanded(
138 | child: Text(desc,
139 | style:
140 | theme.textTheme.bodySmall)),
141 | ],
142 | ),
143 | ))
144 | .toList(),
145 | ),
146 | ],
147 | ),
148 | ),
149 | );
150 | },
151 | );
152 | },
153 | ),
154 | );
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/carrer/carrer_store.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:homepage/app/modules/home/domain/entities/experience_entity.dart';
3 |
4 | class CarrerStore extends ChangeNotifier {
5 | List _experience = [];
6 | List get experience => _experience;
7 | set experience(List value) {
8 | _experience = value;
9 | notifyListeners();
10 | }
11 |
12 | bool _loading = true;
13 | bool get loading => _loading;
14 | set loading(bool value) {
15 | _loading = value;
16 | notifyListeners();
17 | }
18 |
19 | CarrerStore();
20 | }
21 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/contacts/contact_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:localization/localization.dart';
3 | import 'package:url_launcher/url_launcher.dart';
4 |
5 | import '../widgets/contact_widget.dart';
6 | import 'widgets/contact_tile_widget.dart';
7 |
8 | class ContactPage extends StatelessWidget {
9 | const ContactPage({super.key});
10 |
11 | Future _launchUrl(String urlString) async {
12 | final Uri url = Uri.parse(urlString);
13 | if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
14 | // Poderia mostrar um Snackbar ou log de erro aqui
15 |
16 | throw Exception('Could not launch $url'); // Ou lançar uma exceção
17 | }
18 | }
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | backgroundColor: Colors.grey[900],
24 | body: SingleChildScrollView(
25 | padding: const EdgeInsets.all(20.0),
26 | child: Column(
27 | crossAxisAlignment: CrossAxisAlignment.start,
28 | children: [
29 | Text(
30 | 'get_in_touch'.i18n(),
31 | style: TextStyle(
32 | fontSize: 24,
33 | fontWeight: FontWeight.bold,
34 | color: Colors.white,
35 | ),
36 | ),
37 | const SizedBox(height: 30),
38 | ContactTileWidget(
39 | icon: Icons.phone_android,
40 | title: 'phone'.i18n(),
41 | subtitle: '+55 (19) 99120-0273',
42 | url: '5519991200273',
43 | urlType: UrlTypeEnum.tel,
44 | onPressed: _launchUrl,
45 | ),
46 | const Divider(color: Colors.grey, indent: 16, endIndent: 16),
47 | ContactTileWidget(
48 | icon: Icons.email_outlined,
49 | title: 'Email',
50 | subtitle: 'toshiossada@toshiossada.dev',
51 | url: 'toshiossada@toshiossada.dev',
52 | urlType: UrlTypeEnum.email,
53 | onPressed: _launchUrl,
54 | ),
55 | const Divider(color: Colors.grey, indent: 16, endIndent: 16),
56 | ContactTileWidget(
57 | icon: Icons.location_pin,
58 | title: 'address'.i18n(),
59 | subtitle: 'Americana - SP',
60 | url:
61 | 'https://www.google.com/maps/search/?api=1&query=Americana,SP',
62 | urlType: UrlTypeEnum.link,
63 | onPressed: _launchUrl,
64 | ),
65 | const SizedBox(height: 40),
66 | Text(
67 | 'follow'.i18n(),
68 | style: TextStyle(
69 | fontSize: 20,
70 | fontWeight: FontWeight.bold,
71 | color: Colors.white,
72 | ),
73 | ),
74 | const SizedBox(height: 20),
75 | ContactWidget(
76 | onPressed: _launchUrl,
77 | ),
78 | const SizedBox(height: 20),
79 | ],
80 | ),
81 | ),
82 | );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/contacts/widgets/contact_tile_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ContactTileWidget extends StatelessWidget {
4 | final IconData icon;
5 | final String title;
6 | final String subtitle;
7 | final String url;
8 | final UrlTypeEnum urlType;
9 | final Function(String) onPressed;
10 |
11 | const ContactTileWidget({
12 | super.key,
13 | required this.onPressed,
14 | required this.icon,
15 | required this.title,
16 | required this.subtitle,
17 | required this.url,
18 | required this.urlType,
19 | });
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return ListTile(
24 | leading: Icon(icon, color: Colors.tealAccent[400]),
25 | title: Text(title,
26 | style: const TextStyle(
27 | color: Colors.white, fontWeight: FontWeight.bold)),
28 | subtitle:
29 | SelectableText(subtitle, style: TextStyle(color: Colors.grey[400])),
30 | onTap: () {
31 | String launchUrlString;
32 | if (urlType == UrlTypeEnum.tel) {
33 | launchUrlString = 'https://wa.me/$url';
34 | } else if (urlType == UrlTypeEnum.email) {
35 | launchUrlString = 'mailto:$url';
36 | } else {
37 | launchUrlString = url;
38 | }
39 | onPressed(launchUrlString);
40 | },
41 | contentPadding:
42 | const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
43 | );
44 | }
45 | }
46 |
47 | enum UrlTypeEnum {
48 | tel,
49 | email,
50 | link;
51 | }
52 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/dne_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_modular/flutter_modular.dart';
2 |
3 | import 'pages/dne_page.dart';
4 |
5 | class DNEModule extends Module {
6 | @override
7 | void routes(RouteManager r) {
8 | r.child(
9 | '/',
10 | child: (_) => DNEPage(
11 | name: r.args.queryParams['name'] ?? '',
12 | school: r.args.queryParams['school'] ?? '',
13 | course: r.args.queryParams['course'] ?? '',
14 | document: r.args.queryParams['document'] ?? '',
15 | photo: r.args.queryParams['photo'] ?? '',
16 | ),
17 | );
18 | }
19 | }
20 |
21 | // '/dne/?name=Kevlin Toshinari Ossada&school=Faculdade de Tecnologia de Americana&course=Analise e Desenvolvimento de S&document=496271167&photo=https://avatars.githubusercontent.com/u/2637049'
22 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/dne_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:homepage/app/modules/home/pages/dne/pages/widegets/info_widget.dart';
3 |
4 | import 'widegets/app_bar_widget.dart';
5 | import 'widegets/certificate.dart';
6 | import 'widegets/valid_widget.dart';
7 |
8 | class DNEPage extends StatefulWidget {
9 | final String name;
10 | final String school;
11 | final String course;
12 | final String document;
13 | final String photo;
14 |
15 | const DNEPage({
16 | super.key,
17 | required this.name,
18 | required this.school,
19 | required this.course,
20 | required this.document,
21 | required this.photo,
22 | });
23 |
24 | @override
25 | State createState() => _DNEPageState();
26 | }
27 |
28 | class _DNEPageState extends State {
29 | @override
30 | Widget build(BuildContext context) {
31 | return Theme(
32 | data: ThemeData.light(),
33 | child: Scaffold(
34 | backgroundColor: Colors.white,
35 | body: SingleChildScrollView(
36 | child: Column(
37 | children: [
38 | AppBarwidget(),
39 | SingleChildScrollView(
40 | child: Padding(
41 | padding: const EdgeInsets.all(20.0),
42 | child: Column(
43 | crossAxisAlignment: CrossAxisAlignment.start,
44 | children: [
45 | const Text(
46 | 'Validação de CIE (Carteira de Identificação Estudantil)',
47 | style: TextStyle(
48 | fontSize: 22,
49 | fontWeight: FontWeight.bold,
50 | color: Color(0xFF005e9e),
51 | ),
52 | ),
53 | const SizedBox(height: 5),
54 | const Divider(
55 | color: Color(0xFF005e9e),
56 | thickness: 2,
57 | height: 20,
58 | ),
59 | const SizedBox(height: 20),
60 | ValidWidget(),
61 | const SizedBox(height: 25),
62 | Text(
63 | 'UNE atesta que ${widget.name} é estudante e está regularmente matriculado(a) em ${widget.course} da instituição ${widget.school}',
64 | style: TextStyle(fontSize: 15),
65 | textAlign: TextAlign.center,
66 | ),
67 | const SizedBox(height: 30),
68 | InfoWidget(
69 | name: widget.name,
70 | school: widget.school,
71 | course: widget.course,
72 | document: widget.document.padLeft(15, '0'),
73 | photo: widget.photo,
74 | ),
75 | CertificateWidget(
76 | headerText: 'Certificado de Atributo em formato PEM:',
77 | certificateText:
78 | '''MIID6DCCAiACAgbhweKBhzMBgkqhkiG9w0BAQ0EwJUCCjUbegAMIGA1UECgvKUUNSUlUJUXYXpnbDEmMCQGA1UECwwdVU5JdUgU8gTKFDSU0QUJvigRE9TlEVTlVFTVFVQ5URVMxdTAVBgNVBAIMMddmgbpbU3BNoaW55hcmgtT3NyeW1HRlAlCBZlCBjy6SBByDcBXTEkMAkGA1UEBhMCRzEXARgNVBAoMEAoXMCkICU1CcmFzZWFVBgNVBAsMDE00MTIxOTU3MDMwTAVBMRMwMRkwdYDVQQDLDBwWRI2NVbhZmcZkmVU1hMC4wDAYDVQQDLDAVWOuxJRDEXBgEwHgYDVQQJExcwSUGVzc29hZz9hEp1cmKaWnhNEEzMrgiwFgYDVR0QLDdA9BQyBWQUXdURCbCUkFTsUkJxgNkgNVBAMMHVVOsuFPIIE5BC0jpTKhFMdERVpUBU1RFVREVFOVTMADGCSpSggS3IQD3DQEBBQUAA4GgAgZ6ZXMcjIyDzjuwMvMz4MTQzMIEzMvVHgPfMIAyNjAzMzEyMzU6NTlaMIHNMEYGBWMaA0OBmT0TOzE5MDkxOTkyNDE1MzcyMTc4MDAMWDAaMDAxOTEwMTlhWDAaMDAwMDA0MDOTYzExNjcgICAglCAgAQMHgGBWMaAQoC MW0Ta1ZH3Y3VsZGZGeksZBZsBUzwNzub2x2ihIGRIFEFzXxjvJpFy2ySAgLcbTVVBFUkPuKlAgICAgLcbBbmFSaXNiUGUGRGVvVzVzZb2x2aW1lhWRIFGRIFNB0yVVaWhtbnEgICAglCA glCAgfAQIfNAqmsASGBWMaA0QDTADBMgMDMGA1UdIh0wQmhCgYIKwYIHRoUCHjB6MHUuJ9I1bmUzZGtLZnI3YLXL2nYbcC9I6bmJuY3JSgpPTlMwHQYDVR0OBBYEFMIcLSs9s92KkXVR0N g1zkde73OMCEgcGsqG/uFEWBbwEUUwEwyYWKBQQHMAIIEAY4YFSSFRUUFMDQyJzlhcWcNAOEFAgEHQEBAjyxgq+pj195QySzjVsUDp/dIIKh3K2RoAyDnmrbeUhJ9PnBiN YgUDW4G9aYC9CspPdITspwvVsqyaT3bAUlLRD2YHjnYJ8QW6Gs6R7GsaR7pGUBApGTlNbHQvzaS+OkybiVb7DV4xA8mRvVXYKGjRqvW7f7LdlySbyYtsd475DK8T4fTA113zlbYtdgkgx+kgxEs v2gU5UZZAEOHphBda4PHz4aGmxvMatuyA66UBy9is1Bs3xrltNJUpHQNOZXchCWbGjmG38y7NE5pNA6FWS6uDIOn7yCUwmv6KBkBLtAbLbLc1cxwsuMN7Y7WkcbHeAhWgzvcS3zv3y1he0oQ9dpNQtfpc2o=''',
79 | )
80 | ],
81 | ),
82 | ),
83 | ),
84 | ],
85 | ),
86 | ),
87 | ),
88 | );
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/app_bar_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AppBarwidget extends StatelessWidget {
4 | const AppBarwidget({super.key});
5 |
6 | @override
7 | Widget build(BuildContext context) {
8 | const Color orangeColor = Color(0xFFF5A623);
9 | const Color blueColor = Color(0xFF0056B3);
10 |
11 | return Column(
12 | mainAxisAlignment: MainAxisAlignment.start,
13 | mainAxisSize: MainAxisSize.max,
14 | children: [
15 | Container(
16 | height: 5,
17 | color: orangeColor,
18 | ),
19 | Container(
20 | height: 100,
21 | color: blueColor,
22 | padding: const EdgeInsets.symmetric(horizontal: 16.0),
23 | child: Row(
24 | children: [
25 | SizedBox(
26 | width: 100,
27 | ),
28 | Image.asset(
29 | 'assets/images/meia_entrada.png',
30 | ),
31 | const Spacer(),
32 |
33 | Icon(Icons.menu, color: Colors.white),
34 | // LayoutBuilder(
35 | // builder: (context, constraints) {
36 | // if (constraints.maxWidth > 600) {
37 | // return Row(
38 | // children: [
39 | // LinkWidget(
40 | // label: 'Lei da Meia-entrada',
41 | // ),
42 | // LinkWidget(
43 | // label: 'Validação',
44 | // ),
45 | // LinkWidget(
46 | // label: 'Chaves públicas',
47 | // ),
48 | // LinkWidget(
49 | // label: 'FAQ',
50 | // ),
51 | // LinkWidget(
52 | // label: 'Notícias',
53 | // ),
54 | // ],
55 | // );
56 | // } else {
57 | // return Icon(Icons.menu, color: Colors.white);
58 | // }
59 | // },
60 | // )
61 | ],
62 | ),
63 | ),
64 | ],
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/certificate.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CertificateWidget extends StatelessWidget {
4 | final String headerText;
5 | final String certificateText;
6 |
7 | const CertificateWidget({
8 | super.key,
9 | required this.headerText,
10 | required this.certificateText,
11 | });
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Wrap(
16 | children: [
17 | Padding(
18 | padding: const EdgeInsets.all(16.0),
19 | child: Column(
20 | crossAxisAlignment: CrossAxisAlignment.start,
21 | children: [
22 | Text(
23 | headerText,
24 | style: const TextStyle(
25 | fontSize: 18,
26 | fontWeight: FontWeight.bold,
27 | ),
28 | ),
29 | const SizedBox(height: 8),
30 | Text(
31 | certificateText,
32 | style: const TextStyle(fontFamily: 'monospace'),
33 | ),
34 | ],
35 | ),
36 | ),
37 | ],
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/detail_row_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DetailRowWidget extends StatelessWidget {
4 | final String label;
5 | final String value;
6 | const DetailRowWidget({super.key, required this.label, required this.value});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Column(
11 | children: [
12 | Padding(
13 | padding: const EdgeInsets.symmetric(vertical: 8.0),
14 | child: Row(
15 | crossAxisAlignment: CrossAxisAlignment.start,
16 | children: [
17 | SizedBox(
18 | width: 120,
19 | child: Text(
20 | label,
21 | style: const TextStyle(fontWeight: FontWeight.bold),
22 | ),
23 | ),
24 | const SizedBox(width: 10),
25 | Expanded(
26 | child: Text(value),
27 | ),
28 | ],
29 | ),
30 | ),
31 | const Divider(),
32 | ],
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/info_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'detail_row_widget.dart';
4 |
5 | class InfoWidget extends StatelessWidget {
6 | final String name;
7 | final String school;
8 | final String course;
9 | final String document;
10 | final String photo;
11 | const InfoWidget(
12 | {super.key,
13 | required this.name,
14 | required this.school,
15 | required this.course,
16 | required this.document,
17 | required this.photo});
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Row(
22 | crossAxisAlignment: CrossAxisAlignment.start,
23 | children: [
24 | Expanded(
25 | flex: 3,
26 | child: Column(
27 | children: [
28 | DetailRowWidget(label: 'Nome:', value: name),
29 | DetailRowWidget(label: 'Instituição:', value: school),
30 | DetailRowWidget(label: 'Curso:', value: course),
31 | DetailRowWidget(
32 | label: 'Documento de Identificação:', value: document),
33 | DetailRowWidget(label: 'Emissor:', value: 'UNE'),
34 | ],
35 | ),
36 | ),
37 | const SizedBox(width: 20),
38 | Expanded(
39 | flex: 1,
40 | child: Align(
41 | alignment: Alignment.topCenter,
42 | child: Image.network(
43 | photo,
44 | height: 150,
45 | fit: BoxFit.contain,
46 | errorBuilder: (context, error, stackTrace) {
47 | return Container(
48 | height: 150,
49 | width: 100,
50 | color: Colors.grey[200],
51 | child: const Center(
52 | child: Icon(Icons.person, size: 50, color: Colors.grey)),
53 | );
54 | },
55 | ),
56 | ),
57 | ),
58 | ],
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/link_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class LinkWidget extends StatelessWidget {
4 | final String label;
5 | final bool isLast;
6 |
7 | const LinkWidget({super.key, required this.label, this.isLast = false});
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | final Color textColor = Theme.of(context).colorScheme.onPrimary;
12 | return Column(
13 | mainAxisAlignment: MainAxisAlignment.center,
14 | children: [
15 | TextButton(
16 | style: TextButton.styleFrom(
17 | foregroundColor: textColor,
18 | padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
19 | minimumSize: Size.zero,
20 | tapTargetSize: MaterialTapTargetSize.shrinkWrap,
21 | ),
22 | onPressed: () {},
23 | child: Row(
24 | mainAxisSize: MainAxisSize.min,
25 | children: [
26 | Text(label),
27 | ],
28 | ),
29 | ),
30 | const SizedBox(height: 3.0),
31 | if (!isLast) SizedBox(width: 10),
32 | ],
33 | );
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/dne/pages/widegets/valid_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ValidWidget extends StatelessWidget {
4 | const ValidWidget({super.key});
5 |
6 | @override
7 | Widget build(BuildContext context) {
8 | return Container(
9 | width: double.infinity,
10 | padding: const EdgeInsets.all(15.0),
11 | decoration: BoxDecoration(
12 | color: const Color(0xFFDFF0D8),
13 | borderRadius: BorderRadius.circular(4.0),
14 | border: Border.all(color: const Color(0xFFD6E9C6)),
15 | ),
16 | child: const Center(
17 | child: Text(
18 | 'Documento válido!',
19 | style: TextStyle(
20 | color: Color(0xFF3C763D),
21 | fontWeight: FontWeight.bold,
22 | fontSize: 16,
23 | ),
24 | ),
25 | ),
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/generator/experiences_pages.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ExperiencesPage extends StatefulWidget {
4 | const ExperiencesPage({super.key});
5 |
6 | @override
7 | State createState() => _ExperiencesPageState();
8 | }
9 |
10 | class _ExperiencesPageState extends State {
11 | TextEditingController txt = TextEditingController();
12 | TextEditingController txt2 = TextEditingController();
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return Scaffold(
17 | appBar: AppBar(
18 | backgroundColor: Colors.transparent,
19 | elevation: 0,
20 | ),
21 | body: SingleChildScrollView(
22 | child: Column(
23 | children: [
24 | TextFormField(
25 | controller: txt2,
26 | maxLines: 10,
27 | readOnly: true,
28 | ),
29 | TextFormField(
30 | controller: txt,
31 | maxLines: 10,
32 | ),
33 | ElevatedButton(
34 | onPressed: () {
35 | final companyRegex = RegExp(
36 | r'^(.+)( \W )(\d\d\/\d\d\d\d) [A-Za-zA-é]+ (\d\d\/\d\d\d\d)$',
37 | multiLine: true,
38 | );
39 | final roleRegex = RegExp(
40 | r'^(Cargo|Role): (.+)$',
41 | multiLine: true,
42 | );
43 | final descriptionRegex = RegExp(
44 | r'^• (.+)$',
45 | multiLine: true,
46 | );
47 | final companyMatch = companyRegex.allMatches(txt.text);
48 | final roleMatch = roleRegex.allMatches(txt.text);
49 | final descriptionMatch =
50 | descriptionRegex.allMatches(txt.text);
51 |
52 | final company = companyMatch.first.group(1);
53 | final start = companyMatch.first.group(3);
54 | final end = companyMatch.first.group(4);
55 | final role = roleMatch.first.group(2);
56 | final description =
57 | descriptionMatch.map((e) => '"${e.group(1)}"').toList();
58 |
59 | final json = '''{
60 | "company": "$company",
61 | "start": "$start",
62 | "end": "$end",
63 | "role": "$role",
64 | "description": [
65 | ${description.join(',')}
66 | ]
67 | }''';
68 |
69 | txt2.text = json;
70 | },
71 | child: Text('click')),
72 | ],
73 | ),
74 | ),
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/initial/initial_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 | import 'package:localization/localization.dart';
4 | import 'package:seo_renderer/seo_renderer.dart';
5 |
6 | import 'initial_page_controller.dart';
7 |
8 | class InitialPage extends StatefulWidget {
9 | final InitialPageController controller;
10 | const InitialPage({super.key, required this.controller});
11 |
12 | @override
13 | State createState() => _InitialPageState();
14 | }
15 |
16 | class _InitialPageState extends State {
17 | InitialPageController get controller => widget.controller;
18 |
19 | var selectedIndex = 0;
20 |
21 | static const double _breakpoint = 700.0;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 |
27 | final currentRoute = Modular.to.path;
28 | bool routeMatched = false;
29 | for (var page in PagesEnum.values) {
30 | if (currentRoute.startsWith(page.route)) {
31 | selectedIndex = page.pageIndex;
32 | routeMatched = true;
33 | break;
34 | }
35 | }
36 | if (!routeMatched) {
37 | selectedIndex = PagesEnum.about.pageIndex;
38 |
39 | Modular.to.pushReplacementNamed(PagesEnum.about.route);
40 | }
41 | }
42 |
43 | List _buildNavigationItems(BuildContext context, bool isDrawer) {
44 | return List.generate(PagesEnum.values.length, (index) {
45 | final page = PagesEnum.values[index];
46 | final isSelected = page.pageIndex == selectedIndex;
47 |
48 | if (isDrawer) {
49 | return ListTile(
50 | title: Text(
51 | page.description.i18n(),
52 | style: TextStyle(
53 | fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
54 | ),
55 | ),
56 | selected: isSelected,
57 | onTap: () {
58 | Modular.to.navigate(page.route);
59 | Navigator.pop(context);
60 | setState(() {
61 | selectedIndex = page.pageIndex;
62 | });
63 | },
64 | );
65 | } else {
66 | return Padding(
67 | padding: const EdgeInsets.symmetric(horizontal: 16.0),
68 | child: InkWell(
69 | onTap: () {
70 | Modular.to.navigate(page.route);
71 | setState(() {
72 | selectedIndex = page.pageIndex;
73 | });
74 | },
75 | child: Center(
76 | child: Text(
77 | page.description.i18n(),
78 | style: TextStyle(
79 | fontSize: 18,
80 | fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
81 | decoration: isSelected
82 | ? TextDecoration.underline
83 | : TextDecoration.none,
84 | decorationThickness: 2.0,
85 | ),
86 | ),
87 | ),
88 | ),
89 | );
90 | }
91 | });
92 | }
93 |
94 | Widget _buildLanguageMenu() {
95 | return PopupMenuButton(
96 | tooltip: "change_language".i18n(),
97 | onSelected: (Locale newLocale) {
98 | controller.appStore.locale = newLocale;
99 | setState(() {});
100 | },
101 | child: Row(
102 | children: [
103 | Text(
104 | controller.appStore.supportedLocales[controller.appStore.locale] ??
105 | '',
106 | ),
107 | SizedBox.square(
108 | dimension: 10,
109 | ),
110 | Icon(
111 | Icons.language,
112 | color: Theme.of(context).appBarTheme.actionsIconTheme?.color,
113 | ),
114 | ],
115 | ),
116 | itemBuilder: (BuildContext context) {
117 | return controller.appStore.supportedLocales.entries.map((entry) {
118 | final locale = entry.key;
119 | final name = entry.value;
120 |
121 | final bool isSelected = controller.appStore.locale == locale ||
122 | (controller.appStore.locale == null &&
123 | WidgetsBinding.instance.platformDispatcher.locale == locale);
124 |
125 | return PopupMenuItem(
126 | value: locale,
127 | child: Text(
128 | name,
129 | style: TextStyle(
130 | fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
131 | ),
132 | ),
133 | );
134 | }).toList();
135 | },
136 | );
137 | }
138 |
139 | @override
140 | Widget build(BuildContext context) {
141 | final screenWidth = MediaQuery.of(context).size.width;
142 | final bool isSmallScreen = screenWidth < _breakpoint;
143 |
144 | return Scaffold(
145 | drawer: isSmallScreen
146 | ? Drawer(
147 | child: ListView(
148 | padding: EdgeInsets.zero,
149 | children: [
150 | DrawerHeader(
151 | decoration: BoxDecoration(
152 | color: Theme.of(context).primaryColor,
153 | ),
154 | child: Row(
155 | children: [
156 | ImageRenderer(
157 | alt: 'Toshi Ossada Logo',
158 | child: Image.asset(
159 | 'assets/images/favicon.png',
160 | height: 40,
161 | ),
162 | ),
163 | const SizedBox(width: 15),
164 | const Text(
165 | 'Toshi Ossada',
166 | style: TextStyle(color: Colors.white, fontSize: 20),
167 | ),
168 | ],
169 | ),
170 | ),
171 | _buildLanguageMenu(),
172 | ..._buildNavigationItems(context, true),
173 | ],
174 | ),
175 | )
176 | : null,
177 | appBar: AppBar(
178 | title: GestureDetector(
179 | onTap: () {
180 | Modular.to.navigate(PagesEnum.about.route);
181 | setState(() {
182 | selectedIndex = PagesEnum.about.pageIndex;
183 | });
184 | },
185 | child: Row(
186 | mainAxisSize: MainAxisSize.min,
187 | children: [
188 | ImageRenderer(
189 | alt: 'Toshi Ossada Logo',
190 | child: Image.asset(
191 | 'assets/images/favicon.png',
192 | height: 40,
193 | ),
194 | ),
195 | const SizedBox(width: 15),
196 | const Text('Toshi Ossada'),
197 | ],
198 | ),
199 | ),
200 | actions: isSmallScreen
201 | ? null
202 | : [
203 | _buildLanguageMenu(),
204 | ..._buildNavigationItems(context, false),
205 | const SizedBox(width: 16),
206 | ],
207 | ),
208 | body: const RouterOutlet(),
209 | );
210 | }
211 | }
212 |
213 | enum PagesEnum {
214 | about(
215 | pageIndex: 0,
216 | route: '/about',
217 | description: 'about',
218 | ),
219 | carrer(
220 | pageIndex: 1,
221 | route: '/carrer',
222 | description: 'carrer',
223 | ),
224 | contact(
225 | pageIndex: 2,
226 | route: '/contact',
227 | description: 'contact',
228 | );
229 |
230 | const PagesEnum({
231 | required this.pageIndex,
232 | required this.route,
233 | required this.description,
234 | });
235 |
236 | final int pageIndex;
237 | final String route;
238 | final String description;
239 | }
240 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/initial/initial_page_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:homepage/app_store.dart';
2 |
3 | class InitialPageController {
4 | final AppStore appStore;
5 |
6 | InitialPageController({required this.appStore});
7 | }
8 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/widgets/contact_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
3 | import 'package:localization/localization.dart';
4 |
5 | import 'social_button_widget.dart';
6 |
7 | class ContactWidget extends StatelessWidget {
8 | final Function(String) onPressed;
9 | const ContactWidget({super.key, required this.onPressed});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Wrap(
14 | alignment: WrapAlignment.spaceEvenly,
15 | children: [
16 | SocialButtonWidget(
17 | text: 'Flutter Brasil Youtube Channel',
18 | icon: FontAwesomeIcons.youtube,
19 | url: 'https://youtube.flutterbrasil.com.br',
20 | color: Colors.red,
21 | tooltip: 'YouTube',
22 | onPressed: onPressed,
23 | ),
24 | SocialButtonWidget(
25 | text: 'Toshi Ossada Facebook',
26 | icon: FontAwesomeIcons.facebook,
27 | url: 'https://facebook.com/toshiossada',
28 | color: Colors.blue,
29 | tooltip: 'Facebook',
30 | onPressed: onPressed,
31 | ),
32 | SocialButtonWidget(
33 | text: 'Toshi Ossada GitHub',
34 | icon: FontAwesomeIcons.github,
35 | url: 'https://github.com/toshiossada',
36 | color: Colors.white,
37 | tooltip: 'GitHub',
38 | onPressed: onPressed,
39 | ),
40 | SocialButtonWidget(
41 | text: 'Toshi Ossada Linkedin',
42 | icon: FontAwesomeIcons.linkedin,
43 | url: 'https://linkedin.com/in/toshiossada',
44 | color: Colors.lightBlue.shade300,
45 | tooltip: 'LinkedIn',
46 | onPressed: onPressed,
47 | ),
48 | SocialButtonWidget(
49 | text: 'Toshi Ossada Instagram',
50 | icon: FontAwesomeIcons.instagram,
51 | url: 'https://instagram.com/toshiossada',
52 | color: Colors.pinkAccent,
53 | tooltip: 'Instagram',
54 | onPressed: onPressed,
55 | ),
56 | SocialButtonWidget(
57 | text: 'Toshi Ossada Medium Article',
58 | icon: FontAwesomeIcons.medium,
59 | url: 'https://toshiossada.medium.com/',
60 | color: Colors.white,
61 | tooltip: 'Medium',
62 | onPressed: onPressed,
63 | ),
64 | SocialButtonWidget(
65 | text: 'Toshi Ossada Contato Email',
66 | icon: FontAwesomeIcons.solidEnvelope,
67 | url: 'mailto:toshiossada@toshiossada.dev',
68 | color: Colors.grey[400]!,
69 | tooltip: 'send_email'.i18n(),
70 | onPressed: onPressed,
71 | ),
72 | ],
73 | );
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib/app/modules/home/pages/widgets/social_button_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
3 | import 'package:seo_renderer/renderers/link_renderer/link_renderer_web.dart';
4 |
5 | class SocialButtonWidget extends StatelessWidget {
6 | final IconData icon;
7 | final String url;
8 | final String text;
9 | final Color color;
10 | final String tooltip;
11 | final Function(String) onPressed;
12 |
13 | const SocialButtonWidget({
14 | super.key,
15 | required this.icon,
16 | required this.url,
17 | required this.text,
18 | required this.color,
19 | required this.tooltip,
20 | required this.onPressed,
21 | });
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | return LinkRenderer(
26 | text: 'Toshi Ossada Facebook',
27 | href: url,
28 | child: IconButton(
29 | icon: FaIcon(icon, color: color, size: 28.0),
30 | tooltip: tooltip,
31 | onPressed: () => onPressed(url),
32 | splashRadius: 25.0,
33 | constraints: const BoxConstraints(),
34 | padding: const EdgeInsets.all(10),
35 | ),
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/app_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_modular/flutter_modular.dart';
2 |
3 | import 'app/modules/home/home_module.dart';
4 | import 'app/modules/home/pages/dne/dne_module.dart';
5 | import 'core_module.dart';
6 |
7 | class AppModule extends Module {
8 | @override
9 | List get imports => [CoreModule()];
10 | @override
11 | void routes(RouteManager r) {
12 | r
13 | ..module('/', module: HomeModule())
14 | ..module('/dne', module: DNEModule());
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/app_store.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AppStore {
4 | final Map supportedLocales = {
5 | Locale('en', 'US'): 'English',
6 | Locale('pt', 'BR'): 'Português',
7 | };
8 |
9 | final ValueNotifier _locale = ValueNotifier(null);
10 |
11 | ValueNotifier get localeNotifier => _locale;
12 | Locale? get locale => _locale.value;
13 | set locale(Locale? newLocale) {
14 | if (_locale.value != newLocale) {
15 | _locale.value = newLocale;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/app_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_localizations/flutter_localizations.dart';
3 | import 'package:flutter_modular/flutter_modular.dart';
4 | import 'package:localization/localization.dart';
5 | import 'package:seo_renderer/seo_renderer.dart';
6 |
7 | import 'app_store.dart';
8 |
9 | class AppWidget extends StatefulWidget {
10 | const AppWidget({super.key});
11 |
12 | @override
13 | State createState() => _AppWidgetState();
14 | }
15 |
16 | class _AppWidgetState extends State {
17 | AppStore get controller => Modular.get();
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | Modular.setObservers([seoRouteObserver]);
22 | LocalJsonLocalization.delegate.directories = ['assets/lang'];
23 | return RobotDetector(
24 | child: ValueListenableBuilder(
25 | valueListenable: controller.localeNotifier,
26 | builder: (_, value, __) {
27 | return MaterialApp.router(
28 | title: 'Toshi Ossada',
29 | key: Key(value == null
30 | ? 'locale'
31 | : controller.supportedLocales[value]!.toString()),
32 | locale: value,
33 | localeResolutionCallback: (locale, supportedLocales) {
34 | Locale? finalLocale = Locale('en', 'US');
35 |
36 | if (supportedLocales.contains(locale)) {
37 | finalLocale = locale;
38 | }
39 |
40 | if (locale?.languageCode == 'pt') {
41 | finalLocale == Locale('pt', 'BR');
42 | }
43 |
44 | WidgetsBinding.instance.addPostFrameCallback((_) {
45 | if (mounted) {
46 | if (controller.locale != finalLocale) {
47 | controller.locale = finalLocale;
48 | }
49 | }
50 | });
51 |
52 | return finalLocale;
53 | },
54 | localizationsDelegates: [
55 | GlobalMaterialLocalizations.delegate,
56 | GlobalWidgetsLocalizations.delegate,
57 | GlobalCupertinoLocalizations.delegate,
58 | LocalJsonLocalization.delegate,
59 | ],
60 | supportedLocales: controller.supportedLocales.keys,
61 | routerConfig: Modular.routerConfig,
62 | theme: ThemeData(
63 | colorScheme: const ColorScheme.dark(),
64 | ),
65 | );
66 | }),
67 | );
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/core_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_modular/flutter_modular.dart';
2 | import 'package:homepage/app_store.dart';
3 |
4 | class CoreModule extends Module {
5 | @override
6 | void exportedBinds(Injector i) {
7 | i.addSingleton(AppStore.new);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 |
4 | import 'app_module.dart';
5 | import 'app_widget.dart';
6 |
7 | void main() {
8 | runApp(ModularApp(module: AppModule(), child: AppWidget()));
9 | }
10 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
9 | url: "https://pub.dev"
10 | source: hosted
11 | version: "2.12.0"
12 | auto_injector:
13 | dependency: transitive
14 | description:
15 | name: auto_injector
16 | sha256: ad7a95d7c381363d48b54e00cb680f024fd97009067244454e9b4850337608e8
17 | url: "https://pub.dev"
18 | source: hosted
19 | version: "2.1.0"
20 | boolean_selector:
21 | dependency: transitive
22 | description:
23 | name: boolean_selector
24 | sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
25 | url: "https://pub.dev"
26 | source: hosted
27 | version: "2.1.2"
28 | characters:
29 | dependency: transitive
30 | description:
31 | name: characters
32 | sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
33 | url: "https://pub.dev"
34 | source: hosted
35 | version: "1.4.0"
36 | clock:
37 | dependency: transitive
38 | description:
39 | name: clock
40 | sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
41 | url: "https://pub.dev"
42 | source: hosted
43 | version: "1.1.2"
44 | collection:
45 | dependency: transitive
46 | description:
47 | name: collection
48 | sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
49 | url: "https://pub.dev"
50 | source: hosted
51 | version: "1.19.1"
52 | crypto:
53 | dependency: transitive
54 | description:
55 | name: crypto
56 | sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
57 | url: "https://pub.dev"
58 | source: hosted
59 | version: "3.0.6"
60 | cupertino_icons:
61 | dependency: "direct main"
62 | description:
63 | name: cupertino_icons
64 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
65 | url: "https://pub.dev"
66 | source: hosted
67 | version: "1.0.8"
68 | dio:
69 | dependency: "direct main"
70 | description:
71 | name: dio
72 | sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
73 | url: "https://pub.dev"
74 | source: hosted
75 | version: "5.8.0+1"
76 | dio_web_adapter:
77 | dependency: transitive
78 | description:
79 | name: dio_web_adapter
80 | sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
81 | url: "https://pub.dev"
82 | source: hosted
83 | version: "2.1.1"
84 | fake_async:
85 | dependency: transitive
86 | description:
87 | name: fake_async
88 | sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
89 | url: "https://pub.dev"
90 | source: hosted
91 | version: "1.3.2"
92 | fixnum:
93 | dependency: transitive
94 | description:
95 | name: fixnum
96 | sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
97 | url: "https://pub.dev"
98 | source: hosted
99 | version: "1.1.1"
100 | flutter:
101 | dependency: "direct main"
102 | description: flutter
103 | source: sdk
104 | version: "0.0.0"
105 | flutter_lints:
106 | dependency: "direct dev"
107 | description:
108 | name: flutter_lints
109 | sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
110 | url: "https://pub.dev"
111 | source: hosted
112 | version: "5.0.0"
113 | flutter_localizations:
114 | dependency: "direct main"
115 | description: flutter
116 | source: sdk
117 | version: "0.0.0"
118 | flutter_modular:
119 | dependency: "direct main"
120 | description:
121 | name: flutter_modular
122 | sha256: bc17a1eb1da676b9111e59d27834fb6673bdea01aead12f0803a0847ff9d451c
123 | url: "https://pub.dev"
124 | source: hosted
125 | version: "6.3.4"
126 | flutter_test:
127 | dependency: "direct dev"
128 | description: flutter
129 | source: sdk
130 | version: "0.0.0"
131 | flutter_web_plugins:
132 | dependency: "direct main"
133 | description: flutter
134 | source: sdk
135 | version: "0.0.0"
136 | font_awesome_flutter:
137 | dependency: "direct main"
138 | description:
139 | name: font_awesome_flutter
140 | sha256: d3a89184101baec7f4600d58840a764d2ef760fe1c5a20ef9e6b0e9b24a07a3a
141 | url: "https://pub.dev"
142 | source: hosted
143 | version: "10.8.0"
144 | http_parser:
145 | dependency: transitive
146 | description:
147 | name: http_parser
148 | sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
149 | url: "https://pub.dev"
150 | source: hosted
151 | version: "4.1.2"
152 | intl:
153 | dependency: "direct main"
154 | description:
155 | name: intl
156 | sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
157 | url: "https://pub.dev"
158 | source: hosted
159 | version: "0.19.0"
160 | leak_tracker:
161 | dependency: transitive
162 | description:
163 | name: leak_tracker
164 | sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
165 | url: "https://pub.dev"
166 | source: hosted
167 | version: "10.0.8"
168 | leak_tracker_flutter_testing:
169 | dependency: transitive
170 | description:
171 | name: leak_tracker_flutter_testing
172 | sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
173 | url: "https://pub.dev"
174 | source: hosted
175 | version: "3.0.9"
176 | leak_tracker_testing:
177 | dependency: transitive
178 | description:
179 | name: leak_tracker_testing
180 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
181 | url: "https://pub.dev"
182 | source: hosted
183 | version: "3.0.1"
184 | lints:
185 | dependency: transitive
186 | description:
187 | name: lints
188 | sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
189 | url: "https://pub.dev"
190 | source: hosted
191 | version: "5.1.1"
192 | localization:
193 | dependency: "direct main"
194 | description:
195 | name: localization
196 | sha256: "9fa21644b75ca3fe844f8f115d03cd6fdc675054dd9aab6c5de5861145ea57b5"
197 | url: "https://pub.dev"
198 | source: hosted
199 | version: "2.1.1"
200 | mailto:
201 | dependency: "direct main"
202 | description:
203 | name: mailto
204 | sha256: f8c5ce39e0eaa94a856795b2855af7f66aac37f7c3b70ac5c26ab00b94685445
205 | url: "https://pub.dev"
206 | source: hosted
207 | version: "2.0.0"
208 | matcher:
209 | dependency: transitive
210 | description:
211 | name: matcher
212 | sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
213 | url: "https://pub.dev"
214 | source: hosted
215 | version: "0.12.17"
216 | material_color_utilities:
217 | dependency: transitive
218 | description:
219 | name: material_color_utilities
220 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
221 | url: "https://pub.dev"
222 | source: hosted
223 | version: "0.11.1"
224 | meta:
225 | dependency: transitive
226 | description:
227 | name: meta
228 | sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
229 | url: "https://pub.dev"
230 | source: hosted
231 | version: "1.16.0"
232 | modular_core:
233 | dependency: transitive
234 | description:
235 | name: modular_core
236 | sha256: bd60317c81cff3a510aca19d6ddd661c7c79e3cba97b9f39e9ad199156ff255d
237 | url: "https://pub.dev"
238 | source: hosted
239 | version: "3.3.3"
240 | path:
241 | dependency: transitive
242 | description:
243 | name: path
244 | sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
245 | url: "https://pub.dev"
246 | source: hosted
247 | version: "1.9.1"
248 | plugin_platform_interface:
249 | dependency: transitive
250 | description:
251 | name: plugin_platform_interface
252 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
253 | url: "https://pub.dev"
254 | source: hosted
255 | version: "2.1.8"
256 | result_dart:
257 | dependency: transitive
258 | description:
259 | name: result_dart
260 | sha256: "3c69c864a08df0f413a86be211d07405e9a53cc1ac111e3cc8365845a0fb5288"
261 | url: "https://pub.dev"
262 | source: hosted
263 | version: "1.1.1"
264 | seo_renderer:
265 | dependency: "direct main"
266 | description:
267 | name: seo_renderer
268 | sha256: "2f687b566467387625404963ed0a58060d6d06639ff100611df3668dab14d3dc"
269 | url: "https://pub.dev"
270 | source: hosted
271 | version: "0.6.0"
272 | sky_engine:
273 | dependency: transitive
274 | description: flutter
275 | source: sdk
276 | version: "0.0.0"
277 | source_span:
278 | dependency: transitive
279 | description:
280 | name: source_span
281 | sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
282 | url: "https://pub.dev"
283 | source: hosted
284 | version: "1.10.1"
285 | sprintf:
286 | dependency: transitive
287 | description:
288 | name: sprintf
289 | sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
290 | url: "https://pub.dev"
291 | source: hosted
292 | version: "7.0.0"
293 | stack_trace:
294 | dependency: transitive
295 | description:
296 | name: stack_trace
297 | sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
298 | url: "https://pub.dev"
299 | source: hosted
300 | version: "1.12.1"
301 | stream_channel:
302 | dependency: transitive
303 | description:
304 | name: stream_channel
305 | sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
306 | url: "https://pub.dev"
307 | source: hosted
308 | version: "2.1.4"
309 | string_scanner:
310 | dependency: transitive
311 | description:
312 | name: string_scanner
313 | sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
314 | url: "https://pub.dev"
315 | source: hosted
316 | version: "1.4.1"
317 | term_glyph:
318 | dependency: transitive
319 | description:
320 | name: term_glyph
321 | sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
322 | url: "https://pub.dev"
323 | source: hosted
324 | version: "1.2.2"
325 | test_api:
326 | dependency: transitive
327 | description:
328 | name: test_api
329 | sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
330 | url: "https://pub.dev"
331 | source: hosted
332 | version: "0.7.4"
333 | timeline_tile:
334 | dependency: "direct main"
335 | description:
336 | name: timeline_tile
337 | sha256: "85ec2023c67137397c2812e3e848b2fb20b410b67cd9aff304bb5480c376fc0c"
338 | url: "https://pub.dev"
339 | source: hosted
340 | version: "2.0.0"
341 | typed_data:
342 | dependency: transitive
343 | description:
344 | name: typed_data
345 | sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
346 | url: "https://pub.dev"
347 | source: hosted
348 | version: "1.4.0"
349 | url_launcher:
350 | dependency: "direct main"
351 | description:
352 | name: url_launcher
353 | sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
354 | url: "https://pub.dev"
355 | source: hosted
356 | version: "6.3.1"
357 | url_launcher_android:
358 | dependency: transitive
359 | description:
360 | name: url_launcher_android
361 | sha256: "1d0eae19bd7606ef60fe69ef3b312a437a16549476c42321d5dc1506c9ca3bf4"
362 | url: "https://pub.dev"
363 | source: hosted
364 | version: "6.3.15"
365 | url_launcher_ios:
366 | dependency: transitive
367 | description:
368 | name: url_launcher_ios
369 | sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
370 | url: "https://pub.dev"
371 | source: hosted
372 | version: "6.3.3"
373 | url_launcher_linux:
374 | dependency: transitive
375 | description:
376 | name: url_launcher_linux
377 | sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
378 | url: "https://pub.dev"
379 | source: hosted
380 | version: "3.2.1"
381 | url_launcher_macos:
382 | dependency: transitive
383 | description:
384 | name: url_launcher_macos
385 | sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
386 | url: "https://pub.dev"
387 | source: hosted
388 | version: "3.2.2"
389 | url_launcher_platform_interface:
390 | dependency: transitive
391 | description:
392 | name: url_launcher_platform_interface
393 | sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
394 | url: "https://pub.dev"
395 | source: hosted
396 | version: "2.3.2"
397 | url_launcher_web:
398 | dependency: transitive
399 | description:
400 | name: url_launcher_web
401 | sha256: "3ba963161bd0fe395917ba881d320b9c4f6dd3c4a233da62ab18a5025c85f1e9"
402 | url: "https://pub.dev"
403 | source: hosted
404 | version: "2.4.0"
405 | url_launcher_windows:
406 | dependency: transitive
407 | description:
408 | name: url_launcher_windows
409 | sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
410 | url: "https://pub.dev"
411 | source: hosted
412 | version: "3.1.4"
413 | uuid:
414 | dependency: transitive
415 | description:
416 | name: uuid
417 | sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
418 | url: "https://pub.dev"
419 | source: hosted
420 | version: "4.5.1"
421 | vector_math:
422 | dependency: transitive
423 | description:
424 | name: vector_math
425 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
426 | url: "https://pub.dev"
427 | source: hosted
428 | version: "2.1.4"
429 | vm_service:
430 | dependency: transitive
431 | description:
432 | name: vm_service
433 | sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
434 | url: "https://pub.dev"
435 | source: hosted
436 | version: "14.3.1"
437 | web:
438 | dependency: transitive
439 | description:
440 | name: web
441 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
442 | url: "https://pub.dev"
443 | source: hosted
444 | version: "1.1.1"
445 | sdks:
446 | dart: ">=3.7.0-0 <4.0.0"
447 | flutter: ">=3.27.0"
448 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: homepage
2 | description: A new Flutter project.
3 |
4 | publish_to: 'none'
5 |
6 | version: 1.0.0+1
7 |
8 | environment:
9 | sdk: '>=3.6.1 <4.0.0'
10 |
11 | dependencies:
12 | flutter:
13 | sdk: flutter
14 | flutter_web_plugins:
15 | sdk: flutter
16 | flutter_localizations:
17 | sdk: flutter
18 |
19 | cupertino_icons: ^1.0.2
20 | font_awesome_flutter: ^10.8.0
21 | url_launcher: ^6.0.12
22 | mailto: ^2.0.0
23 | seo_renderer: ^0.6.0
24 | flutter_modular: ^6.3.4
25 | intl: ^0.19.0
26 | timeline_tile: ^2.0.0
27 | localization: ^2.1.1
28 | dio: ^5.8.0+1
29 |
30 | dev_dependencies:
31 | flutter_test:
32 | sdk: flutter
33 |
34 | flutter_lints: ^5.0.0
35 |
36 | flutter:
37 | uses-material-design: true
38 | assets:
39 | - assets/images/
40 | - assets/images/awards/
41 | - assets/images/flutterbrasil/
42 | - assets/experiences.json
43 | - assets/experiences_enUs.json
44 | - assets/lang/
45 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:homepage/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/favicon.ico
--------------------------------------------------------------------------------
/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/favicon.png
--------------------------------------------------------------------------------
/web/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/web/icons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/web/icons/android-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-144x144.png
--------------------------------------------------------------------------------
/web/icons/android-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-192x192.png
--------------------------------------------------------------------------------
/web/icons/android-icon-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-36x36.png
--------------------------------------------------------------------------------
/web/icons/android-icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-48x48.png
--------------------------------------------------------------------------------
/web/icons/android-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-72x72.png
--------------------------------------------------------------------------------
/web/icons/android-icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/android-icon-96x96.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-114x114.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-120x120.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-144x144.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-152x152.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-180x180.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-57x57.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-60x60.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-72x72.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-76x76.png
--------------------------------------------------------------------------------
/web/icons/apple-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon-precomposed.png
--------------------------------------------------------------------------------
/web/icons/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-icon.png
--------------------------------------------------------------------------------
/web/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/web/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
--------------------------------------------------------------------------------
/web/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/web/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/web/icons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/favicon-96x96.png
--------------------------------------------------------------------------------
/web/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/favicon.ico
--------------------------------------------------------------------------------
/web/icons/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "App",
3 | "icons": [
4 | {
5 | "src": "\/android-icon-36x36.png",
6 | "sizes": "36x36",
7 | "type": "image\/png",
8 | "density": "0.75"
9 | },
10 | {
11 | "src": "\/android-icon-48x48.png",
12 | "sizes": "48x48",
13 | "type": "image\/png",
14 | "density": "1.0"
15 | },
16 | {
17 | "src": "\/android-icon-72x72.png",
18 | "sizes": "72x72",
19 | "type": "image\/png",
20 | "density": "1.5"
21 | },
22 | {
23 | "src": "\/android-icon-96x96.png",
24 | "sizes": "96x96",
25 | "type": "image\/png",
26 | "density": "2.0"
27 | },
28 | {
29 | "src": "\/android-icon-144x144.png",
30 | "sizes": "144x144",
31 | "type": "image\/png",
32 | "density": "3.0"
33 | },
34 | {
35 | "src": "\/android-icon-192x192.png",
36 | "sizes": "192x192",
37 | "type": "image\/png",
38 | "density": "4.0"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/web/icons/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/ms-icon-144x144.png
--------------------------------------------------------------------------------
/web/icons/ms-icon-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/ms-icon-150x150.png
--------------------------------------------------------------------------------
/web/icons/ms-icon-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/ms-icon-310x310.png
--------------------------------------------------------------------------------
/web/icons/ms-icon-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/icons/ms-icon-70x70.png
--------------------------------------------------------------------------------
/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Toshi Ossada
6 |
10 |
14 |
18 |
19 |
20 |
21 |
22 |
27 |
32 |
37 |
42 |
47 |
52 |
57 |
62 |
67 |
73 |
79 |
85 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
107 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/web/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/web/logo.png
--------------------------------------------------------------------------------
/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "homepage",
3 | "short_name": "homepage",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "A new Flutter project.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/android-chrome-192x192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/android-chrome-512x512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/android-chrome-512x512.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/android-chrome-512x512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
--------------------------------------------------------------------------------
/web/style.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Roboto);
2 |
3 | @import url(/packages/font_awesome/css/all.css); /* font_awesome css file is imported here */
4 |
5 | html, body {
6 | width: 100%;
7 | height: 100%;
8 | margin: 0;
9 | padding: 0;
10 | font-family: 'Roboto', sans-serif;
11 | }
12 |
13 | #output {
14 | padding: 20px;
15 | text-align: center;
16 | }
--------------------------------------------------------------------------------
/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/windows/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(homepage LANGUAGES CXX)
3 |
4 | set(BINARY_NAME "homepage")
5 |
6 | cmake_policy(SET CMP0063 NEW)
7 |
8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
9 |
10 | # Configure build options.
11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
12 | if(IS_MULTICONFIG)
13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
14 | CACHE STRING "" FORCE)
15 | else()
16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
17 | set(CMAKE_BUILD_TYPE "Debug" CACHE
18 | STRING "Flutter build mode" FORCE)
19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
20 | "Debug" "Profile" "Release")
21 | endif()
22 | endif()
23 |
24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
28 |
29 | # Use Unicode for all projects.
30 | add_definitions(-DUNICODE -D_UNICODE)
31 |
32 | # Compilation settings that should be applied to most targets.
33 | function(APPLY_STANDARD_SETTINGS TARGET)
34 | target_compile_features(${TARGET} PUBLIC cxx_std_17)
35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
36 | target_compile_options(${TARGET} PRIVATE /EHsc)
37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>")
39 | endfunction()
40 |
41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
42 |
43 | # Flutter library and tool build rules.
44 | add_subdirectory(${FLUTTER_MANAGED_DIR})
45 |
46 | # Application build
47 | add_subdirectory("runner")
48 |
49 | # Generated plugin build rules, which manage building the plugins and adding
50 | # them to the application.
51 | include(flutter/generated_plugins.cmake)
52 |
53 |
54 | # === Installation ===
55 | # Support files are copied into place next to the executable, so that it can
56 | # run in place. This is done instead of making a separate bundle (as on Linux)
57 | # so that building and running from within Visual Studio will work.
58 | set(BUILD_BUNDLE_DIR "$")
59 | # Make the "install" step default, as it's required to run.
60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
63 | endif()
64 |
65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
67 |
68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
69 | COMPONENT Runtime)
70 |
71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
72 | COMPONENT Runtime)
73 |
74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
75 | COMPONENT Runtime)
76 |
77 | if(PLUGIN_BUNDLED_LIBRARIES)
78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
80 | COMPONENT Runtime)
81 | endif()
82 |
83 | # Fully re-copy the assets directory on each build to avoid having stale files
84 | # from a previous install.
85 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
86 | install(CODE "
87 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
88 | " COMPONENT Runtime)
89 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
90 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
91 |
92 | # Install the AOT library on non-Debug builds only.
93 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
94 | CONFIGURATIONS Profile;Release
95 | COMPONENT Runtime)
96 |
--------------------------------------------------------------------------------
/windows/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 |
3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
4 |
5 | # Configuration provided via flutter tool.
6 | include(${EPHEMERAL_DIR}/generated_config.cmake)
7 |
8 | # TODO: Move the rest of this into files in ephemeral. See
9 | # https://github.com/flutter/flutter/issues/57146.
10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
11 |
12 | # Set fallback configurations for older versions of the flutter tool.
13 | if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
14 | set(FLUTTER_TARGET_PLATFORM "windows-x64")
15 | endif()
16 |
17 | # === Flutter Library ===
18 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
19 |
20 | # Published to parent scope for install step.
21 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
22 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
23 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
24 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
25 |
26 | list(APPEND FLUTTER_LIBRARY_HEADERS
27 | "flutter_export.h"
28 | "flutter_windows.h"
29 | "flutter_messenger.h"
30 | "flutter_plugin_registrar.h"
31 | "flutter_texture_registrar.h"
32 | )
33 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
34 | add_library(flutter INTERFACE)
35 | target_include_directories(flutter INTERFACE
36 | "${EPHEMERAL_DIR}"
37 | )
38 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
39 | add_dependencies(flutter flutter_assemble)
40 |
41 | # === Wrapper ===
42 | list(APPEND CPP_WRAPPER_SOURCES_CORE
43 | "core_implementations.cc"
44 | "standard_codec.cc"
45 | )
46 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
47 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
48 | "plugin_registrar.cc"
49 | )
50 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
51 | list(APPEND CPP_WRAPPER_SOURCES_APP
52 | "flutter_engine.cc"
53 | "flutter_view_controller.cc"
54 | )
55 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
56 |
57 | # Wrapper sources needed for a plugin.
58 | add_library(flutter_wrapper_plugin STATIC
59 | ${CPP_WRAPPER_SOURCES_CORE}
60 | ${CPP_WRAPPER_SOURCES_PLUGIN}
61 | )
62 | apply_standard_settings(flutter_wrapper_plugin)
63 | set_target_properties(flutter_wrapper_plugin PROPERTIES
64 | POSITION_INDEPENDENT_CODE ON)
65 | set_target_properties(flutter_wrapper_plugin PROPERTIES
66 | CXX_VISIBILITY_PRESET hidden)
67 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
68 | target_include_directories(flutter_wrapper_plugin PUBLIC
69 | "${WRAPPER_ROOT}/include"
70 | )
71 | add_dependencies(flutter_wrapper_plugin flutter_assemble)
72 |
73 | # Wrapper sources needed for the runner.
74 | add_library(flutter_wrapper_app STATIC
75 | ${CPP_WRAPPER_SOURCES_CORE}
76 | ${CPP_WRAPPER_SOURCES_APP}
77 | )
78 | apply_standard_settings(flutter_wrapper_app)
79 | target_link_libraries(flutter_wrapper_app PUBLIC flutter)
80 | target_include_directories(flutter_wrapper_app PUBLIC
81 | "${WRAPPER_ROOT}/include"
82 | )
83 | add_dependencies(flutter_wrapper_app flutter_assemble)
84 |
85 | # === Flutter tool backend ===
86 | # _phony_ is a non-existent file to force this command to run every time,
87 | # since currently there's no way to get a full input/output list from the
88 | # flutter tool.
89 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
90 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
91 | add_custom_command(
92 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
93 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
94 | ${CPP_WRAPPER_SOURCES_APP}
95 | ${PHONY_OUTPUT}
96 | COMMAND ${CMAKE_COMMAND} -E env
97 | ${FLUTTER_TOOL_ENVIRONMENT}
98 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
99 | ${FLUTTER_TARGET_PLATFORM} $
100 | VERBATIM
101 | )
102 | add_custom_target(flutter_assemble DEPENDS
103 | "${FLUTTER_LIBRARY}"
104 | ${FLUTTER_LIBRARY_HEADERS}
105 | ${CPP_WRAPPER_SOURCES_CORE}
106 | ${CPP_WRAPPER_SOURCES_PLUGIN}
107 | ${CPP_WRAPPER_SOURCES_APP}
108 | )
109 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 | #include
10 |
11 | void RegisterPlugins(flutter::PluginRegistry* registry) {
12 | UrlLauncherWindowsRegisterWithRegistrar(
13 | registry->GetRegistrarForPlugin("UrlLauncherWindows"));
14 | }
15 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void RegisterPlugins(flutter::PluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | url_launcher_windows
7 | )
8 |
9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
10 | )
11 |
12 | set(PLUGIN_BUNDLED_LIBRARIES)
13 |
14 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
19 | endforeach(plugin)
20 |
21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
24 | endforeach(ffi_plugin)
25 |
--------------------------------------------------------------------------------
/windows/runner/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 | project(runner LANGUAGES CXX)
3 |
4 | add_executable(${BINARY_NAME} WIN32
5 | "flutter_window.cpp"
6 | "main.cpp"
7 | "utils.cpp"
8 | "win32_window.cpp"
9 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
10 | "Runner.rc"
11 | "runner.exe.manifest"
12 | )
13 | apply_standard_settings(${BINARY_NAME})
14 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
15 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
16 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
17 | add_dependencies(${BINARY_NAME} flutter_assemble)
18 |
--------------------------------------------------------------------------------
/windows/runner/Runner.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #pragma code_page(65001)
4 | #include "resource.h"
5 |
6 | #define APSTUDIO_READONLY_SYMBOLS
7 | /////////////////////////////////////////////////////////////////////////////
8 | //
9 | // Generated from the TEXTINCLUDE 2 resource.
10 | //
11 | #include "winres.h"
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 | #undef APSTUDIO_READONLY_SYMBOLS
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // English (United States) resources
18 |
19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""winres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "\r\n"
42 | "\0"
43 | END
44 |
45 | #endif // APSTUDIO_INVOKED
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | //
50 | // Icon
51 | //
52 |
53 | // Icon with lowest ID value placed first to ensure application icon
54 | // remains consistent on all systems.
55 | IDI_APP_ICON ICON "resources\\app_icon.ico"
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Version
61 | //
62 |
63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
65 | #else
66 | #define VERSION_AS_NUMBER 1,0,0,0
67 | #endif
68 |
69 | #if defined(FLUTTER_VERSION)
70 | #define VERSION_AS_STRING FLUTTER_VERSION
71 | #else
72 | #define VERSION_AS_STRING "1.0.0"
73 | #endif
74 |
75 | VS_VERSION_INFO VERSIONINFO
76 | FILEVERSION VERSION_AS_NUMBER
77 | PRODUCTVERSION VERSION_AS_NUMBER
78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79 | #ifdef _DEBUG
80 | FILEFLAGS VS_FF_DEBUG
81 | #else
82 | FILEFLAGS 0x0L
83 | #endif
84 | FILEOS VOS__WINDOWS32
85 | FILETYPE VFT_APP
86 | FILESUBTYPE 0x0L
87 | BEGIN
88 | BLOCK "StringFileInfo"
89 | BEGIN
90 | BLOCK "040904e4"
91 | BEGIN
92 | VALUE "CompanyName", "br.com.toshiossada" "\0"
93 | VALUE "FileDescription", "A new Flutter project." "\0"
94 | VALUE "FileVersion", VERSION_AS_STRING "\0"
95 | VALUE "InternalName", "homepage" "\0"
96 | VALUE "LegalCopyright", "Copyright (C) 2021 br.com.toshiossada. All rights reserved." "\0"
97 | VALUE "OriginalFilename", "homepage.exe" "\0"
98 | VALUE "ProductName", "homepage" "\0"
99 | VALUE "ProductVersion", VERSION_AS_STRING "\0"
100 | END
101 | END
102 | BLOCK "VarFileInfo"
103 | BEGIN
104 | VALUE "Translation", 0x409, 1252
105 | END
106 | END
107 |
108 | #endif // English (United States) resources
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 |
112 |
113 | #ifndef APSTUDIO_INVOKED
114 | /////////////////////////////////////////////////////////////////////////////
115 | //
116 | // Generated from the TEXTINCLUDE 3 resource.
117 | //
118 |
119 |
120 | /////////////////////////////////////////////////////////////////////////////
121 | #endif // not APSTUDIO_INVOKED
122 |
--------------------------------------------------------------------------------
/windows/runner/flutter_window.cpp:
--------------------------------------------------------------------------------
1 | #include "flutter_window.h"
2 |
3 | #include
4 |
5 | #include "flutter/generated_plugin_registrant.h"
6 |
7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project)
8 | : project_(project) {}
9 |
10 | FlutterWindow::~FlutterWindow() {}
11 |
12 | bool FlutterWindow::OnCreate() {
13 | if (!Win32Window::OnCreate()) {
14 | return false;
15 | }
16 |
17 | RECT frame = GetClientArea();
18 |
19 | // The size here must match the window dimensions to avoid unnecessary surface
20 | // creation / destruction in the startup path.
21 | flutter_controller_ = std::make_unique(
22 | frame.right - frame.left, frame.bottom - frame.top, project_);
23 | // Ensure that basic setup of the controller was successful.
24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) {
25 | return false;
26 | }
27 | RegisterPlugins(flutter_controller_->engine());
28 | SetChildContent(flutter_controller_->view()->GetNativeWindow());
29 | return true;
30 | }
31 |
32 | void FlutterWindow::OnDestroy() {
33 | if (flutter_controller_) {
34 | flutter_controller_ = nullptr;
35 | }
36 |
37 | Win32Window::OnDestroy();
38 | }
39 |
40 | LRESULT
41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
42 | WPARAM const wparam,
43 | LPARAM const lparam) noexcept {
44 | // Give Flutter, including plugins, an opportunity to handle window messages.
45 | if (flutter_controller_) {
46 | std::optional result =
47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
48 | lparam);
49 | if (result) {
50 | return *result;
51 | }
52 | }
53 |
54 | switch (message) {
55 | case WM_FONTCHANGE:
56 | flutter_controller_->engine()->ReloadSystemFonts();
57 | break;
58 | }
59 |
60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
61 | }
62 |
--------------------------------------------------------------------------------
/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "win32_window.h"
10 |
11 | // A window that does nothing but host a Flutter view.
12 | class FlutterWindow : public Win32Window {
13 | public:
14 | // Creates a new FlutterWindow hosting a Flutter view running |project|.
15 | explicit FlutterWindow(const flutter::DartProject& project);
16 | virtual ~FlutterWindow();
17 |
18 | protected:
19 | // Win32Window:
20 | bool OnCreate() override;
21 | void OnDestroy() override;
22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
23 | LPARAM const lparam) noexcept override;
24 |
25 | private:
26 | // The project to run.
27 | flutter::DartProject project_;
28 |
29 | // The Flutter instance hosted by this window.
30 | std::unique_ptr flutter_controller_;
31 | };
32 |
33 | #endif // RUNNER_FLUTTER_WINDOW_H_
34 |
--------------------------------------------------------------------------------
/windows/runner/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "flutter_window.h"
6 | #include "utils.h"
7 |
8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
9 | _In_ wchar_t *command_line, _In_ int show_command) {
10 | // Attach to console when present (e.g., 'flutter run') or create a
11 | // new console when running with a debugger.
12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
13 | CreateAndAttachConsole();
14 | }
15 |
16 | // Initialize COM, so that it is available for use in the library and/or
17 | // plugins.
18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
19 |
20 | flutter::DartProject project(L"data");
21 |
22 | std::vector command_line_arguments =
23 | GetCommandLineArguments();
24 |
25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
26 |
27 | FlutterWindow window(project);
28 | Win32Window::Point origin(10, 10);
29 | Win32Window::Size size(1280, 720);
30 | if (!window.CreateAndShow(L"homepage", origin, size)) {
31 | return EXIT_FAILURE;
32 | }
33 | window.SetQuitOnClose(true);
34 |
35 | ::MSG msg;
36 | while (::GetMessage(&msg, nullptr, 0, 0)) {
37 | ::TranslateMessage(&msg);
38 | ::DispatchMessage(&msg);
39 | }
40 |
41 | ::CoUninitialize();
42 | return EXIT_SUCCESS;
43 | }
44 |
--------------------------------------------------------------------------------
/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/toshiossada/flutter_web_site/f8199459b83efa10d698d08633217ada9aaa86c2/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/windows/runner/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void CreateAndAttachConsole() {
11 | if (::AllocConsole()) {
12 | FILE *unused;
13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14 | _dup2(_fileno(stdout), 1);
15 | }
16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17 | _dup2(_fileno(stdout), 2);
18 | }
19 | std::ios::sync_with_stdio();
20 | FlutterDesktopResyncOutputStreams();
21 | }
22 | }
23 |
24 | std::vector GetCommandLineArguments() {
25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26 | int argc;
27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28 | if (argv == nullptr) {
29 | return std::vector();
30 | }
31 |
32 | std::vector command_line_arguments;
33 |
34 | // Skip the first argument as it's the binary name.
35 | for (int i = 1; i < argc; i++) {
36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37 | }
38 |
39 | ::LocalFree(argv);
40 |
41 | return command_line_arguments;
42 | }
43 |
44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45 | if (utf16_string == nullptr) {
46 | return std::string();
47 | }
48 | int target_length = ::WideCharToMultiByte(
49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50 | -1, nullptr, 0, nullptr, nullptr);
51 | if (target_length == 0) {
52 | return std::string();
53 | }
54 | std::string utf8_string;
55 | utf8_string.resize(target_length);
56 | int converted_length = ::WideCharToMultiByte(
57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
58 | -1, utf8_string.data(),
59 | target_length, nullptr, nullptr);
60 | if (converted_length == 0) {
61 | return std::string();
62 | }
63 | return utf8_string;
64 | }
65 |
--------------------------------------------------------------------------------
/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/windows/runner/win32_window.cpp:
--------------------------------------------------------------------------------
1 | #include "win32_window.h"
2 |
3 | #include
4 |
5 | #include "resource.h"
6 |
7 | namespace {
8 |
9 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
10 |
11 | // The number of Win32Window objects that currently exist.
12 | static int g_active_window_count = 0;
13 |
14 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
15 |
16 | // Scale helper to convert logical scaler values to physical using passed in
17 | // scale factor
18 | int Scale(int source, double scale_factor) {
19 | return static_cast(source * scale_factor);
20 | }
21 |
22 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
23 | // This API is only needed for PerMonitor V1 awareness mode.
24 | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
25 | HMODULE user32_module = LoadLibraryA("User32.dll");
26 | if (!user32_module) {
27 | return;
28 | }
29 | auto enable_non_client_dpi_scaling =
30 | reinterpret_cast(
31 | GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
32 | if (enable_non_client_dpi_scaling != nullptr) {
33 | enable_non_client_dpi_scaling(hwnd);
34 | FreeLibrary(user32_module);
35 | }
36 | }
37 |
38 | } // namespace
39 |
40 | // Manages the Win32Window's window class registration.
41 | class WindowClassRegistrar {
42 | public:
43 | ~WindowClassRegistrar() = default;
44 |
45 | // Returns the singleton registar instance.
46 | static WindowClassRegistrar* GetInstance() {
47 | if (!instance_) {
48 | instance_ = new WindowClassRegistrar();
49 | }
50 | return instance_;
51 | }
52 |
53 | // Returns the name of the window class, registering the class if it hasn't
54 | // previously been registered.
55 | const wchar_t* GetWindowClass();
56 |
57 | // Unregisters the window class. Should only be called if there are no
58 | // instances of the window.
59 | void UnregisterWindowClass();
60 |
61 | private:
62 | WindowClassRegistrar() = default;
63 |
64 | static WindowClassRegistrar* instance_;
65 |
66 | bool class_registered_ = false;
67 | };
68 |
69 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
70 |
71 | const wchar_t* WindowClassRegistrar::GetWindowClass() {
72 | if (!class_registered_) {
73 | WNDCLASS window_class{};
74 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
75 | window_class.lpszClassName = kWindowClassName;
76 | window_class.style = CS_HREDRAW | CS_VREDRAW;
77 | window_class.cbClsExtra = 0;
78 | window_class.cbWndExtra = 0;
79 | window_class.hInstance = GetModuleHandle(nullptr);
80 | window_class.hIcon =
81 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
82 | window_class.hbrBackground = 0;
83 | window_class.lpszMenuName = nullptr;
84 | window_class.lpfnWndProc = Win32Window::WndProc;
85 | RegisterClass(&window_class);
86 | class_registered_ = true;
87 | }
88 | return kWindowClassName;
89 | }
90 |
91 | void WindowClassRegistrar::UnregisterWindowClass() {
92 | UnregisterClass(kWindowClassName, nullptr);
93 | class_registered_ = false;
94 | }
95 |
96 | Win32Window::Win32Window() {
97 | ++g_active_window_count;
98 | }
99 |
100 | Win32Window::~Win32Window() {
101 | --g_active_window_count;
102 | Destroy();
103 | }
104 |
105 | bool Win32Window::CreateAndShow(const std::wstring& title,
106 | const Point& origin,
107 | const Size& size) {
108 | Destroy();
109 |
110 | const wchar_t* window_class =
111 | WindowClassRegistrar::GetInstance()->GetWindowClass();
112 |
113 | const POINT target_point = {static_cast(origin.x),
114 | static_cast(origin.y)};
115 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
116 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
117 | double scale_factor = dpi / 96.0;
118 |
119 | HWND window = CreateWindow(
120 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
121 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
122 | Scale(size.width, scale_factor), Scale(size.height, scale_factor),
123 | nullptr, nullptr, GetModuleHandle(nullptr), this);
124 |
125 | if (!window) {
126 | return false;
127 | }
128 |
129 | return OnCreate();
130 | }
131 |
132 | // static
133 | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
134 | UINT const message,
135 | WPARAM const wparam,
136 | LPARAM const lparam) noexcept {
137 | if (message == WM_NCCREATE) {
138 | auto window_struct = reinterpret_cast(lparam);
139 | SetWindowLongPtr(window, GWLP_USERDATA,
140 | reinterpret_cast(window_struct->lpCreateParams));
141 |
142 | auto that = static_cast(window_struct->lpCreateParams);
143 | EnableFullDpiSupportIfAvailable(window);
144 | that->window_handle_ = window;
145 | } else if (Win32Window* that = GetThisFromHandle(window)) {
146 | return that->MessageHandler(window, message, wparam, lparam);
147 | }
148 |
149 | return DefWindowProc(window, message, wparam, lparam);
150 | }
151 |
152 | LRESULT
153 | Win32Window::MessageHandler(HWND hwnd,
154 | UINT const message,
155 | WPARAM const wparam,
156 | LPARAM const lparam) noexcept {
157 | switch (message) {
158 | case WM_DESTROY:
159 | window_handle_ = nullptr;
160 | Destroy();
161 | if (quit_on_close_) {
162 | PostQuitMessage(0);
163 | }
164 | return 0;
165 |
166 | case WM_DPICHANGED: {
167 | auto newRectSize = reinterpret_cast(lparam);
168 | LONG newWidth = newRectSize->right - newRectSize->left;
169 | LONG newHeight = newRectSize->bottom - newRectSize->top;
170 |
171 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
172 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
173 |
174 | return 0;
175 | }
176 | case WM_SIZE: {
177 | RECT rect = GetClientArea();
178 | if (child_content_ != nullptr) {
179 | // Size and position the child window.
180 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
181 | rect.bottom - rect.top, TRUE);
182 | }
183 | return 0;
184 | }
185 |
186 | case WM_ACTIVATE:
187 | if (child_content_ != nullptr) {
188 | SetFocus(child_content_);
189 | }
190 | return 0;
191 | }
192 |
193 | return DefWindowProc(window_handle_, message, wparam, lparam);
194 | }
195 |
196 | void Win32Window::Destroy() {
197 | OnDestroy();
198 |
199 | if (window_handle_) {
200 | DestroyWindow(window_handle_);
201 | window_handle_ = nullptr;
202 | }
203 | if (g_active_window_count == 0) {
204 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
205 | }
206 | }
207 |
208 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
209 | return reinterpret_cast(
210 | GetWindowLongPtr(window, GWLP_USERDATA));
211 | }
212 |
213 | void Win32Window::SetChildContent(HWND content) {
214 | child_content_ = content;
215 | SetParent(content, window_handle_);
216 | RECT frame = GetClientArea();
217 |
218 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
219 | frame.bottom - frame.top, true);
220 |
221 | SetFocus(child_content_);
222 | }
223 |
224 | RECT Win32Window::GetClientArea() {
225 | RECT frame;
226 | GetClientRect(window_handle_, &frame);
227 | return frame;
228 | }
229 |
230 | HWND Win32Window::GetHandle() {
231 | return window_handle_;
232 | }
233 |
234 | void Win32Window::SetQuitOnClose(bool quit_on_close) {
235 | quit_on_close_ = quit_on_close;
236 | }
237 |
238 | bool Win32Window::OnCreate() {
239 | // No-op; provided for subclasses.
240 | return true;
241 | }
242 |
243 | void Win32Window::OnDestroy() {
244 | // No-op; provided for subclasses.
245 | }
246 |
--------------------------------------------------------------------------------
/windows/runner/win32_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_WIN32_WINDOW_H_
2 | #define RUNNER_WIN32_WINDOW_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
11 | // inherited from by classes that wish to specialize with custom
12 | // rendering and input handling
13 | class Win32Window {
14 | public:
15 | struct Point {
16 | unsigned int x;
17 | unsigned int y;
18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19 | };
20 |
21 | struct Size {
22 | unsigned int width;
23 | unsigned int height;
24 | Size(unsigned int width, unsigned int height)
25 | : width(width), height(height) {}
26 | };
27 |
28 | Win32Window();
29 | virtual ~Win32Window();
30 |
31 | // Creates and shows a win32 window with |title| and position and size using
32 | // |origin| and |size|. New windows are created on the default monitor. Window
33 | // sizes are specified to the OS in physical pixels, hence to ensure a
34 | // consistent size to will treat the width height passed in to this function
35 | // as logical pixels and scale to appropriate for the default monitor. Returns
36 | // true if the window was created successfully.
37 | bool CreateAndShow(const std::wstring& title,
38 | const Point& origin,
39 | const Size& size);
40 |
41 | // Release OS resources associated with window.
42 | void Destroy();
43 |
44 | // Inserts |content| into the window tree.
45 | void SetChildContent(HWND content);
46 |
47 | // Returns the backing Window handle to enable clients to set icon and other
48 | // window properties. Returns nullptr if the window has been destroyed.
49 | HWND GetHandle();
50 |
51 | // If true, closing this window will quit the application.
52 | void SetQuitOnClose(bool quit_on_close);
53 |
54 | // Return a RECT representing the bounds of the current client area.
55 | RECT GetClientArea();
56 |
57 | protected:
58 | // Processes and route salient window messages for mouse handling,
59 | // size change and DPI. Delegates handling of these to member overloads that
60 | // inheriting classes can handle.
61 | virtual LRESULT MessageHandler(HWND window,
62 | UINT const message,
63 | WPARAM const wparam,
64 | LPARAM const lparam) noexcept;
65 |
66 | // Called when CreateAndShow is called, allowing subclass window-related
67 | // setup. Subclasses should return false if setup fails.
68 | virtual bool OnCreate();
69 |
70 | // Called when Destroy is called.
71 | virtual void OnDestroy();
72 |
73 | private:
74 | friend class WindowClassRegistrar;
75 |
76 | // OS callback called by message pump. Handles the WM_NCCREATE message which
77 | // is passed when the non-client area is being created and enables automatic
78 | // non-client DPI scaling so that the non-client area automatically
79 | // responsponds to changes in DPI. All other messages are handled by
80 | // MessageHandler.
81 | static LRESULT CALLBACK WndProc(HWND const window,
82 | UINT const message,
83 | WPARAM const wparam,
84 | LPARAM const lparam) noexcept;
85 |
86 | // Retrieves a class instance pointer for |window|
87 | static Win32Window* GetThisFromHandle(HWND const window) noexcept;
88 |
89 | bool quit_on_close_ = false;
90 |
91 | // window handle for top level window.
92 | HWND window_handle_ = nullptr;
93 |
94 | // window handle for hosted content.
95 | HWND child_content_ = nullptr;
96 | };
97 |
98 | #endif // RUNNER_WIN32_WINDOW_H_
99 |
--------------------------------------------------------------------------------