├── linux ├── .gitignore ├── main.cc ├── flutter │ ├── generated_plugin_registrant.h │ ├── generated_plugin_registrant.cc │ ├── generated_plugins.cmake │ └── CMakeLists.txt ├── my_application.h ├── my_application.cc └── CMakeLists.txt ├── .env ├── ios ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── WorkspaceSettings.xcsettings │ │ └── IDEWorkspaceChecks.plist ├── .gitignore ├── Podfile.lock └── Podfile ├── macos ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ ├── ephemeral │ │ ├── Flutter-Generated.xcconfig │ │ └── flutter_export_environment.sh │ └── GeneratedPluginRegistrant.swift ├── .gitignore ├── Runner │ ├── Configs │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ ├── Warnings.xcconfig │ │ └── AppInfo.xcconfig │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ ├── app_icon_64.png │ │ │ ├── app_icon_1024.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Release.entitlements │ ├── DebugProfile.entitlements │ ├── MainFlutterWindow.swift │ └── Info.plist ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner.xcodeproj │ ├── project.xcworkspace │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ └── xcschemes │ └── Runner.xcscheme ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── manifest.json └── index.html ├── lib ├── constants │ ├── secrets.sample.dart │ └── app_constants.dart ├── widgets │ ├── user_widgets │ │ ├── robots │ │ │ ├── secrets.dart │ │ │ ├── monster_controller.dart │ │ │ ├── robots_models.dart │ │ │ └── bloc │ │ │ │ └── robots_state.dart │ │ ├── widget_info.dart │ │ ├── goober0329 │ │ │ ├── qr_game_of_life │ │ │ │ ├── game_of_life_controller.dart │ │ │ │ ├── gol_display.dart │ │ │ │ ├── game_of_life_widget.dart │ │ │ │ └── gol_glider.dart │ │ │ └── goober_widget.dart │ │ ├── example │ │ │ └── example.dart │ │ ├── daseed │ │ │ ├── widgets │ │ │ │ ├── decoration_painter.dart │ │ │ │ └── my_profile.dart │ │ │ └── pierre-emmanuel_legrain.dart │ │ ├── thgehr │ │ │ └── thomasgehrmann.dart │ │ ├── user_widgets.dart │ │ ├── hsinats │ │ │ └── hsinats_widget.dart │ │ └── slovnicki │ │ │ └── slovnicki_widget.dart │ ├── app_bar_icon.dart │ ├── section_header.dart │ ├── event_card.dart │ └── project_card.dart ├── data │ ├── models │ │ ├── event.dart │ │ └── project.dart │ └── repositories │ │ ├── project_repository.dart │ │ └── event_repository.dart ├── main.dart └── modules │ └── screens │ ├── about_screen.dart │ ├── schedule_screen.dart │ ├── user_widgets_screen.dart │ └── projects_screen.dart ├── assets ├── global_images │ ├── Event_Image.png │ ├── flutter-logo.png │ ├── flutterbuddies.png │ ├── quantum_dots.jpg │ ├── Discord-Logo-Shadowed.png │ ├── GitHub-Logo-Shadowed.png │ ├── Twitter-Logo-Shadowed.png │ ├── Website-Logo-Shadowed.png │ └── YouTube-Logo-Shadowed.png ├── profile_images │ ├── jason_profile.jpg │ ├── daseed_profile.jpg │ ├── hsinats_profile.jpg │ ├── Zambrella_profile.jpg │ ├── harrington_profile.jpg │ ├── robots_avatar_min.png │ ├── slovnicki_profile.jpeg │ ├── yazeedalkhalaf_profile.jpg │ └── sleepingisimportant_profile.jpg └── profile_logos │ └── flutter_buddy.png ├── windows ├── runner │ ├── resources │ │ └── app_icon.ico │ ├── resource.h │ ├── CMakeLists.txt │ ├── utils.h │ ├── runner.exe.manifest │ ├── run_loop.h │ ├── flutter_window.h │ ├── main.cpp │ ├── utils.cpp │ ├── flutter_window.cpp │ ├── run_loop.cpp │ ├── Runner.rc │ └── win32_window.h ├── flutter │ ├── generated_plugin_registrant.h │ ├── generated_plugin_registrant.cc │ ├── generated_plugins.cmake │ └── CMakeLists.txt ├── .gitignore └── CMakeLists.txt ├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── 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 │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── flutter_buddies │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ ├── gen │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── flutter_buddies │ │ │ │ │ ├── R.java │ │ │ │ │ └── Manifest.java │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle └── build.gradle ├── .metadata ├── .github └── workflows │ ├── test.yml │ └── build.yml ├── .vscode └── launch.json ├── test └── widget_test.dart ├── .gitignore ├── analysis_options.yaml ├── pubspec.yaml └── README.md /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | CALENDAR_KEY=AIzaSyCsE2qQTfNBpyT9JRfZYuTZKRNROvqQH_c -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/web/favicon.png -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/web/icons/Icon-512.png -------------------------------------------------------------------------------- /lib/constants/secrets.sample.dart: -------------------------------------------------------------------------------- 1 | class Secrets { 2 | static const String calendar_key = 'YOUR_API_KEY'; 3 | } 4 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /assets/global_images/Event_Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/Event_Image.png -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /assets/global_images/flutter-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/flutter-logo.png -------------------------------------------------------------------------------- /assets/global_images/flutterbuddies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/flutterbuddies.png -------------------------------------------------------------------------------- /assets/global_images/quantum_dots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/quantum_dots.jpg -------------------------------------------------------------------------------- /assets/profile_images/jason_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/jason_profile.jpg -------------------------------------------------------------------------------- /assets/profile_logos/flutter_buddy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_logos/flutter_buddy.png -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /assets/profile_images/daseed_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/daseed_profile.jpg -------------------------------------------------------------------------------- /assets/profile_images/hsinats_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/hsinats_profile.jpg -------------------------------------------------------------------------------- /assets/profile_images/Zambrella_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/Zambrella_profile.jpg -------------------------------------------------------------------------------- /assets/profile_images/harrington_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/harrington_profile.jpg -------------------------------------------------------------------------------- /assets/profile_images/robots_avatar_min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/robots_avatar_min.png -------------------------------------------------------------------------------- /assets/profile_images/slovnicki_profile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/slovnicki_profile.jpeg -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | android.enableR8=true 5 | -------------------------------------------------------------------------------- /assets/global_images/Discord-Logo-Shadowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/Discord-Logo-Shadowed.png -------------------------------------------------------------------------------- /assets/global_images/GitHub-Logo-Shadowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/GitHub-Logo-Shadowed.png -------------------------------------------------------------------------------- /assets/global_images/Twitter-Logo-Shadowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/Twitter-Logo-Shadowed.png -------------------------------------------------------------------------------- /assets/global_images/Website-Logo-Shadowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/Website-Logo-Shadowed.png -------------------------------------------------------------------------------- /assets/global_images/YouTube-Logo-Shadowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/global_images/YouTube-Logo-Shadowed.png -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /assets/profile_images/yazeedalkhalaf_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/yazeedalkhalaf_profile.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /assets/profile_images/sleepingisimportant_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/assets/profile_images/sleepingisimportant_profile.jpg -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/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/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Flutter-Buddies/App/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_buddies/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_buddies 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/debug/gen/com/example/flutter_buddies/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.example.flutter_buddies; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /android/app/src/debug/gen/com/example/flutter_buddies/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.example.flutter_buddies; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /lib/constants/app_constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | //* colors 4 | const Color kLightBlue = Color(0xffF5FCFE); 5 | const Color kBlue = Color(0xff7ED3F9); 6 | const Color kDarkBlue = Color(0xff065A9D); 7 | const Color kVeryDarkBlue = Color(0xff1C2834); 8 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /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-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.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: d408d302e22179d598f467e11da5dd968dbdc9ec 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void fl_register_plugins(FlPluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void RegisterPlugins(flutter::PluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | #include 8 | 9 | void RegisterPlugins(flutter::PluginRegistry* registry) { 10 | UrlLauncherPluginRegisterWithRegistrar( 11 | registry->GetRegistrarForPlugin("UrlLauncherPlugin")); 12 | } 13 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: tests 2 | on: 3 | push: 4 | branches: [main] 5 | workflow_dispatch: 6 | jobs: 7 | test: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: subosito/flutter-action@v1 12 | with: 13 | channel: stable 14 | - run: cp .env-example .env 15 | - run: flutter pub get 16 | - run: flutter test 17 | -------------------------------------------------------------------------------- /.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 | "name": "App", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/Flutter-Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=Y:\extra\flutter 3 | FLUTTER_APPLICATION_PATH=Y:\code\my_projects\flutter_projects\flutter_buddies 4 | FLUTTER_BUILD_DIR=build 5 | FLUTTER_BUILD_NAME=1.0.0 6 | FLUTTER_BUILD_NUMBER=1 7 | EXCLUDED_ARCHS=arm64 8 | DART_OBFUSCATION=false 9 | TRACK_WIDGET_CREATION=false 10 | TREE_SHAKE_ICONS=false 11 | PACKAGE_CONFIG=.packages 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | #include 8 | 9 | void fl_register_plugins(FlPluginRegistry* registry) { 10 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = 11 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); 12 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); 13 | } 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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_test/flutter_test.dart'; 9 | 10 | void main() { 11 | test('pass', () => expect(true, true)); 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/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=Y:\extra\flutter" 4 | export "FLUTTER_APPLICATION_PATH=Y:\code\my_projects\flutter_projects\flutter_buddies" 5 | export "FLUTTER_BUILD_DIR=build" 6 | export "FLUTTER_BUILD_NAME=1.0.0" 7 | export "FLUTTER_BUILD_NUMBER=1" 8 | export "EXCLUDED_ARCHS=arm64" 9 | export "DART_OBFUSCATION=false" 10 | export "TRACK_WIDGET_CREATION=false" 11 | export "TREE_SHAKE_ICONS=false" 12 | export "PACKAGE_CONFIG=.packages" 13 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/robots/secrets.dart: -------------------------------------------------------------------------------- 1 | class RobotsSecrets { 2 | static const List SECRETS = [ 3 | 'Hello! My name is Kris :)', 4 | 'This is not a drill!', 5 | 'Treats and Good Times, is that too much to ask?', 6 | 'When I grow up I want to be an astronaut', 7 | 'Sometimes I wonder what is the difference between a tool and a device?', 8 | 'Are all tools also devices? Are all devices also tools?', 9 | 'Does the difference lie in the thing itself or in how it is used?', 10 | 'Some questions may never be answered', 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_linux 7 | ) 8 | 9 | set(PLUGIN_BUNDLED_LIBRARIES) 10 | 11 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 16 | endforeach(plugin) 17 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import path_provider_macos 9 | import sqflite 10 | import url_launcher_macos 11 | 12 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 13 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 14 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 15 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 16 | } 17 | -------------------------------------------------------------------------------- /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 | set(PLUGIN_BUNDLED_LIBRARIES) 10 | 11 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 12 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 13 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 15 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 16 | endforeach(plugin) 17 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/widget_info.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | abstract class WidgetInfo { 4 | final String _name = 'Blank'; 5 | final String _description = 'Blank'; 6 | final String _developer = 'Blank'; 7 | final String _logoPath = 'path/to/blank.png'; 8 | 9 | Widget _widget; 10 | 11 | String get name => _name; 12 | String get description => _description; 13 | String get developer => _developer; 14 | String get logoPath => _logoPath; 15 | Widget get widget => _widget; 16 | int get projectsCount => 1; 17 | 18 | // can something like this work to add to the list dynamically? 19 | //void addToList() => widgetInfoList.add(this); 20 | } 21 | -------------------------------------------------------------------------------- /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 | "run_loop.cpp" 8 | "utils.cpp" 9 | "win32_window.cpp" 10 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 11 | "Runner.rc" 12 | "runner.exe.manifest" 13 | ) 14 | apply_standard_settings(${BINARY_NAME}) 15 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 16 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 17 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 18 | add_dependencies(${BINARY_NAME} flutter_assemble) 19 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_buddies 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBuddies 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_buddies", 3 | "short_name": "flutter_buddies", 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/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: [release] 5 | workflow_dispatch: 6 | jobs: 7 | build-apk-ios: 8 | runs-on: macos-latest 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-java@v1 12 | with: 13 | java-version: "12.x" 14 | - uses: subosito/flutter-action@v1 15 | with: 16 | channel: stable 17 | - run: cp .env-example .env 18 | - run: flutter pub get 19 | - run: flutter build apk 20 | - uses: actions/upload-artifact@v2 21 | with: 22 | name: builds 23 | path: build/app/outputs/apk/release/app-release.apk 24 | - run: flutter build ios --release --no-codesign 25 | -------------------------------------------------------------------------------- /lib/widgets/app_bar_icon.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AppBarIcon extends StatelessWidget { 4 | final String iconText; 5 | final Function iconFunction; 6 | final Color iconColor; 7 | final ImageProvider iconImage; 8 | AppBarIcon( 9 | {this.iconText, this.iconFunction, this.iconColor, this.iconImage}); 10 | @override 11 | Widget build(BuildContext context) { 12 | return InkWell( 13 | onTap: iconFunction, 14 | child: Column( 15 | crossAxisAlignment: CrossAxisAlignment.center, 16 | children: [ 17 | Image( 18 | image: iconImage, 19 | height: 42, 20 | ), 21 | Text(iconText), 22 | ], 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | # secrets 44 | lib/constants/secrets.dart -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/data/models/event.dart: -------------------------------------------------------------------------------- 1 | import 'package:faker/faker.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class Event { 5 | final String name; 6 | final ImageProvider image; 7 | final DateTime dateTime; 8 | 9 | Event.fromJson(Map json) 10 | : name = json['summary'], 11 | image = NetworkImage( 12 | 'https://picsum.photos/seed/' + faker.lorem.word() + '/600'), 13 | dateTime = DateTime.parse(json['start']['dateTime']); 14 | 15 | static Event get fake { 16 | final Faker faker = Faker(); 17 | return Event.fromJson({ 18 | 'summary': faker.lorem 19 | .words( 20 | faker.randomGenerator.integer(6, min: 1), 21 | ) 22 | .join(' '), 23 | 'imageUrl': 'https://picsum.photos/seed/' + faker.lorem.word() + '/600', 24 | 'start': { 25 | 'dateTime': 26 | faker.date.dateTime(minYear: 2020, maxYear: 2022).toString(), 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_controller.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:async'; 3 | 4 | import 'package:flutter_buddies/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_model.dart'; 5 | 6 | class GoLController extends ChangeNotifier { 7 | Duration timeStep; 8 | Timer _timer; 9 | bool _active = false; 10 | 11 | GoLController({@required this.timeStep}); 12 | 13 | bool get isActive => _active; 14 | 15 | void start(GameOfLife gol, Function callBack) { 16 | _timer = Timer.periodic(timeStep, (timer) => _nextStep(gol, callBack)); 17 | _active = true; 18 | } 19 | 20 | void stop() { 21 | if (_timer != null) { 22 | _timer.cancel(); 23 | } 24 | _active = false; 25 | } 26 | 27 | void _nextStep(GameOfLife gol, Function callBack) { 28 | gol.step(); 29 | callBack(); 30 | } 31 | 32 | void setSpeed(Duration newTimeStep) { 33 | timeStep = newTimeStep; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_buddies/modules/screens/about_screen.dart'; 3 | import 'modules/screens/user_widgets_screen.dart'; 4 | import 'modules/screens/home_screen.dart'; 5 | import 'modules/screens/projects_screen.dart'; 6 | import 'modules/screens/schedule_screen.dart'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | debugShowCheckedModeBanner: false, 17 | title: 'Flutter Buddies', 18 | theme: ThemeData( 19 | primarySwatch: Colors.blue, 20 | visualDensity: VisualDensity.adaptivePlatformDensity, 21 | ), 22 | initialRoute: 'home', 23 | routes: { 24 | 'home': (context) => HomeScreen(), 25 | 'user_widgets_screen': (context) => UserWidgetsScreen(), 26 | 'schedule': (context) => ScheduleScreen(), 27 | 'projects': (context) => ProjectsScreen(), 28 | 'about': (context) => AboutScreen(), 29 | }); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/example/example.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | //user defines from abstract class needed information 4 | class ExampleInfo extends WidgetInfo { 5 | @override 6 | String get name => 7 | 'My Widget'; //name your widget, not used in design currently 8 | 9 | @override 10 | String get description => 'This is an example of a basic widget'; 11 | 12 | @override 13 | String get developer => 'Joey Marino'; //use any name for yourself 14 | 15 | @override 16 | String get logoPath => 'assets/profile_logos/flutter_buddy.png'; 17 | 18 | @override 19 | Widget get widget => ExampleWidget(); 20 | } 21 | 22 | ExampleInfo exampleInfo = ExampleInfo(); 23 | 24 | // User's widget lives here 25 | class ExampleWidget extends StatelessWidget { 26 | @override 27 | Widget build(BuildContext context) { 28 | return SafeArea( 29 | child: Scaffold( 30 | appBar: AppBar(), 31 | body: Column( 32 | children: [ 33 | Center( 34 | child: Text('Example Widget'), 35 | ), 36 | ], 37 | ), 38 | ), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/daseed/widgets/decoration_painter.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DecorationPainter extends CustomPainter { 4 | final double height; 5 | final double width; 6 | final Color color; 7 | 8 | DecorationPainter(this.height, this.width, this.color); 9 | 10 | @override 11 | void paint(Canvas canvas, Size size) { 12 | final Paint paint = Paint() 13 | ..color = color 14 | ..style = PaintingStyle.fill; 15 | final Path path = Path()..moveTo(0, 0); 16 | path.quadraticBezierTo(0, 30, width * 0.35, 17); 17 | path.quadraticBezierTo(width * 0.4, 15, width * 0.4, 30); 18 | path.arcToPoint(Offset(width * 0.6, 30), 19 | radius: const Radius.circular(5.0), clockwise: false); 20 | path.quadraticBezierTo(width * 0.6, 15, width * 0.65, 20); 21 | path.quadraticBezierTo(width, 30, width, 0); 22 | path.lineTo(width, height); 23 | path.lineTo(0, height); 24 | path.close(); 25 | canvas.drawShadow(path, Colors.black, 5, true); 26 | canvas.drawPath(path, paint); 27 | } 28 | 29 | @override 30 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /windows/runner/run_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_RUN_LOOP_H_ 2 | #define RUNNER_RUN_LOOP_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | // A runloop that will service events for Flutter instances as well 10 | // as native messages. 11 | class RunLoop { 12 | public: 13 | RunLoop(); 14 | ~RunLoop(); 15 | 16 | // Prevent copying 17 | RunLoop(RunLoop const&) = delete; 18 | RunLoop& operator=(RunLoop const&) = delete; 19 | 20 | // Runs the run loop until the application quits. 21 | void Run(); 22 | 23 | // Registers the given Flutter instance for event servicing. 24 | void RegisterFlutterInstance( 25 | flutter::FlutterEngine* flutter_instance); 26 | 27 | // Unregisters the given Flutter instance from event servicing. 28 | void UnregisterFlutterInstance( 29 | flutter::FlutterEngine* flutter_instance); 30 | 31 | private: 32 | using TimePoint = std::chrono::steady_clock::time_point; 33 | 34 | // Processes all currently pending messages for registered Flutter instances. 35 | TimePoint ProcessFlutterMessages(); 36 | 37 | std::set flutter_instances_; 38 | }; 39 | 40 | #endif // RUNNER_RUN_LOOP_H_ 41 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/robots/monster_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter_buddies/widgets/user_widgets/robots/bloc/robots_bloc.dart'; 4 | 5 | class MonsterController { 6 | int minMonsterSpawnTime = 8000; 7 | int minMonsterFireTime = 1000; 8 | double monsterSpawnChance = .05; 9 | double monsterFireChance = .2; 10 | 11 | int lastMonsterSpawnTime = 0; 12 | int lastMonsterFireTime = 0; 13 | 14 | final RobotsBloc bloc; 15 | final Random random = Random(); 16 | 17 | MonsterController(this.bloc); 18 | 19 | void tick() { 20 | int now = DateTime.now().millisecondsSinceEpoch; 21 | double rand1 = random.nextDouble(); 22 | double rand2 = random.nextDouble(); 23 | 24 | if (rand1 < monsterSpawnChance + (bloc.state.level * .01) && 25 | now - lastMonsterSpawnTime > minMonsterSpawnTime - (500 * bloc.state.level)) { 26 | bloc.testMonster(); 27 | lastMonsterSpawnTime = now; 28 | } 29 | if (rand2 < monsterFireChance + (bloc.state.level * .04) && 30 | now - lastMonsterFireTime > minMonsterFireTime - (100 * bloc.state.level)) { 31 | lastMonsterFireTime = now; 32 | bloc.fireMonsterMissile(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - path_provider (0.0.1): 7 | - Flutter 8 | - sqflite (0.0.2): 9 | - Flutter 10 | - FMDB (>= 2.7.5) 11 | - url_launcher (0.0.1): 12 | - Flutter 13 | 14 | DEPENDENCIES: 15 | - Flutter (from `Flutter`) 16 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 17 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 18 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 19 | 20 | SPEC REPOS: 21 | trunk: 22 | - FMDB 23 | 24 | EXTERNAL SOURCES: 25 | Flutter: 26 | :path: Flutter 27 | path_provider: 28 | :path: ".symlinks/plugins/path_provider/ios" 29 | sqflite: 30 | :path: ".symlinks/plugins/sqflite/ios" 31 | url_launcher: 32 | :path: ".symlinks/plugins/url_launcher/ios" 33 | 34 | SPEC CHECKSUMS: 35 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c 36 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 37 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 38 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 39 | url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef 40 | 41 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 42 | 43 | COCOAPODS: 1.10.0 44 | -------------------------------------------------------------------------------- /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 "run_loop.h" 10 | #include "win32_window.h" 11 | 12 | // A window that does nothing but host a Flutter view. 13 | class FlutterWindow : public Win32Window { 14 | public: 15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a 16 | // Flutter view running |project|. 17 | explicit FlutterWindow(RunLoop* run_loop, 18 | const flutter::DartProject& project); 19 | virtual ~FlutterWindow(); 20 | 21 | protected: 22 | // Win32Window: 23 | bool OnCreate() override; 24 | void OnDestroy() override; 25 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 26 | LPARAM const lparam) noexcept override; 27 | 28 | private: 29 | // The run loop driving events for this window. 30 | RunLoop* run_loop_; 31 | 32 | // The project to run. 33 | flutter::DartProject project_; 34 | 35 | // The Flutter instance hosted by this window. 36 | std::unique_ptr flutter_controller_; 37 | }; 38 | 39 | #endif // RUNNER_FLUTTER_WINDOW_H_ 40 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/robots/robots_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Missile { 4 | final double x; 5 | final double y; 6 | 7 | static const List MISSILE_COLORS = [ 8 | Colors.orange, 9 | Colors.yellow, 10 | Colors.red, 11 | Colors.yellowAccent, 12 | Colors.pink, 13 | Colors.redAccent 14 | ]; 15 | 16 | Missile( 17 | this.x, { 18 | this.y = 20, 19 | }); 20 | } 21 | 22 | class Monster { 23 | final double x; 24 | final double y; 25 | final double size; 26 | final double maxHealth; 27 | double health; 28 | 29 | Monster( 30 | this.x, 31 | this.y, { 32 | this.size = 20, 33 | this.maxHealth = 3, 34 | this.health = 3, 35 | }); 36 | } 37 | 38 | class Laser { 39 | static const LASER_DURATION = 2000; 40 | 41 | final int timeFired; 42 | final double xPos; 43 | final bool active; 44 | 45 | const Laser({ 46 | this.timeFired = 0, 47 | this.xPos, 48 | this.active = false, 49 | }); 50 | 51 | Laser copyWith({ 52 | int timeFired, 53 | double xPos, 54 | bool active, 55 | }) => 56 | Laser( 57 | active: active ?? this.active, 58 | xPos: xPos ?? this.xPos, 59 | timeFired: timeFired ?? this.timeFired, 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /lib/widgets/section_header.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SectionHeader extends StatelessWidget { 4 | final IconData leadingIcon; 5 | final String headerText; 6 | final Widget trailingWidget; 7 | final Function headerFunction; 8 | SectionHeader( 9 | {this.leadingIcon, 10 | this.headerText, 11 | this.trailingWidget, 12 | this.headerFunction}); 13 | @override 14 | Widget build(BuildContext context) { 15 | return Padding( 16 | padding: const EdgeInsets.all(16.0), 17 | child: GestureDetector( 18 | onTap: headerFunction, 19 | child: Row( 20 | crossAxisAlignment: CrossAxisAlignment.center, 21 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 22 | children: [ 23 | Container( 24 | child: Row( 25 | children: [ 26 | Icon(leadingIcon), 27 | SizedBox( 28 | width: 4, 29 | ), 30 | Text( 31 | headerText + ' >', 32 | style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18), 33 | ), 34 | ], 35 | ), 36 | ), 37 | trailingWidget, 38 | ], 39 | ), 40 | ), 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "run_loop.h" 7 | #include "utils.h" 8 | 9 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 10 | _In_ wchar_t *command_line, _In_ int show_command) { 11 | // Attach to console when present (e.g., 'flutter run') or create a 12 | // new console when running with a debugger. 13 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 14 | CreateAndAttachConsole(); 15 | } 16 | 17 | // Initialize COM, so that it is available for use in the library and/or 18 | // plugins. 19 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 20 | 21 | RunLoop run_loop; 22 | 23 | flutter::DartProject project(L"data"); 24 | 25 | std::vector command_line_arguments = 26 | GetCommandLineArguments(); 27 | 28 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 29 | 30 | FlutterWindow window(&run_loop, project); 31 | Win32Window::Point origin(10, 10); 32 | Win32Window::Size size(1280, 720); 33 | if (!window.CreateAndShow(L"flutter_buddies", origin, size)) { 34 | return EXIT_FAILURE; 35 | } 36 | window.SetQuitOnClose(true); 37 | 38 | run_loop.Run(); 39 | 40 | ::CoUninitialize(); 41 | return EXIT_SUCCESS; 42 | } 43 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | flutter_buddies 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /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 | flutter_buddies 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file 2 | # for details. All rights reserved. Use of this source code is governed by a 3 | # BSD-style license that can be found in the LICENSE file. 4 | # 5 | # Google internally enforced rules. See README.md for more information, 6 | # including a list of lints that are intentionally _not_ enforced. 7 | # 8 | # https://github.com/google/pedantic 9 | 10 | linter: 11 | rules: 12 | - always_declare_return_types 13 | - always_require_non_null_named_parameters 14 | - annotate_overrides 15 | - avoid_empty_else 16 | - avoid_init_to_null 17 | - avoid_null_checks_in_equality_operators 18 | - avoid_relative_lib_imports 19 | - avoid_return_types_on_setters 20 | - avoid_shadowing_type_parameters 21 | - avoid_types_as_parameter_names 22 | - camel_case_extensions 23 | - curly_braces_in_flow_control_structures 24 | - empty_catches 25 | - empty_constructor_bodies 26 | - library_names 27 | - library_prefixes 28 | - no_duplicate_case_values 29 | - null_closures 30 | - prefer_adjacent_string_concatenation 31 | - prefer_collection_literals 32 | - prefer_conditional_assignment 33 | - prefer_contains 34 | - prefer_equal_for_default_values 35 | - prefer_final_fields 36 | - prefer_for_elements_to_map_fromIterable 37 | - prefer_generic_function_type_aliases 38 | - prefer_if_null_operators 39 | - prefer_is_empty 40 | - prefer_is_not_empty 41 | - prefer_iterable_whereType 42 | - prefer_single_quotes 43 | - prefer_spread_collections 44 | - recursive_getters 45 | - slash_for_doc_comments 46 | - type_init_formals 47 | - unawaited_futures 48 | - unnecessary_const 49 | - unnecessary_new 50 | - unnecessary_null_in_if_null_operators 51 | - unnecessary_this 52 | - unrelated_type_equality_checks 53 | - use_function_type_syntax_for_parameters 54 | - use_rethrow_when_possible 55 | - valid_regexps 56 | -------------------------------------------------------------------------------- /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 29 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.flutter_buddies" 42 | minSdkVersion 16 43 | targetSdkVersion 29 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_buddies 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | cupertino_icons: ^1.0.0 27 | faker: ^1.3.0 28 | flip_card: ^0.4.4 29 | font_awesome_flutter: ^8.11.0 30 | http: ^0.13.0 31 | intl: ^0.16.1 32 | url_launcher: ^5.7.10 33 | cached_network_image: ^2.5.0 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | # For information on the generic Dart part of this file, see the 40 | # following page: https://dart.dev/tools/pub/pubspec 41 | # The following section is specific to Flutter. 42 | flutter: 43 | # The following line ensures that the Material Icons font is 44 | # included with your application, so that you can use the icons in 45 | # the material Icons class. 46 | uses-material-design: true 47 | 48 | # To add assets to your application, add an assets section, like this: 49 | assets: 50 | - assets/profile_images/ 51 | - assets/global_images/ 52 | - assets/profile_logos/ 53 | - .env 54 | -------------------------------------------------------------------------------- /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(RunLoop* run_loop, 8 | const flutter::DartProject& project) 9 | : run_loop_(run_loop), project_(project) {} 10 | 11 | FlutterWindow::~FlutterWindow() {} 12 | 13 | bool FlutterWindow::OnCreate() { 14 | if (!Win32Window::OnCreate()) { 15 | return false; 16 | } 17 | 18 | RECT frame = GetClientArea(); 19 | 20 | // The size here must match the window dimensions to avoid unnecessary surface 21 | // creation / destruction in the startup path. 22 | flutter_controller_ = std::make_unique( 23 | frame.right - frame.left, frame.bottom - frame.top, project_); 24 | // Ensure that basic setup of the controller was successful. 25 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 26 | return false; 27 | } 28 | RegisterPlugins(flutter_controller_->engine()); 29 | run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); 30 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 31 | return true; 32 | } 33 | 34 | void FlutterWindow::OnDestroy() { 35 | if (flutter_controller_) { 36 | run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); 37 | flutter_controller_ = nullptr; 38 | } 39 | 40 | Win32Window::OnDestroy(); 41 | } 42 | 43 | LRESULT 44 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 45 | WPARAM const wparam, 46 | LPARAM const lparam) noexcept { 47 | // Give Flutter, including plugins, an opporutunity to handle window messages. 48 | if (flutter_controller_) { 49 | std::optional result = 50 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 51 | lparam); 52 | if (result) { 53 | return *result; 54 | } 55 | } 56 | 57 | switch (message) { 58 | case WM_FONTCHANGE: 59 | flutter_controller_->engine()->ReloadSystemFonts(); 60 | break; 61 | } 62 | 63 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 64 | } 65 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/goober0329/qr_game_of_life/gol_display.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:flutter_buddies/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_model.dart'; 4 | 5 | class GoLDisplay extends StatelessWidget { 6 | final GameOfLife gol; 7 | final double cellSize; 8 | final bool displayAge; 9 | final Color color; 10 | final double cornerRadiusRatio; 11 | GoLDisplay({ 12 | @required this.gol, 13 | @required this.cellSize, 14 | this.displayAge = false, 15 | this.color = Colors.black, 16 | this.cornerRadiusRatio = 0, 17 | }); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return buildGoLGrid(); 22 | } 23 | 24 | /// function to build the GoL grid 25 | Widget buildGoLGrid() { 26 | List rows = []; 27 | for (int i = 0; i < gol.cells.length; i++) { 28 | List row = []; 29 | for (int j = 0; j < gol.cells[0].length; j++) { 30 | row.add(buildGoLCell(i, j)); 31 | } 32 | rows.add(Row( 33 | children: row, 34 | mainAxisSize: MainAxisSize.min, 35 | )); 36 | } 37 | return Column( 38 | mainAxisSize: MainAxisSize.min, 39 | children: rows, 40 | ); 41 | } 42 | 43 | /// function to build individual GoL cells 44 | Widget buildGoLCell(int i, int j) { 45 | if (gol.cells[i][j].current) { 46 | return Container( 47 | width: cellSize, 48 | height: cellSize, 49 | decoration: BoxDecoration( 50 | color: color, 51 | borderRadius: BorderRadius.circular(cornerRadiusRatio * cellSize), 52 | ), 53 | ); 54 | } else { 55 | if (displayAge) { 56 | return Container( 57 | width: cellSize, 58 | height: cellSize, 59 | decoration: BoxDecoration( 60 | color: Color.lerp( 61 | color, 62 | Colors.white.withOpacity(0.0), 63 | gol.cells[i][j].age / gol.numAgeSteps, 64 | ), 65 | borderRadius: BorderRadius.circular(cornerRadiusRatio * cellSize), 66 | ), 67 | ); 68 | } else { 69 | return Container( 70 | width: cellSize, 71 | height: cellSize, 72 | ); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/data/models/project.dart: -------------------------------------------------------------------------------- 1 | import 'package:faker/faker.dart'; 2 | 3 | String _makeTag(bool archived, bool disabled) { 4 | if (archived) { 5 | return 'Archived'; 6 | } 7 | if (disabled) { 8 | return 'Disabled'; 9 | } 10 | return 'Active'; 11 | } 12 | 13 | const String SCHEME = 'https'; 14 | const String HOST = 'raw.githubusercontent.com'; 15 | const String PATH_COMPONENT_BASE = 'Flutter-Buddies'; 16 | const String PATH_COMPONENT_FILENAME = 'cover_image.png'; 17 | 18 | //Todo: Bring in more details for full list 19 | //Todo: figure out images from repo 20 | 21 | class Project { 22 | final String title; 23 | final String repoName; 24 | final String description; 25 | // final Future image; // COMMENTED OUT - Only download the image if we actually ever display it. 26 | final String tag; 27 | final String url; 28 | final String defaultBranch; 29 | 30 | Project.fromJson(Map json) 31 | : title = (json['name']).toString().replaceAll('-', ' '), 32 | repoName = json['name'], 33 | description = json['description'] ?? 'No description available', 34 | // image = 35 | // _getImage(json['html_url'], json['default_branch'], json['name']), 36 | tag = _makeTag(json['archived'], json['disabled']), 37 | url = json['html_url'], 38 | defaultBranch = json['default_branch']; 39 | 40 | static Project get fake { 41 | final Faker faker = Faker(); 42 | return Project.fromJson({ 43 | 'name': faker.lorem 44 | .words( 45 | faker.randomGenerator.integer(4, min: 1), 46 | ) 47 | .join(' '), 48 | 'description': faker.lorem 49 | .sentences( 50 | faker.randomGenerator.integer(3, min: 1), 51 | ) 52 | .join(' '), 53 | 'imageUrl': 'https://picsum.photos/seed/' + faker.lorem.word() + '/600', 54 | 'archived': false, 55 | 'disabled': false, 56 | 'defaultBranch': 'master', 57 | }); 58 | } 59 | 60 | // Let flutter do the hard work of making sure that the URL structure is valid. 61 | Uri get imageUri => Uri( 62 | scheme: SCHEME, 63 | host: HOST, 64 | pathSegments: [ 65 | PATH_COMPONENT_BASE, 66 | repoName, 67 | defaultBranch, 68 | PATH_COMPONENT_FILENAME 69 | ], 70 | ); 71 | } 72 | -------------------------------------------------------------------------------- /lib/data/repositories/project_repository.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:http/http.dart' as http; 3 | 4 | import 'package:flutter_buddies/data/models/project.dart'; 5 | 6 | class ProjectRepository { 7 | static final ProjectRepository _projectRepository = ProjectRepository._(); 8 | List _projects = []; 9 | 10 | static ProjectRepository get() => _projectRepository; 11 | 12 | factory ProjectRepository() { 13 | return _projectRepository; 14 | } 15 | 16 | ProjectRepository._(); 17 | 18 | Future> fetchAll({bool fresh = false}) async { 19 | if (_projects.isEmpty || fresh) { 20 | // fetch projects from GitHub API 21 | final response = await http 22 | .get(Uri.parse('https://api.github.com/orgs/Flutter-Buddies/repos')); 23 | if (response.statusCode != 200) { 24 | // TODO handle error 25 | print('ERROR ${response.statusCode}: ${response.reasonPhrase}'); 26 | } else { 27 | // decode body if response status is OK 28 | final List projectsJson = json.decode(response.body); 29 | // transform to Projects 30 | _projects = projectsJson.map((json) => Project.fromJson(json)).toList(); 31 | } 32 | } 33 | return _projects; 34 | } 35 | 36 | Future> take([int count = 3]) async { 37 | await fetchAll(); 38 | return _projects.take(count).toList(); 39 | } 40 | 41 | Future> takeAll() async { 42 | return await fetchAll(); 43 | } 44 | } 45 | 46 | class FakeProjectRepository implements ProjectRepository { 47 | final ProjectRepository _delegate; 48 | 49 | List get _projects => _delegate._projects; 50 | set _projects(value) => _delegate._projects = value; 51 | 52 | FakeProjectRepository() : _delegate = ProjectRepository(); 53 | 54 | Future> take([int count = 3]) => _delegate.take(); 55 | Future> takeAll() => _delegate.takeAll(); 56 | 57 | @override 58 | Future> fetchAll({bool fresh = false}) async { 59 | int projectsNumber = 10; 60 | if (_projects.isEmpty || _projects.length != projectsNumber || fresh) { 61 | _projects = []; 62 | while (projectsNumber-- > 0) { 63 | _projects.add(Project.fake); 64 | } 65 | } 66 | await Future.delayed(Duration(milliseconds: 400)); 67 | return _projects; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /windows/runner/run_loop.cpp: -------------------------------------------------------------------------------- 1 | #include "run_loop.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | RunLoop::RunLoop() {} 8 | 9 | RunLoop::~RunLoop() {} 10 | 11 | void RunLoop::Run() { 12 | bool keep_running = true; 13 | TimePoint next_flutter_event_time = TimePoint::clock::now(); 14 | while (keep_running) { 15 | std::chrono::nanoseconds wait_duration = 16 | std::max(std::chrono::nanoseconds(0), 17 | next_flutter_event_time - TimePoint::clock::now()); 18 | ::MsgWaitForMultipleObjects( 19 | 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), 20 | QS_ALLINPUT); 21 | bool processed_events = false; 22 | MSG message; 23 | // All pending Windows messages must be processed; MsgWaitForMultipleObjects 24 | // won't return again for items left in the queue after PeekMessage. 25 | while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { 26 | processed_events = true; 27 | if (message.message == WM_QUIT) { 28 | keep_running = false; 29 | break; 30 | } 31 | ::TranslateMessage(&message); 32 | ::DispatchMessage(&message); 33 | // Allow Flutter to process messages each time a Windows message is 34 | // processed, to prevent starvation. 35 | next_flutter_event_time = 36 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 37 | } 38 | // If the PeekMessage loop didn't run, process Flutter messages. 39 | if (!processed_events) { 40 | next_flutter_event_time = 41 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 42 | } 43 | } 44 | } 45 | 46 | void RunLoop::RegisterFlutterInstance( 47 | flutter::FlutterEngine* flutter_instance) { 48 | flutter_instances_.insert(flutter_instance); 49 | } 50 | 51 | void RunLoop::UnregisterFlutterInstance( 52 | flutter::FlutterEngine* flutter_instance) { 53 | flutter_instances_.erase(flutter_instance); 54 | } 55 | 56 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { 57 | TimePoint next_event_time = TimePoint::max(); 58 | for (auto instance : flutter_instances_) { 59 | std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); 60 | if (wait_duration != std::chrono::nanoseconds::max()) { 61 | next_event_time = 62 | std::min(next_event_time, TimePoint::clock::now() + wait_duration); 63 | } 64 | } 65 | return next_event_time; 66 | } 67 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/thgehr/thomasgehrmann.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | //user defines from abstract class needed information 4 | class GehrmannInfo extends WidgetInfo { 5 | @override 6 | String get name => 7 | 'My Widget'; //name your widget, not used in design currently 8 | 9 | @override 10 | String get description => 'This is an example of a basic widget'; 11 | 12 | @override 13 | String get developer => 'Thomas Gehrmann'; //use any name for yourself 14 | 15 | @override 16 | String get logoPath => 'assets/profile_logos/flutter_buddy.png'; 17 | 18 | @override 19 | Widget get widget => GehrmannWidget(); 20 | } 21 | 22 | GehrmannInfo gehrmannInfo = GehrmannInfo(); 23 | 24 | // User's widget lives here 25 | class GehrmannWidget extends StatelessWidget { 26 | @override 27 | Widget build(BuildContext context) { 28 | return SafeArea( 29 | child: Scaffold( 30 | extendBodyBehindAppBar: true, 31 | appBar: AppBar( 32 | backgroundColor: Colors.transparent, 33 | ), 34 | body: Container( 35 | decoration: BoxDecoration( 36 | gradient: LinearGradient( 37 | begin: Alignment.bottomLeft, 38 | end: Alignment.topRight, 39 | stops: [0.1, 0.5, 0.8, 0.9], 40 | colors: [Colors.red, Colors.yellow, Colors.blue, Colors.purple], 41 | ), 42 | ), 43 | child: Center( 44 | child: Column( 45 | mainAxisAlignment: MainAxisAlignment.center, 46 | //crossAxisAlignment: CrossAxisAlignment.stretch, 47 | children: [ 48 | Text( 49 | 'Thomas Gehrmann', 50 | style: TextStyle( 51 | color: Colors.white, 52 | fontSize: 32, 53 | ), 54 | ), 55 | Text('AI, Blockchain and Flutter Enthusiast'), 56 | SizedBox( 57 | height: 16, 58 | ), 59 | Padding( 60 | padding: const EdgeInsets.symmetric(horizontal: 48), 61 | child: 62 | Text('''I studied Physics and Economics in Bonn, Germany. 63 | I am very curios and fascinated by new technologies, like AI and Blockchain. 64 | '''), 65 | ), 66 | ], 67 | ), 68 | ), 69 | ), 70 | ), 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/daseed/pierre-emmanuel_legrain.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | class DaseedInfo extends WidgetInfo { 4 | @override 5 | String get name => "Pierre-emmanuel aka Daseed's widget "; 6 | 7 | @override 8 | String get description => 9 | '.NET Software Engineer - Boardgamer - Flutter maniac'; 10 | 11 | @override 12 | String get developer => 'Pierre-emmanuel Legrain'; 13 | 14 | @override 15 | String get logoPath => 'assets/profile_images/daseed_profile.jpg'; 16 | 17 | @override 18 | Widget get widget => DaseedWidget(); 19 | } 20 | 21 | DaseedInfo daseed = DaseedInfo(); 22 | 23 | class DaseedWidget extends StatelessWidget { 24 | @override 25 | Widget build(BuildContext context) { 26 | final size = MediaQuery.of(context).size; 27 | final color = Theme.of(context).primaryColor; 28 | return SafeArea( 29 | child: Scaffold( 30 | backgroundColor: Colors.white, 31 | appBar: AppBar( 32 | iconTheme: IconThemeData( 33 | color: Colors.black, 34 | ), 35 | elevation: 0, 36 | backgroundColor: Colors.white, 37 | title: Text( 38 | DaseedInfo().developer, 39 | style: TextStyle(color: Colors.black), 40 | ), 41 | ), 42 | // The stack is here only for a matter of design 43 | body: Stack( 44 | children: [ 45 | // It offers me the possibility to draw a shape in the background 46 | CustomPaint( 47 | painter: DecorationPainter(size.height, size.width, color), 48 | size: size), 49 | // Then draws the useful widgets in front of it. 50 | Column( 51 | mainAxisAlignment: MainAxisAlignment.spaceAround, 52 | children: [ 53 | SizedBox( 54 | height: 80, 55 | ), 56 | Center( 57 | child: Container( 58 | child: CircleAvatar( 59 | radius: size.width / 10, 60 | backgroundImage: ExactAssetImage( 61 | daseed.logoPath, 62 | ), 63 | ), 64 | ), 65 | ), 66 | SizedBox( 67 | height: 10, 68 | ), 69 | MyProfile(), 70 | ], 71 | ), 72 | ], 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/data/repositories/event_repository.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter_buddies/constants/secrets.dart'; 4 | import 'package:http/http.dart' as http; 5 | 6 | import 'package:flutter_buddies/data/models/event.dart'; 7 | 8 | class EventRepository { 9 | static final EventRepository _eventRepository = EventRepository._(); 10 | List _events = []; 11 | 12 | static EventRepository get() => _eventRepository; 13 | 14 | factory EventRepository() { 15 | return _eventRepository; 16 | } 17 | 18 | EventRepository._(); 19 | 20 | Future> fetchAll({bool fresh = false}) async { 21 | if (_events.isEmpty || fresh) { 22 | // fetch events from calendar API 23 | final response = await http.get( 24 | Uri.parse( 25 | 'https://www.googleapis.com/calendar/v3/calendars/gh1n5rutlqgsjpvqrba97e9atk@group.calendar.google.com/events?key=' + 26 | Secrets.calendar_key), 27 | ); 28 | if (response.statusCode != 200) { 29 | // handle error 30 | print('ERROR ${response.statusCode}: ${response.reasonPhrase}'); 31 | } else { 32 | // decode body if response status is OK 33 | final Map eventsJson = json.decode(response.body); 34 | final List eventItems = eventsJson['items']; 35 | // transform to Events 36 | eventItems.forEach((itemJson) { 37 | try { 38 | // some of the events are 'cancelled' and 39 | // don't have required attributes for parsing into Event 40 | _events.add(Event.fromJson(itemJson)); 41 | } catch (e) { 42 | //print('ERROR (fetchAll): $e'); 43 | } 44 | }); 45 | } 46 | } 47 | return _events; 48 | } 49 | 50 | Future> take([int count = 4]) async { 51 | await fetchAll(); 52 | return _events.take(count).toList(); 53 | } 54 | } 55 | 56 | class FakeEventRepository implements EventRepository { 57 | final EventRepository _delegate; 58 | 59 | List get _events => _delegate._events; 60 | set _events(value) => _delegate._events = value; 61 | 62 | FakeEventRepository() : _delegate = EventRepository(); 63 | 64 | Future> take([int count = 4]) => _delegate.take(); 65 | 66 | @override 67 | Future> fetchAll({bool fresh = false}) async { 68 | int eventsNumber = 10; 69 | if (_events.isEmpty || _events.length != eventsNumber || fresh) { 70 | _events = []; 71 | while (eventsNumber-- > 0) { 72 | _events.add(Event.fake); 73 | } 74 | } 75 | await Future.delayed(Duration(milliseconds: 400)); 76 | return _events; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_buddies/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_controller.dart'; 3 | 4 | import 'package:flutter_buddies/widgets/user_widgets/goober0329/qr_game_of_life/game_of_life_model.dart'; 5 | import 'package:flutter_buddies/widgets/user_widgets/goober0329/qr_game_of_life/gol_display.dart'; 6 | import 'package:flutter_buddies/widgets/user_widgets/user_widgets.dart'; 7 | 8 | class GoLWidget extends StatefulWidget { 9 | final double size; 10 | GoLWidget({@required this.size}); 11 | 12 | @override 13 | _GoLWidgetState createState() => _GoLWidgetState(); 14 | } 15 | 16 | class _GoLWidgetState extends State { 17 | GameOfLife gol; 18 | GoLController controller; 19 | bool playing = false; 20 | 21 | @override 22 | void initState() { 23 | super.initState(); 24 | 25 | gol = GameOfLife(); 26 | controller = GoLController(timeStep: Duration(milliseconds: 350)); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return Column( 32 | children: [ 33 | GoLDisplay( 34 | gol: gol, 35 | cellSize: widget.size / gol.width, 36 | color: golColor, 37 | cornerRadiusRatio: golCornerRadiusRatio, 38 | ), 39 | SizedBox(height: 20), 40 | Row( 41 | mainAxisSize: MainAxisSize.min, 42 | children: [ 43 | IconButton( 44 | iconSize: 40, 45 | icon: Icon( 46 | playing 47 | ? Icons.pause_circle_outline 48 | : Icons.play_circle_outline, 49 | color: golColor, 50 | ), 51 | onPressed: () { 52 | if (playing) { 53 | setState(() { 54 | controller.stop(); 55 | playing = false; 56 | }); 57 | } else { 58 | setState(() { 59 | controller.start(gol, () { 60 | setState(() {}); 61 | }); 62 | playing = true; 63 | }); 64 | } 65 | }, 66 | ), 67 | IconButton( 68 | iconSize: 40, 69 | icon: Icon( 70 | Icons.shuffle, 71 | color: golColor, 72 | ), 73 | onPressed: () { 74 | setState(() { 75 | gol.randomize(); 76 | }); 77 | }, 78 | ), 79 | ], 80 | ), 81 | ], 82 | ); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /lib/modules/screens/about_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | class AboutScreen extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Scaffold( 8 | body: AnnotatedRegion( 9 | value: SystemUiOverlayStyle.light, 10 | child: CustomScrollView( 11 | slivers: [ 12 | SliverAppBar( 13 | backgroundColor: Colors.white10, 14 | leading: Image( 15 | image: AssetImage('assets/global_images/flutterbuddies.png'), 16 | ), 17 | centerTitle: true, 18 | title: Text( 19 | 'About', 20 | style: TextStyle(color: Colors.black, fontSize: 24), 21 | ), 22 | ), 23 | SliverList( 24 | delegate: SliverChildListDelegate( 25 | [ 26 | Padding( 27 | padding: const EdgeInsets.all(16.0), 28 | child: Text(''' 29 | Flutter Buddies is a Discord community for Flutter developers using regular online meetups to help and motivate others with their flutter journey and in return receive help and motivation on yours. 30 | 31 | Think of it like a study group on steroids for flutter devs. The core of our community is based on the regular small group meetups and getting to know and help other Flutter devs, no matter your background. We have set weekly timed meetups to get together on discord voice chat and discuss our projects, problems we're facing, suggestions, and more. The channel acts as a way to interact between meetups. 32 | 33 | This concept works best if we get to know each other a little, give some commitment to the group, be present, and be willing to give back to the group when you can. 34 | 35 | Interactivity is key to your success here! Being a part of the active group will help you find a core group of people to help you and for you to grow with as a Flutter dev. 36 | '''), 37 | ), 38 | Padding( 39 | padding: const EdgeInsets.symmetric(horizontal: 16), 40 | child: Row( 41 | children: [ 42 | Text('Find out more on '), 43 | Text( 44 | 'GitHub', 45 | style: TextStyle( 46 | decoration: TextDecoration.underline, 47 | color: Colors.blue), 48 | ), 49 | Text('.'), 50 | ], 51 | ), 52 | ), 53 | ], 54 | ), 55 | ), 56 | ], 57 | ), 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/user_widgets.dart: -------------------------------------------------------------------------------- 1 | library user_widgets; 2 | 3 | // all included parts (widgets) have the packages listed here available to them 4 | // add your required dependencies here 5 | /// communal imports 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter/cupertino.dart'; 8 | import 'package:flutter/services.dart'; 9 | import 'package:flutter/gestures.dart'; 10 | import 'package:url_launcher/url_launcher.dart'; // Added so we can link to socials or Discord 11 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 12 | 13 | //imports for Rift 14 | import 'package:flip_card/flip_card.dart'; 15 | 16 | /// imports for Grayson's developer widget 17 | import 'goober0329/qr_game_of_life/gol_glider.dart'; 18 | import 'goober0329/qr_game_of_life/game_of_life_widget.dart'; 19 | 20 | // imports for daseed 21 | import 'package:flutter_buddies/widgets/user_widgets/daseed/widgets/decoration_painter.dart'; 22 | import 'package:flutter_buddies/widgets/user_widgets/daseed/widgets/my_profile.dart'; 23 | 24 | // imports for robots 25 | import 'dart:async'; 26 | import 'dart:math'; 27 | import 'package:flutter/scheduler.dart'; 28 | 29 | import 'robots/secrets.dart'; 30 | import 'robots/monster_controller.dart'; 31 | import 'robots/bloc/robots_bloc.dart'; 32 | import 'robots/robots_models.dart'; 33 | 34 | //defines the widget info abstract class 35 | part 'widget_info.dart'; 36 | 37 | // You need do the following to add your widget to the project 38 | // TODO: 1. Add "part of user_widgets;" to your widget file. 39 | // TODO: 2. Add "part /.dart;" below. 40 | // TODO: 3. Build your widget in your directory 41 | // TODO: 4. Extend WidgetInfo class from './widget_info.dart' in your main widget file. 42 | // TODO: 4a. Instantiate your WidgetInfo Object in your widget's dart file 43 | // TODO: 4b. See example/example.dart for an example of step 4 44 | 45 | part 'example/example.dart'; // <-- from TODO step 2 46 | part 'zambrella/zambrella_widget.dart'; 47 | part 'goober0329/goober_widget.dart'; 48 | part 'rift/rift_widget.dart'; 49 | part 'slovnicki/slovnicki_widget.dart'; 50 | part 'hsinats/hsinats_widget.dart'; 51 | part 'daseed/pierre-emmanuel_legrain.dart'; 52 | part 'sleepingisimportant/sleepingisimportant_widget.dart'; 53 | part 'robots/robots_widget.dart'; 54 | part 'yazeedalkhalaf/yazeedalkhalaf_widget.dart'; 55 | part 'thgehr/thomasgehrmann.dart'; 56 | 57 | // TODO: 5. Add your Widget Info class object from step 4a to the list 58 | List widgetInfoList = [ 59 | zambrella, //user @Zambrella 60 | goober, 61 | rift, 62 | slovnicki, 63 | hsinats, 64 | daseed, 65 | sleepingisimportant, 66 | robots, 67 | yazeedAlKhalaf, 68 | gehrmannInfo, 69 | //exampleInfo, // <-- from TODO step 5: add your widgetinfo class here 70 | ]; 71 | // can this be done without instantiating or adding the widgetinfo to the list? (see user_widgets.dart) 72 | 73 | // TODO: 6. Create a Pull Request on Github 74 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/robots/bloc/robots_state.dart: -------------------------------------------------------------------------------- 1 | part of 'robots_bloc.dart'; 2 | 3 | 4 | class RobotsState { 5 | final int level; 6 | final bool gameOver; 7 | final bool robotDestroyed; 8 | final double robotPosition; 9 | final double robotHealth; 10 | final double robotVelocity; 11 | final double screenX; 12 | final double screenY; 13 | final List missiles; 14 | final List monsters; 15 | final List monsterMissiles; 16 | final double monsterVelocity; 17 | final int monstersDefeated; 18 | final int lastTimeFired; 19 | final int robotFireRate; 20 | final Laser laser; 21 | final bool upgradeAvailable; 22 | final int robotCannons; 23 | 24 | const RobotsState({ 25 | this.level = 1, 26 | this.gameOver = false, 27 | this.robotDestroyed = false, 28 | this.screenX = 0, 29 | this.screenY = 0, 30 | this.robotVelocity = 0, 31 | this.robotHealth = 10, 32 | this.robotPosition = 0, 33 | this.missiles = const [], 34 | this.monsters = const [], 35 | this.monsterVelocity = 4, 36 | this.monstersDefeated = 0, 37 | this.monsterMissiles = const [], 38 | this.lastTimeFired = 0, 39 | this.robotFireRate = 1000, 40 | this.laser = const Laser(), 41 | this.upgradeAvailable = false, 42 | this.robotCannons = 1, 43 | }); 44 | 45 | RobotsState copyWith({ 46 | int level, 47 | bool gameOver, 48 | bool robotDestroyed, 49 | double robotPosition, 50 | double robotVelocity, 51 | double robotHealth, 52 | double screenX, 53 | double screenY, 54 | List missiles, 55 | List monsters, 56 | double monsterVelocity, 57 | int monstersDefeated, 58 | List monsterMissiles, 59 | int lastTimeFired, 60 | int robotFireRate, 61 | Laser laser, 62 | bool upgradeAvailable, 63 | int robotCannons, 64 | }) => 65 | RobotsState( 66 | level: level ?? this.level, 67 | robotDestroyed: robotDestroyed ?? this.robotDestroyed, 68 | gameOver: gameOver ?? this.gameOver, 69 | robotPosition: robotPosition ?? this.robotPosition, 70 | robotVelocity: robotVelocity ?? this.robotVelocity, 71 | robotHealth: robotHealth ?? this.robotHealth, 72 | screenX: screenX ?? this.screenX, 73 | screenY: screenY ?? this.screenY, 74 | missiles: missiles ?? this.missiles, 75 | monsters: monsters ?? this.monsters, 76 | monsterVelocity: monsterVelocity ?? this.monsterVelocity, 77 | monsterMissiles: monsterMissiles ?? this.monsterMissiles, 78 | monstersDefeated: monstersDefeated ?? this.monstersDefeated, 79 | lastTimeFired: lastTimeFired ?? this.lastTimeFired, 80 | robotFireRate: robotFireRate ?? this.robotFireRate, 81 | laser: laser ?? this.laser, 82 | upgradeAvailable: upgradeAvailable ?? this.upgradeAvailable, 83 | robotCannons: robotCannons ?? this.robotCannons, 84 | ); 85 | } 86 | 87 | enum Upgrade { fireRate, health, cannons, shield } 88 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/widgets/event_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:intl/intl.dart'; 3 | 4 | class EventCard extends StatelessWidget { 5 | final ImageProvider eventImage; 6 | final DateTime eventDateTime; 7 | final String eventName; 8 | EventCard({this.eventImage, this.eventDateTime, this.eventName}); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | clipBehavior: Clip.antiAlias, 13 | decoration: BoxDecoration( 14 | borderRadius: BorderRadius.circular(6), 15 | boxShadow: [ 16 | BoxShadow( 17 | color: Colors.grey.withOpacity(0.3), 18 | spreadRadius: 3, 19 | blurRadius: 3, 20 | offset: Offset(0, 1), 21 | ) 22 | ], 23 | ), 24 | child: Stack( 25 | alignment: Alignment.bottomCenter, 26 | children: [ 27 | // Image at the bottom 28 | Container( 29 | decoration: BoxDecoration( 30 | image: DecorationImage( 31 | fit: BoxFit.cover, 32 | image: eventImage, 33 | ), 34 | ), 35 | ), 36 | // Gradient over the image to make the text clear 37 | Container( 38 | decoration: BoxDecoration( 39 | gradient: LinearGradient( 40 | begin: Alignment.bottomCenter, 41 | end: Alignment.topCenter, 42 | colors: [Colors.black.withOpacity(0.75), Colors.transparent]), 43 | ), 44 | ), 45 | // Text over the top 46 | Padding( 47 | padding: const EdgeInsets.all(8.0), 48 | child: Column( 49 | crossAxisAlignment: CrossAxisAlignment.stretch, 50 | mainAxisAlignment: MainAxisAlignment.end, 51 | children: [ 52 | // I've decided to have the date resize based on the width because the date should always be visible 53 | FittedBox( 54 | alignment: Alignment.centerLeft, 55 | fit: BoxFit.scaleDown, 56 | child: Text( 57 | DateFormat('MMMEd').format(eventDateTime.toLocal()) + 58 | ' ' + 59 | DateFormat.Hm().format(eventDateTime.toLocal()) + 60 | ' ${DateTime.now().timeZoneName}', 61 | maxLines: 1, 62 | style: TextStyle( 63 | color: Colors.white, 64 | fontSize: 14, 65 | fontWeight: FontWeight.w300), 66 | ), 67 | ), 68 | // For the name of the event, it will be much more variabel in length so I'm happy to have an overflow and keep the text size constant 69 | Text( 70 | eventName, 71 | maxLines: 2, 72 | overflow: TextOverflow.ellipsis, 73 | style: TextStyle( 74 | color: Colors.white, fontWeight: FontWeight.bold), 75 | ), 76 | ], 77 | ), 78 | ) 79 | ], 80 | ), 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 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 | 11 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 12 | # which isn't available in 3.10. 13 | function(list_prepend LIST_NAME PREFIX) 14 | set(NEW_LIST "") 15 | foreach(element ${${LIST_NAME}}) 16 | list(APPEND NEW_LIST "${PREFIX}${element}") 17 | endforeach(element) 18 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | # === Flutter Library === 22 | # System-level dependencies. 23 | find_package(PkgConfig REQUIRED) 24 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 25 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 26 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 27 | pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) 28 | pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) 29 | 30 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 31 | 32 | # Published to parent scope for install step. 33 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 34 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 35 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 36 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 37 | 38 | list(APPEND FLUTTER_LIBRARY_HEADERS 39 | "fl_basic_message_channel.h" 40 | "fl_binary_codec.h" 41 | "fl_binary_messenger.h" 42 | "fl_dart_project.h" 43 | "fl_engine.h" 44 | "fl_json_message_codec.h" 45 | "fl_json_method_codec.h" 46 | "fl_message_codec.h" 47 | "fl_method_call.h" 48 | "fl_method_channel.h" 49 | "fl_method_codec.h" 50 | "fl_method_response.h" 51 | "fl_plugin_registrar.h" 52 | "fl_plugin_registry.h" 53 | "fl_standard_message_codec.h" 54 | "fl_standard_method_codec.h" 55 | "fl_string_codec.h" 56 | "fl_value.h" 57 | "fl_view.h" 58 | "flutter_linux.h" 59 | ) 60 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 61 | add_library(flutter INTERFACE) 62 | target_include_directories(flutter INTERFACE 63 | "${EPHEMERAL_DIR}" 64 | ) 65 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 66 | target_link_libraries(flutter INTERFACE 67 | PkgConfig::GTK 68 | PkgConfig::GLIB 69 | PkgConfig::GIO 70 | PkgConfig::BLKID 71 | PkgConfig::LZMA 72 | ) 73 | add_dependencies(flutter flutter_assemble) 74 | 75 | # === Flutter tool backend === 76 | # _phony_ is a non-existent file to force this command to run every time, 77 | # since currently there's no way to get a full input/output list from the 78 | # flutter tool. 79 | add_custom_command( 80 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 81 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 82 | COMMAND ${CMAKE_COMMAND} -E env 83 | ${FLUTTER_TOOL_ENVIRONMENT} 84 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 85 | linux-x64 ${CMAKE_BUILD_TYPE} 86 | VERBATIM 87 | ) 88 | add_custom_target(flutter_assemble DEPENDS 89 | "${FLUTTER_LIBRARY}" 90 | ${FLUTTER_LIBRARY_HEADERS} 91 | ) 92 | -------------------------------------------------------------------------------- /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 | #ifdef FLUTTER_BUILD_NUMBER 64 | #define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0 67 | #endif 68 | 69 | #ifdef FLUTTER_BUILD_NAME 70 | #define VERSION_AS_STRING #FLUTTER_BUILD_NAME 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", "com.example" "\0" 93 | VALUE "FileDescription", "A new Flutter project." "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "flutter_buddies" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2021 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "flutter_buddies.exe" "\0" 98 | VALUE "ProductName", "flutter_buddies" "\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 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(flutter_buddies LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "flutter_buddies") 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 | -------------------------------------------------------------------------------- /lib/widgets/project_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:url_launcher/url_launcher.dart'; 4 | 5 | class ProjectCard extends StatelessWidget { 6 | final String projectTitle; 7 | final String projectDescription; 8 | final Uri projectImageUri; 9 | final String projectTag; 10 | final String url; 11 | 12 | ProjectCard({ 13 | this.projectTitle, 14 | this.projectDescription, 15 | this.projectImageUri, 16 | this.projectTag, 17 | this.url, 18 | }); 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | final double imageSize = 23 | (MediaQuery.of(context).orientation == Orientation.landscape 24 | ? MediaQuery.of(context).size.height 25 | : MediaQuery.of(context).size.width) * 26 | 0.5; 27 | return GestureDetector( 28 | onTap: () => launch(url), 29 | child: Container( 30 | clipBehavior: Clip.antiAlias, 31 | decoration: BoxDecoration( 32 | borderRadius: BorderRadius.circular(6), 33 | boxShadow: [ 34 | BoxShadow( 35 | color: Colors.grey.withOpacity(0.3), 36 | spreadRadius: 3, 37 | blurRadius: 3, 38 | offset: Offset(0, 1), 39 | ) 40 | ], 41 | ), 42 | child: Column( 43 | children: [ 44 | Stack( 45 | children: [ 46 | // TODONE: Add spinner while loading 47 | // TODO: Implement a less naive image size control 48 | // Image.network( 49 | // projectImageUri.toString(), 50 | // height: imageSize, 51 | // ), 52 | 53 | Container( 54 | height: imageSize, 55 | width: imageSize, 56 | child: CachedNetworkImage( 57 | imageUrl: projectImageUri.toString(), 58 | placeholder: (context, _) => Container( 59 | height: imageSize * 0.3, 60 | width: imageSize * 0.3, 61 | child: CircularProgressIndicator(), 62 | ), 63 | errorWidget: (context, _, __) => 64 | Image.asset('assets/global_images/flutterbuddies.png'), 65 | ), 66 | ), 67 | Positioned( 68 | top: 10, 69 | right: 10, 70 | child: Container( 71 | padding: EdgeInsets.all(6), 72 | decoration: BoxDecoration( 73 | color: Color(0xff065A9D), 74 | borderRadius: BorderRadius.circular(3), 75 | ), 76 | child: Text( 77 | projectTag, 78 | style: TextStyle(color: Colors.white), 79 | ), 80 | ), 81 | ), 82 | ], 83 | ), 84 | Container( 85 | padding: EdgeInsets.all(8), 86 | color: Colors.white, 87 | width: double.infinity, 88 | child: Column( 89 | crossAxisAlignment: CrossAxisAlignment.start, 90 | children: [ 91 | Text( 92 | projectTitle, 93 | style: TextStyle(fontWeight: FontWeight.bold), 94 | ), 95 | Text( 96 | projectDescription, 97 | maxLines: 2, 98 | overflow: TextOverflow.ellipsis, 99 | ), 100 | ], 101 | ), 102 | ), 103 | ], 104 | ), 105 | ), 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /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 | # === Flutter Library === 13 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 14 | 15 | # Published to parent scope for install step. 16 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 17 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 18 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 19 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 20 | 21 | list(APPEND FLUTTER_LIBRARY_HEADERS 22 | "flutter_export.h" 23 | "flutter_windows.h" 24 | "flutter_messenger.h" 25 | "flutter_plugin_registrar.h" 26 | "flutter_texture_registrar.h" 27 | ) 28 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 29 | add_library(flutter INTERFACE) 30 | target_include_directories(flutter INTERFACE 31 | "${EPHEMERAL_DIR}" 32 | ) 33 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 34 | add_dependencies(flutter flutter_assemble) 35 | 36 | # === Wrapper === 37 | list(APPEND CPP_WRAPPER_SOURCES_CORE 38 | "core_implementations.cc" 39 | "standard_codec.cc" 40 | ) 41 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 42 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 43 | "plugin_registrar.cc" 44 | ) 45 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 46 | list(APPEND CPP_WRAPPER_SOURCES_APP 47 | "flutter_engine.cc" 48 | "flutter_view_controller.cc" 49 | ) 50 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 51 | 52 | # Wrapper sources needed for a plugin. 53 | add_library(flutter_wrapper_plugin STATIC 54 | ${CPP_WRAPPER_SOURCES_CORE} 55 | ${CPP_WRAPPER_SOURCES_PLUGIN} 56 | ) 57 | apply_standard_settings(flutter_wrapper_plugin) 58 | set_target_properties(flutter_wrapper_plugin PROPERTIES 59 | POSITION_INDEPENDENT_CODE ON) 60 | set_target_properties(flutter_wrapper_plugin PROPERTIES 61 | CXX_VISIBILITY_PRESET hidden) 62 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 63 | target_include_directories(flutter_wrapper_plugin PUBLIC 64 | "${WRAPPER_ROOT}/include" 65 | ) 66 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 67 | 68 | # Wrapper sources needed for the runner. 69 | add_library(flutter_wrapper_app STATIC 70 | ${CPP_WRAPPER_SOURCES_CORE} 71 | ${CPP_WRAPPER_SOURCES_APP} 72 | ) 73 | apply_standard_settings(flutter_wrapper_app) 74 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 75 | target_include_directories(flutter_wrapper_app PUBLIC 76 | "${WRAPPER_ROOT}/include" 77 | ) 78 | add_dependencies(flutter_wrapper_app flutter_assemble) 79 | 80 | # === Flutter tool backend === 81 | # _phony_ is a non-existent file to force this command to run every time, 82 | # since currently there's no way to get a full input/output list from the 83 | # flutter tool. 84 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 85 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 86 | add_custom_command( 87 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 88 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 89 | ${CPP_WRAPPER_SOURCES_APP} 90 | ${PHONY_OUTPUT} 91 | COMMAND ${CMAKE_COMMAND} -E env 92 | ${FLUTTER_TOOL_ENVIRONMENT} 93 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 94 | windows-x64 $ 95 | VERBATIM 96 | ) 97 | add_custom_target(flutter_assemble DEPENDS 98 | "${FLUTTER_LIBRARY}" 99 | ${FLUTTER_LIBRARY_HEADERS} 100 | ${CPP_WRAPPER_SOURCES_CORE} 101 | ${CPP_WRAPPER_SOURCES_PLUGIN} 102 | ${CPP_WRAPPER_SOURCES_APP} 103 | ) 104 | -------------------------------------------------------------------------------- /linux/my_application.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | #include 4 | #ifdef GDK_WINDOWING_X11 5 | #include 6 | #endif 7 | 8 | #include "flutter/generated_plugin_registrant.h" 9 | 10 | struct _MyApplication { 11 | GtkApplication parent_instance; 12 | char** dart_entrypoint_arguments; 13 | }; 14 | 15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) 16 | 17 | // Implements GApplication::activate. 18 | static void my_application_activate(GApplication* application) { 19 | MyApplication* self = MY_APPLICATION(application); 20 | GtkWindow* window = 21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); 22 | 23 | // Use a header bar when running in GNOME as this is the common style used 24 | // by applications and is the setup most users will be using (e.g. Ubuntu 25 | // desktop). 26 | // If running on X and not using GNOME then just use a traditional title bar 27 | // in case the window manager does more exotic layout, e.g. tiling. 28 | // If running on Wayland assume the header bar will work (may need changing 29 | // if future cases occur). 30 | gboolean use_header_bar = TRUE; 31 | #ifdef GDK_WINDOWING_X11 32 | GdkScreen *screen = gtk_window_get_screen(window); 33 | if (GDK_IS_X11_SCREEN(screen)) { 34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); 35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) { 36 | use_header_bar = FALSE; 37 | } 38 | } 39 | #endif 40 | if (use_header_bar) { 41 | GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); 42 | gtk_widget_show(GTK_WIDGET(header_bar)); 43 | gtk_header_bar_set_title(header_bar, "flutter_buddies"); 44 | gtk_header_bar_set_show_close_button(header_bar, TRUE); 45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); 46 | } 47 | else { 48 | gtk_window_set_title(window, "flutter_buddies"); 49 | } 50 | 51 | gtk_window_set_default_size(window, 1280, 720); 52 | gtk_widget_show(GTK_WIDGET(window)); 53 | 54 | g_autoptr(FlDartProject) project = fl_dart_project_new(); 55 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); 56 | 57 | FlView* view = fl_view_new(project); 58 | gtk_widget_show(GTK_WIDGET(view)); 59 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); 60 | 61 | fl_register_plugins(FL_PLUGIN_REGISTRY(view)); 62 | 63 | gtk_widget_grab_focus(GTK_WIDGET(view)); 64 | } 65 | 66 | // Implements GApplication::local_command_line. 67 | static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { 68 | MyApplication* self = MY_APPLICATION(application); 69 | // Strip out the first argument as it is the binary name. 70 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); 71 | 72 | g_autoptr(GError) error = nullptr; 73 | if (!g_application_register(application, nullptr, &error)) { 74 | g_warning("Failed to register: %s", error->message); 75 | *exit_status = 1; 76 | return TRUE; 77 | } 78 | 79 | g_application_activate(application); 80 | *exit_status = 0; 81 | 82 | return TRUE; 83 | } 84 | 85 | // Implements GObject::dispose. 86 | static void my_application_dispose(GObject *object) { 87 | MyApplication* self = MY_APPLICATION(object); 88 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); 89 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object); 90 | } 91 | 92 | static void my_application_class_init(MyApplicationClass* klass) { 93 | G_APPLICATION_CLASS(klass)->activate = my_application_activate; 94 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; 95 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose; 96 | } 97 | 98 | static void my_application_init(MyApplication* self) {} 99 | 100 | MyApplication* my_application_new() { 101 | return MY_APPLICATION(g_object_new(my_application_get_type(), 102 | "application-id", APPLICATION_ID, 103 | nullptr)); 104 | } 105 | -------------------------------------------------------------------------------- /linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | project(runner LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "flutter_buddies") 5 | set(APPLICATION_ID "com.example.flutter_buddies") 6 | 7 | cmake_policy(SET CMP0063 NEW) 8 | 9 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 10 | 11 | # Configure build options. 12 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 13 | set(CMAKE_BUILD_TYPE "Debug" CACHE 14 | STRING "Flutter build mode" FORCE) 15 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 16 | "Debug" "Profile" "Release") 17 | endif() 18 | 19 | # Compilation settings that should be applied to most targets. 20 | function(APPLY_STANDARD_SETTINGS TARGET) 21 | target_compile_features(${TARGET} PUBLIC cxx_std_14) 22 | target_compile_options(${TARGET} PRIVATE -Wall -Werror) 23 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") 24 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") 25 | endfunction() 26 | 27 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 28 | 29 | # Flutter library and tool build rules. 30 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 31 | 32 | # System-level dependencies. 33 | find_package(PkgConfig REQUIRED) 34 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 35 | 36 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") 37 | 38 | # Application build 39 | add_executable(${BINARY_NAME} 40 | "main.cc" 41 | "my_application.cc" 42 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 43 | ) 44 | apply_standard_settings(${BINARY_NAME}) 45 | target_link_libraries(${BINARY_NAME} PRIVATE flutter) 46 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) 47 | add_dependencies(${BINARY_NAME} flutter_assemble) 48 | # Only the install-generated bundle's copy of the executable will launch 49 | # correctly, since the resources must in the right relative locations. To avoid 50 | # people trying to run the unbundled copy, put it in a subdirectory instead of 51 | # the default top-level location. 52 | set_target_properties(${BINARY_NAME} 53 | PROPERTIES 54 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" 55 | ) 56 | 57 | # Generated plugin build rules, which manage building the plugins and adding 58 | # them to the application. 59 | include(flutter/generated_plugins.cmake) 60 | 61 | 62 | # === Installation === 63 | # By default, "installing" just makes a relocatable bundle in the build 64 | # directory. 65 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") 66 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 67 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 68 | endif() 69 | 70 | # Start with a clean build bundle directory every time. 71 | install(CODE " 72 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") 73 | " COMPONENT Runtime) 74 | 75 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 76 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 77 | 78 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 79 | COMPONENT Runtime) 80 | 81 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 82 | COMPONENT Runtime) 83 | 84 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 85 | COMPONENT Runtime) 86 | 87 | if(PLUGIN_BUNDLED_LIBRARIES) 88 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 89 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 90 | COMPONENT Runtime) 91 | endif() 92 | 93 | # Fully re-copy the assets directory on each build to avoid having stale files 94 | # from a previous install. 95 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 96 | install(CODE " 97 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 98 | " COMPONENT Runtime) 99 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 100 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 101 | 102 | # Install the AOT library on non-Debug builds only. 103 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") 104 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 105 | COMPONENT Runtime) 106 | endif() 107 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/hsinats/hsinats_widget.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | class Hsinats extends WidgetInfo { 4 | @override 5 | String get name => "Paul's Developer Widget"; 6 | 7 | @override 8 | String get description => 'Chemist | Educator | Flutter Developer'; 9 | 10 | @override 11 | String get developer => 'Paul Stanish'; 12 | 13 | @override 14 | String get logoPath => 'assets/profile_images/hsinats_profile.jpg'; 15 | 16 | @override 17 | Widget get widget => HsinatsWidget(); 18 | } 19 | 20 | Hsinats hsinats = Hsinats(); 21 | 22 | String myStory = ''' 23 | I have a Ph.D. in chemistry from the University of Waterloo. I love talking about science and am currently designing cirricula for an e-learning startup. 24 | 25 | I love Flutter because it has allowed me make the ideas in my head a real thing. 26 | '''; 27 | 28 | // TODO only works in landscape 29 | class HsinatsWidget extends StatelessWidget { 30 | final Radius bodyRadius = Radius.circular(16); 31 | final double dividerIndent = 12; 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | Size size = MediaQuery.of(context).size; 36 | return Scaffold( 37 | backgroundColor: Colors.black, 38 | body: SafeArea( 39 | child: Stack( 40 | children: [ 41 | Image(image: AssetImage('assets/global_images/quantum_dots.jpg')), 42 | Align( 43 | alignment: Alignment.bottomCenter, 44 | child: Container( 45 | height: size.height - size.width / 16 * 9 * 0.6 - 88, 46 | width: size.width, 47 | decoration: BoxDecoration( 48 | color: Colors.white, 49 | borderRadius: BorderRadius.only( 50 | topLeft: bodyRadius, 51 | topRight: bodyRadius, 52 | ), 53 | ), 54 | child: Column( 55 | children: [ 56 | SizedBox( 57 | height: 68, 58 | ), 59 | Text( 60 | hsinats.developer, 61 | style: TextStyle( 62 | fontSize: 24, 63 | fontWeight: FontWeight.w600, 64 | ), 65 | ), 66 | Text(hsinats.description), 67 | Divider( 68 | color: Colors.red, 69 | indent: dividerIndent, 70 | endIndent: dividerIndent, 71 | ), 72 | SingleChildScrollView( 73 | child: Padding( 74 | padding: const EdgeInsets.all(12.0), 75 | child: Text( 76 | myStory, 77 | textAlign: TextAlign.left, 78 | ), 79 | ), 80 | ), 81 | ], 82 | ), 83 | ), 84 | ), 85 | buildAvatar(size), 86 | IconButton( 87 | icon: Icon(Icons.arrow_back, color: Colors.grey[300]), 88 | onPressed: () => Navigator.pop(context), 89 | ) 90 | ], 91 | ), 92 | ), 93 | ); 94 | } 95 | 96 | Positioned buildAvatar(Size size) { 97 | return Positioned( 98 | top: size.width / 16 * 9 * .6, 99 | left: size.width / 2 - 60, 100 | child: Container( 101 | height: 120, 102 | width: 120, 103 | decoration: BoxDecoration( 104 | borderRadius: BorderRadius.circular(60), 105 | boxShadow: [ 106 | BoxShadow(color: Colors.black, blurRadius: 8.0), 107 | ], 108 | ), 109 | child: ClipRRect( 110 | borderRadius: BorderRadius.circular(60), 111 | child: Image( 112 | image: AssetImage(hsinats.logoPath), 113 | ), 114 | ) 115 | // CircleAvatar( 116 | // backgroundImage: AssetImage(hsinats.logoPath), 117 | // radius: 60, 118 | // ), 119 | ), 120 | ); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Community App 2 | 3 | ![tests](https://github.com/Flutter-Buddies/App/workflows/tests/badge.svg) 4 | ![build](https://github.com/Flutter-Buddies/App/workflows/build/badge.svg) 5 | 6 | A Flutter app with community features like a time zone translated calendar of events, list of group projects and a showcase of member created widgets. This app will get published to the app stores and shared among our brand, so get your name in the list! 7 | 8 | ## Contribution notice 9 | 10 | Before you start contributing, you need to copy `lib/constants/secrets.sample.dart` file and name the copy `secrets.dart` (**don't** delete the `lib/constants/secrets.sample.dart`). This is mandatory for app to build and is enough to get you going, but you won't see any events in app. If you wish to contribute to events part of the app, ask admins to give you the key. Then, put the key instead of `YOUR_API_KEY` in your `secrets.dart` file. 11 | 12 | NOTICE: Don't push `secrets.dart` to source control, it is in the `.gitignore` 13 | 14 | ## Adding your widget to the app 15 | 16 | The app will have a list of member user created widgets to display. 17 | The app will push your widget on as a new page, but you can have multiple pages. 18 | Your widget will have the entire screen. 19 | Your widget can be anything you want, get creative with a mini-app, a unique animation, or simply post a mi-card, whatever you want. 20 | 21 | Some guidelines and best practices to follow: 22 | 23 | - Users must be able to go back to the listview of user widgets. You should create back buttons for ease and use Navigator.pop(). 24 | - If you need a package, add it to /lib/widgets/user_widgets/user_widgets.dart and include it in in your pull request, but it's a good idea to check to make sure that your merge won't conflict with other user widgets already submitted or the rest of the app. 25 | - Try to use stateful widgets, setstate and inherited widgets for state management, if you need a state management package be sure to ask. 26 | - You can add image assets, but keep the filesize as low as possible and try to keep your entire directory under 500KB, if possible. You are able to load network images. If you have a large dataset, you'll need to load that dynamically. 27 | 28 | ### Steps to add your widget to the app 29 | 30 | You need do the following to add your widget to the project 31 | 32 | 1. Fork the repo, clone your fork, and checkout a new branch 33 | 1. Fork a copy of the repo at https://github.com/Flutter-Buddies/App on your github account 34 | 2. Clone your forked repo to your development environment 35 | 3. (optional) Checkout a custom "feature" branch (username? widget name?) 36 | - If you need more help with this process, check out our [community contributing guidelines](https://github.com/Flutter-Buddies/README/blob/main/CONTRIBUTING.md) or ask for assistance. 37 | 2. Create your widget file or files in a separate folder under a new directory at /lib/widgets/user_widgets/ 38 | - Your directory path should be /lib/widgets/user_widgets// (you can have any number of dirs in yours) 39 | - You don't need to create a main(), just extend a Widget type class that returns any Widget type. 40 | - See /lib/widgets/user_widgets/example.dart for reference. 41 | 3. Add `part of user_widgets;` to the top of your main widget file that you want to hook into the project. 42 | - See /lib/widgets/user_widgets/example.dart for reference. 43 | 4. Extend and define a custom WidgetInfo class from 'widget_info.dart in your widget file. 44 | - This class needs a unique name from the other user's WidgetInfo extended classes. 45 | - See /lib/widgets/user_widgets/example.dart for reference. 46 | 5. Add your project to user_widgets.dart 47 | 1. Add `part /.dart;` for your main file to the list of parts in /lib/widgets/user_widgets/user_widgets.dart. 48 | 2. Instantiate your widget info class. Example: `ExampleInfo info = ExampleInfo();` and add it to the list `widgetInfoList` 49 | - If you add a package to this file, make sure to include pubspec.yaml and why you need it in your pull request. 50 | 6. Push your code to your forked repo and use github to create a pull request describing your widget and anything that is needed to know to merge the code. 51 | - Check out the [community contributing guidelines](https://github.com/Flutter-Buddies/README/blob/main/CONTRIBUTING.md) for assistance. 52 | - If your PR is approved, your code will be merged, if not you may need to change something, we'll let you know. 53 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/slovnicki/slovnicki_widget.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | class Slovnicki extends WidgetInfo { 4 | @override 5 | String get name => 'Sandro Lovnički\n@sly, @slovnicki'; 6 | 7 | @override 8 | String get description => 9 | 'Computer Scientist, Mathematician, Software Engineer, Flutter Enthusiast'; 10 | 11 | @override 12 | String get developer => 'Sandro Lovnički'; 13 | 14 | @override 15 | String get logoPath => 'assets/profile_images/slovnicki_profile.jpeg'; 16 | 17 | @override 18 | Widget get widget => SlovnickiWidget(); 19 | 20 | @override 21 | int projectsCount = 2; 22 | } 23 | 24 | Slovnicki slovnicki = Slovnicki(); 25 | 26 | class SlovnickiWidget extends StatelessWidget { 27 | @override 28 | Widget build(BuildContext context) { 29 | return Scaffold( 30 | backgroundColor: const Color(0xFF600000), 31 | extendBodyBehindAppBar: true, 32 | appBar: AppBar( 33 | backgroundColor: Colors.transparent, 34 | ), 35 | body: SingleChildScrollView( 36 | physics: BouncingScrollPhysics(), 37 | child: Center( 38 | child: Column( 39 | children: [ 40 | SizedBox(height: kToolbarHeight + 32.0), 41 | CircleAvatar( 42 | backgroundImage: AssetImage(slovnicki.logoPath), 43 | radius: 60, 44 | ), 45 | Text( 46 | slovnicki.name, 47 | style: TextStyle( 48 | color: Colors.white, 49 | ), 50 | ), 51 | SizedBox(height: 16.0), 52 | Padding( 53 | padding: const EdgeInsets.symmetric(horizontal: 48.0), 54 | child: _textSpan(), 55 | ), 56 | SizedBox(height: 8.0), 57 | RichText( 58 | text: TextSpan( 59 | text: 'https://github.com/slovnicki', 60 | style: TextStyle(color: Colors.blue), 61 | recognizer: TapGestureRecognizer() 62 | ..onTap = () => launch('https://github.com/slovnicki'), 63 | ), 64 | ), 65 | Padding( 66 | padding: const EdgeInsets.all(16.0), 67 | child: Text( 68 | '''I studied (and finished) Computer Science and Mathematics in Zagreb, Croatia. 69 | 70 | I am the creator of pLam - a programming language for studying and exploring pure λ-calculus. 71 | 72 | Lately, I am very passionate about Dart and Flutter to which I contribute by developing packages and paving the road for Flutter web and desktop. 73 | 74 | I would like to build an AI to peacefully rule the world or invent a new model of computation.''', 75 | style: TextStyle( 76 | color: Colors.grey[300], 77 | ), 78 | ), 79 | ), 80 | Padding( 81 | padding: const EdgeInsets.all(16.0), 82 | child: Text( 83 | 'More coming soon... this is just a test', 84 | style: TextStyle( 85 | color: Colors.white, 86 | fontWeight: FontWeight.bold, 87 | ), 88 | ), 89 | ), 90 | ], 91 | ), 92 | ), 93 | ), 94 | ); 95 | } 96 | 97 | Widget _textSpan() { 98 | return RichText( 99 | textAlign: TextAlign.center, 100 | text: const TextSpan( 101 | style: TextStyle( 102 | color: Colors.white, 103 | fontWeight: FontWeight.bold, 104 | ), 105 | children: [ 106 | TextSpan( 107 | text: 'Computer Scientist', 108 | ), 109 | TextSpan( 110 | text: ' && ', 111 | style: TextStyle( 112 | color: Color(0xFF9E9E9E), 113 | ), 114 | ), 115 | TextSpan( 116 | text: 'Mathematician', 117 | ), 118 | TextSpan( 119 | text: ' && ', 120 | style: TextStyle( 121 | color: Color(0xFF9E9E9E), 122 | ), 123 | ), 124 | TextSpan( 125 | text: 'Software Engineer', 126 | ), 127 | TextSpan( 128 | text: ' && ', 129 | style: TextStyle( 130 | color: Color(0xFF9E9E9E), 131 | ), 132 | ), 133 | TextSpan( 134 | text: 'Flutter Enthusiast', 135 | ), 136 | ], 137 | ), 138 | ); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/goober0329/goober_widget.dart: -------------------------------------------------------------------------------- 1 | part of user_widgets; 2 | 3 | class Goober extends WidgetInfo { 4 | @override 5 | String get name => "Grayson's Developer Widget"; 6 | 7 | @override 8 | String get description => '''Materials Engineer | Avid Cyclist 9 | | Programming Enthusiast | Adventure Seeker'''; 10 | 11 | @override 12 | String get developer => 'Grayson Harrington'; 13 | 14 | @override 15 | String get logoPath => 'assets/profile_images/harrington_profile.jpg'; 16 | 17 | @override 18 | Widget get widget => GooberWidget(); 19 | } 20 | 21 | Goober goober = Goober(); 22 | 23 | final Color backgroundColor = Colors.white; 24 | 25 | final Color golColor = Color(0xFF00DE59); 26 | final double golCornerRadiusRatio = 0.25; 27 | 28 | /// My Developer Widget 29 | class GooberWidget extends StatelessWidget { 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | backgroundColor: backgroundColor, 34 | body: SafeArea( 35 | child: Column( 36 | children: [ 37 | Row( 38 | children: [ 39 | IconButton( 40 | iconSize: 35, 41 | icon: Icon(Icons.arrow_back), 42 | onPressed: () { 43 | Navigator.pop(context); 44 | }, 45 | ) 46 | ], 47 | ), 48 | Expanded( 49 | child: ListView( 50 | physics: BouncingScrollPhysics(), 51 | children: [ 52 | // AVATAR DISPLAY 53 | AvatarDisplay(), 54 | WidgetTileDivider(), 55 | // ABOUT ME 56 | AboutMe(), 57 | WidgetTileDivider(), 58 | // CONWAY'S GAME OF LIFE 59 | WidgetTile( 60 | text: "John Conway's Game of Life", 61 | widget: GoLWidget( 62 | size: MediaQuery.of(context).size.width * 0.6, 63 | ), 64 | ), 65 | WidgetTileDivider(), 66 | // GOL GLIDER 67 | WidgetTile( 68 | text: 'Game of Life Glider Animation', 69 | widget: Center( 70 | child: GoLGlider( 71 | gliderSize: MediaQuery.of(context).size.width * 0.6, 72 | color: golColor, 73 | borderRadiusRatio: golCornerRadiusRatio, 74 | ), 75 | ), 76 | ), 77 | WidgetTileDivider(), 78 | WidgetTile( 79 | text: 'To be continued', 80 | widget: Icon( 81 | Icons.more_horiz, 82 | size: 30, 83 | color: Colors.black, 84 | ), 85 | ), 86 | ], 87 | ), 88 | ), 89 | ], 90 | ), 91 | ), 92 | ); 93 | } 94 | } 95 | 96 | /// Tile to be used in my ListView of favorite widgets 97 | class WidgetTile extends StatelessWidget { 98 | final Widget widget; 99 | final String text; 100 | WidgetTile({@required this.widget, @required this.text}); 101 | 102 | @override 103 | Widget build(BuildContext context) { 104 | return Column( 105 | children: [ 106 | Padding( 107 | padding: const EdgeInsets.symmetric(vertical: 15.0), 108 | child: Text( 109 | text, 110 | style: TextStyle( 111 | fontSize: 20, 112 | fontWeight: FontWeight.bold, 113 | ), 114 | ), 115 | ), 116 | widget, 117 | ], 118 | ); 119 | } 120 | } 121 | 122 | /// Divider between the ListView WidgetTiles 123 | class WidgetTileDivider extends StatelessWidget { 124 | @override 125 | Widget build(BuildContext context) { 126 | return Divider( 127 | height: 40.0, 128 | thickness: 1, 129 | color: Colors.black, 130 | indent: 50, 131 | endIndent: 50, 132 | ); 133 | } 134 | } 135 | 136 | /// AboutMe portion of the ListView 137 | class AboutMe extends StatelessWidget { 138 | @override 139 | Widget build(BuildContext context) { 140 | return Padding( 141 | padding: const EdgeInsets.symmetric(horizontal: 30), 142 | child: Text( 143 | '''I graduated from Iowa State University with a degree in Materials Engineering. 144 | Along with my interest for Materials Engineering I also actively pursue 145 | my interest in programming. Recently I started learning Flutter in my 146 | spare time and I have really loved the language. 147 | \n\nBelow are some of my favorite widgets that I have made while working on 148 | different projects. 149 | \nEnjoy!''', 150 | style: TextStyle(fontSize: 16), 151 | textAlign: TextAlign.center, 152 | ), 153 | ); 154 | } 155 | } 156 | 157 | /// AvatarDisplay portion of ListView 158 | class AvatarDisplay extends StatelessWidget { 159 | @override 160 | Widget build(BuildContext context) { 161 | return Column( 162 | children: [ 163 | Center( 164 | child: Padding( 165 | padding: const EdgeInsets.all(8.0), 166 | child: CircleAvatar( 167 | backgroundImage: AssetImage(goober.logoPath), 168 | radius: 80, 169 | ), 170 | ), 171 | ), 172 | Center( 173 | child: Text( 174 | goober.developer, 175 | textAlign: TextAlign.center, 176 | style: TextStyle( 177 | fontSize: 24, 178 | ), 179 | ), 180 | ), 181 | Center( 182 | child: Padding( 183 | padding: const EdgeInsets.symmetric(horizontal: 40), 184 | child: Text( 185 | goober.description, 186 | textAlign: TextAlign.center, 187 | style: TextStyle( 188 | fontSize: 13, 189 | ), 190 | ), 191 | ), 192 | ), 193 | ], 194 | ); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/goober0329/qr_game_of_life/gol_glider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_buddies/widgets/user_widgets/user_widgets.dart'; 3 | 4 | /// Stateful Widget to control the glider animation 5 | /// that will go on the splash screen and loading screens 6 | class GoLGlider extends StatefulWidget { 7 | final List> modulePositions = [ 8 | [0, 1], 9 | [1, 2], 10 | [2, 2], 11 | [2, 1], 12 | [2, 0] 13 | ]; 14 | 15 | final List>> modulePositionStateChange = [ 16 | [ 17 | [1, -1], 18 | [0, 0], 19 | [0, 0], 20 | [0, 0], 21 | [1, 1] 22 | ], 23 | [ 24 | [1, 0], 25 | [0, 0], 26 | [0, 0], 27 | [1, 1], 28 | [0, 0] 29 | ], 30 | [ 31 | [-1, 1], 32 | [1, 1], 33 | [0, 0], 34 | [0, 0], 35 | [0, 0] 36 | ], 37 | [ 38 | [0, 1], 39 | [0, 0], 40 | [1, 1], 41 | [0, 0], 42 | [0, 0] 43 | ], 44 | ]; 45 | final double gliderSize; 46 | final Duration duration; 47 | final Color color; 48 | final double borderRadiusRatio; 49 | 50 | GoLGlider({ 51 | @required this.gliderSize, 52 | this.duration = const Duration(milliseconds: 1500), 53 | @required this.color, 54 | @required this.borderRadiusRatio, 55 | }); 56 | 57 | @override 58 | _GoLGliderState createState() => _GoLGliderState(); 59 | } 60 | 61 | class _GoLGliderState extends State 62 | with SingleTickerProviderStateMixin { 63 | List> modulePositions; 64 | double moduleSize; 65 | Container module; 66 | 67 | double gliderOffInit; 68 | Animation gliderOff; 69 | 70 | int curState; 71 | 72 | AnimationController _controller; 73 | 74 | @override 75 | void initState() { 76 | super.initState(); 77 | modulePositions = widget.modulePositions; 78 | moduleSize = widget.gliderSize / 5; 79 | module = Container( 80 | width: widget.gliderSize / 5, 81 | height: widget.gliderSize / 5, 82 | decoration: BoxDecoration( 83 | color: widget.color, 84 | borderRadius: BorderRadius.circular( 85 | widget.borderRadiusRatio * widget.gliderSize / 5, 86 | ), 87 | ), 88 | ); 89 | 90 | gliderOffInit = widget.gliderSize / 2 - moduleSize * 3 / 2; 91 | 92 | curState = -1; 93 | 94 | _controller = AnimationController( 95 | vsync: this, 96 | duration: Duration(milliseconds: widget.duration.inMilliseconds ~/ 4), 97 | ); 98 | 99 | gliderOff = Tween( 100 | begin: 0, 101 | end: moduleSize / 4, 102 | ).animate( 103 | CurvedAnimation( 104 | parent: _controller, 105 | curve: Interval(0, 1, curve: Curves.linear), 106 | ), 107 | ); 108 | 109 | _controller.addListener(updateModulePositions); 110 | _controller.forward(); 111 | } 112 | 113 | @override 114 | void dispose() { 115 | _controller.dispose(); 116 | super.dispose(); 117 | } 118 | 119 | /// this is where the meat of the animation occurs. the glider as a whole 120 | /// moves toward the top left corner based on the controller value, and the 121 | /// glider transitions through its four states during that period of time too. 122 | void updateModulePositions() { 123 | // TODO things are wrong 124 | if (_controller.isCompleted) { 125 | int oldState = curState; 126 | curState = (curState + 1) % 4; 127 | int nextIter = (curState == 0 && oldState == 3) ? 1 : 0; 128 | for (int i = 0; i < modulePositions.length; i++) { 129 | modulePositions[i][0] += 130 | widget.modulePositionStateChange[curState][i][0] - nextIter; 131 | modulePositions[i][1] += 132 | widget.modulePositionStateChange[curState][i][1] - nextIter; 133 | } 134 | _controller.reset(); 135 | _controller.forward(); 136 | } 137 | } 138 | 139 | @override 140 | Widget build(BuildContext context) { 141 | return Column( 142 | children: [ 143 | AnimatedBuilder( 144 | animation: _controller, 145 | builder: (context, child) { 146 | double gliderOffTrue = 147 | gliderOffInit - gliderOff.value - curState * moduleSize / 4; 148 | return Container( 149 | width: widget.gliderSize, 150 | height: widget.gliderSize, 151 | child: Stack( 152 | children: [ 153 | Positioned( 154 | left: modulePositions[0][0] * moduleSize + gliderOffTrue, 155 | top: modulePositions[0][1] * moduleSize + gliderOffTrue, 156 | child: module, 157 | ), 158 | Positioned( 159 | left: modulePositions[1][0] * moduleSize + gliderOffTrue, 160 | top: modulePositions[1][1] * moduleSize + gliderOffTrue, 161 | child: module, 162 | ), 163 | Positioned( 164 | left: modulePositions[2][0] * moduleSize + gliderOffTrue, 165 | top: modulePositions[2][1] * moduleSize + gliderOffTrue, 166 | child: module, 167 | ), 168 | Positioned( 169 | left: modulePositions[3][0] * moduleSize + gliderOffTrue, 170 | top: modulePositions[3][1] * moduleSize + gliderOffTrue, 171 | child: module, 172 | ), 173 | Positioned( 174 | left: modulePositions[4][0] * moduleSize + gliderOffTrue, 175 | top: modulePositions[4][1] * moduleSize + gliderOffTrue, 176 | child: module, 177 | ), 178 | ], 179 | ), 180 | ); 181 | }, 182 | ), 183 | IconButton( 184 | iconSize: 40, 185 | icon: Icon( 186 | _controller.isAnimating 187 | ? Icons.pause_circle_outline 188 | : Icons.play_circle_outline, 189 | color: golColor, 190 | ), 191 | onPressed: () { 192 | if (_controller.isAnimating) { 193 | setState(() { 194 | _controller.stop(); 195 | }); 196 | } else { 197 | setState(() { 198 | _controller.forward(); 199 | }); 200 | } 201 | }, 202 | ), 203 | ], 204 | ); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /lib/widgets/user_widgets/daseed/widgets/my_profile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | class MyProfile extends StatefulWidget { 5 | @override 6 | _MyProfileState createState() => _MyProfileState(); 7 | } 8 | 9 | class _MyProfileState extends State { 10 | // Those values are used to animate the text card 11 | double opacity = 1.0; 12 | double height = 195.0; 13 | // This variable is used to test if the text card 14 | int textNumber = 0; 15 | static final String _textZero = 16 | "After spending 12 years in the professional audio universe, I made a conversion to the world of software development. \r\n \r\nBeing a boardgame geek made me a problem solver, I think that's why I love code so much. \r\nI really see it has problems to solve to win the game. \r\n \r\nWhich is fun as life can be !"; 17 | static final String _textOne = 18 | 'In my free time my main passions are boardgames, playing music, creating music, developing with Flutter, and of course spending time with my loved family.'; 19 | static final String _textTwo = 20 | 'My projects are to become a better developer, help my son to grow the best way will fit him, and love my wife as much as I can.\r\nOf course all of this without forgetting my friends and family.'; 21 | var texts = [_textZero, _textOne, _textTwo]; 22 | final TextEditingController _textController = TextEditingController(); 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | _textController.text = texts[textNumber]; 27 | final size = MediaQuery.of(context).size; 28 | return Expanded( 29 | flex: 1, 30 | child: Container( 31 | width: size.width * 0.95, 32 | height: size.height * 0.6, 33 | child: Stack(children: [ 34 | Column( 35 | children: [ 36 | SizedBox( 37 | height: 130, 38 | ), 39 | Expanded( 40 | flex: 1, 41 | child: SingleChildScrollView( 42 | child: Column( 43 | children: [ 44 | Card( 45 | margin: EdgeInsets.only(left: 16.0, right: 16.0), 46 | elevation: 10.0, 47 | child: Padding( 48 | padding: const EdgeInsets.all(8.0), 49 | child: AnimatedContainer( 50 | duration: const Duration(milliseconds: 400), 51 | curve: Curves.easeInOut, 52 | height: height, 53 | child: AnimatedOpacity( 54 | duration: const Duration(milliseconds: 500), 55 | curve: Curves.easeInOut, 56 | opacity: opacity, 57 | child: Text( 58 | _textController.text, 59 | textAlign: TextAlign.center, 60 | style: TextStyle(fontWeight: FontWeight.bold), 61 | ), 62 | ), 63 | ), 64 | ), 65 | ), 66 | SizedBox( 67 | height: 10.0, 68 | ), 69 | ], 70 | ), 71 | ), 72 | ), 73 | ], 74 | ), 75 | Positioned( 76 | top: 0, 77 | left: 0, 78 | child: Column( 79 | children: [ 80 | Card( 81 | margin: EdgeInsets.only(left: 16.0, right: 16.0), 82 | elevation: 10.0, 83 | child: Padding( 84 | padding: const EdgeInsets.all(8.0), 85 | child: Text( 86 | 'Pierre-emmanuel Legrain\r\n.NET Software Engineer & Flutter maniac', 87 | textAlign: TextAlign.center, 88 | style: TextStyle(fontWeight: FontWeight.bold), 89 | ), 90 | ), 91 | ), 92 | SizedBox( 93 | height: 10.0, 94 | ), 95 | Card( 96 | margin: EdgeInsets.only(left: 16.0, right: 16.0), 97 | child: Padding( 98 | padding: const EdgeInsets.only( 99 | top: 8.0, 100 | bottom: 8.0, 101 | ), 102 | child: Container( 103 | width: (size.width * 0.95) - 32, 104 | child: Row( 105 | mainAxisAlignment: MainAxisAlignment.spaceAround, 106 | children: [ 107 | IconButton( 108 | icon: Icon(Icons.backpack), 109 | onPressed: () async { 110 | if (textNumber != 0) { 111 | setState(() { 112 | opacity = 0.0; 113 | }); 114 | await Future.delayed( 115 | const Duration(milliseconds: 500)); 116 | setState(() { 117 | height = 195.0; 118 | opacity = 1.0; 119 | }); 120 | textNumber = 0; 121 | } 122 | }), 123 | IconButton( 124 | icon: Icon(Icons.casino), 125 | onPressed: () async { 126 | if (textNumber != 1) { 127 | setState(() { 128 | opacity = 0.0; 129 | }); 130 | await Future.delayed( 131 | const Duration(milliseconds: 500)); 132 | setState(() { 133 | height = 80.0; 134 | opacity = 1.0; 135 | }); 136 | } 137 | textNumber = 1; 138 | }), 139 | IconButton( 140 | icon: Icon(Icons.dashboard), 141 | onPressed: () async { 142 | if (textNumber != 2) { 143 | setState(() { 144 | opacity = 0.0; 145 | }); 146 | await Future.delayed( 147 | const Duration(milliseconds: 500)); 148 | setState(() { 149 | height = 100.0; 150 | opacity = 1.0; 151 | }); 152 | textNumber = 2; 153 | } 154 | }, 155 | ), 156 | ], 157 | ), 158 | ), 159 | ), 160 | ), 161 | ], 162 | ), 163 | ), 164 | ]), 165 | ), 166 | ); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /lib/modules/screens/schedule_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter_buddies/data/models/event.dart'; 4 | import 'package:flutter_buddies/data/repositories/event_repository.dart'; 5 | import 'package:flutter_buddies/widgets/app_bar_icon.dart'; 6 | import 'package:flutter_buddies/widgets/event_card.dart'; 7 | import 'package:url_launcher/url_launcher.dart'; 8 | 9 | class ScheduleScreen extends StatelessWidget { 10 | final EventRepository _eventRepository = EventRepository.get(); 11 | final String pageName = 'Upcoming Events'; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | body: AnnotatedRegion( 17 | value: SystemUiOverlayStyle.light, 18 | child: CustomScrollView( 19 | slivers: [ 20 | SliverAppBar( 21 | backgroundColor: Colors.white10, 22 | leading: GestureDetector( 23 | onTap: () { 24 | Navigator.pop(context); 25 | }, 26 | child: Image( 27 | image: AssetImage('assets/global_images/flutterbuddies.png'), 28 | ), 29 | ), 30 | centerTitle: true, 31 | title: Text( 32 | pageName, 33 | style: TextStyle(color: Colors.black, fontSize: 24), 34 | ), 35 | bottom: PreferredSize( 36 | preferredSize: Size(double.infinity, 80), 37 | child: Padding( 38 | padding: const EdgeInsets.all(8.0), 39 | child: Row( 40 | crossAxisAlignment: CrossAxisAlignment.center, 41 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 42 | children: [ 43 | AppBarIcon( 44 | iconImage: AssetImage( 45 | 'assets/global_images/Discord-Logo-Shadowed.png'), 46 | iconText: 'Discord', 47 | iconColor: Color(0xff8C9EFF), 48 | iconFunction: () async { 49 | await launch('http://flutterbuddies.com'); 50 | }, 51 | ), 52 | AppBarIcon( 53 | iconImage: AssetImage( 54 | 'assets/global_images/Twitter-Logo-Shadowed.png'), 55 | iconText: 'Twitter', 56 | iconColor: Color(0xff00A2F5), 57 | iconFunction: () async { 58 | await launch('https://twitter.com/Flutter_Buddies'); 59 | }, 60 | ), 61 | AppBarIcon( 62 | iconImage: AssetImage( 63 | 'assets/global_images/YouTube-Logo-Shadowed.png'), 64 | iconText: 'YouTube', 65 | iconColor: Color(0xffFF0000), 66 | iconFunction: () async { 67 | await launch( 68 | 'https://www.youtube.com/channel/UCxBpCSJUJFj26S-4KwNNR1w'); 69 | }, 70 | ), 71 | AppBarIcon( 72 | iconImage: AssetImage( 73 | 'assets/global_images/Website-Logo-Shadowed.png'), 74 | iconText: 'Website', 75 | iconColor: Color(0xff2771BB), 76 | iconFunction: () async { 77 | await launch( 78 | 'https://github.com/Flutter-Buddies/README'); 79 | }, 80 | ), 81 | ], 82 | ), 83 | ), 84 | ), 85 | ), 86 | SliverList( 87 | delegate: SliverChildListDelegate( 88 | [ 89 | Padding( 90 | padding: const EdgeInsets.all(16.0), 91 | child: GestureDetector( 92 | onTap: () { 93 | Navigator.pop(context); 94 | }, 95 | child: Row( 96 | crossAxisAlignment: CrossAxisAlignment.center, 97 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 98 | children: [ 99 | Container( 100 | child: Row( 101 | children: [ 102 | Text( 103 | '< ', 104 | style: TextStyle( 105 | fontWeight: FontWeight.bold, 106 | fontSize: 18), 107 | ), 108 | Icon(Icons.calendar_today), 109 | SizedBox( 110 | width: 4, 111 | ), 112 | Text( 113 | 'Schedule of Events', 114 | style: TextStyle( 115 | fontWeight: FontWeight.bold, 116 | fontSize: 18), 117 | ), 118 | ], 119 | ), 120 | ), 121 | ], 122 | ), 123 | ), 124 | ), 125 | FutureBuilder>( 126 | future: _eventRepository.take(14), 127 | builder: (context, snapshot) { 128 | if (snapshot.hasData) { 129 | return GridView.count( 130 | // Shrink wrap tells the grid view to let the children define the size 131 | shrinkWrap: true, 132 | padding: EdgeInsets.symmetric(horizontal: 16), 133 | mainAxisSpacing: 16, 134 | crossAxisSpacing: 16, 135 | // Setting to none so that the shadow isn't clipped 136 | clipBehavior: Clip.none, 137 | childAspectRatio: 1.50, 138 | crossAxisCount: 2, 139 | physics: NeverScrollableScrollPhysics(), 140 | children: snapshot.data 141 | .map((event) => EventCard( 142 | eventName: event.name, 143 | eventImage: AssetImage( 144 | 'assets/global_images/Event_Image.png'), // Use generic image 145 | eventDateTime: event.dateTime, 146 | )) 147 | .toList(), 148 | ); 149 | } else { 150 | return SizedBox( 151 | height: 240, 152 | child: Center( 153 | child: CircularProgressIndicator(), 154 | ), 155 | ); 156 | } 157 | }, 158 | ), 159 | SizedBox( 160 | height: 8.0, 161 | ), 162 | ], 163 | ), 164 | ), 165 | ], 166 | ), 167 | ), 168 | ); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /lib/modules/screens/user_widgets_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_buddies/constants/app_constants.dart'; 3 | 4 | import '../../widgets/user_widgets/user_widgets.dart'; 5 | 6 | //TODO: Test 7 | 8 | class UserWidgetsScreen extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | //debugPrint(widgetInfoList.toString()); 12 | // Removed SafeArea because on iOS it's not needed as long as you have an AppBar 13 | return Scaffold( 14 | appBar: AppBar( 15 | backgroundColor: kDarkBlue, 16 | title: Text('Developer Widgets'), 17 | actions: [ 18 | IconButton( 19 | icon: Icon(Icons.search), 20 | onPressed: () { 21 | showSearch( 22 | context: context, 23 | delegate: CustomSearchDelegate(), 24 | ); 25 | }, 26 | ), 27 | ], 28 | ), 29 | body: ListView.builder( 30 | itemCount: widgetInfoList.length, 31 | itemBuilder: (context, index) { 32 | return InkWell( 33 | splashColor: Colors.transparent, 34 | onTap: () { 35 | Navigator.push( 36 | context, 37 | MaterialPageRoute( 38 | builder: (context) => widgetInfoList[index].widget, 39 | ), 40 | ); 41 | }, 42 | child: DeveloperCard( 43 | developerName: widgetInfoList[index].developer, 44 | developerDescription: widgetInfoList[index].description, 45 | ), 46 | ); 47 | }, 48 | ), 49 | ); 50 | } 51 | } 52 | 53 | // Mostly just followed this article: https://medium.com/codechai/implementing-search-in-flutter-17dc5aa72018 54 | class CustomSearchDelegate extends SearchDelegate { 55 | @override 56 | List buildActions(BuildContext context) { 57 | return [ 58 | IconButton( 59 | icon: Icon(Icons.clear), 60 | onPressed: () { 61 | query = ''; 62 | }, 63 | ), 64 | ]; 65 | } 66 | 67 | @override 68 | Widget buildLeading(BuildContext context) { 69 | return IconButton( 70 | icon: Icon(Icons.arrow_back), 71 | onPressed: () { 72 | close(context, null); 73 | }, 74 | ); 75 | } 76 | 77 | // Called when the user presses search/enter on keyboard 78 | @override 79 | Widget buildResults(BuildContext context) { 80 | // query is a built in getter of [SearchDelegate] 81 | List filteredList = widgetInfoList 82 | .where((object) => 83 | object.developer.toLowerCase().contains(query.toLowerCase())) 84 | .toList(); 85 | 86 | if (filteredList.isEmpty) { 87 | return Center(child: Text('No results found :(')); 88 | } 89 | return ListView.builder( 90 | itemCount: filteredList.length, 91 | itemBuilder: (context, index) { 92 | return InkWell( 93 | onTap: () { 94 | Navigator.push( 95 | context, 96 | MaterialPageRoute( 97 | builder: (context) => filteredList[index].widget, 98 | ), 99 | ); 100 | }, 101 | child: ListTile( 102 | title: Text(filteredList[index].developer), 103 | ), 104 | ); 105 | }, 106 | ); 107 | } 108 | 109 | @override 110 | Widget buildSuggestions(BuildContext context) { 111 | // This is where the suggestions are built 112 | return Column(); 113 | } 114 | 115 | @override 116 | ThemeData appBarTheme(BuildContext context) { 117 | assert(context != null); 118 | final ThemeData theme = Theme.of(context); 119 | assert(theme != null); 120 | return theme.copyWith( 121 | primaryColor: kDarkBlue, 122 | primaryIconTheme: theme.primaryIconTheme.copyWith(color: Colors.white), 123 | primaryColorBrightness: Brightness.dark, 124 | // primaryTextTheme: theme.textTheme, 125 | textTheme: Theme.of(context).textTheme.apply( 126 | bodyColor: Colors.white, 127 | displayColor: Colors.white, 128 | ), 129 | // Can't find a way to change the hint text colour to white :( 130 | ); 131 | } 132 | } 133 | 134 | class DeveloperCard extends StatelessWidget { 135 | final String developerName; 136 | final String developerDescription; 137 | DeveloperCard({this.developerName, this.developerDescription}); 138 | @override 139 | Widget build(BuildContext context) { 140 | return Container( 141 | // Sets the overall height of the 'card' 142 | height: 130, 143 | margin: EdgeInsets.symmetric(horizontal: 24, vertical: 16), 144 | // Stacks the 2 painters, and the body text 145 | // The developer name is part of the top custom painter widget to make alignment easier 146 | // Stacks render bottom to top 147 | child: Stack( 148 | children: [ 149 | RotatedBox( 150 | quarterTurns: 1, 151 | child: SizedBox( 152 | height: 40, 153 | // Fill the width of the container 154 | width: double.infinity, 155 | child: CustomPaint( 156 | painter: AngledLine(shapeColor: kDarkBlue, version: 'Side'), 157 | ), 158 | ), 159 | ), 160 | SizedBox( 161 | height: 40, 162 | width: double.infinity, 163 | child: CustomPaint( 164 | painter: AngledLine( 165 | shapeColor: kBlue.withOpacity(0.8), 166 | version: 'Top', 167 | ), 168 | child: Align( 169 | alignment: Alignment.centerLeft, 170 | child: Padding( 171 | padding: const EdgeInsets.only(left: 50), 172 | child: Row( 173 | children: [ 174 | Text( 175 | developerName, 176 | style: TextStyle( 177 | color: kVeryDarkBlue, 178 | fontSize: 18, 179 | fontWeight: FontWeight.bold), 180 | ), 181 | Icon(Icons.chevron_right), 182 | ], 183 | ), 184 | ), 185 | ), 186 | ), 187 | ), 188 | Padding( 189 | padding: const EdgeInsets.only(left: 50, top: 45, right: 45), 190 | child: Text( 191 | developerDescription, 192 | maxLines: 3, 193 | overflow: TextOverflow.ellipsis, 194 | style: 195 | TextStyle(color: kVeryDarkBlue, fontWeight: FontWeight.w500), 196 | ), 197 | ), 198 | ], 199 | ), 200 | ); 201 | } 202 | } 203 | 204 | class AngledLine extends CustomPainter { 205 | final Color shapeColor; 206 | // Version can either be 'Side' or 'Top' 207 | final String version; 208 | 209 | AngledLine({this.shapeColor, this.version}); 210 | @override 211 | void paint(Canvas canvas, Size size) { 212 | // Initialise the painter 213 | final paint = Paint(); 214 | 215 | // Set the colour of the painter 216 | paint.color = shapeColor; 217 | 218 | // Initialise the path 219 | var path = Path(); 220 | 221 | // Draw the outline of the shape 222 | path.lineTo(0, size.height); 223 | path.lineTo(size.width, size.height); 224 | // Change the 'angle' depending on what side the shape is drawn 225 | path.lineTo(size.width - (version == 'Top' ? 45 : 25), 0); 226 | path.close(); 227 | 228 | // Tell the canvas to draw the path 229 | canvas.drawPath(path, paint); 230 | } 231 | 232 | @override 233 | bool shouldRepaint(covariant CustomPainter oldDelegate) { 234 | return false; 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /lib/modules/screens/projects_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter_buddies/data/models/project.dart'; 4 | import 'package:flutter_buddies/data/repositories/project_repository.dart'; 5 | import 'package:flutter_buddies/widgets/app_bar_icon.dart'; 6 | import 'package:flutter_buddies/widgets/project_card.dart'; 7 | import 'package:url_launcher/url_launcher.dart'; 8 | 9 | class ProjectsScreen extends StatelessWidget { 10 | final ProjectRepository _projectRepository = ProjectRepository.get(); 11 | final String pageName = 'Group Projects'; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Scaffold( 16 | body: AnnotatedRegion( 17 | //! this should change the notification area text to black but it isn't 18 | value: SystemUiOverlayStyle.light, 19 | child: CustomScrollView( 20 | slivers: [ 21 | SliverAppBar( 22 | backgroundColor: Colors.white10, 23 | leading: Image( 24 | image: AssetImage('assets/global_images/flutterbuddies.png'), 25 | ), 26 | centerTitle: true, 27 | title: Text( 28 | pageName, 29 | style: TextStyle(color: Colors.black, fontSize: 24), 30 | ), 31 | bottom: PreferredSize( 32 | preferredSize: Size(double.infinity, 80), 33 | child: Padding( 34 | padding: const EdgeInsets.all(8.0), 35 | child: Row( 36 | crossAxisAlignment: CrossAxisAlignment.center, 37 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 38 | children: [ 39 | AppBarIcon( 40 | iconImage: AssetImage( 41 | 'assets/global_images/Discord-Logo-Shadowed.png'), 42 | iconText: 'Discord', 43 | iconColor: Color(0xff8C9EFF), 44 | iconFunction: () async { 45 | await launch('http://flutterbuddies.com'); 46 | }, 47 | ), 48 | AppBarIcon( 49 | iconImage: AssetImage( 50 | 'assets/global_images/Twitter-Logo-Shadowed.png'), 51 | iconText: 'Twitter', 52 | iconColor: Color(0xff00A2F5), 53 | iconFunction: () async { 54 | await launch('https://twitter.com/Flutter_Buddies'); 55 | }, 56 | ), 57 | AppBarIcon( 58 | iconImage: AssetImage( 59 | 'assets/global_images/YouTube-Logo-Shadowed.png'), 60 | iconText: 'YouTube', 61 | iconColor: Color(0xffFF0000), 62 | iconFunction: () async { 63 | await launch( 64 | 'https://www.youtube.com/channel/UCxBpCSJUJFj26S-4KwNNR1w'); 65 | }, 66 | ), 67 | AppBarIcon( 68 | iconImage: AssetImage( 69 | 'assets/global_images/Website-Logo-Shadowed.png'), 70 | iconText: 'Website', 71 | iconColor: Color(0xff2771BB), 72 | iconFunction: () async { 73 | await launch( 74 | 'https://github.com/Flutter-Buddies/README'); 75 | }, 76 | ), 77 | ], 78 | ), 79 | ), 80 | ), 81 | ), 82 | SliverList( 83 | delegate: SliverChildListDelegate( 84 | [ 85 | Padding( 86 | padding: const EdgeInsets.all(16.0), 87 | child: GestureDetector( 88 | onTap: () { 89 | Navigator.pop(context); 90 | }, 91 | child: Row( 92 | crossAxisAlignment: CrossAxisAlignment.center, 93 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 94 | children: [ 95 | Container( 96 | child: Row( 97 | children: [ 98 | Text( 99 | '< ', 100 | style: TextStyle( 101 | fontWeight: FontWeight.bold, 102 | fontSize: 18), 103 | ), 104 | Icon(Icons.calendar_today), 105 | SizedBox( 106 | width: 4, 107 | ), 108 | Text( 109 | 'Group Projects', 110 | style: TextStyle( 111 | fontWeight: FontWeight.bold, 112 | fontSize: 18), 113 | ), 114 | ], 115 | ), 116 | ), 117 | GestureDetector( 118 | onTap: () async { 119 | await launch( 120 | 'https://github.com/Flutter-Buddies'); 121 | }, 122 | child: Text( 123 | 'View on Github...', 124 | style: TextStyle( 125 | color: Colors.blue, 126 | decoration: TextDecoration.underline), 127 | ), 128 | ), 129 | ], 130 | ), 131 | ), 132 | ), 133 | FutureBuilder>( 134 | future: _projectRepository.takeAll(), 135 | builder: (context, snapshot) { 136 | if (snapshot.hasData) { 137 | return Column( 138 | children: snapshot.data 139 | .map((project) => Padding( 140 | padding: const EdgeInsets.only( 141 | left: 16, right: 16, bottom: 16), 142 | child: ProjectCard( 143 | projectTitle: project.title, 144 | projectDescription: project.description, 145 | projectImageUri: project.imageUri, 146 | projectTag: project.tag, 147 | url: project.url, 148 | ), 149 | )) 150 | .toList(), 151 | ); 152 | } else { 153 | return SizedBox( 154 | height: 240, 155 | child: Center( 156 | child: CircularProgressIndicator(), 157 | ), 158 | ); 159 | } 160 | }, 161 | ), 162 | SizedBox( 163 | height: 8, 164 | ), 165 | ], 166 | ), 167 | ), 168 | ], 169 | ), 170 | ), 171 | ); 172 | } 173 | } 174 | --------------------------------------------------------------------------------