diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b43254094..ae93fcaa8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -8,8 +8,9 @@ reduce redundant work.* - [ ] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [ ] I signed the [CLA]. - [ ] I read the [Contributors Guide]. +- [ ] I have added sample code updates to the [changelog]. - [ ] I updated/added relevant documentation (doc comments with `///`). -- [ ] All existing and new tests are passing. + If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. @@ -17,4 +18,5 @@ If you need help, consider asking for advice on the #hackers-devrel channel on [ [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md -[Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md \ No newline at end of file +[Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md +[changelog]: ../CHANGELOG.md \ No newline at end of file diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index b42e880fd..b2484eaf4 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -31,7 +31,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: beta - run: ./tool/flutter_ci_script_stable.sh @@ -47,7 +47,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + # - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # with: # channel: beta # - run: ./tool/android_ci_script.sh @@ -63,7 +63,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: beta - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index eaa28cec1..76cbe1e07 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -21,7 +21,7 @@ jobs: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff - name: Init scripts run: dart pub get diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f87b47949..ba65d80a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: ${{ matrix.flutter_version }} - run: ./tool/flutter_ci_script_${{ matrix.flutter_version }}.sh @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff - run: | dart pub get dart run grinder generate @@ -57,7 +57,7 @@ jobs: # with: # distribution: 'zulu' # java-version: '17' - # - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + # - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff # with: # channel: stable # - run: ./tool/android_ci_script.sh @@ -71,7 +71,7 @@ jobs: with: distribution: 'zulu' java-version: '17' - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: stable - run: ./tool/ios_ci_script.sh diff --git a/.github/workflows/verify-web-demos.yml b/.github/workflows/verify-web-demos.yml index 3d579e468..8a1e92650 100644 --- a/.github/workflows/verify-web-demos.yml +++ b/.github/workflows/verify-web-demos.yml @@ -25,7 +25,7 @@ jobs: with: submodules: true fetch-depth: 0 - - uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 + - uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff with: channel: ${{ matrix.flutter_version }} - name: Init scripts diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..7d8e5b733 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,32 @@ +# Changelog + +The purpose of this changelog is to track the freshness of samples and which +samples reflect *current best practices*. It describes **human-made, significant +** changes made to the repository or samples in the repository. + +While all samples in this repository build and run, some of them were written +long ago, and no longer reflect what we want developers to learn. For example, +samples should have been refactored when Dart 3 released to include patterns and +records, where appropriate. + +* **DO include:** + * The addition of new samples. + * The removal of existing samples. + * Considerable refactoring of any given sample. + +* **DO NOT include:** + * Simple changes that reflect minor version bumps in Flutter. For example, + in a recent Flutter update, `Color.red` became `Color.r`. + * Dependency updates. + * Bug fixes. + * Any changes made to simply 'keep the lights on'. + +# Log + +| DATE (YYYY-MM-DD) | Sample(s) | author | Changes | +|-------------------|-------------------|--------------|-----------------------------------------------| +| NEXT GOES HERE | | | | +| | | | | +| 2024-12-04 | N/A - repo change | ericwindmill | Added changelog | +| 2024-11-27 | fake_sample | ericwindmill | Refactored fake_sample to use Dart 3 features | +| 2020-04-17 | fake_sample | ericwindmill | Created fake_sample | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a3d0b818..68fdd7e8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,46 +1,45 @@ # Contributing -_See also: [Flutter's code of conduct](https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md)_ - Want to contribute to the Flutter sample ecosystem? Great! First, read this page (including the small print at the end). -## Is this the right place for your contribution? +Do you work at Google? Great! You should **definitely** read this page before submitting a PR :) + +* [Before you contribute] +* [Contribute enhancements and fixes] +* [Write a new sample] +* [Sample checklist] + +_See also: [Flutter's code of conduct]_ + +
+ +# Before you contribute -This repo is used by members of the Flutter team and a few partners as a place -to store example apps and demos. It's not meant to be the one and only source of -truth for Flutter samples or the only place people go to learn about the best -ways to build with Flutter. What that means in practice is that if you've -written a great example app, it doesn't need to be maintained here in order to -get noticed, be of help to new Flutter devs, and have an impact on the -community. -You can maintain your sample app in your own repo (or with another source -control provider) and still be as important a part of the Flutter-verse as -anything you see here. You can let us know on the -[FlutterDev Google Group](https://groups.google.com/forum/#!forum/flutter-dev) -when you've published something and Tweet about it with the -[#FlutterDev](https://twitter.com/search?q=%23FlutterDev) hashtag. +## Is this the right place for your sample? -## So what should be contributed here, then? +In most cases, if you've written a great sample app, it should be maintained +in your own repoistory. You can maintain your sample app in your own repo +(or with another source control provider) and still be as important a part of +the Flutter-verse as anything you see here. -Fixes and necessary improvements to the existing samples, mostly. +**What should be contributed here, then?** -## Before you contribute +Fixes and necessary improvements to the existing samples, mostly. -### File an issue first! +## File an issue first! If you see a bug or have an idea for a feature that you feel would improve one -of the samples already in the repo, **please -[file an issue](https://github.com/flutter/samples/issues/new) before you begin +of the samples already in the repo, **please [file an issue] before you begin coding or send a PR**. This will help prevent duplicate work by letting us know what you're up to. It will help avoid a situation in which you spend a lot of time coding something that's not quite right for the repo or its goals. -### Sign the license agreement. +## Sign the license agreement. Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) +[Google Individual Contributor License Agreement] (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also @@ -54,47 +53,177 @@ us first through the issue tracker with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on. -## A few ground rules - -This is monorepo containing a bunch of projects. While different codebases have -different needs, there are a few basic conventions that every project here is -expected to follow. All of them are based on our experience over the last -couple years keeping the repo tidy and running smooth. - -Each app should: - -* Be designed to build against the current - [stable](https://github.com/flutter/flutter/blob/master/docs/releases/Flutter-build-release-channels.md) - release of the Flutter SDK. -* Include the top level - [`analysis_options.yaml`](analysis_options.yaml) - file used throughout the repo. This file include a base set of analyzer - conventions and lints. -* Have no analyzer errors or warnings. -* Be formatted with `dart format`. -* Include at least one working test in its `test` folder. -* Be wired into the list of projects in the CI scripts for [stable](tool/flutter_ci_script_stable.sh), - [beta](tool/flutter_ci_script_beta.sh), and [master](tool/flutter_ci_script_master.sh), - which runs the analyzer, the formatter, and `flutter test`. -* Add the new project directory to the [dependabot](.github/dependabot.yaml) configuration - to keep dependencies updated in an on-going basis. -* Avoid adding an onerous amount of blobs (typically images or other assets) to - the repo. - -In addition, sample code is, at the end of the day, still code. It should be -written with at least as much care as the Flutter code you'd find in the SDK -itself. For that reason, most of the -[Flutter style guide](https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md) -also applies to code in this repo. +
+ +# Contribute enhancements and fixes + +Enhancements and bug fixes are welcome and appreciated. +If you spot an [issue] that you might want to fix but aren't sure how to get started, +feel free to comment on the issue and tag @ericwindmill with questions. + +## Filing issues and evaluating existing samples + +You can also contribute by filing issues against existing samples. This is thankless work +and is _greatly_ appreciated. It's also a good way to familiarize yourself with the repository. + +To evaluate a sample for possible issues, use the [Sample checklist] below. + +
+ +# Writing a new sample + +Before filing an issue for a new sample or submitting a PR, you must read the rest of this page. + +## What is a sample? + +Samples are reference materials that teach developers how to solve a specific problem. +Samples contain **correct and concise code** that developers can +**quickly understand** and **easily reuse** with minimal side effects. + +### What samples should we have? + +Samples in this repo demonstrates how to **use current features** of the **Flutter and Dart SDKs** using **best practices**. +In other words, a sample should meet the following criteria: + +* Demonstrates _how to use the SDKS_ rather than show an end-product. +* Covers a critical developer journey in the SDK that is useful to >80% of developers. +* Prefers primitives in the SDK over libraries. +* Demonstrates features available on the stable channel of Flutter. + +These guidelines can be broken in rare cases. For example, this is likely the best place in the +Flutter github org for demo apps, but those demo apps must be justified. + +## Is this the right place for your sample? (revisited) + +Validate your idea against the following criteria: + +1. **The sample solves a single problem or set of tightly coupled problems.**
+ If not, you're either writing a Demo app or an extended sample. These might + still be appropriate for the samples repos, but need to be justified. + +2. **The target audience for the sample isn’t beginners.** +3. **The sample code isn’t so complex that it needs video or text explanation.**
+ Samples are reference materials, and the code should speak for itself. If either of these aren't true, + you may prefer to write a blogpost or tutorial. + +5. **The sample isn’t tied to an event.**
+ If it is, you should likely use a personal repository. + +5. **The sample isn’t tied to a library or package.**
+ If it is, the usage example should likely be in the [repository of that package]. + +6. **The topic doesn’t have crossover with any existing samples.**
+ If it does, ensure that it wouldn't be better to update the existing sample. + +## What are your ongoing maintenance resposibilities? + +All sample code has an unbound maintenance cost. If you cannot commit to maintaining a sample +(for the forseeable future, barring changes in life circumstances), then you should talk to the +[primary maintainers] of this project, particularly @ericwindmill, before submitting a PR. + +Any new sample **must** have a CODEOWNER, and that owner is most likely you (the author). + +## What type of sample are your writing? + +This repository contains two types of sample apps: **quickstarts** and **demo apps**. + +### Quickstarts + +* **Purpose**: Provides starting points that a developer can extend. + Solves specific problems or implements generic app features. +* **Size**: <= 200 lines of code, not including boiler plate (guide, not rule) +* **Qualities:** + * Contains one feature or a small set of related features, but generally runnable. + * Generic and un-opinionated about the context in which it is used. + * Prioritizes being generic over best practices. + * The code is Copy+paste-able. + * In Flutter, this means that the code that is being demonstrated should be separated from and boiler plate (i.e. `runApp`) +* **Audience:** + * Developers with Flutter and Dart experience that don't need code explained to them. +* **Answers the questions:** + * “What’s the minimal amount of code needed to implement this feature…” + * “... so I can understand how it works?” + * “... so I can understand how to add it to my app?” + * “How can I make sure I know how to extend this feature without missing anything?” + * "What code should I use as a starting point given I want to solve a very similar problem?" + +### Demo apps + +* **Purpose**: Meant to be built and ran. Demos the _product_, not how to write code. +* **Criteria**: Demo apps _only_ belong here if they... + * ...aren't tied to an event or moment in time. + * ...aren't tied to another resource (website, workshop, etc). + * ...don't require explanation (other than a short README). + * ...aren't primarily used to demonstrate an SDK feature. + +### Other sample types + +Other sample types, like demo apps that accompany docs or events, do not belong in this repository. +They should be maintained alongside the accompanying resources (i.e. in the website repository), or in a personal repository. ### The `experimental` folder -Projects in the repo's top-level `experimental` directory are allowed to skirt -some of the above rules. These apps are either experimental in nature or use -APIs that haven't landed in the SDK's `stable` channel. They build against -`main`, and aren't (by default) wired into our CI system. +The experimental folder is being deprecated. If you have an experiemental sample project, +you should manage it in a personal repository until it runs on the stable channel. + +
+ +# Sample checklist + +Every piece of code will have value to someone, but it is easy for maintenance costs to grow over time. +The more items checked on this list, the higher the value and lower the maintenance costs. + +Use this checklist to write new samples and evaluate existing ones. + +**NB:** Demo apps have looser requirements. Use your best judgement when following the guidelines. + +* Code + - [ ] Be designed to build against the current [stable] + release of the Flutter SDK. + - [ ] Sample is the only one for the API in question (across all Dash samples) + - [ ] Repository and pubspec name are titled for its ingredients (i.e. mvvm_architecture instead of compass_app) + - [ ] Only includes the minimal required code to demonstrate the feature or API and run the code. + - [ ] Sample favors 1P dependencies over 3P. + - [ ] Code has been sufficiently explained with doc comments. + - [ ] The sample app separates its bespoke code from general Flutter or Dart code. + - [ ] Favor readability over best practices unless readability requires an anti pattern. Use your best judgment. + - [ ] Avoid adding an onerous amount of blobs (typically images or other assets) to the repo. + - [ ] All files in the project must start with the appropriate [file headers]. + +* Tests, style and maintenance + - [ ] Sample has Dart tests that cover the business logic + - [ ] Sample is wired into the list of projects in the CI scripts for [stable](tool/flutter_ci_script_stable.sh), + [beta](tool/flutter_ci_script_beta.sh), and [master](tool/flutter_ci_script_master.sh), + which runs the analyzer, the formatter, and `flutter test`. + - [ ] Sample has a codeowner (it's likely you, the author) + - [ ] Sample is formatted with `dart format`. + - [ ] Sample has no analyzer errors or warnings. + - [ ] Add the new project directory to the [dependabot](.github/dependabot.yaml) configuration + to keep dependencies updated in an on-going basis. + - [ ] Follows the [Flutter style guide] + - [ ] Include the top level [`analysis_options.yaml`](analysis_options.yaml) + file used throughout the repo. This file include a base set of analyzer + conventions and lints. + +* README + - [ ] Describes the apps design and purpose. + - [ ] Describes common errors and debugging steps. + - [ ] Describes any steps necessary to build and run. + - [ ] Has ‘Open in IDX’ button, and a nix file (if compatible with IDX). + +## File headers + +All files in the project must start with the following header. + +``` +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +``` + +
-## Code reviews +# Code reviews All submissions, including submissions by project members, require review. @@ -107,7 +236,7 @@ primary maintainers, though, are: * [@domesticmouse](https://github.com/domesticmouse) * [@ericwindmill](https://github.com/ericwindmill) -You are free to add one of these folks (particularly @RedBrogdon) as a reviewer +You are free to add one of these folks (particularly @ericwindmill) as a reviewer to any PR sent to this repo. We're happy to comment, answer (or ask) questions, and provide feedback. @@ -121,18 +250,24 @@ before, or changing something that's a meta-concern like the CI setup, web hosting, project setup, etc., please include one of the primary maintainers as a reviewer. -## File headers - -All files in the project must start with the following header. - -``` -// Copyright 2024 The Flutter team. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -``` +
-## The small print +# The small print Contributions made by corporations are covered by a different agreement than the -one above, the -[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). +one above, the [Software Grant and Corporate Contributor License Agreement]. + +[Flutter's code of conduct]: https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md +[Before you contribute]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#before-you-contribute +[Contribute enhancements and fixes]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#contribute-enhancements-and-fixes +[Write a new sample]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#write-a-new-sample +[Sample checklist]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#samples-checklist +[file headers]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#file-headers +[Software Grant and Corporate Contributor License Agreement]: https://developers.google.com/open-source/cla/corporate +[issue]: https://github.com/flutter/samples/issues +[file an issue]: https://github.com/flutter/samples/issues/new +[repository of that package]: https://dart.dev/tools/pub/package-layout#examples +[stable]: https://github.com/flutter/flutter/blob/master/docs/releases/Flutter-build-release-channels.md +[Flutter style guide]: (https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md) +[Google Individual Contributor License Agreement]: https://cla.developers.google.com/about/google-individual +[primary maintainers]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.md#code-reviews diff --git a/README.md b/README.md index 854013835..b2fdcd257 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,112 @@ [![Build Status](https://github.com/flutter/samples/workflows/Main%20Branch%20CI/badge.svg)](https://github.com/flutter/samples/actions?workflow=Main%20Branch%20CI) A collection of open source samples that illustrate best practices for -[Flutter](https://flutter.dev). - -## Visual samples index - -The easiest way to browse through the samples in this repo (as well as a few others!) -is the [visual samples index](https://flutter.github.io/samples). - -## Tip: minimize download size - -As this repository is quite big, you can use svn to download a single example. +[Flutter]. + +## Index + +### Quickstarts + +* [`asset_transformation`] - Demonstrates how to transform images' color scales and formats. +* [`background_isolate_channels`] - Demonstrates how to use long-lived isolates. +* [`code_sharing`] - Demonstrates how to share business logic between Flutter client and Dart server using [`package:shelf`] ) +* [`context_menus`] - This sample shows how to create and customize cross-platform context menus, such as the text selection toolbar on mobile or the right click menu on desktop. +* [`desktop_photo_search`] - Demonstrates desktop features in both Material and FluentUI design systems. +* [`dynamic_theme`] - A developer sample demonstrating how to call on-device Flutter APIs based on output from the Gemini API. +* [`form_app`] - A sample demonstrating different types of forms and best practices. +* [`game_template`] - (**note: deprecated!**) A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game. +* [`gemini_tasks`] - A developer sample written in Flutter demonstrating how to interact with a to-do list in natural language using the Gemini API. +* [`google_maps`] - Demonstrates the Google Maps for Flutter plugin. +* [`infinite_list`] - A Flutter sample app that shows an implementation of the "infinite list" UX pattern. +* [`isolate_example`] - A sample application that demonstrate best practices when using [isolates]. +* [`navigation_and_routing`] - A sample that shows how to use [go_router] API to handle common navigation scenarios. +* [`place_tracker`] - A sample place tracking app that uses the [google_maps_flutter plugin]. +* [`platform_design`] - This sample project shows a Flutter app that maximizes application code reuse while adhering to different design patterns on Android and iOS. +* [`provider_counter`] - The starter Flutter application, but using [package:provider] to manage state. +* [`provider_shopper`] - A Flutter sample app that shows a state management approach using [package:provider]. +* [`simple_shader`] - A simple [Flutter fragment shaders] sample project. +* [`simplistic_calculator`] - A calculator to demonstrate a simple start for a desktop Flutter app. +* [`simplistic_editor`] - This sample text editor showcases the use of [TextEditingDeltas] and a DeltaTextInputClient to expand and contract styled ranges of text. +* [`testing_app`] - A sample app that shows different types of testing in Flutter. +* [`web_embedding`] - This directory contains examples of how to embed Flutter in web apps (without iframes). + * [`element_embedding_demo`] - Modifies the index.html of a flutter app so it is launched in a custom hostElement. This is the most basic embedding example. + * [`ng-flutter`] - A simple Angular app (and component) that replicates the above example, but in an Angular style. + +### Native platform samples + +* [`add-to-app`] - Collection of samples that demonstrate embedding Flutter a view into a native app. + * [`fullscreen`] — Embeds a full screen instance of + Flutter into an existing iOS or Android app. + * [`prebuilt_module`] — Embeds a full screen + instance of Flutter as a prebuilt library that can be loaded into an existing + iOS or Android app. + * [`plugin`] — Embeds a full screen Flutter instance that + is using plugins into an existing iOS or Android app. + * [`books`] — Mimics a real world use-case of embedding Flutter into an + existing Android app and demonstrates using [Pigeon] to communicate between Flutter and + the host application. + * [`multiple_flutters`] — Shows the usage of the Flutter + Engine Group APIs to embed multiple instances of Flutter into an existing app + with low memory cost. + * [`android_view`] — Shows how to integrate a Flutter + add-to-app module at a view level for Android. +* [`android_splash_screen`] +* [`ios_app_clip`] +* [`platform_channels`] - A sample app which demonstrates how to use MethodChannel, EventChannel, BasicMessageChannel and MessageCodec in Flutter. +* [`platform_view_swift`] - A Flutter sample app that combines a native iOS UIViewController with a full-screen Flutter view. + +### Demo galleries + +* [`animations`] - Showcases Flutter's animation features +* [`material_3_demo`] - showcases [Material 3] features in the Flutter Material library. + +### Demo apps + +* [`compass_app`] - A sample application that implements MVVM architecture. +* [`deeplink_store_example`] - A demo app that implements deep-linking with go_router. +* [`veggie_seasons`] - A demo application. + +## Flutter sample code + +Samples are **correct and concise code** that developers +can **quickly understand** and **easily reuse** with minimal side effects. +Samples teach developers how to be successful using Flutter and Dart. +They are maintained on an ongoing basis +to reflect changing APIs and best practices. + +### Types of samples + +There are two types of sample code in this repository: + +* **Quickstarts** provide a starting point to extend. They answer the question, + "What is the minimal amount of code needed to implement this feature?" +* **Demo apps** are meant to be built and ran. They demo the _product_, + not how to write code. + +A majority of samples in this repository are quickstarts. + +## Usage + +Every sample in this repo is fully runnable. To run an example, +use `flutter run` inside that example's directory. +See the [getting started guide] to install the `flutter` tool. + +> [!IMPORTANT] +> If you want to run an add-to-app sample, there are additional requirements. +> We suggest reading the [add-to-app documentation]. + +### Tip: minimize download size + +As this repository is quite big, you can use +[svn] to download a single example. For example: ``` svn co https://github.com/flutter/samples/trunk/provider_shopper ``` -You can also use a -[partial clone](https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/) -to skip blob objects that aren't currently checked out, -while including the full commit history: +You can also use a [partial clone] to skip blob objects +that aren't currently checked out, while including the full commit history: ``` git clone --filter=blob:none https://github.com/flutter/samples.git @@ -30,16 +116,76 @@ git clone --filter=blob:none https://github.com/flutter/samples.git ## Interested in contributing? -See the [contributor's guide](CONTRIBUTING.md)! +See the [contributor's guide]! ## Questions or issues? If you have a general question about one of these samples or how to adapt its techniques for one of your own apps, try one of these resources: -* [The FlutterDev Discord](https://discord.gg/rflutterdev) -* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter) +* [The FlutterDev Discord] +* [The Flutter Community forum] If you run into a bug in one of the samples, please file an issue in the -[`flutter/samples` issue tracker](https://github.com/flutter/samples/issues). - +[`flutter/samples` issue tracker]. + + +[`asset_transformation`]: ./asset_transformation +[`background_isolate_channels`]: ./background_isolate_channels +[`code_sharing`]: ./code_sharing +[`context_menus`]: ./context_menus +[`desktop_photo_search`]: ./desktop_photo_search +[`dynamic_theme`]: ./dynamic_theme +[`form_app`]: ./form_app +[`game_template`]: ./game_template +[`gemini_tasks`]: ./gemini_tasks +[`google_maps`]: ./google_maps +[`infinite_list`]: ./infinite_list +[`isolate_example`]: ./isolate_example +[`navigation_and_routing`]: ./navigation_and_routing +[`place_tracker`]: ./place_tracker +[`platform_design`]: ./platform_design +[`provider_counter`]: ./provider_counter +[`provider_shopper`]: ./provider_shopper +[`simple_shader`]: ./simple_shader +[`simplistic_calculator`]: ./simplistic_calculator +[`simplistic_editor`]: ./simplistic_editor +[`testing_app`]: ./testing_app +[`web_embedding`]: ./web_embedding +[`element_embedding_demo`]: ./web_embedding/element_embedding_demo +[`ng-flutter`]: ./web_embedding/ng-flutter +[`add-to-app`]: ./add_to_app +[`fullscreen`]: ./add_to_app/fullscreen +[`prebuilt_module`]: ./add_to_app/prebuilt_module +[`plugin`]: ./add_to_app/plugin +[`books`]: ./add_to_app/books +[`multiple_flutters`]: ./add_to_app/multiple_flutters +[`android_view`]: ./add_to_app/android_view +[`android_splash_screen`]: ./android_splash_screen +[`ios_app_clip`]: ./ios_app_clip +[`platform_channels`]: ./platform_channels +[`platform_view_swift`]: ./platform_view_swift +[`animations`]: ./animations +[`material_3_demo`]: ./material_3_demo +[`compass_app`]: ./compass_app +[`deeplink_store_example`]: ./deeplink_store_example +[`veggie_seasons`]: ./veggieseasons + +[Flutter]: https://flutter.dev +[getting started guide]: https://docs.flutter.dev/get-started/install +[add-to-app documentation]: https://docs.flutter.dev/add-to-app +[isolates]: https://api.dart.dev/dart-isolate/Isolate-class.html +[Material 3]: https://m3.material.io +[go_router]: https://pub.dev/packages/go_router +[google_maps_flutter plugin]: https://github.com/flutter/plugins/tree/master/packages/google_maps_flutter +[package:provider]: https://pub.dev/packages/provider +[Flutter fragment shaders]: https://docs.flutter.dev/development/ui/advanced/shaders +[TextEditingDeltas]: https://api.flutter.dev/flutter/services/TextEditingDelta-class.html +[Pigeon]: https://pub.dev/packages/pigeon +[`package:shelf`]: https://pub.dev/packages/shelf +[svn]: https://subversion.apache.org/ +[partial clone]: https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/ +[contributing guide]: CONTRIBUTING.md +[The FlutterDev Discord]: https://discord.gg/rflutterdev +[The Flutter Community forum]: https://forum.itsallwidgets.com/latest +[`flutter/samples` issue tracker]: https://github.com/flutter/samples/issues diff --git a/ai_recipe_generation/.gitignore b/ai_recipe_generation/.gitignore deleted file mode 100644 index 86e0c2c5c..000000000 --- a/ai_recipe_generation/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ -.env - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.pub-cache/ -.pub/ -/build/ - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/ai_recipe_generation/.metadata b/ai_recipe_generation/.metadata deleted file mode 100644 index ff2d6f151..000000000 --- a/ai_recipe_generation/.metadata +++ /dev/null @@ -1,45 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: "2e9cb0aa71a386a91f73f7088d115c0d96654829" - channel: "stable" - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: android - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: ios - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: linux - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: macos - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: web - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - platform: windows - create_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - base_revision: 2e9cb0aa71a386a91f73f7088d115c0d96654829 - - # User provided section - - # List of Local paths (relative to this file) that should be - # ignored by the migrate tool. - # - # Files that are not part of the templates will be ignored by default. - unmanaged_files: - - 'lib/main.dart' - - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ai_recipe_generation/README.md b/ai_recipe_generation/README.md index ca96ee952..1336a6878 100644 --- a/ai_recipe_generation/README.md +++ b/ai_recipe_generation/README.md @@ -1,17 +1,16 @@ -This is a demo app created for the Google I/O talk "Gemini API and Flutter: Practical, AI-driven apps with Google AI tools" +# Sample retired -Check out the [the prompt we used on Google AI Studio](https://aistudio.google.com/app/prompts/1RsTAt6_N8BPhXbrrd8gSJcdeuYV834kf). +The `ai_recipe_generation` sample has been retired. -## Running the app +The sample was written for an event (Google IO 2024). Per our policies, +we don't maintain samples that are tied to events. -Before running the app: -* Get an API key from [ai.google.dev](ai.google.dev). -* Create a Firebase project, and install the Flutter Firebase CLI, and configure the platforms that you want to run this app on. You can find instructions by following [steps 2-4 of the Get to know Firebase for Flutter](https://firebase.google.com/codelabs/firebase-get-to-know-flutter?hl=en#2) codelab. +This sample has been copied to [another repository](https://github.com/ericwindmill/gemini_recipe_generation). It will not be updated to reflect changes to Gemini. -Then, pass the API key in with dart define when running the app: - -```bash -flutter run --dart-define=API_KEY=your_api_key -``` +## Other Gemini resources +The following resources can assist you in integrating Gemini with Flutter: +* [gemini_tasks sample](https://github.com/flutter/samples/tree/main/gemini_tasks) is a Gemini sample in this repository. +* [google_generative_ai package](https://pub.dev/packages/google_generative_ai) is the package that Flutter apps use to integrate with gemini, and it has additional samples. +* The [google-gemini github](https://github.com/google-gemini) has additional Flutter samples. \ No newline at end of file diff --git a/ai_recipe_generation/analysis_options.yaml b/ai_recipe_generation/analysis_options.yaml deleted file mode 100644 index 1b30f7553..000000000 --- a/ai_recipe_generation/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -include: package:analysis_defaults/flutter.yaml \ No newline at end of file diff --git a/ai_recipe_generation/android/.gitignore b/ai_recipe_generation/android/.gitignore deleted file mode 100644 index 6f568019d..000000000 --- a/ai_recipe_generation/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/ai_recipe_generation/android/app/build.gradle b/ai_recipe_generation/android/app/build.gradle deleted file mode 100644 index 1d7d65b8b..000000000 --- a/ai_recipe_generation/android/app/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -android { - namespace "com.example.gemini_io_talk" - compileSdkVersion flutter.compileSdkVersion - ndkVersion flutter.ndkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.gemini_io_talk" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies {} diff --git a/ai_recipe_generation/android/app/google-services.json b/ai_recipe_generation/android/app/google-services.json deleted file mode 100644 index 3cf8eab78..000000000 --- a/ai_recipe_generation/android/app/google-services.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "project_info": { - "project_number": "44885228795", - "project_id": "gemini-cat-chef", - "storage_bucket": "gemini-cat-chef.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:44885228795:android:d1ed69a5c617a8b98f845e", - "android_client_info": { - "package_name": "com.example.gemini_io_talk" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyANxBBzc4s-Yuol0xqs-mEtXe-pNcut3OU" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml b/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 399f6981d..000000000 --- a/ai_recipe_generation/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/ai_recipe_generation/android/app/src/main/AndroidManifest.xml b/ai_recipe_generation/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index b8d463506..000000000 --- a/ai_recipe_generation/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt b/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt deleted file mode 100644 index 3df14b9aa..000000000 --- a/ai_recipe_generation/android/app/src/main/kotlin/com/example/gemini_io_talk/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.gemini_io_talk - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml b/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f3f..000000000 --- a/ai_recipe_generation/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml b/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f88..000000000 --- a/ai_recipe_generation/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7..000000000 Binary files a/ai_recipe_generation/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79b..000000000 Binary files a/ai_recipe_generation/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d439148..000000000 Binary files a/ai_recipe_generation/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34..000000000 Binary files a/ai_recipe_generation/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eeb..000000000 Binary files a/ai_recipe_generation/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml b/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 06952be74..000000000 --- a/ai_recipe_generation/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/android/app/src/main/res/values/styles.xml b/ai_recipe_generation/android/app/src/main/res/values/styles.xml deleted file mode 100644 index cb1ef8805..000000000 --- a/ai_recipe_generation/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml b/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 399f6981d..000000000 --- a/ai_recipe_generation/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/ai_recipe_generation/android/build.gradle b/ai_recipe_generation/android/build.gradle deleted file mode 100644 index e83fb5dac..000000000 --- a/ai_recipe_generation/android/build.gradle +++ /dev/null @@ -1,30 +0,0 @@ -buildscript { - ext.kotlin_version = '1.7.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -tasks.register("clean", Delete) { - delete rootProject.buildDir -} diff --git a/ai_recipe_generation/android/gradle.properties b/ai_recipe_generation/android/gradle.properties deleted file mode 100644 index 598d13fee..000000000 --- a/ai_recipe_generation/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx4G -android.useAndroidX=true -android.enableJetifier=true diff --git a/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties b/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3c472b99c..000000000 --- a/ai_recipe_generation/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/ai_recipe_generation/android/settings.gradle b/ai_recipe_generation/android/settings.gradle deleted file mode 100644 index 7cd712855..000000000 --- a/ai_recipe_generation/android/settings.gradle +++ /dev/null @@ -1,29 +0,0 @@ -pluginManagement { - def flutterSdkPath = { - def properties = new Properties() - file("local.properties").withInputStream { properties.load(it) } - def flutterSdkPath = properties.getProperty("flutter.sdk") - assert flutterSdkPath != null, "flutter.sdk not set in local.properties" - return flutterSdkPath - } - settings.ext.flutterSdkPath = flutterSdkPath() - - includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } - - plugins { - id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false -} - -include ":app" diff --git a/ai_recipe_generation/assets/chef_cat.svg b/ai_recipe_generation/assets/chef_cat.svg deleted file mode 100644 index 2e579bcbe..000000000 --- a/ai_recipe_generation/assets/chef_cat.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/assets/fridge_test_image.jpeg b/ai_recipe_generation/assets/fridge_test_image.jpeg deleted file mode 100644 index 6fd02efe0..000000000 Binary files a/ai_recipe_generation/assets/fridge_test_image.jpeg and /dev/null differ diff --git a/ai_recipe_generation/assets/user_icon.svg b/ai_recipe_generation/assets/user_icon.svg deleted file mode 100644 index 6a76c6f67..000000000 --- a/ai_recipe_generation/assets/user_icon.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/.gitignore b/ai_recipe_generation/ios/.gitignore deleted file mode 100644 index 7a7f9873a..000000000 --- a/ai_recipe_generation/ios/.gitignore +++ /dev/null @@ -1,34 +0,0 @@ -**/dgph -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/ephemeral/ -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist b/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 7c5696400..000000000 --- a/ai_recipe_generation/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 12.0 - - diff --git a/ai_recipe_generation/ios/Flutter/Debug.xcconfig b/ai_recipe_generation/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6f3..000000000 --- a/ai_recipe_generation/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/ai_recipe_generation/ios/Flutter/Release.xcconfig b/ai_recipe_generation/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bfe2..000000000 --- a/ai_recipe_generation/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/ai_recipe_generation/ios/Podfile b/ai_recipe_generation/ios/Podfile deleted file mode 100644 index d97f17e22..000000000 --- a/ai_recipe_generation/ios/Podfile +++ /dev/null @@ -1,44 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '12.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj b/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 9f8fe71ca..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,728 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 6CEAC1BB3402D2FB3D949175 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - D176046199A01D7761A9B663 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */; }; - EC8FDDE32B650F9294E84E49 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 560968E9DE345774409B17C1 /* Pods_Runner.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 97C146E61CF9000F007C117D /* Project object */; - proxyType = 1; - remoteGlobalIDString = 97C146ED1CF9000F007C117D; - remoteInfo = Runner; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 560968E9DE345774409B17C1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 8AC0061116C886C86A9B5490 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - 8C41D0F2AC811E3A0FF6FC41 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - D397ABCFD4CECC2D1C87B0F5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 3C97DB56F9108CED1F143C54 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D176046199A01D7761A9B663 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EC8FDDE32B650F9294E84E49 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C8082294A63A400263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C807B294A618700263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 4DC0F3FBD4704312B8DDA602 /* Pods */ = { - isa = PBXGroup; - children = ( - D397ABCFD4CECC2D1C87B0F5 /* Pods-Runner.debug.xcconfig */, - 8AC0061116C886C86A9B5490 /* Pods-Runner.release.xcconfig */, - 8C41D0F2AC811E3A0FF6FC41 /* Pods-Runner.profile.xcconfig */, - 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */, - 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */, - CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - 774D05E8B814CE61D1EBF4C8 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 560968E9DE345774409B17C1 /* Pods_Runner.framework */, - 55AAE8E90222A83A2A3C5725 /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - 331C8082294A63A400263BE5 /* RunnerTests */, - 4DC0F3FBD4704312B8DDA602 /* Pods */, - 774D05E8B814CE61D1EBF4C8 /* Frameworks */, - 3AEDF9CC1F2478538C36F4EC /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - 331C8081294A63A400263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C8080294A63A400263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - 825D4F9DB9CE5CD128B67AF7 /* [CP] Check Pods Manifest.lock */, - 331C807D294A63A400263BE5 /* Sources */, - 331C807F294A63A400263BE5 /* Resources */, - 3C97DB56F9108CED1F143C54 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 331C8086294A63A400263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9B274ACE53869D8B50572937 /* [CP] Check Pods Manifest.lock */, - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 04F3356025EB4C21B4C3E754 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C8080294A63A400263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 97C146ED1CF9000F007C117D; - }; - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - 331C8080294A63A400263BE5 /* RunnerTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C807F294A63A400263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - 6CEAC1BB3402D2FB3D949175 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 04F3356025EB4C21B4C3E754 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 825D4F9DB9CE5CD128B67AF7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; - 9B274ACE53869D8B50572937 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C807D294A63A400263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 97C146ED1CF9000F007C117D /* Runner */; - targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 331C8088294A63A400263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 26885269168D3B8FD1AC5E99 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Debug; - }; - 331C8089294A63A400263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 6E452F04B76B6311A2D269D2 /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Release; - }; - 331C808A294A63A400263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = CE028EB35B4B427E70F8476C /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 2UUT9AMTS2; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C8088294A63A400263BE5 /* Debug */, - 331C8089294A63A400263BE5 /* Release */, - 331C808A294A63A400263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a62..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5e..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 8e3ca5dfe..000000000 --- a/ai_recipe_generation/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c5e..000000000 --- a/ai_recipe_generation/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/ai_recipe_generation/ios/Runner/AppDelegate.swift b/ai_recipe_generation/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4a8..000000000 --- a/ai_recipe_generation/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada472..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 7353c41ec..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 797d452e4..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index 6ed2d933e..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cd7b0099..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index fe730945a..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index 321773cd8..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 797d452e4..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index 502f463a9..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index 0ec303439..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index 0ec303439..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index e9f5fea27..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index 84ac32ae7..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 8953cba09..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index 0467bf12a..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2fd..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b7..000000000 --- a/ai_recipe_generation/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -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. \ No newline at end of file diff --git a/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c..000000000 --- a/ai_recipe_generation/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard b/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516f..000000000 --- a/ai_recipe_generation/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/ios/Runner/GoogleService-Info.plist b/ai_recipe_generation/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index a22623df5..000000000 --- a/ai_recipe_generation/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - API_KEY - AIzaSyBNEtAHdjm3oFV6JZ6nbx5t6Pfyj4w4hbo - GCM_SENDER_ID - 44885228795 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.geminiIoTalk - PROJECT_ID - gemini-cat-chef - STORAGE_BUCKET - gemini-cat-chef.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:44885228795:ios:8ef52eb95f012a148f845e - - \ No newline at end of file diff --git a/ai_recipe_generation/ios/Runner/Info.plist b/ai_recipe_generation/ios/Runner/Info.plist deleted file mode 100644 index 04e544b40..000000000 --- a/ai_recipe_generation/ios/Runner/Info.plist +++ /dev/null @@ -1,59 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Gemini Io Talk - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - gemini_io_talk - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - NSCameraUsageDescription - Used to demonstrate image picker plugin - NSMicrophoneUsageDescription - Used to capture audio for image picker plugin - NSPhotoLibraryUsageDescription - Used to demonstrate image picker plugin - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - - NSCameraUsageDescription - your usage description here - NSMicrophoneUsageDescription - your usage description here - - diff --git a/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h b/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a560..000000000 --- a/ai_recipe_generation/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift b/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift deleted file mode 100644 index 86a7c3b1b..000000000 --- a/ai_recipe_generation/ios/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Flutter -import UIKit -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/ai_recipe_generation/ios/firebase_app_id_file.json b/ai_recipe_generation/ios/firebase_app_id_file.json deleted file mode 100644 index 2e5b1c36b..000000000 --- a/ai_recipe_generation/ios/firebase_app_id_file.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_generated_by": "FlutterFire CLI", - "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", - "GOOGLE_APP_ID": "1:44885228795:ios:8ef52eb95f012a148f845e", - "FIREBASE_PROJECT_ID": "gemini-cat-chef", - "GCM_SENDER_ID": "44885228795" -} \ No newline at end of file diff --git a/ai_recipe_generation/lib/app_bar.dart b/ai_recipe_generation/lib/app_bar.dart deleted file mode 100644 index 487deb3d5..000000000 --- a/ai_recipe_generation/lib/app_bar.dart +++ /dev/null @@ -1,160 +0,0 @@ -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import 'features/prompt/widgets/app_info_dialog_widget.dart'; -import 'theme.dart'; -import 'widgets/appbar_shape_border.dart'; - -class AnimatedAppBar extends StatelessWidget { - const AnimatedAppBar({ - super.key, - required this.scrollController, - required this.textStyle, - required this.tabController, - }); - - final ScrollController scrollController; - final double collapsedHeight = 100; - final double expandedHeight = 300; - final double avatarSize = 50; - final TextStyle textStyle; - final TabController tabController; - - String get headerText { - return switch (tabController.index) { - 0 => 'Create a recipe', - 1 => 'Saved recipes', - 2 => 'Settings', - _ => 'Uh oh!', - }; - } - - String get helperText { - return switch (tabController.index) { - 0 => - "Tell me what ingredients you have and what you're feelin', and I'll create a recipe for you!", - 1 => "These are all my saved recipes created by Chef Noodle.", - 2 => 'Settings', - _ => 'Uh oh!', - }; - } - - @override - Widget build(BuildContext context) { - return SliverLayoutBuilder( - builder: (context, constraints) { - return SliverAppBar( - automaticallyImplyLeading: false, - pinned: true, - forceElevated: true, - elevation: 2, - shadowColor: Colors.black, - expandedHeight: expandedHeight, - collapsedHeight: collapsedHeight, - backgroundColor: Theme.of(context).primaryColor, - shape: const AppBarShapeBorder(50), - title: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: avatarSize, - height: avatarSize, - child: SvgPicture.asset( - 'assets/chef_cat.svg', - semanticsLabel: 'Chef cat icon', - ), - ), - const SizedBox( - width: MarketplaceTheme.spacing1, - ), - if (scrollController.positions.isNotEmpty && - scrollController.offset < 200) - Text( - "Meowdy! Let's get cooking!", - style: MarketplaceTheme.heading3, - ), - if (scrollController.positions.isNotEmpty && - scrollController.offset > 200) - Text( - headerText, - style: MarketplaceTheme.heading3, - ), - const Spacer(), - if (scrollController.positions.isNotEmpty && - scrollController.offset > 200) - IconButton( - onPressed: () => showDialog( - context: context, - builder: (context) => const AppInfoDialog(), - ), - icon: const Icon( - Symbols.info, - color: Colors.black12, - ), - ), - ], - ), - ], - ), - flexibleSpace: FlexibleSpaceBar( - background: Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - child: Text( - helperText, - style: constraints.isMobile - ? MarketplaceTheme.subheading2 - : MarketplaceTheme.subheading1, - ), - ), - IconButton( - onPressed: () { - showDialog( - context: context, - builder: (context) => const AppInfoDialog(), - ); - }, - icon: const Icon( - Symbols.info, - color: Colors.black12, - ), - ), - ], - ), - ), - ), - ), - bottom: PreferredSize( - preferredSize: const Size(double.infinity, 0), - child: Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only( - left: constraints.isMobile - ? MarketplaceTheme.spacing2 - : MarketplaceTheme.spacing1, - ), - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 0), - style: textStyle, - child: Text( - headerText, - ), - ), - ), - ), - ), - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_model.dart b/ai_recipe_generation/lib/features/prompt/prompt_model.dart deleted file mode 100644 index 8ff1222d4..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_model.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -import '../../util/filter_chip_enums.dart'; - -class PromptData { - PromptData({ - required this.images, - required this.textInput, - Set? basicIngredients, - Set? cuisines, - Set? dietaryRestrictions, - List? additionalTextInputs, - }) : additionalTextInputs = additionalTextInputs ?? [], - selectedBasicIngredients = basicIngredients ?? {}, - selectedCuisines = cuisines ?? {}, - selectedDietaryRestrictions = dietaryRestrictions ?? {}; - - PromptData.empty() - : images = [], - additionalTextInputs = [], - selectedBasicIngredients = {}, - selectedCuisines = {}, - selectedDietaryRestrictions = {}, - textInput = ''; - - String get cuisines { - return selectedCuisines.map((catFilter) => catFilter.name).join(","); - } - - String get ingredients { - return selectedBasicIngredients - .map((ingredient) => ingredient.name) - .join(", "); - } - - String get dietaryRestrictions { - return selectedDietaryRestrictions - .map((restriction) => restriction.name) - .join(", "); - } - - List images; - String textInput; - List additionalTextInputs; - Set selectedBasicIngredients; - Set selectedCuisines; - Set selectedDietaryRestrictions; - - PromptData copyWith({ - List? images, - String? textInput, - List? additionalTextInputs, - Set? basicIngredients, - Set? cuisineSelections, - Set? dietaryRestrictions, - }) { - return PromptData( - images: images ?? this.images, - textInput: textInput ?? this.textInput, - additionalTextInputs: additionalTextInputs ?? this.additionalTextInputs, - basicIngredients: basicIngredients ?? selectedBasicIngredients, - cuisines: cuisineSelections ?? selectedCuisines, - dietaryRestrictions: dietaryRestrictions ?? selectedDietaryRestrictions, - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_screen.dart b/ai_recipe_generation/lib/features/prompt/prompt_screen.dart deleted file mode 100644 index a22aa57c0..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_screen.dart +++ /dev/null @@ -1,391 +0,0 @@ -import 'package:ai_recipe_generation/features/prompt/prompt_view_model.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/material_symbols_icons.dart'; -import 'package:provider/provider.dart'; - -import '../../theme.dart'; -import '../../util/filter_chip_enums.dart'; -import '../../widgets/filter_chip_selection_input.dart'; -import '../../widgets/highlight_border_on_hover_widget.dart'; -import '../../widgets/marketplace_button_widget.dart'; -import '../recipes/widgets/recipe_fullscreen_dialog.dart'; -import 'widgets/full_prompt_dialog_widget.dart'; -import 'widgets/image_input_widget.dart'; - -const double kAvatarSize = 50; -const double collapsedHeight = 100; -const double expandedHeight = 300; -const double elementPadding = MarketplaceTheme.spacing7; - -class PromptScreen extends StatelessWidget { - const PromptScreen({super.key, required this.canScroll}); - - final bool canScroll; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return LayoutBuilder( - builder: (context, constraints) { - return SingleChildScrollView( - physics: canScroll - ? const BouncingScrollPhysics() - : const NeverScrollableScrollPhysics(), - child: Container( - padding: constraints.isMobile - ? const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ) - : const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing1, - top: MarketplaceTheme.spacing7, - ), - child: Container( - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color: MarketplaceTheme.borderColor), - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(4), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(elementPadding + 10), - child: Text( - 'Create a recipe:', - style: MarketplaceTheme.dossierParagraph.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18, - ), - ), - ), - Padding( - padding: const EdgeInsets.all( - elementPadding, - ), - child: SizedBox( - height: constraints.isMobile ? 130 : 230, - child: AddImageToPromptWidget( - height: constraints.isMobile ? 100 : 200, - width: constraints.isMobile ? 100 : 200, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I also have these staple ingredients: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addBasicIngredients( - selected as Set); - }, - allValues: BasicIngredientsFilter.values, - selectedValues: - viewModel.userPrompt.selectedBasicIngredients, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I'm in the mood for: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addCategoryFilters( - selected as Set); - }, - allValues: CuisineFilter.values, - selectedValues: viewModel.userPrompt.selectedCuisines, - ), - ), - ), - if (constraints.isMobile) - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I have the following dietary restrictions:", - child: - FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addDietaryRestrictionFilter( - selected as Set); - }, - allValues: DietaryRestrictionsFilter.values, - selectedValues: - viewModel.userPrompt.selectedDietaryRestrictions, - ), - ), - ), - if (!constraints.isMobile) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I'm in the mood for: ", - child: FilterChipSelectionInput( - onChipSelected: (selected) { - viewModel.addCategoryFilters( - selected as Set); - }, - allValues: CuisineFilter.values, - selectedValues: - viewModel.userPrompt.selectedCuisines, - ), - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: "I also have these staple ingredients: ", - child: FilterChipSelectionInput< - BasicIngredientsFilter>( - onChipSelected: (selected) { - viewModel.addBasicIngredients( - selected as Set); - }, - allValues: BasicIngredientsFilter.values, - selectedValues: viewModel - .userPrompt.selectedBasicIngredients, - ), - ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(elementPadding), - child: _FilterChipSection( - label: - "I have the following dietary restrictions:", - child: FilterChipSelectionInput< - DietaryRestrictionsFilter>( - onChipSelected: (selected) { - viewModel.addDietaryRestrictionFilter(selected - as Set); - }, - allValues: DietaryRestrictionsFilter.values, - selectedValues: viewModel - .userPrompt.selectedDietaryRestrictions, - ), - ), - ), - ), - ], - ), - Padding( - padding: const EdgeInsets.all(elementPadding), - child: _TextField( - controller: viewModel.promptTextController, - onChanged: (value) { - viewModel.notify(); - }, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing4, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (!constraints.isMobile) const Spacer(flex: 1), - if (!constraints.isMobile) - Expanded( - flex: 3, - child: MarketplaceButton( - onPressed: viewModel.resetPrompt, - buttonText: 'Reset prompt', - icon: Symbols.restart_alt, - iconColor: Colors.black45, - buttonBackgroundColor: Colors.transparent, - hoverColor: - MarketplaceTheme.secondary.withAlpha(25), - ), - ), - const Spacer(flex: 1), - Expanded( - flex: constraints.isMobile ? 10 : 3, - child: MarketplaceButton( - onPressed: () { - final promptData = viewModel.buildPrompt(); - showDialog( - context: context, - builder: (context) { - return FullPromptDialog( - promptData: promptData, - ); - }, - ); - }, - buttonText: 'Full prompt', - icon: Symbols.info_rounded, - ), - ), - const Spacer(flex: 1), - Expanded( - flex: constraints.isMobile ? 10 : 3, - child: MarketplaceButton( - onPressed: () async { - await viewModel.submitPrompt().then((_) async { - if (!context.mounted) return; - if (viewModel.recipe != null) { - bool? shouldSave = await showDialog( - context: context, - barrierDismissible: false, - builder: (context) => RecipeDialogScreen( - recipe: viewModel.recipe!, - actions: [ - MarketplaceButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - buttonText: "Save Recipe", - icon: Symbols.save, - ), - ], - ), - ); - if (shouldSave != null && shouldSave) { - viewModel.saveRecipe(); - } - } - }); - }, - buttonText: 'Submit prompt', - icon: Symbols.send, - ), - ), - const Spacer(flex: 1), - ], - ), - ), - if (constraints.isMobile) - Align( - alignment: Alignment.center, - child: MarketplaceButton( - onPressed: viewModel.resetPrompt, - buttonText: 'Reset prompt', - icon: Symbols.restart_alt, - iconColor: Colors.black45, - buttonBackgroundColor: Colors.transparent, - hoverColor: MarketplaceTheme.secondary.withAlpha(25), - ), - ), - const SizedBox(height: 200.0), - ], - ), - ), - ), - ); - }, - ); - } -} - -class _FilterChipSection extends StatelessWidget { - const _FilterChipSection({ - required this.child, - required this.label, - }); - - final Widget child; - final String label; - - @override - Widget build(BuildContext context) { - return HighlightBorderOnHoverWidget( - borderRadius: BorderRadius.zero, - child: Container( - height: 230, - decoration: BoxDecoration( - color: Theme.of(context).splashColor.withAlpha(25), - border: Border.all( - color: MarketplaceTheme.borderColor, - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - mainAxisSize: MainAxisSize.max, - children: [ - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: Text( - label, - style: MarketplaceTheme.dossierParagraph, - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: child, - ), - ), - ], - ), - ), - ); - } -} - -class _TextField extends StatelessWidget { - const _TextField({ - required this.controller, - this.onChanged, - }); - - final TextEditingController controller; - final Null Function(String)? onChanged; - - @override - Widget build(BuildContext context) { - return TextField( - scrollPadding: const EdgeInsets.only(bottom: 150), - maxLines: null, - onChanged: onChanged, - minLines: 3, - controller: controller, - style: WidgetStateTextStyle.resolveWith( - (states) => MarketplaceTheme.dossierParagraph), - decoration: InputDecoration( - fillColor: Theme.of(context).splashColor, - hintText: "Add additional context...", - hintStyle: WidgetStateTextStyle.resolveWith( - (states) => MarketplaceTheme.dossierParagraph, - ), - enabledBorder: const OutlineInputBorder( - borderRadius: BorderRadius.zero, - borderSide: BorderSide(width: 1, color: Colors.black12), - ), - focusedBorder: const OutlineInputBorder( - borderRadius: BorderRadius.zero, - borderSide: BorderSide(width: 1, color: Colors.black45), - ), - filled: true, - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart b/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart deleted file mode 100644 index adb1d99e6..000000000 --- a/ai_recipe_generation/lib/features/prompt/prompt_view_model.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'package:ai_recipe_generation/services/gemini.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; -import 'package:image_picker/image_picker.dart'; - -import '../../services/firestore.dart'; -import '../../util/filter_chip_enums.dart'; -import '../recipes/recipe_model.dart'; -import 'prompt_model.dart'; - -class PromptViewModel extends ChangeNotifier { - PromptViewModel({ - required this.multiModalModel, - required this.textModel, - }); - - final GenerativeModel multiModalModel; - final GenerativeModel textModel; - bool loadingNewRecipe = false; - - PromptData userPrompt = PromptData.empty(); - TextEditingController promptTextController = TextEditingController(); - - String badImageFailure = - "The recipe request either does not contain images, or does not contain images of food items. I cannot recommend a recipe."; - - Recipe? recipe; - String? _geminiFailureResponse; - String? get geminiFailureResponse => _geminiFailureResponse; - set geminiFailureResponse(String? value) { - _geminiFailureResponse = value; - notifyListeners(); - } - - void notify() => notifyListeners(); - - void addImage(XFile image) { - userPrompt.images.insert(0, image); - notifyListeners(); - } - - void addAdditionalPromptContext(String text) { - final existingInputs = userPrompt.additionalTextInputs; - userPrompt.copyWith(additionalTextInputs: [...existingInputs, text]); - } - - void removeImage(XFile image) { - userPrompt.images.removeWhere((el) => el.path == image.path); - notifyListeners(); - } - - void resetPrompt() { - userPrompt = PromptData.empty(); - notifyListeners(); - } - - // Creates an ephemeral prompt with additional text that the user shouldn't be - // concerned with to send to Gemini, such as formatting. - PromptData buildPrompt() { - return PromptData( - images: userPrompt.images, - textInput: mainPrompt, - basicIngredients: userPrompt.selectedBasicIngredients, - cuisines: userPrompt.selectedCuisines, - dietaryRestrictions: userPrompt.selectedDietaryRestrictions, - additionalTextInputs: [format], - ); - } - - Future submitPrompt() async { - loadingNewRecipe = true; - notifyListeners(); - // Create an ephemeral PromptData, preserving the user prompt data without - // adding the additional context to it. - var model = userPrompt.images.isEmpty ? textModel : multiModalModel; - final prompt = buildPrompt(); - - try { - final content = await GeminiService.generateContent(model, prompt); - - // handle no image or image of not-food - if (content.text != null && content.text!.contains(badImageFailure)) { - geminiFailureResponse = badImageFailure; - } else { - recipe = Recipe.fromGeneratedContent(content); - } - } catch (error) { - geminiFailureResponse = 'Failed to reach Gemini. \n\n$error'; - if (kDebugMode) { - print(error); - } - loadingNewRecipe = false; - } - - loadingNewRecipe = false; - resetPrompt(); - notifyListeners(); - } - - void saveRecipe() { - FirestoreService.saveRecipe(recipe!); - } - - void addBasicIngredients(Set ingredients) { - userPrompt.selectedBasicIngredients.addAll(ingredients); - notifyListeners(); - } - - void addCategoryFilters(Set categories) { - userPrompt.selectedCuisines.addAll(categories); - notifyListeners(); - } - - void addDietaryRestrictionFilter( - Set restrictions) { - userPrompt.selectedDietaryRestrictions.addAll(restrictions); - notifyListeners(); - } - - String get mainPrompt { - return ''' -You are a Cat who's a chef that travels around the world a lot, and your travels inspire recipes. - -Recommend a recipe for me based on the provided image. -The recipe should only contain real, edible ingredients. -If there are no images attached, or if the image does not contain food items, respond exactly with: $badImageFailure - -Adhere to food safety and handling best practices like ensuring that poultry is fully cooked. -I'm in the mood for the following types of cuisine: ${userPrompt.cuisines}, -I have the following dietary restrictions: ${userPrompt.dietaryRestrictions} -Optionally also include the following ingredients: ${userPrompt.ingredients} -Do not repeat any ingredients. - -After providing the recipe, add an descriptions that creatively explains why the recipe is good based on only the ingredients used in the recipe. Tell a short story of a travel experience that inspired the recipe. -List out any ingredients that are potential allergens. -Provide a summary of how many people the recipe will serve and the the nutritional information per serving. - -${promptTextController.text.isNotEmpty ? promptTextController.text : ''} -'''; - } - - final String format = ''' -Return the recipe as valid JSON using the following structure: -{ - "id": \$uniqueId, - "title": \$recipeTitle, - "ingredients": \$ingredients, - "description": \$description, - "instructions": \$instructions, - "cuisine": \$cuisineType, - "allergens": \$allergens, - "servings": \$servings, - "nutritionInformation": { - "calories": "\$calories", - "fat": "\$fat", - "carbohydrates": "\$carbohydrates", - "protein": "\$protein", - }, -} - -uniqueId should be unique and of type String. -title, description, cuisine, allergens, and servings should be of String type. -ingredients and instructions should be of type List. -nutritionInformation should be of type Map. -'''; -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart deleted file mode 100644 index 5aa2a2ae0..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/app_info_dialog_widget.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; - -class AppInfoDialog extends StatelessWidget { - const AppInfoDialog({super.key}); - - Widget bulletRow(String text, {IconData? icon}) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon(icon ?? Symbols.label_important_outline), - const SizedBox( - width: 10, - ), - Expanded( - child: Text( - text, - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return Dialog( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "Use the form on this screen to ask Cat Chef to make a recipe for you.", - style: MarketplaceTheme.heading3, - ), - const SizedBox( - height: MarketplaceTheme.spacing4, - ), - bulletRow( - "Add images of ingredients you have, like a picture of the inside of your fridge or pantry.", - icon: Symbols.looks_one, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "Choose what kind of food you're in the mood for, and what staple ingredients you have that might not be pictured.", - icon: Symbols.looks_two, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "In the text box at the bottom, add any additional context that you'd like. \nFor example, you could say \"I'm in a hurry! Make sure the recipe doesn't take longer than 30 minutes to make.\"", - icon: Symbols.looks_3, - ), - const SizedBox( - height: MarketplaceTheme.spacing7, - ), - bulletRow( - "Submit the prompt, and Chef Noodle will give you a recipe!", - icon: Symbols.looks_4, - ), - const SizedBox( - height: MarketplaceTheme.spacing4, - ), - Text( - "Steps 1, 2 and 3 are optional. More information will provide better results.", - style: MarketplaceTheme.label, - ), - const SizedBox(height: MarketplaceTheme.spacing4), - TextButton.icon( - icon: const Icon( - Symbols.close, - color: Colors.black87, - ), - label: Text( - 'Close', - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: () { - Navigator.pop(context); - }, - style: ButtonStyle( - shape: WidgetStateProperty.resolveWith( - (states) { - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph - .copyWith(color: Colors.black45); - }, - ), - ), - ), - ], - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart deleted file mode 100644 index 420667c06..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/full_prompt_dialog_widget.dart +++ /dev/null @@ -1,112 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../../../widgets/prompt_image_widget.dart'; -import '../prompt_model.dart'; - -class FullPromptDialog extends StatelessWidget { - const FullPromptDialog({super.key, required this.promptData}); - - final PromptData promptData; - - Widget bulletRow(String text, {IconData? icon}) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Icon(icon ?? Symbols.label_important_outline), - const SizedBox( - width: 10, - ), - Expanded( - child: Text( - text, - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - return Dialog.fullscreen( - child: SingleChildScrollView( - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "This is the full prompt that will be sent to Google's Gemini model.", - style: MarketplaceTheme.heading3, - ), - const SizedBox(height: MarketplaceTheme.spacing4), - if (promptData.images.isNotEmpty) - Container( - height: 100, - decoration: const BoxDecoration( - border: Border.symmetric( - horizontal: BorderSide( - color: MarketplaceTheme.borderColor, - ), - ), - ), - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - for (var image in promptData.images) - Padding( - padding: const EdgeInsets.all(8.0), - child: PromptImage( - file: image, - ), - ), - ], - ), - ), - const SizedBox(height: MarketplaceTheme.spacing4), - bulletRow(promptData.textInput), - if (promptData.additionalTextInputs.isNotEmpty) - ...promptData.additionalTextInputs.map((i) => bulletRow(i)), - const SizedBox(height: MarketplaceTheme.spacing4), - TextButton.icon( - icon: const Icon( - Symbols.close, - color: Colors.black87, - ), - label: Text( - 'Close', - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: () { - Navigator.pop(context); - }, - style: ButtonStyle( - shape: WidgetStateProperty.resolveWith( - (states) { - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph - .copyWith(color: Colors.black45); - }, - ), - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart b/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart deleted file mode 100644 index 70484a16a..000000000 --- a/ai_recipe_generation/lib/features/prompt/widgets/image_input_widget.dart +++ /dev/null @@ -1,278 +0,0 @@ -import 'package:ai_recipe_generation/widgets/highlight_border_on_hover_widget.dart'; -import 'package:camera/camera.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import '../../../main.dart'; -import '../../../theme.dart'; -import '../../../util/device_info.dart'; -import '../../../widgets/add_image_widget.dart'; -import '../../../widgets/prompt_image_widget.dart'; -import '../prompt_view_model.dart'; - -class AddImageToPromptWidget extends StatefulWidget { - const AddImageToPromptWidget({ - super.key, - this.width = 100, - this.height = 100, - }); - - final double width; - final double height; - - @override - State createState() => _AddImageToPromptWidgetState(); -} - -class _AddImageToPromptWidgetState extends State { - final ImagePicker picker = ImagePicker(); - late CameraController _controller; - late Future _initializeControllerFuture; - bool flashOn = false; - - @override - void initState() { - super.initState(); - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - _controller = CameraController( - camera, - ResolutionPreset.medium, - ); - _initializeControllerFuture = _controller.initialize(); - } - } - - Future _showCamera() async { - final image = await showGeneralDialog( - context: context, - transitionBuilder: (context, animation, secondaryAnimation, child) { - return AnimatedOpacity( - opacity: animation.value, - duration: const Duration(milliseconds: 100), - child: child, - ); - }, - pageBuilder: (context, animation, secondaryAnimation) { - return Dialog.fullscreen( - insetAnimationDuration: const Duration(seconds: 1), - child: FutureBuilder( - future: _initializeControllerFuture, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - // If the Future is complete, display the preview. - return CameraView( - controller: _controller, - initializeControllerFuture: _initializeControllerFuture, - ); - } else { - // Otherwise, display a loading indicator. - return const Center(child: CircularProgressIndicator()); - } - }, - ), - ); - }, - ); - - if (image != null) { - return image; - } else { - throw "failed to take image"; - } - } - - Future _pickImage() async { - final image = await picker.pickImage(source: ImageSource.gallery); - if (image != null) { - return image; - } else { - throw "failed to take image"; - } - } - - Future _addImage() async { - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - return await _showCamera(); - } else { - return await _pickImage(); - } - } - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return HighlightBorderOnHoverWidget( - borderRadius: BorderRadius.zero, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ), - child: Text( - 'I have these ingredients:', - style: MarketplaceTheme.dossierParagraph, - ), - ), - SizedBox( - height: widget.height, - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: AddImage( - width: widget.width, - height: widget.height, - onTap: () async { - final image = await _addImage(); - viewModel.addImage(image); - }), - ), - for (var image in viewModel.userPrompt.images) - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: PromptImage( - width: widget.width, - file: image, - onTapIcon: () => viewModel.removeImage(image), - ), - ), - ], - ), - ), - ], - ), - ); - } -} - -class CameraView extends StatefulWidget { - final CameraController controller; - final Future initializeControllerFuture; - const CameraView( - {super.key, - required this.controller, - required this.initializeControllerFuture}); - - @override - State createState() => _CameraViewState(); -} - -class _CameraViewState extends State { - bool flashOn = false; - - @override - Widget build(BuildContext context) { - CameraController controller = widget.controller; - return Stack( - children: [ - Center( - child: AspectRatio( - aspectRatio: 9 / 14, - child: ClipRect( - child: FittedBox( - fit: BoxFit.cover, - child: SizedBox( - height: controller.value.previewSize!.width, - width: controller.value.previewSize!.height, - child: Center( - child: CameraPreview( - controller, - // child: ElevatedButton( - // child: Text('Button'), - // onPressed: () {}, - // ), - ), - ), - ), - ), - ), - ), - ), - Positioned( - top: 0, - left: 0, - right: 0, - height: 89.5, - child: Container( - color: Colors.black.withAlpha(179), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: - const EdgeInsets.only(left: MarketplaceTheme.spacing4), - child: IconButton( - icon: Icon( - flashOn ? Symbols.flash_on : Symbols.flash_off, - size: 40, - color: flashOn ? Colors.yellowAccent : Colors.white, - ), - onPressed: () { - controller.setFlashMode( - flashOn ? FlashMode.off : FlashMode.always); - setState(() { - flashOn = !flashOn; - }); - }, - ), - ), - Padding( - padding: - const EdgeInsets.only(right: MarketplaceTheme.spacing4), - child: IconButton( - icon: const Icon( - Symbols.cancel, - color: Colors.white, - size: 40, - ), - onPressed: () async { - Navigator.of(context).pop(); - }, - ), - ), - ], - ), - ), - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - height: 150, - child: Container( - color: Colors.black.withAlpha(179), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - IconButton( - icon: const Icon( - Symbols.camera, - color: Colors.white, - size: 70, - ), - onPressed: () async { - try { - await widget.initializeControllerFuture; - final image = await controller.takePicture(); - if (!context.mounted) return; - Navigator.of(context).pop(image); - } catch (e) { - rethrow; - } - }, - ), - ], - ), - ), - ) - ], - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/recipe_model.dart b/ai_recipe_generation/lib/features/recipes/recipe_model.dart deleted file mode 100644 index 00d4a7e79..000000000 --- a/ai_recipe_generation/lib/features/recipes/recipe_model.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'dart:convert'; - -import 'package:ai_recipe_generation/util/json_parsing.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; - -class Recipe { - Recipe({ - required this.title, - required this.id, - required this.description, - required this.ingredients, - required this.instructions, - required this.cuisine, - required this.allergens, - required this.servings, - required this.nutritionInformation, - this.rating = -1, - }); - - final String id; - final String title; - final String description; - final List ingredients; - final List instructions; - final String cuisine; - final List allergens; - final String servings; - final Map nutritionInformation; - int rating; - - factory Recipe.fromGeneratedContent(GenerateContentResponse content) { - /// failures should be handled when the response is received - assert(content.text != null); - - final validJson = cleanJson(content.text!); - final json = jsonDecode(validJson); - - if (json - case { - "ingredients": List ingredients, - "instructions": List instructions, - "title": String title, - "id": String id, - "cuisine": String cuisine, - "description": String description, - "servings": String servings, - "nutritionInformation": Map nutritionInformation, - "allergens": List allergens, - }) { - return Recipe( - id: id, - title: title, - ingredients: ingredients.map((i) => i.toString()).toList(), - instructions: instructions.map((i) => i.toString()).toList(), - nutritionInformation: nutritionInformation, - allergens: allergens.map((i) => i.toString()).toList(), - cuisine: cuisine, - servings: servings, - description: description); - } - - throw JsonUnsupportedObjectError(json); - } - - Map toFirestore() { - return { - 'id': id, - 'title': title, - 'instructions': instructions, - 'ingredients': ingredients, - 'cuisine': cuisine, - 'rating': rating, - 'allergens': allergens, - 'nutritionInformation': nutritionInformation, - 'servings': servings, - 'description': description, - }; - } - - factory Recipe.fromFirestore(Map data) { - if (data - case { - "ingredients": List ingredients, - "instructions": List instructions, - "title": String title, - "id": String id, - "cuisine": String cuisine, - "description": String description, - "servings": String servings, - "nutritionInformation": Map nutritionInformation, - "allergens": List allergens, - "rating": int rating - }) { - return Recipe( - id: id, - title: title, - ingredients: ingredients.map((i) => i.toString()).toList(), - instructions: instructions.map((i) => i.toString()).toList(), - nutritionInformation: nutritionInformation, - allergens: allergens.map((i) => i.toString()).toList(), - cuisine: cuisine, - servings: servings, - description: description, - rating: rating, - ); - } - - throw "Malformed Firestore data"; - } -} diff --git a/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart b/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart deleted file mode 100644 index 494115dc3..000000000 --- a/ai_recipe_generation/lib/features/recipes/recipes_view_model.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:flutter/cupertino.dart'; - -import '../../services/firestore.dart'; -import 'recipe_model.dart'; - -class SavedRecipesViewModel extends ChangeNotifier { - List recipes = []; - - final recipePath = '/recipes'; - final firestore = FirebaseFirestore.instance; - - SavedRecipesViewModel() { - firestore.collection(recipePath).snapshots().listen((querySnapshot) { - recipes = querySnapshot.docs.map((doc) { - final data = doc.data(); - return Recipe.fromFirestore(data); - }).toList(); - notifyListeners(); - }); - } - - void deleteRecipe(Recipe recipe) { - FirestoreService.deleteRecipe(recipe); - } - - void updateRecipe(Recipe recipe) { - FirestoreService.updateRecipe(recipe); - notifyListeners(); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart b/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart deleted file mode 100644 index 604ac64ad..000000000 --- a/ai_recipe_generation/lib/features/recipes/saved_recipes_screen.dart +++ /dev/null @@ -1,263 +0,0 @@ -import 'package:ai_recipe_generation/features/recipes/recipes_view_model.dart'; -import 'package:ai_recipe_generation/features/recipes/widgets/recipe_fullscreen_dialog.dart'; -import 'package:ai_recipe_generation/theme.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:ai_recipe_generation/widgets/highlight_border_on_hover_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import '../../widgets/marketplace_button_widget.dart'; -import '../../widgets/star_rating.dart'; -import 'recipe_model.dart'; - -class SavedRecipesScreen extends StatefulWidget { - const SavedRecipesScreen({super.key, required this.canScroll}); - - final bool canScroll; - - @override - State createState() => _SavedRecipesScreenState(); -} - -class _SavedRecipesScreenState extends State - with TickerProviderStateMixin { - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - return LayoutBuilder( - builder: (context, constraints) { - return Padding( - padding: constraints.isMobile - ? const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing7, - top: MarketplaceTheme.spacing7, - ) - : const EdgeInsets.only( - left: MarketplaceTheme.spacing7, - right: MarketplaceTheme.spacing7, - bottom: MarketplaceTheme.spacing1, - top: MarketplaceTheme.spacing7, - ), - child: ClipRRect( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - child: Container( - decoration: BoxDecoration( - border: Border.all(color: MarketplaceTheme.borderColor), - borderRadius: const BorderRadius.only( - topLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: Colors.white, - ), - child: constraints.isMobile - ? ListView.builder( - physics: widget.canScroll - ? const PageScrollPhysics() - : const NeverScrollableScrollPhysics(), - itemCount: viewModel.recipes.length, - itemBuilder: (context, idx) { - final recipe = viewModel.recipes[idx]; - return Container( - margin: EdgeInsets.only(top: idx == 0 ? 70 : 0), - child: Align( - heightFactor: .5, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: MarketplaceTheme.spacing7, - vertical: MarketplaceTheme.spacing7, - ), - child: SizedBox( - width: MediaQuery.of(context).size.width * .99, - height: 200, - child: _ListTile( - constraints: constraints, - key: Key('$idx-${recipe.hashCode}'), - recipe: recipe, - idx: idx, - ), - ), - ), - ), - ); - }, - ) - : GridView.count( - physics: widget.canScroll - ? const PageScrollPhysics() - : const NeverScrollableScrollPhysics(), - crossAxisCount: 3, - childAspectRatio: 1.5, - children: [ - ...List.generate(viewModel.recipes.length, (idx) { - final recipe = viewModel.recipes[idx]; - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: MarketplaceTheme.spacing7, - vertical: MarketplaceTheme.spacing7, - ), - child: _ListTile( - key: Key('$idx-${recipe.hashCode}'), - recipe: recipe, - idx: idx, - constraints: constraints, - ), - ); - }), - ], - ), - ), - ), - ); - }, - ); - } -} - -class _ListTile extends StatefulWidget { - const _ListTile({ - super.key, - required this.recipe, - this.idx = 0, - required this.constraints, - }); - - final Recipe recipe; - final int idx; - final BoxConstraints constraints; - - @override - State<_ListTile> createState() => _ListTileState(); -} - -class _ListTileState extends State<_ListTile> { - final List colors = [ - MarketplaceTheme.primary, - MarketplaceTheme.secondary, - MarketplaceTheme.tertiary, - MarketplaceTheme.scrim, - ]; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - final color = colors[widget.idx % colors.length]; - - return GestureDetector( - child: HighlightBorderOnHoverWidget( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: color, - child: Container( - decoration: const BoxDecoration( - boxShadow: [ - BoxShadow( - offset: Offset(0, -2), - color: Colors.black38, - blurRadius: 5, - ), - ], - borderRadius: BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: Colors.white, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(MarketplaceTheme.defaultBorderRadius), - topRight: Radius.circular(50), - bottomRight: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - bottomLeft: - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - color: color.withAlpha(77), - ), - padding: const EdgeInsets.all(MarketplaceTheme.spacing7), - child: Stack( - children: [ - Text( - widget.recipe.title, - style: MarketplaceTheme.heading3, - ), - Positioned( - top: widget.constraints.isMobile ? 40 : 60, - left: 0, - child: Text( - widget.recipe.cuisine, - style: MarketplaceTheme.subheading1, - ), - ), - Positioned( - right: 15, - top: widget.constraints.isMobile ? 40 : 60, - child: StartRating( - initialRating: widget.recipe.rating, - starColor: color, - onTap: null, - ), - ) - ], - ), - ), - ), - ), - onTap: () async { - await showDialog( - context: context, - builder: (context) { - return RecipeDialogScreen( - recipe: widget.recipe, - subheading: Row( - children: [ - const Text('My rating:'), - const SizedBox(width: 10), - StartRating( - initialRating: widget.recipe.rating, - starColor: MarketplaceTheme.tertiary, - onTap: (index) { - widget.recipe.rating = index + 1; - viewModel.updateRecipe(widget.recipe); - }, - ), - ], - ), - actions: [ - MarketplaceButton( - onPressed: () { - viewModel.deleteRecipe(widget.recipe); - Navigator.of(context).pop(); - }, - buttonText: "Delete Recipe", - icon: Symbols.delete, - ), - ], - ); - }, - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart b/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart deleted file mode 100644 index 113f2015b..000000000 --- a/ai_recipe_generation/lib/features/recipes/widgets/recipe_display_widget.dart +++ /dev/null @@ -1,277 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../recipe_model.dart'; - -class RecipeDisplayWidget extends StatelessWidget { - const RecipeDisplayWidget({ - super.key, - required this.recipe, - this.subheading, - }); - - final Recipe recipe; - final Widget? subheading; - - List _buildIngredients(List ingredients) { - final widgets = []; - for (var ingredient in ingredients) { - widgets.add( - Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Symbols.stat_0_rounded, - size: 12, - ), - const SizedBox( - width: 5, - ), - Expanded( - child: Text( - ingredient, - softWrap: true, - ), - ), - ], - ), - ); - } - - return widgets; - } - - List _buildInstructions(List instructions) { - final widgets = []; - - // check for existing numbers in instructions. - if (instructions.first.startsWith(RegExp('[0-9]'))) { - for (var instruction in instructions) { - widgets.add(Text(instruction)); - widgets.add(const SizedBox(height: MarketplaceTheme.spacing6)); - } - } else { - for (var i = 0; i < instructions.length; i++) { - widgets.add(Text( - '${i + 1}. ${instructions[i]}', - softWrap: true, - )); - widgets.add(const SizedBox(height: MarketplaceTheme.spacing6)); - } - } - - return widgets; - } - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - physics: const ClampingScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: const EdgeInsets.all(MarketplaceTheme.defaultBorderRadius), - color: MarketplaceTheme.primary.withAlpha(128), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - recipe.title, - softWrap: true, - style: MarketplaceTheme.heading2, - ), - if (subheading != null) - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7, - ), - child: subheading, - ), - ], - ), - ), - TextButton( - style: ButtonStyle( - backgroundColor: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return MarketplaceTheme.scrim.withAlpha(153); - } - return Colors.white; - }), - shape: WidgetStateProperty.resolveWith( - (states) { - return RoundedRectangleBorder( - side: const BorderSide( - color: MarketplaceTheme.primary), - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph.copyWith( - color: Colors.black45, - ); - }, - ), - ), - onPressed: () async { - await showDialog( - context: context, - builder: (context) { - return AlertDialog( - content: Padding( - padding: const EdgeInsets.all( - MarketplaceTheme.spacing7), - child: Text(recipe.description), - ), - ); - }, - ); - }, - child: Transform.translate( - offset: const Offset(0, 5), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing6), - child: Row( - children: [ - SizedBox( - width: 35, - height: 35, - child: SvgPicture.asset( - 'assets/chef_cat.svg', - semanticsLabel: 'Chef cat icon', - ), - ), - Transform.translate( - offset: const Offset(1, -6), - child: Transform.rotate( - angle: -pi / 20.0, - child: Text( - 'Chef Noodle \n says...', - style: MarketplaceTheme.label, - ), - ), - ) - ], - ), - ), - ), - ) - ], - ), - const Divider( - height: 40, - color: Colors.black26, - ), - Table( - columnWidths: const { - 0: FlexColumnWidth(2), - 1: FlexColumnWidth(3), - }, - children: [ - TableRow( - children: [ - Text( - 'Allergens:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Text(recipe.allergens.join(', ')) - ], - ), - TableRow(children: [ - Text( - 'Servings:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - Text(recipe.servings) - ]), - TableRow(children: [ - Text( - 'Nutrition per serving:', - style: MarketplaceTheme.paragraph.copyWith( - fontWeight: FontWeight.bold, - ), - ), - const Text(''), - ]), - ...recipe.nutritionInformation.entries.map((entry) { - return TableRow(children: [ - Row( - children: [ - const Icon( - Symbols.stat_0_rounded, - size: 12, - ), - const SizedBox( - width: 5, - ), - Expanded( - child: Text( - entry.key, - style: MarketplaceTheme.label, - softWrap: true, - ), - ), - ], - ), - Text(entry.value as String, - style: MarketplaceTheme.label) - ]); - }), - ], - ), - ], - ), - ), - - /// Body section - Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing4), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7, - ), - child: - Text('Ingredients:', style: MarketplaceTheme.subheading1), - ), - ..._buildIngredients(recipe.ingredients), - const SizedBox(height: MarketplaceTheme.spacing4), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing7), - child: Text('Instructions:', - style: MarketplaceTheme.subheading1), - ), - ..._buildInstructions(recipe.instructions), - ], - ), - ) - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart b/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart deleted file mode 100644 index 61c21b3e2..000000000 --- a/ai_recipe_generation/lib/features/recipes/widgets/recipe_fullscreen_dialog.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:ai_recipe_generation/features/recipes/widgets/recipe_display_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../../../theme.dart'; -import '../../../widgets/marketplace_button_widget.dart'; -import '../recipe_model.dart'; - -class RecipeDialogScreen extends StatelessWidget { - const RecipeDialogScreen({ - super.key, - required this.recipe, - required this.actions, - this.subheading, - }); - - final Recipe recipe; - final List actions; - final Widget? subheading; - - @override - Widget build(BuildContext context) { - return Dialog.fullscreen( - backgroundColor: Colors.white, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: RecipeDisplayWidget( - recipe: recipe, - subheading: subheading, - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - vertical: MarketplaceTheme.spacing5, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MarketplaceButton( - onPressed: () { - Navigator.of(context).pop(true); - }, - buttonText: 'Close', - icon: Symbols.close, - ), - ...actions, - ], - ), - ), - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/firebase_options.dart b/ai_recipe_generation/lib/firebase_options.dart deleted file mode 100644 index 428d75fe1..000000000 --- a/ai_recipe_generation/lib/firebase_options.dart +++ /dev/null @@ -1,81 +0,0 @@ -// File generated by FlutterFire CLI. -// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members -import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; -import 'package:flutter/foundation.dart' - show defaultTargetPlatform, kIsWeb, TargetPlatform; - -/// Default [FirebaseOptions] for use with your Firebase apps. -/// -/// Example: -/// ```dart -/// import 'firebase_options.dart'; -/// // ... -/// await Firebase.initializeApp( -/// options: DefaultFirebaseOptions.currentPlatform, -/// ); -/// ``` -class DefaultFirebaseOptions { - static FirebaseOptions get currentPlatform { - if (kIsWeb) { - return web; - } - switch (defaultTargetPlatform) { - case TargetPlatform.android: - return android; - case TargetPlatform.iOS: - return ios; - case TargetPlatform.macOS: - return macos; - case TargetPlatform.windows: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for windows - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - case TargetPlatform.linux: - throw UnsupportedError( - 'DefaultFirebaseOptions have not been configured for linux - ' - 'you can reconfigure this by running the FlutterFire CLI again.', - ); - default: - throw UnsupportedError( - 'DefaultFirebaseOptions are not supported for this platform.', - ); - } - } - - static const FirebaseOptions web = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions android = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions ios = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); - - static const FirebaseOptions macos = FirebaseOptions( - apiKey: 'FIREBASE API KEY', - appId: 'FIREBASE APP ID', - messagingSenderId: 'FIREBASE MESSAGING ID', - projectId: 'PROJECT ID', - authDomain: 'AUTH DOMAIN', - storageBucket: 'STORAGE BUCKET ID', - ); -} diff --git a/ai_recipe_generation/lib/main.dart b/ai_recipe_generation/lib/main.dart deleted file mode 100644 index 432c1bb36..000000000 --- a/ai_recipe_generation/lib/main.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:ai_recipe_generation/util/device_info.dart'; -import 'package:ai_recipe_generation/util/tap_recorder.dart'; -import 'package:camera/camera.dart'; -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/material.dart'; -import 'package:google_generative_ai/google_generative_ai.dart'; -import 'package:provider/provider.dart'; - -import 'features/prompt/prompt_view_model.dart'; -import 'features/recipes/recipes_view_model.dart'; -import 'firebase_options.dart'; -import 'router.dart'; -import 'theme.dart'; - -late CameraDescription camera; -late BaseDeviceInfo deviceInfo; - -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: DefaultFirebaseOptions.currentPlatform, - ); - deviceInfo = await DeviceInfo.initialize(DeviceInfoPlugin()); - if (DeviceInfo.isPhysicalDeviceWithCamera(deviceInfo)) { - final cameras = await availableCameras(); - camera = cameras.first; - } - - runApp(const MainApp()); -} - -class MainApp extends StatefulWidget { - const MainApp({super.key}); - - @override - State createState() => _MainAppState(); -} - -class _MainAppState extends State { - late GenerativeModel geminiVisionProModel; - late GenerativeModel geminiProModel; - @override - void initState() { - const apiKey = - String.fromEnvironment('API_KEY', defaultValue: 'key not found'); - if (apiKey == 'key not found') { - throw InvalidApiKey( - 'Key not found in environment. Please add an API key.', - ); - } - - geminiVisionProModel = GenerativeModel( - model: 'gemini-pro-vision', - apiKey: apiKey, - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - - geminiProModel = GenerativeModel( - model: 'gemini-pro', - apiKey: const String.fromEnvironment('API_KEY'), - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - - super.initState(); - } - - @override - Widget build(BuildContext context) { - final recipesViewModel = SavedRecipesViewModel(); - - return TapRecorder( - child: MultiProvider( - providers: [ - ChangeNotifierProvider( - create: (_) => PromptViewModel( - multiModalModel: geminiVisionProModel, - textModel: geminiProModel, - ), - ), - ChangeNotifierProvider( - create: (_) => recipesViewModel, - ), - ], - child: SafeArea( - child: MaterialApp( - debugShowCheckedModeBanner: false, - theme: MarketplaceTheme.theme, - scrollBehavior: const ScrollBehavior().copyWith( - dragDevices: { - PointerDeviceKind.mouse, - PointerDeviceKind.touch, - PointerDeviceKind.stylus, - PointerDeviceKind.unknown, - }, - ), - home: const AdaptiveRouter(), - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/router.dart b/ai_recipe_generation/lib/router.dart deleted file mode 100644 index 0ca954f95..000000000 --- a/ai_recipe_generation/lib/router.dart +++ /dev/null @@ -1,244 +0,0 @@ -import 'package:ai_recipe_generation/app_bar.dart'; -import 'package:ai_recipe_generation/features/prompt/prompt_screen.dart'; -import 'package:ai_recipe_generation/features/prompt/prompt_view_model.dart'; -import 'package:ai_recipe_generation/features/recipes/saved_recipes_screen.dart'; -import 'package:ai_recipe_generation/widgets/bottom_bar_shape_border.dart'; -import 'package:ai_recipe_generation/widgets/marketplace_button_widget.dart'; -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; -import 'package:provider/provider.dart'; - -import 'theme.dart'; -import 'widgets/icon_loading_indicator.dart'; - -const double avatarSize = 50; -const double collapsedHeight = 100; -const double expandedHeight = 300; -const double bottomTabBarHeight = 50; - -class AdaptiveRouter extends StatefulWidget { - const AdaptiveRouter({super.key}); - - @override - State createState() => _AdaptiveRouterState(); -} - -class _AdaptiveRouterState extends State - with TickerProviderStateMixin { - late TextStyle _textStyle; - late ScrollController scrollController; - late TabController tabController; - bool innerScrollAllowed = false; - - @override - void initState() { - super.initState(); - tabController = TabController(length: 2, vsync: this); - _textStyle = MarketplaceTheme.heading1.copyWith( - color: Colors.black87.withAlpha(255), - ); - - scrollController = ScrollController(); - scrollController.addListener(_scrollListener); - } - - double prevOffset = 0; - void _scrollListener() { - setState(() { - innerScrollAllowed = scrollController.offset >= 230; - if (scrollController.offset >= 230) { - scrollController.animateTo(230, - duration: const Duration(milliseconds: 100), - curve: Curves.decelerate); - } - - // Don't change the text opacity if scrolling down from original position (overscroll) - if (scrollController.offset < 0) return; - - // By offset 200, ensure the text is transparent - if (scrollController.offset > 200) { - _textStyle = _textStyle.copyWith( - color: Colors.black87.withAlpha(0), - ); - return; - } - - var value = double.parse( - (1 - (scrollController.offset - 50) / 100).toStringAsFixed(2), - ); - - if (scrollController.offset > 200 && value > 0) value = 0; - if (value > 1) value = 1; - if (value < 0) value = 0; - _textStyle = _textStyle.copyWith( - color: Colors.black87.withAlpha((255 * value).ceil()), - ); - }); - } - - @override - void dispose() { - scrollController.dispose(); - tabController.dispose(); - super.dispose(); - } - - List destinations = [ - const NavigationRailDestination( - icon: Icon(Symbols.home), - label: Text('Create a recipe'), - ), - const NavigationRailDestination( - icon: Icon(Symbols.bookmarks), - label: Text('Saved Recipes'), - ) - ]; - - @override - Widget build(BuildContext context) { - final viewModel = context.watch(); - - return LayoutBuilder( - builder: (context, constraints) { - return Scaffold( - body: Stack( - children: [ - CustomScrollView( - controller: scrollController, - keyboardDismissBehavior: - ScrollViewKeyboardDismissBehavior.onDrag, - slivers: [ - AnimatedAppBar( - scrollController: scrollController, - textStyle: _textStyle, - tabController: tabController, - ), - SliverToBoxAdapter( - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: constraints.minHeight, - ), - child: TabBarView( - controller: tabController, - children: [ - PromptScreen( - canScroll: innerScrollAllowed, - ), - SavedRecipesScreen( - canScroll: innerScrollAllowed, - ), - ], - ), - ), - ) - ], - ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container( - height: bottomTabBarHeight, - decoration: ShapeDecoration( - shadows: const [ - BoxShadow( - offset: Offset(1, -1), - color: Colors.black45, - blurRadius: 5, - ) - ], - shape: const BottomBarShapeBorder(50), - color: Theme.of(context).primaryColor, - ), - child: TabBar( - labelColor: Colors.black, - unselectedLabelColor: Colors.black26, - controller: tabController, - onTap: (idx) { - setState(() {}); - }, - dividerColor: Colors.transparent, - tabs: [ - for (var destination in destinations) destination.icon, - ], - ), - ), - ), - if (viewModel.loadingNewRecipe) - Positioned( - top: (MediaQuery.of(context).size.height / 2) - 80, - left: (MediaQuery.of(context).size.width / 2) - 80, - height: 160, - width: 160, - child: IconLoadingAnimator( - icons: const [ - Symbols.icecream, - Symbols.local_pizza, - Symbols.restaurant_menu, - Symbols.egg, - Symbols.bakery_dining, - Symbols.skillet, - Symbols.nutrition, - Symbols.grocery, - Symbols.set_meal, - Icons.egg_alt, - Symbols.oven, - Icons.dinner_dining, - Icons.outdoor_grill, - Icons.cookie, - Icons.blender, - Symbols.stockpot, - ], - ), - ), - if (viewModel.geminiFailureResponse != null) - Positioned( - top: (MediaQuery.of(context).size.height / 4), - left: (MediaQuery.of(context).size.width / 2) - 160, - height: MediaQuery.of(context).size.height / 4, - width: 320, - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular( - MarketplaceTheme.defaultBorderRadius), - boxShadow: const [ - BoxShadow( - offset: Offset(-1, 1), - color: Colors.black45, - blurRadius: 5, - ) - ], - color: Colors.white, - border: Border.all( - color: MarketplaceTheme.focusedBorderColor, - width: 1, - ), - ), - child: Padding( - padding: const EdgeInsets.all(MarketplaceTheme.spacing6), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(viewModel.geminiFailureResponse!), - Align( - alignment: Alignment.bottomRight, - child: MarketplaceButton( - onPressed: () { - viewModel.geminiFailureResponse = null; - }, - buttonText: "Dismiss", - icon: Symbols.close, - ), - ) - ], - ), - ), - ), - ), - ], - ), - ); - }, - ); - } -} diff --git a/ai_recipe_generation/lib/services/firestore.dart b/ai_recipe_generation/lib/services/firestore.dart deleted file mode 100644 index 2a1e599c8..000000000 --- a/ai_recipe_generation/lib/services/firestore.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -import '../features/recipes/recipe_model.dart'; - -const recipePath = '/recipes'; -final firestore = FirebaseFirestore.instance; - -class FirestoreService { - static Future saveRecipe(Recipe recipe) async { - await firestore - .collection(recipePath) - .doc(recipe.id) - .set(recipe.toFirestore()); - } - - static Future deleteRecipe(Recipe recipe) async { - await firestore.doc("$recipePath/${recipe.id}").delete(); - } - - static Future updateRecipe(Recipe recipe) async { - await firestore - .doc("$recipePath/${recipe.id}") - .update(recipe.toFirestore()); - } -} diff --git a/ai_recipe_generation/lib/services/gemini.dart b/ai_recipe_generation/lib/services/gemini.dart deleted file mode 100644 index 56c2a6fb2..000000000 --- a/ai_recipe_generation/lib/services/gemini.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:google_generative_ai/google_generative_ai.dart'; - -import '../features/prompt/prompt_model.dart'; - -class GeminiService { - static Future generateContent( - GenerativeModel model, PromptData prompt) async { - if (prompt.images.isEmpty) { - return await GeminiService.generateContentFromText(model, prompt); - } else { - return await GeminiService.generateContentFromMultiModal(model, prompt); - } - } - - static Future generateContentFromMultiModal( - GenerativeModel model, PromptData prompt) async { - final mainText = TextPart(prompt.textInput); - final additionalTextParts = - prompt.additionalTextInputs.map((t) => TextPart(t)); - final imagesParts = []; - - for (var f in prompt.images) { - final bytes = await (f.readAsBytes()); - imagesParts.add(DataPart('image/jpeg', bytes)); - } - - final input = [ - Content.multi([...imagesParts, mainText, ...additionalTextParts]) - ]; - - return await model.generateContent( - input, - generationConfig: GenerationConfig( - temperature: 0.4, - topK: 32, - topP: 1, - maxOutputTokens: 4096, - ), - safetySettings: [ - SafetySetting(HarmCategory.harassment, HarmBlockThreshold.high), - SafetySetting(HarmCategory.hateSpeech, HarmBlockThreshold.high), - ], - ); - } - - static Future generateContentFromText( - GenerativeModel model, PromptData prompt) async { - final mainText = TextPart(prompt.textInput); - final additionalTextParts = - prompt.additionalTextInputs.map((t) => TextPart(t)).join("\n"); - - return await model.generateContent([ - Content.text( - '${mainText.text} \n $additionalTextParts', - ) - ]); - } -} diff --git a/ai_recipe_generation/lib/theme.dart b/ai_recipe_generation/lib/theme.dart deleted file mode 100644 index 1d546de95..000000000 --- a/ai_recipe_generation/lib/theme.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; - -abstract class MarketplaceTheme { - static ThemeData theme = ThemeData( - fontFamily: GoogleFonts.lexend().fontFamily, - textTheme: GoogleFonts.lexendTextTheme().copyWith().apply( - bodyColor: const Color(0xff000000), - displayColor: const Color(0xff000000)), - colorScheme: const ColorScheme.light( - primary: Color(0xffA2E3F6), - secondary: Color(0xff4FAD85), - tertiary: Color(0xffDE7A60), - scrim: Color(0xffFFABC7), - surface: Color(0xffFDF7F0), - onSecondary: Color(0xff000000), - shadow: Color(0xffAEAEAE), - onPrimary: Color(0xffFFFFFF), - ), - useMaterial3: true, - canvasColor: Colors.transparent, - navigationBarTheme: NavigationBarThemeData( - indicatorColor: const Color(0xffA2E3F6), - indicatorShape: CircleBorder( - side: BorderSide.lerp( - const BorderSide( - color: Color(0xff000000), - width: 2, - ), - const BorderSide( - color: Color(0xff000000), - width: 2, - ), - 1), - ), - ), - ); - - static const Color primary = Color(0xffA2E3F6); - static const Color scrim = Color(0xffFFABC7); - static const Color tertiary = Color(0xffDE7A60); - static const Color secondary = Color(0xff4FAD85); - static const Color borderColor = Colors.black12; - static const Color focusedBorderColor = Colors.black45; - - static const double defaultBorderRadius = 16; - - static const double defaultTextSize = 16; - - static const Color defaultTextColor = Colors.black87; - - static TextStyle get heading1 => theme.textTheme.headlineLarge!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 28, - //height: 36, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get heading2 => theme.textTheme.headlineMedium!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 24, - //height: 32, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get heading3 => theme.textTheme.headlineSmall!.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18, - //height: 24, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get subheading1 => theme.textTheme.bodyLarge!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 18, - //height: 20, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get subheading2 => theme.textTheme.bodyMedium!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - static TextStyle get paragraph => theme.textTheme.bodySmall!.copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get label => theme.textTheme.labelSmall!.copyWith( - fontWeight: FontWeight.w600, - fontSize: 11, - //height: 16, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierParagraph => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.normal, - fontSize: 14, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierSubheading => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.normal, - fontSize: 18, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static TextStyle get dossierHeading => GoogleFonts.anonymousPro().copyWith( - fontWeight: FontWeight.bold, - fontSize: 28, - //height: 18, - color: theme.colorScheme.onSecondary, - ); - - static const double _spacingUnit = 8; - static const double spacing8 = _spacingUnit / 2; - static const double spacing7 = _spacingUnit; - static const double spacing6 = _spacingUnit * 1.5; - static const double spacing5 = _spacingUnit * 2; - static const double spacing4 = _spacingUnit * 2.5; - static const double spacing3 = _spacingUnit * 3; - static const double spacing2 = _spacingUnit * 3.5; - static const double spacing1 = _spacingUnit * 4; - - static double lineWidth = 1; - - static const Widget verticalSpacer = SizedBox(height: spacing5); -} diff --git a/ai_recipe_generation/lib/util/device_info.dart b/ai_recipe_generation/lib/util/device_info.dart deleted file mode 100644 index 9006fbddd..000000000 --- a/ai_recipe_generation/lib/util/device_info.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:flutter/foundation.dart'; - -class DeviceInfo { - static Future initialize(DeviceInfoPlugin plugin) async { - if (kIsWeb) { - return await plugin.webBrowserInfo; - } - switch (defaultTargetPlatform) { - case TargetPlatform.android: - return await plugin.androidInfo; - case TargetPlatform.iOS: - return await plugin.iosInfo; - case TargetPlatform.macOS: - return plugin.macOsInfo; - case TargetPlatform.windows: - return await plugin.windowsInfo; - case TargetPlatform.linux: - return await plugin.linuxInfo; - default: - throw UnsupportedError( - 'Device info not supported for this platform', - ); - } - } - - static bool isPhysicalDeviceWithCamera(BaseDeviceInfo deviceInfo) { - if (deviceInfo is! IosDeviceInfo && deviceInfo is! AndroidDeviceInfo) { - return false; - } - if (deviceInfo is IosDeviceInfo && deviceInfo.isPhysicalDevice) { - return true; - } - if (deviceInfo is AndroidDeviceInfo && deviceInfo.isPhysicalDevice) { - return true; - } - return false; - } -} diff --git a/ai_recipe_generation/lib/util/extensions.dart b/ai_recipe_generation/lib/util/extensions.dart deleted file mode 100644 index 8239f8f8b..000000000 --- a/ai_recipe_generation/lib/util/extensions.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/rendering.dart'; - -extension SliverBreakpointUtils on SliverConstraints { - bool get isTablet => crossAxisExtent > 730 && crossAxisExtent < 1000; - bool get isDesktop => crossAxisExtent > 1000; - bool get isMobile => crossAxisExtent < 730; -} - -extension BoxBreakpointUtils on BoxConstraints { - bool get isTablet => maxWidth > 730 && maxWidth < 1000; - bool get isDesktop => maxWidth > 1000; - bool get isMobile => maxWidth < 730; -} diff --git a/ai_recipe_generation/lib/util/filter_chip_enums.dart b/ai_recipe_generation/lib/util/filter_chip_enums.dart deleted file mode 100644 index da118888f..000000000 --- a/ai_recipe_generation/lib/util/filter_chip_enums.dart +++ /dev/null @@ -1,66 +0,0 @@ -enum CuisineFilter { - italian, - mexican, - american, - french, - japanese, - chinese, - indian, - greek, - moroccan, - ethiopian, - southAfrican, -} - -enum BasicIngredientsFilter { - oil, - butter, - flour, - salt, - pepper, - sugar, - milk, - vinegar, -} - -enum DietaryRestrictionsFilter { - vegan, - vegetarian, - lactoseIntolerant, - kosher, - // keto, - wheatAllergies, - nutAllergies, - fishAllergies, - soyAllergies, -} - -String dietaryRestrictionReadable(DietaryRestrictionsFilter filter) { - return switch (filter) { - DietaryRestrictionsFilter.vegan => 'vegan', - DietaryRestrictionsFilter.vegetarian => 'vegetarian', - DietaryRestrictionsFilter.lactoseIntolerant => 'dairy free', - DietaryRestrictionsFilter.kosher => 'kosher', - // DietaryRestrictionsFilter.keto => 'low carb', - DietaryRestrictionsFilter.wheatAllergies => 'wheat allergy', - DietaryRestrictionsFilter.nutAllergies => 'nut allergy', - DietaryRestrictionsFilter.fishAllergies => 'fish allergy', - DietaryRestrictionsFilter.soyAllergies => 'soy allergy', - }; -} - -String cuisineReadable(CuisineFilter filter) { - return switch (filter) { - CuisineFilter.italian => 'Italian', - CuisineFilter.mexican => 'Mexican', - CuisineFilter.american => 'American', - CuisineFilter.french => 'French', - CuisineFilter.japanese => 'Japanese', - CuisineFilter.chinese => 'Chinese', - CuisineFilter.indian => 'Indian', - CuisineFilter.ethiopian => 'Ethiopian', - CuisineFilter.moroccan => 'Moroccan', - CuisineFilter.greek => 'Greek', - CuisineFilter.southAfrican => 'South African', - }; -} diff --git a/ai_recipe_generation/lib/util/json_parsing.dart b/ai_recipe_generation/lib/util/json_parsing.dart deleted file mode 100644 index 515a3404e..000000000 --- a/ai_recipe_generation/lib/util/json_parsing.dart +++ /dev/null @@ -1,8 +0,0 @@ -String cleanJson(String maybeInvalidJson) { - if (maybeInvalidJson.contains('```')) { - final withoutLeading = maybeInvalidJson.split('```json').last; - final withoutTrailing = withoutLeading.split('```').first; - return withoutTrailing; - } - return maybeInvalidJson; -} diff --git a/ai_recipe_generation/lib/util/tap_recorder.dart b/ai_recipe_generation/lib/util/tap_recorder.dart deleted file mode 100644 index d411473c5..000000000 --- a/ai_recipe_generation/lib/util/tap_recorder.dart +++ /dev/null @@ -1,121 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/scheduler.dart'; - -/// From: https://gist.github.com/creativecreatorormaybenot/cd42b60cb33c9962b19f629ec638d4de -/// This is code that I (https://twitter.com/creativemaybeno) wrote for a -/// StackOverflow answer. -/// You can find it here: https://stackoverflow.com/a/65067655/6509751. -/// List of the taps recorded by [TapRecorder]. -/// -/// This is only a make-shift solution of course. This will only be viable -/// when using a single [TapRecorder] because it is saved as a top-level -/// variable. -@visibleForTesting -final recordedTaps = []; - -/// These are the parameters for the visualization of the recorded taps. -const _tapRadius = 15.0, - _tapDuration = Duration(milliseconds: 420), - _tapColor = Colors.white, - _shadowColor = Colors.black, - _shadowElevation = 2.0; - -/// Widget that records any taps that hit its child. -/// -/// It does not matter to this widget whether the child accepts the hit events. -/// Everything hitting the rect of the child will be recorded. -/// -/// It will both visualize them and add them to [recordedTaps]. -class TapRecorder extends SingleChildRenderObjectWidget { - const TapRecorder({super.key, required Widget child}) : super(child: child); - - @override - RenderObject createRenderObject(BuildContext context) { - return _RenderTapRecorder(); - } -} - -class _RenderTapRecorder extends RenderProxyBox with _SilentTickerProvider { - final _recordedTaps = <_RecordedTap>[]; - - @override - void detach() { - for (final recordedTap in _recordedTaps) { - (recordedTap.animation as AnimationController).dispose(); - } - _recordedTaps.clear(); - super.detach(); - } - - @override - bool hitTest(BoxHitTestResult result, {required Offset position}) { - if (!size.contains(position)) return false; - // We always want to add a hit test entry for ourselves as we want to react - // to each and every hit event. - result.add(BoxHitTestEntry(this, position)); - return hitTestChildren(result, position: position); - } - - @override - void handleEvent(PointerEvent event, covariant HitTestEntry entry) { - // We do not want to interfere in the gesture arena, which is why we are not - // using regular tap recognizers. Instead, we handle it ourselves and always - // react to the hit events (ignoring the gesture arena). - if (event is PointerDownEvent) { - // Records the global position. - recordedTaps.add(event.position); - - final controller = AnimationController( - vsync: this, - duration: _tapDuration, - ), - recordedTap = _RecordedTap(event.localPosition, controller); - _recordedTaps.add(recordedTap); - - controller - ..addListener(markNeedsPaint) - ..addStatusListener((status) { - if (status == AnimationStatus.completed) { - controller.dispose(); - _recordedTaps.remove(recordedTap); - } - }) - ..forward(); - } - } - - @override - void paint(PaintingContext context, Offset offset) { - context.paintChild(child!, offset); - - final canvas = context.canvas; - for (final tap in _recordedTaps) { - final path = Path() - ..addOval( - Rect.fromCircle(center: tap.localPosition, radius: _tapRadius)); - final opacity = 1 - tap.animation.value; - - canvas.drawShadow(path, _shadowColor.withAlpha((2565 * opacity).ceil()), - _shadowElevation, true); - canvas.drawPath( - path, Paint()..color = _tapColor.withAlpha((2565 * opacity).ceil())); - } - } -} - -class _RecordedTap { - _RecordedTap(this.localPosition, this.animation); - - final Offset localPosition; - final Animation animation; -} - -/// Ticker provider that does not perform any diagnostics. -/// -/// We trust that the [_RenderTapRecorder] instance will dispose all tickers -/// by disposing the animation controllers. -mixin _SilentTickerProvider implements TickerProvider { - @override - Ticker createTicker(TickerCallback onTick) => Ticker(onTick); -} diff --git a/ai_recipe_generation/lib/widgets/add_image_widget.dart b/ai_recipe_generation/lib/widgets/add_image_widget.dart deleted file mode 100644 index 8f1fe6dee..000000000 --- a/ai_recipe_generation/lib/widgets/add_image_widget.dart +++ /dev/null @@ -1,85 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '../theme.dart'; - -class AddImage extends StatefulWidget { - const AddImage({ - super.key, - required this.onTap, - this.height = 100, - this.width = 100, - }); - - final VoidCallback onTap; - final double height; - final double width; - - @override - State createState() => _AddImageState(); -} - -class _AddImageState extends State { - bool hovered = false; - bool tappedDown = false; - - Color get buttonColor { - var state = (hovered, tappedDown); - return switch (state) { - // tapped down state - (_, true) => MarketplaceTheme.secondary.withAlpha(179), - // hovered - (true, _) => MarketplaceTheme.secondary.withAlpha(77), - // base color - (_, _) => MarketplaceTheme.secondary.withAlpha(77), - }; - } - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - hovered = true; - }); - }, - onExit: (event) { - setState(() { - hovered = false; - }); - }, - child: GestureDetector( - onTapDown: (details) { - setState(() { - tappedDown = true; - }); - }, - onTapUp: (details) { - setState(() { - tappedDown = false; - }); - widget.onTap(); - }, - child: SizedBox( - width: widget.width, - height: widget.height, - child: ClipRRect( - borderRadius: - BorderRadius.circular(MarketplaceTheme.defaultBorderRadius), - child: Container( - decoration: BoxDecoration( - color: buttonColor, - ), - child: const Center( - child: Icon( - Symbols.add_photo_alternate_rounded, - size: 32, - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/appbar_shape_border.dart b/ai_recipe_generation/lib/widgets/appbar_shape_border.dart deleted file mode 100644 index e9198c10e..000000000 --- a/ai_recipe_generation/lib/widgets/appbar_shape_border.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -class AppBarShapeBorder extends ShapeBorder { - final double radius; - - const AppBarShapeBorder(this.radius); - - @override - EdgeInsetsGeometry get dimensions => EdgeInsets.zero; - - @override - Path getInnerPath(Rect rect, {TextDirection? textDirection}) { - return Path(); // Define inner path if needed - } - - @override - Path getOuterPath(Rect rect, {TextDirection? textDirection}) { - // Define your custom shape path here - Path path = Path(); - path.moveTo(rect.left, rect.top); - path.lineTo(rect.left, rect.bottom - (radius * 2)); - - path.quadraticBezierTo( - rect.left, - rect.bottom - radius, - rect.left + radius, - rect.bottom - radius, - ); - - path.lineTo(rect.right - radius, rect.bottom - radius); - - path.quadraticBezierTo( - rect.right, rect.bottom - radius, rect.right, rect.bottom); - - path.lineTo(rect.right, rect.top); - path.close(); - return path; - } - - @override - void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { - // Define your painting logic here - Paint paint = Paint()..color = Colors.transparent; - canvas.drawPath(getOuterPath(rect), paint); - } - - @override - ShapeBorder scale(double t) { - // Implement scaling if needed - return this; - } -} diff --git a/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart b/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart deleted file mode 100644 index f55fa02e6..000000000 --- a/ai_recipe_generation/lib/widgets/bottom_bar_shape_border.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; - -class BottomBarShapeBorder extends ShapeBorder { - final double radius; - - const BottomBarShapeBorder(this.radius); - - @override - EdgeInsetsGeometry get dimensions => EdgeInsets.zero; - - @override - Path getInnerPath(Rect rect, {TextDirection? textDirection}) { - return Path(); // Define inner path if needed - } - - @override - Path getOuterPath(Rect rect, {TextDirection? textDirection}) { - // Define your custom shape path here - Path path = Path(); - path.moveTo(rect.left, rect.top - radius); - path.quadraticBezierTo( - rect.left, - rect.top, - rect.left + radius, - rect.top, - ); - - path.lineTo(rect.right - radius, rect.top); - path.quadraticBezierTo( - rect.right, - rect.top, - rect.right, - rect.bottom, - ); - - path.lineTo(rect.left, rect.bottom); - path.lineTo(rect.left, rect.top + radius); - path.close(); - return path; - } - - @override - void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) { - // Define your painting logic here - Paint paint = Paint()..color = Colors.transparent; - canvas.drawPath(getOuterPath(rect), paint); - } - - @override - ShapeBorder scale(double t) { - // Implement scaling if needed - return this; - } -} diff --git a/ai_recipe_generation/lib/widgets/cross_image_widget.dart b/ai_recipe_generation/lib/widgets/cross_image_widget.dart deleted file mode 100644 index 308204731..000000000 --- a/ai_recipe_generation/lib/widgets/cross_image_widget.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; - -class CrossImage extends StatelessWidget { - const CrossImage({ - super.key, - required this.file, - this.fit = BoxFit.cover, - this.height = 100, - this.width = 100, - }); - - final XFile file; - final BoxFit fit; - final double width; - final double height; - - @override - Widget build(BuildContext context) { - if (kIsWeb) { - return Image.network( - file.path, - fit: fit, - ); - } else { - return Image.file( - File(file.path), - height: height, - width: width, - ); - } - } - - static DecorationImage decoration(XFile file, {BoxFit fit = BoxFit.cover}) { - final image = kIsWeb ? NetworkImage(file.path) : FileImage(File(file.path)); - return DecorationImage(image: image as ImageProvider, fit: fit); - } -} diff --git a/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart b/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart deleted file mode 100644 index 5d403699c..000000000 --- a/ai_recipe_generation/lib/widgets/filter_chip_selection_input.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:ai_recipe_generation/theme.dart'; -import 'package:ai_recipe_generation/util/extensions.dart'; -import 'package:ai_recipe_generation/util/filter_chip_enums.dart'; -import 'package:flutter/material.dart'; - -class FilterChipSelectionInput extends StatefulWidget { - const FilterChipSelectionInput({ - super.key, - required this.onChipSelected, - required this.selectedValues, - required this.allValues, - }); - - final Null Function(Set) onChipSelected; - final Set selectedValues; - final List allValues; - - @override - State createState() => - _CategorySelectionInputState(); -} - -class _CategorySelectionInputState - extends State { - bool isExpanded = false; - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, constraints) { - return Theme( - data: Theme.of(context).copyWith(canvasColor: Colors.transparent), - child: Wrap( - spacing: 5.0, - runSpacing: constraints.isMobile ? 5.0 : -5.0, - children: List.generate( - widget.allValues.length, - (idx) { - final chipData = widget.allValues[idx]; - String label(dynamic chipData) { - if (chipData is CuisineFilter) { - return cuisineReadable(chipData); - } else if (chipData is DietaryRestrictionsFilter) { - return dietaryRestrictionReadable(chipData); - } else if (chipData is BasicIngredientsFilter) { - return chipData.name; - } else { - throw "unknown enum"; - } - } - - return FilterChip( - color: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return MarketplaceTheme.secondary.withAlpha(128); - } - if (states.contains(WidgetState.selected)) { - return MarketplaceTheme.secondary.withAlpha(77); - } - return Theme.of(context).splashColor; - }), - surfaceTintColor: Colors.transparent, - shadowColor: Colors.transparent, - backgroundColor: Colors.transparent, - padding: const EdgeInsets.all(4), - label: Text( - label(chipData), - style: MarketplaceTheme.dossierParagraph, - ), - selected: widget.selectedValues.contains(chipData), - onSelected: (selected) { - setState( - () { - if (selected) { - widget.selectedValues.add(chipData as T); - } else { - widget.selectedValues.remove(chipData); - } - widget.onChipSelected(widget.selectedValues); - }, - ); - }, - ); - }, - ).toList(), - ), - ); - }); - } -} diff --git a/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart b/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart deleted file mode 100644 index d6fe3591c..000000000 --- a/ai_recipe_generation/lib/widgets/highlight_border_on_hover_widget.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../theme.dart'; - -class HighlightBorderOnHoverWidget extends StatefulWidget { - const HighlightBorderOnHoverWidget({ - super.key, - required this.child, - this.color = MarketplaceTheme.secondary, - required this.borderRadius, - }); - - final Widget child; - final Color color; - final BorderRadius borderRadius; - - @override - State createState() => - _HighlightBorderOnHoverWidgetState(); -} - -class _HighlightBorderOnHoverWidgetState - extends State { - bool hovered = false; - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (event) { - setState(() { - hovered = true; - }); - }, - onExit: (event) { - setState(() { - hovered = false; - }); - }, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).splashColor.withAlpha(25), - border: Border.all( - color: hovered ? widget.color : MarketplaceTheme.borderColor, - ), - borderRadius: widget.borderRadius, - ), - child: widget.child, - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart b/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart deleted file mode 100644 index 3b746222c..000000000 --- a/ai_recipe_generation/lib/widgets/icon_loading_indicator.dart +++ /dev/null @@ -1,93 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:ai_recipe_generation/theme.dart'; -import 'package:flutter/material.dart'; - -class IconLoadingAnimator extends StatefulWidget { - IconLoadingAnimator({ - super.key, - required this.icons, - this.animationDuration, - this.millisecondsBetweenAnimations, - }); - - final List icons; - final Duration? animationDuration; - final int? millisecondsBetweenAnimations; - final List colors = [ - MarketplaceTheme.primary, - MarketplaceTheme.secondary, - MarketplaceTheme.tertiary, - MarketplaceTheme.scrim, - Colors.black87, - ]; - - @override - State createState() => _IconLoadingAnimatorState(); -} - -var rand = Random(); - -class _IconLoadingAnimatorState extends State { - late IconData currentIcon; - late Color currentColor; - late Timer timer; - - @override - void initState() { - super.initState(); - - currentIcon = widget.icons[rand.nextInt(widget.icons.length)]; - currentColor = widget.colors[rand.nextInt(widget.colors.length)]; - - timer = Timer.periodic( - Duration(milliseconds: widget.millisecondsBetweenAnimations ?? 1000), - (timer) { - nextIcon(); - }, - ); - } - - void nextIcon() { - setState(() { - currentIcon = widget.icons[rand.nextInt(widget.icons.length)]; - currentColor = widget.colors[rand.nextInt(widget.colors.length)]; - }); - } - - @override - void dispose() { - timer.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.white, - border: Border.all( - color: MarketplaceTheme.focusedBorderColor, - width: 2, - ), - ), - child: AnimatedSwitcher( - duration: widget.animationDuration ?? const Duration(milliseconds: 200), - transitionBuilder: (child, animation) { - return ScaleTransition( - scale: animation, - child: child, - ); - }, - child: Icon( - size: 75, - color: currentColor, - key: Key(currentIcon.hashCode.toString()), - currentIcon, - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart b/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart deleted file mode 100644 index 53cce4aaa..000000000 --- a/ai_recipe_generation/lib/widgets/marketplace_button_widget.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../theme.dart'; - -class MarketplaceButton extends StatefulWidget { - const MarketplaceButton({ - super.key, - required this.onPressed, - required this.buttonText, - required this.icon, - this.iconRotateAngle, - this.iconBackgroundColor, - this.iconColor, - this.buttonBackgroundColor, - this.hoverColor, - }); - - final VoidCallback? onPressed; - final String buttonText; - final IconData icon; - final double? iconRotateAngle; - final Color? iconBackgroundColor; - final Color? iconColor; - final Color? buttonBackgroundColor; - final Color? hoverColor; - - @override - State createState() => _MarketplaceButtonState(); -} - -class _MarketplaceButtonState extends State { - @override - Widget build(BuildContext context) { - return TextButton.icon( - icon: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - color: widget.iconBackgroundColor ?? Colors.transparent, - ), - child: Transform.rotate( - angle: widget.iconRotateAngle ?? 0, - child: Icon( - widget.icon, - color: widget.iconColor ?? Colors.black87, - size: 20.0, - ), - ), - ), - label: Text( - widget.buttonText, - style: MarketplaceTheme.dossierParagraph, - ), - onPressed: widget.onPressed, - style: ButtonStyle( - backgroundColor: WidgetStateColor.resolveWith((states) { - if (states.contains(WidgetState.hovered)) { - return widget.hoverColor ?? - MarketplaceTheme.secondary.withAlpha(77); - } - return widget.buttonBackgroundColor ?? - Theme.of(context).splashColor.withAlpha(77); - }), - shape: WidgetStateProperty.resolveWith( - (states) { - if (states.contains(WidgetState.hovered)) { - // TODO: how can I animate between states? - } - return const RoundedRectangleBorder( - side: BorderSide(color: Colors.black26), - borderRadius: BorderRadius.all( - Radius.circular(MarketplaceTheme.defaultBorderRadius), - ), - ); - }, - ), - textStyle: WidgetStateTextStyle.resolveWith( - (states) { - return MarketplaceTheme.dossierParagraph.copyWith( - color: Colors.black45, - ); - }, - ), - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/prompt_image_widget.dart b/ai_recipe_generation/lib/widgets/prompt_image_widget.dart deleted file mode 100644 index 860726f8c..000000000 --- a/ai_recipe_generation/lib/widgets/prompt_image_widget.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:ai_recipe_generation/theme.dart'; -import 'package:flutter/material.dart'; -import 'package:image_picker/image_picker.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import 'cross_image_widget.dart'; - -typedef OnTapRemoveImageCallback = void Function(XFile); - -class PromptImage extends StatelessWidget { - const PromptImage({ - super.key, - required this.file, - this.onTapIcon, - this.width = 100, - }); - - final XFile file; - final VoidCallback? onTapIcon; - final double width; - - @override - Widget build(BuildContext context) { - return SizedBox( - width: width, - child: Stack( - children: [ - Positioned( - child: ClipRRect( - borderRadius: const BorderRadius.all( - Radius.circular( - MarketplaceTheme.defaultBorderRadius, - ), - ), - child: Container( - foregroundDecoration: BoxDecoration( - image: CrossImage.decoration(file), - ), - ), - ), - ), - if (onTapIcon != null) - Positioned( - right: 5, - top: 5, - child: GestureDetector( - onTap: onTapIcon, - child: Container( - decoration: const BoxDecoration( - color: Colors.white, - shape: BoxShape.circle, - ), - child: Icon( - Symbols.remove, - size: 16, - color: Colors.red.shade400, - ), - ), - ), - ), - ], - ), - ); - } -} diff --git a/ai_recipe_generation/lib/widgets/star_rating.dart b/ai_recipe_generation/lib/widgets/star_rating.dart deleted file mode 100644 index 8650ca8d9..000000000 --- a/ai_recipe_generation/lib/widgets/star_rating.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -typedef StarRatingCallback = void Function(int); - -class StartRating extends StatefulWidget { - const StartRating({ - super.key, - required this.starColor, - required this.onTap, - this.initialRating = -1, - }); - - final Color starColor; - final int initialRating; - - /// If [onTap] is not null, the stars are interactive - final StarRatingCallback? onTap; - - @override - State createState() => _StartRatingState(); -} - -class _StartRatingState extends State { - late int selectedIdx; - - @override - void initState() { - selectedIdx = widget.initialRating - 1; - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Row( - children: [ - ...List.generate( - 5, - (index) => GestureDetector( - onTap: widget.onTap != null - ? () { - setState(() { - selectedIdx = index; - }); - widget.onTap!(index); - } - : null, - child: Icon( - Symbols.kid_star, - color: widget.starColor, - fill: selectedIdx >= index ? 1 : 0, - ), - ), - ) - ], - ); - } -} diff --git a/ai_recipe_generation/linux/.gitignore b/ai_recipe_generation/linux/.gitignore deleted file mode 100644 index d3896c984..000000000 --- a/ai_recipe_generation/linux/.gitignore +++ /dev/null @@ -1 +0,0 @@ -flutter/ephemeral diff --git a/ai_recipe_generation/linux/CMakeLists.txt b/ai_recipe_generation/linux/CMakeLists.txt deleted file mode 100644 index 7eaab24db..000000000 --- a/ai_recipe_generation/linux/CMakeLists.txt +++ /dev/null @@ -1,145 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "gemini_io_talk") -# The unique GTK application identifier for this application. See: -# https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.gemini_io_talk") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(SET CMP0063 NEW) - -# Load bundled libraries from the lib/ directory relative to the binary. -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Define build configuration options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_14) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) - -add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") - -# Define the application target. To change its name, change BINARY_NAME above, -# not the value here, or `flutter run` will no longer work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} - "main.cc" - "my_application.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add dependency libraries. Add any application-specific dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) - -# Only the install-generated bundle's copy of the executable will launch -# correctly, since the resources must in the right relative locations. To avoid -# people trying to run the unbundled copy, put it in a subdirectory instead of -# the default top-level location. -set_target_properties(${BINARY_NAME} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" -) - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) - install(FILES "${bundled_library}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endforeach(bundled_library) - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/ai_recipe_generation/linux/flutter/CMakeLists.txt b/ai_recipe_generation/linux/flutter/CMakeLists.txt deleted file mode 100644 index d5bd01648..000000000 --- a/ai_recipe_generation/linux/flutter/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -find_package(PkgConfig REQUIRED) -pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) -pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) - -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "fl_basic_message_channel.h" - "fl_binary_codec.h" - "fl_binary_messenger.h" - "fl_dart_project.h" - "fl_engine.h" - "fl_json_message_codec.h" - "fl_json_method_codec.h" - "fl_message_codec.h" - "fl_method_call.h" - "fl_method_channel.h" - "fl_method_codec.h" - "fl_method_response.h" - "fl_plugin_registrar.h" - "fl_plugin_registry.h" - "fl_standard_message_codec.h" - "fl_standard_method_codec.h" - "fl_string_codec.h" - "fl_value.h" - "fl_view.h" - "flutter_linux.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE - PkgConfig::GTK - PkgConfig::GLIB - PkgConfig::GIO -) -add_dependencies(flutter flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CMAKE_CURRENT_BINARY_DIR}/_phony_ - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" - ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} -) diff --git a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc b/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 64a0ecea4..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include - -void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); - file_selector_plugin_register_with_registrar(file_selector_linux_registrar); -} diff --git a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h b/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h deleted file mode 100644 index e0f0a47bc..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void fl_register_plugins(FlPluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/ai_recipe_generation/linux/flutter/generated_plugins.cmake b/ai_recipe_generation/linux/flutter/generated_plugins.cmake deleted file mode 100644 index 2db3c22ae..000000000 --- a/ai_recipe_generation/linux/flutter/generated_plugins.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - file_selector_linux -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/ai_recipe_generation/linux/main.cc b/ai_recipe_generation/linux/main.cc deleted file mode 100644 index e7c5c5437..000000000 --- a/ai_recipe_generation/linux/main.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "my_application.h" - -int main(int argc, char** argv) { - g_autoptr(MyApplication) app = my_application_new(); - return g_application_run(G_APPLICATION(app), argc, argv); -} diff --git a/ai_recipe_generation/linux/my_application.cc b/ai_recipe_generation/linux/my_application.cc deleted file mode 100644 index 1e94f6892..000000000 --- a/ai_recipe_generation/linux/my_application.cc +++ /dev/null @@ -1,104 +0,0 @@ -#include "my_application.h" - -#include -#ifdef GDK_WINDOWING_X11 -#include -#endif - -#include "flutter/generated_plugin_registrant.h" - -struct _MyApplication { - GtkApplication parent_instance; - char** dart_entrypoint_arguments; -}; - -G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) - -// Implements GApplication::activate. -static void my_application_activate(GApplication* application) { - MyApplication* self = MY_APPLICATION(application); - GtkWindow* window = - GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); - - // Use a header bar when running in GNOME as this is the common style used - // by applications and is the setup most users will be using (e.g. Ubuntu - // desktop). - // If running on X and not using GNOME then just use a traditional title bar - // in case the window manager does more exotic layout, e.g. tiling. - // If running on Wayland assume the header bar will work (may need changing - // if future cases occur). - gboolean use_header_bar = TRUE; -#ifdef GDK_WINDOWING_X11 - GdkScreen* screen = gtk_window_get_screen(window); - if (GDK_IS_X11_SCREEN(screen)) { - const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); - if (g_strcmp0(wm_name, "GNOME Shell") != 0) { - use_header_bar = FALSE; - } - } -#endif - if (use_header_bar) { - GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); - gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "gemini_io_talk"); - gtk_header_bar_set_show_close_button(header_bar, TRUE); - gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); - } else { - gtk_window_set_title(window, "gemini_io_talk"); - } - - gtk_window_set_default_size(window, 1280, 720); - gtk_widget_show(GTK_WIDGET(window)); - - g_autoptr(FlDartProject) project = fl_dart_project_new(); - fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); - - FlView* view = fl_view_new(project); - gtk_widget_show(GTK_WIDGET(view)); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); - - fl_register_plugins(FL_PLUGIN_REGISTRY(view)); - - gtk_widget_grab_focus(GTK_WIDGET(view)); -} - -// Implements GApplication::local_command_line. -static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { - MyApplication* self = MY_APPLICATION(application); - // Strip out the first argument as it is the binary name. - self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); - - g_autoptr(GError) error = nullptr; - if (!g_application_register(application, nullptr, &error)) { - g_warning("Failed to register: %s", error->message); - *exit_status = 1; - return TRUE; - } - - g_application_activate(application); - *exit_status = 0; - - return TRUE; -} - -// Implements GObject::dispose. -static void my_application_dispose(GObject* object) { - MyApplication* self = MY_APPLICATION(object); - g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); - G_OBJECT_CLASS(my_application_parent_class)->dispose(object); -} - -static void my_application_class_init(MyApplicationClass* klass) { - G_APPLICATION_CLASS(klass)->activate = my_application_activate; - G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; - G_OBJECT_CLASS(klass)->dispose = my_application_dispose; -} - -static void my_application_init(MyApplication* self) {} - -MyApplication* my_application_new() { - return MY_APPLICATION(g_object_new(my_application_get_type(), - "application-id", APPLICATION_ID, - "flags", G_APPLICATION_NON_UNIQUE, - nullptr)); -} diff --git a/ai_recipe_generation/linux/my_application.h b/ai_recipe_generation/linux/my_application.h deleted file mode 100644 index 72271d5e4..000000000 --- a/ai_recipe_generation/linux/my_application.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef FLUTTER_MY_APPLICATION_H_ -#define FLUTTER_MY_APPLICATION_H_ - -#include - -G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, - GtkApplication) - -/** - * my_application_new: - * - * Creates a new Flutter-based application. - * - * Returns: a new #MyApplication. - */ -MyApplication* my_application_new(); - -#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/ai_recipe_generation/macos/.gitignore b/ai_recipe_generation/macos/.gitignore deleted file mode 100644 index 746adbb6b..000000000 --- a/ai_recipe_generation/macos/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# Flutter-related -**/Flutter/ephemeral/ -**/Pods/ - -# Xcode-related -**/dgph -**/xcuserdata/ diff --git a/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig b/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig deleted file mode 100644 index 4b81f9b2d..000000000 --- a/ai_recipe_generation/macos/Flutter/Flutter-Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig b/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig deleted file mode 100644 index 5caa9d157..000000000 --- a/ai_recipe_generation/macos/Flutter/Flutter-Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift b/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift deleted file mode 100644 index 400a1a849..000000000 --- a/ai_recipe_generation/macos/Flutter/GeneratedPluginRegistrant.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// Generated file. Do not edit. -// - -import FlutterMacOS -import Foundation - -import cloud_firestore -import device_info_plus -import file_selector_macos -import firebase_core -import path_provider_foundation -import shared_preferences_foundation - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { - FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) - DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) - FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) - FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) - PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) - SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) -} diff --git a/ai_recipe_generation/macos/Podfile b/ai_recipe_generation/macos/Podfile deleted file mode 100644 index c795730db..000000000 --- a/ai_recipe_generation/macos/Podfile +++ /dev/null @@ -1,43 +0,0 @@ -platform :osx, '10.14' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_macos_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) - target 'RunnerTests' do - inherit! :search_paths - end -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_macos_build_settings(target) - end -end diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj b/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 153f28d0d..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,795 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXAggregateTarget section */ - 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; - buildPhases = ( - 33CC111E2044C6BF0003C045 /* ShellScript */, - ); - dependencies = ( - ); - name = "Flutter Assemble"; - productName = FLX; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 045ED23A4B33E4F2FA434896 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */; }; - 244B07C54A330077F9A2F055 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */; }; - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 4A9C215D043B623939727167 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC10EC2044A3C60003C045; - remoteInfo = Runner; - }; - 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 33CC10E52044A3C60003C045 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 33CC111A2044C6BA0003C045; - remoteInfo = FLX; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 33CC110E2044A8840003C045 /* Bundle Framework */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Bundle Framework"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = gemini_io_talk.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; - 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; - 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; - 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; - 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = ""; }; - 7358AE11276B20A48E44DAF5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - B82D42F50A1CA25092D94C23 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; - B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; - C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C359B5621FA51EC13E1CF60F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 331C80D2294CF70F00263BE5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4A9C215D043B623939727167 /* Pods_RunnerTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EA2044A3C60003C045 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 244B07C54A330077F9A2F055 /* Pods_Runner.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 331C80D6294CF71000263BE5 /* RunnerTests */ = { - isa = PBXGroup; - children = ( - 331C80D7294CF71000263BE5 /* RunnerTests.swift */, - ); - path = RunnerTests; - sourceTree = ""; - }; - 33BA886A226E78AF003329D5 /* Configs */ = { - isa = PBXGroup; - children = ( - 33E5194F232828860026EE4D /* AppInfo.xcconfig */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, - ); - path = Configs; - sourceTree = ""; - }; - 33CC10E42044A3C60003C045 = { - isa = PBXGroup; - children = ( - 33FAB671232836740065AC1E /* Runner */, - 33CEB47122A05771004F2AC0 /* Flutter */, - 331C80D6294CF71000263BE5 /* RunnerTests */, - 33CC10EE2044A3C60003C045 /* Products */, - D73912EC22F37F3D000D13A0 /* Frameworks */, - 4641E830ED1DA52584603D32 /* Pods */, - 38F9AD322406A70F654D9022 /* GoogleService-Info.plist */, - ); - sourceTree = ""; - }; - 33CC10EE2044A3C60003C045 /* Products */ = { - isa = PBXGroup; - children = ( - 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */, - 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 33CC11242044D66E0003C045 /* Resources */ = { - isa = PBXGroup; - children = ( - 33CC10F22044A3C60003C045 /* Assets.xcassets */, - 33CC10F42044A3C60003C045 /* MainMenu.xib */, - 33CC10F72044A3C60003C045 /* Info.plist */, - ); - name = Resources; - path = ..; - sourceTree = ""; - }; - 33CEB47122A05771004F2AC0 /* Flutter */ = { - isa = PBXGroup; - children = ( - 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, - 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, - 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, - 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - ); - path = Flutter; - sourceTree = ""; - }; - 33FAB671232836740065AC1E /* Runner */ = { - isa = PBXGroup; - children = ( - 33CC10F02044A3C60003C045 /* AppDelegate.swift */, - 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, - 33E51913231747F40026EE4D /* DebugProfile.entitlements */, - 33E51914231749380026EE4D /* Release.entitlements */, - 33CC11242044D66E0003C045 /* Resources */, - 33BA886A226E78AF003329D5 /* Configs */, - ); - path = Runner; - sourceTree = ""; - }; - 4641E830ED1DA52584603D32 /* Pods */ = { - isa = PBXGroup; - children = ( - 7358AE11276B20A48E44DAF5 /* Pods-Runner.debug.xcconfig */, - B82D42F50A1CA25092D94C23 /* Pods-Runner.release.xcconfig */, - C359B5621FA51EC13E1CF60F /* Pods-Runner.profile.xcconfig */, - B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */, - 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */, - 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; - D73912EC22F37F3D000D13A0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 08283E03A7D1FDC603938AE0 /* Pods_Runner.framework */, - C2B3A731FA44098272D037D5 /* Pods_RunnerTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 331C80D4294CF70F00263BE5 /* RunnerTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; - buildPhases = ( - D55612DEAFE1622F2EAF6516 /* [CP] Check Pods Manifest.lock */, - 331C80D1294CF70F00263BE5 /* Sources */, - 331C80D2294CF70F00263BE5 /* Frameworks */, - 331C80D3294CF70F00263BE5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 331C80DA294CF71000263BE5 /* PBXTargetDependency */, - ); - name = RunnerTests; - productName = RunnerTests; - productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 33CC10EC2044A3C60003C045 /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 1DCEDE898738D93BCB6F7DE0 /* [CP] Check Pods Manifest.lock */, - 33CC10E92044A3C60003C045 /* Sources */, - 33CC10EA2044A3C60003C045 /* Frameworks */, - 33CC10EB2044A3C60003C045 /* Resources */, - 33CC110E2044A8840003C045 /* Bundle Framework */, - 3399D490228B24CF009A79C7 /* ShellScript */, - 86416C488D6732C2DB9D683A /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 33CC11202044C79F0003C045 /* PBXTargetDependency */, - ); - name = Runner; - productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* gemini_io_talk.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 33CC10E52044A3C60003C045 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1510; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 331C80D4294CF70F00263BE5 = { - CreatedOnToolsVersion = 14.0; - TestTargetID = 33CC10EC2044A3C60003C045; - }; - 33CC10EC2044A3C60003C045 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - SystemCapabilities = { - com.apple.Sandbox = { - enabled = 1; - }; - }; - }; - 33CC111A2044C6BA0003C045 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 33CC10E42044A3C60003C045; - productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 33CC10EC2044A3C60003C045 /* Runner */, - 331C80D4294CF70F00263BE5 /* RunnerTests */, - 33CC111A2044C6BA0003C045 /* Flutter Assemble */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 331C80D3294CF70F00263BE5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10EB2044A3C60003C045 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, - 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, - 045ED23A4B33E4F2FA434896 /* GoogleService-Info.plist in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 1DCEDE898738D93BCB6F7DE0 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 3399D490228B24CF009A79C7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; - }; - 33CC111E2044C6BF0003C045 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - Flutter/ephemeral/FlutterInputs.xcfilelist, - ); - inputPaths = ( - Flutter/ephemeral/tripwire, - ); - outputFileListPaths = ( - Flutter/ephemeral/FlutterOutputs.xcfilelist, - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; - }; - 86416C488D6732C2DB9D683A /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - D55612DEAFE1622F2EAF6516 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 331C80D1294CF70F00263BE5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 33CC10E92044A3C60003C045 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, - 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, - 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC10EC2044A3C60003C045 /* Runner */; - targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; - }; - 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; - targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { - isa = PBXVariantGroup; - children = ( - 33CC10F52044A3C60003C045 /* Base */, - ); - name = MainMenu.xib; - path = Runner; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 331C80DB294CF71000263BE5 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = B8C09668FAC2FC05DF59B887 /* Pods-RunnerTests.debug.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Debug; - }; - 331C80DC294CF71000263BE5 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 20E24AD12C2A08D4C5838D8F /* Pods-RunnerTests.release.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Release; - }; - 331C80DD294CF71000263BE5 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7DC58890B42AAC39F0F3C3BA /* Pods-RunnerTests.profile.xcconfig */; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 1; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk.RunnerTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gemini_io_talk.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/gemini_io_talk"; - }; - name = Profile; - }; - 338D0CE9231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Profile; - }; - 338D0CEA231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Profile; - }; - 338D0CEB231458BD00FA5F75 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Profile; - }; - 33CC10F92044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 33CC10FA2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.14; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 33CC10FC2044A3C60003C045 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 33CC10FD2044A3C60003C045 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 33CC111C2044C6BA0003C045 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Manual; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 33CC111D2044C6BA0003C045 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 331C80DB294CF71000263BE5 /* Debug */, - 331C80DC294CF71000263BE5 /* Release */, - 331C80DD294CF71000263BE5 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10F92044A3C60003C045 /* Debug */, - 33CC10FA2044A3C60003C045 /* Release */, - 338D0CE9231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC10FC2044A3C60003C045 /* Debug */, - 33CC10FD2044A3C60003C045 /* Release */, - 338D0CEA231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 33CC111C2044C6BA0003C045 /* Debug */, - 33CC111D2044C6BA0003C045 /* Release */, - 338D0CEB231458BD00FA5F75 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 33CC10E52044A3C60003C045 /* Project object */; -} diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index f9c57d700..000000000 --- a/ai_recipe_generation/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata b/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 21a3cc14c..000000000 --- a/ai_recipe_generation/macos/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/ai_recipe_generation/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/ai_recipe_generation/macos/Runner/AppDelegate.swift b/ai_recipe_generation/macos/Runner/AppDelegate.swift deleted file mode 100644 index d53ef6437..000000000 --- a/ai_recipe_generation/macos/Runner/AppDelegate.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Cocoa -import FlutterMacOS - -@NSApplicationMain -class AppDelegate: FlutterAppDelegate { - override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { - return true - } -} diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index a2ec33f19..000000000 --- a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "app_icon_64.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "app_icon_1024.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png deleted file mode 100644 index 82b6f9d9a..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png deleted file mode 100644 index 13b35eba5..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png deleted file mode 100644 index 0a3f5fa40..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png deleted file mode 100644 index bdb57226d..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png deleted file mode 100644 index f083318e0..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png deleted file mode 100644 index 326c0e72c..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png deleted file mode 100644 index 2f1632cfd..000000000 Binary files a/ai_recipe_generation/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png and /dev/null differ diff --git a/ai_recipe_generation/macos/Runner/Base.lproj/MainMenu.xib b/ai_recipe_generation/macos/Runner/Base.lproj/MainMenu.xib deleted file mode 100644 index 80e867a4e..000000000 --- a/ai_recipe_generation/macos/Runner/Base.lproj/MainMenu.xib +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig b/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig deleted file mode 100644 index 63f79321d..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/AppInfo.xcconfig +++ /dev/null @@ -1,14 +0,0 @@ -// Application-level settings for the Runner target. -// -// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the -// future. If not, the values below would default to using the project name when this becomes a -// 'flutter create' template. - -// The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = gemini_io_talk - -// The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.geminiIoTalk - -// The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. diff --git a/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig deleted file mode 100644 index 36b0fd946..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Debug.xcconfig" -#include "Warnings.xcconfig" diff --git a/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig deleted file mode 100644 index dff4f4956..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include "../../Flutter/Flutter-Release.xcconfig" -#include "Warnings.xcconfig" diff --git a/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig b/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig deleted file mode 100644 index 42bcbf478..000000000 --- a/ai_recipe_generation/macos/Runner/Configs/Warnings.xcconfig +++ /dev/null @@ -1,13 +0,0 @@ -WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES -CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_PRAGMA_PACK = YES -CLANG_WARN_STRICT_PROTOTYPES = YES -CLANG_WARN_COMMA = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -GCC_WARN_SHADOW = YES -CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/ai_recipe_generation/macos/Runner/DebugProfile.entitlements b/ai_recipe_generation/macos/Runner/DebugProfile.entitlements deleted file mode 100644 index 58268b7ac..000000000 --- a/ai_recipe_generation/macos/Runner/DebugProfile.entitlements +++ /dev/null @@ -1,16 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.cs.allow-jit - - com.apple.security.network.server - - com.apple.security.files.user-selected.read-only - - com.apple.security.network.client - - - diff --git a/ai_recipe_generation/macos/Runner/GoogleService-Info.plist b/ai_recipe_generation/macos/Runner/GoogleService-Info.plist deleted file mode 100644 index 6f047004f..000000000 --- a/ai_recipe_generation/macos/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - API_KEY - AIzaSyBNEtAHdjm3oFV6JZ6nbx5t6Pfyj4w4hbo - GCM_SENDER_ID - 44885228795 - PLIST_VERSION - 1 - BUNDLE_ID - com.example.geminiIoTalk.RunnerTests - PROJECT_ID - gemini-cat-chef - STORAGE_BUCKET - gemini-cat-chef.appspot.com - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:44885228795:ios:9585fdfdf50acdd18f845e - - \ No newline at end of file diff --git a/ai_recipe_generation/macos/Runner/Info.plist b/ai_recipe_generation/macos/Runner/Info.plist deleted file mode 100644 index 49ba8eb6a..000000000 --- a/ai_recipe_generation/macos/Runner/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - $(PRODUCT_COPYRIGHT) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSCameraUsageDescription - Explanation on why the camera access is needed. - NSMicrophoneUsageDescription - Explanation on why the microphone access is needed. - - diff --git a/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift b/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift deleted file mode 100644 index 3cc05eb23..000000000 --- a/ai_recipe_generation/macos/Runner/MainFlutterWindow.swift +++ /dev/null @@ -1,15 +0,0 @@ -import Cocoa -import FlutterMacOS - -class MainFlutterWindow: NSWindow { - override func awakeFromNib() { - let flutterViewController = FlutterViewController() - let windowFrame = self.frame - self.contentViewController = flutterViewController - self.setFrame(windowFrame, display: true) - - RegisterGeneratedPlugins(registry: flutterViewController) - - super.awakeFromNib() - } -} diff --git a/ai_recipe_generation/macos/Runner/Release.entitlements b/ai_recipe_generation/macos/Runner/Release.entitlements deleted file mode 100644 index b03a19487..000000000 --- a/ai_recipe_generation/macos/Runner/Release.entitlements +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.security.app-sandbox - - com.apple.security.network.client - - - diff --git a/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift b/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift deleted file mode 100644 index 5418c9f53..000000000 --- a/ai_recipe_generation/macos/RunnerTests/RunnerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import FlutterMacOS -import Cocoa -import XCTest - -class RunnerTests: XCTestCase { - - func testExample() { - // If you add code to the Runner application, consider adding tests here. - // See https://developer.apple.com/documentation/xctest for more information about using XCTest. - } - -} diff --git a/ai_recipe_generation/macos/firebase_app_id_file.json b/ai_recipe_generation/macos/firebase_app_id_file.json deleted file mode 100644 index a98a4b36f..000000000 --- a/ai_recipe_generation/macos/firebase_app_id_file.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "file_generated_by": "FlutterFire CLI", - "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", - "GOOGLE_APP_ID": "1:44885228795:ios:9585fdfdf50acdd18f845e", - "FIREBASE_PROJECT_ID": "gemini-cat-chef", - "GCM_SENDER_ID": "44885228795" -} \ No newline at end of file diff --git a/ai_recipe_generation/pubspec.yaml b/ai_recipe_generation/pubspec.yaml deleted file mode 100644 index c4d1cc4e0..000000000 --- a/ai_recipe_generation/pubspec.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: ai_recipe_generation -description: "A new Flutter project." -publish_to: 'none' -version: 0.1.0 - -environment: - sdk: ^3.5.0 - -dependencies: - async: ^2.11.0 - camera: ^0.10.5+9 - cloud_firestore: ^4.15.7 - device_info_plus: ^9.1.2 - firebase_core: ^2.26.0 - flutter: - sdk: flutter - flutter_floating_bottom_bar: ^1.2.0 - flutter_markdown: ^0.7.3 - flutter_svg: ^2.0.9 - google_fonts: 6.1.0 - google_generative_ai: ^0.4.0 - image_picker: ^1.0.7 - material_symbols_icons: ^4.2719.1 - path: ^1.9.0 - path_provider: ^2.1.2 - provider: ^6.1.1 - shared_preferences: ^2.2.2 - sticky_headers: ^0.3.0+2 - -dev_dependencies: - flutter_test: - sdk: flutter - analysis_defaults: - path: ../analysis_defaults - -flutter: - uses-material-design: true - - assets: - - assets/ diff --git a/ai_recipe_generation/web/favicon.png b/ai_recipe_generation/web/favicon.png deleted file mode 100644 index 8aaa46ac1..000000000 Binary files a/ai_recipe_generation/web/favicon.png and /dev/null differ diff --git a/ai_recipe_generation/web/icons/Icon-192.png b/ai_recipe_generation/web/icons/Icon-192.png deleted file mode 100644 index b749bfef0..000000000 Binary files a/ai_recipe_generation/web/icons/Icon-192.png and /dev/null differ diff --git a/ai_recipe_generation/web/icons/Icon-512.png b/ai_recipe_generation/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48df..000000000 Binary files a/ai_recipe_generation/web/icons/Icon-512.png and /dev/null differ diff --git a/ai_recipe_generation/web/icons/Icon-maskable-192.png b/ai_recipe_generation/web/icons/Icon-maskable-192.png deleted file mode 100644 index eb9b4d76e..000000000 Binary files a/ai_recipe_generation/web/icons/Icon-maskable-192.png and /dev/null differ diff --git a/ai_recipe_generation/web/icons/Icon-maskable-512.png b/ai_recipe_generation/web/icons/Icon-maskable-512.png deleted file mode 100644 index d69c56691..000000000 Binary files a/ai_recipe_generation/web/icons/Icon-maskable-512.png and /dev/null differ diff --git a/ai_recipe_generation/web/index.html b/ai_recipe_generation/web/index.html deleted file mode 100644 index 52540c77e..000000000 --- a/ai_recipe_generation/web/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - gemini_io_talk - - - - - - diff --git a/ai_recipe_generation/web/manifest.json b/ai_recipe_generation/web/manifest.json deleted file mode 100644 index 5ac7cda4b..000000000 --- a/ai_recipe_generation/web/manifest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "gemini_io_talk", - "short_name": "gemini_io_talk", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ] -} diff --git a/ai_recipe_generation/windows/.gitignore b/ai_recipe_generation/windows/.gitignore deleted file mode 100644 index d492d0d98..000000000 --- a/ai_recipe_generation/windows/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -flutter/ephemeral/ - -# Visual Studio user-specific files. -*.suo -*.user -*.userosscache -*.sln.docstates - -# Visual Studio build-related files. -x64/ -x86/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ diff --git a/ai_recipe_generation/windows/CMakeLists.txt b/ai_recipe_generation/windows/CMakeLists.txt deleted file mode 100644 index 28eca8f13..000000000 --- a/ai_recipe_generation/windows/CMakeLists.txt +++ /dev/null @@ -1,108 +0,0 @@ -# Project-level configuration. -cmake_minimum_required(VERSION 3.14) -project(gemini_io_talk LANGUAGES CXX) - -# The name of the executable created for the application. Change this to change -# the on-disk name of your application. -set(BINARY_NAME "gemini_io_talk") - -# Explicitly opt in to modern CMake behaviors to avoid warnings with recent -# versions of CMake. -cmake_policy(VERSION 3.14...3.25) - -# Define build configuration option. -get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(IS_MULTICONFIG) - set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" - CACHE STRING "" FORCE) -else() - if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") - endif() -endif() -# Define settings for the Profile build mode. -set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") -set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") -set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") - -# Use Unicode for all projects. -add_definitions(-DUNICODE -D_UNICODE) - -# Compilation settings that should be applied to most targets. -# -# Be cautious about adding new options here, as plugins use this function by -# default. In most cases, you should add new options to specific targets instead -# of modifying this function. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") - target_compile_options(${TARGET} PRIVATE /EHsc) - target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") - target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") -endfunction() - -# Flutter library and tool build rules. -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build; see runner/CMakeLists.txt. -add_subdirectory("runner") - - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - - -# === Installation === -# Support files are copied into place next to the executable, so that it can -# run in place. This is done instead of making a separate bundle (as on Linux) -# so that building and running from within Visual Studio will work. -set(BUILD_BUNDLE_DIR "$") -# Make the "install" step default, as it's required to run. -set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Copy the native assets provided by the build.dart from all packages. -set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") -install(DIRECTORY "${NATIVE_ASSETS_DIR}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - CONFIGURATIONS Profile;Release - COMPONENT Runtime) diff --git a/ai_recipe_generation/windows/flutter/CMakeLists.txt b/ai_recipe_generation/windows/flutter/CMakeLists.txt deleted file mode 100644 index 903f4899d..000000000 --- a/ai_recipe_generation/windows/flutter/CMakeLists.txt +++ /dev/null @@ -1,109 +0,0 @@ -# This file controls Flutter-level build steps. It should not be edited. -cmake_minimum_required(VERSION 3.14) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -# TODO: Move the rest of this into files in ephemeral. See -# https://github.com/flutter/flutter/issues/57146. -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# Set fallback configurations for older versions of the flutter tool. -if (NOT DEFINED FLUTTER_TARGET_PLATFORM) - set(FLUTTER_TARGET_PLATFORM "windows-x64") -endif() - -# === Flutter Library === -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) -set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_windows.h" - "flutter_messenger.h" - "flutter_plugin_registrar.h" - "flutter_texture_registrar.h" -) -list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -# === Flutter tool backend === -# _phony_ is a non-existent file to force this command to run every time, -# since currently there's no way to get a full input/output list from the -# flutter tool. -set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") -set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) -add_custom_command( - OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} - ${PHONY_OUTPUT} - COMMAND ${CMAKE_COMMAND} -E env - ${FLUTTER_TOOL_ENVIRONMENT} - "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - ${FLUTTER_TARGET_PLATFORM} $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc b/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc deleted file mode 100644 index ffc1b3875..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,20 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -#include -#include -#include - -void RegisterPlugins(flutter::PluginRegistry* registry) { - CloudFirestorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); - FileSelectorWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FileSelectorWindows")); - FirebaseCorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); -} diff --git a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h b/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h deleted file mode 100644 index dc139d85a..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/ai_recipe_generation/windows/flutter/generated_plugins.cmake b/ai_recipe_generation/windows/flutter/generated_plugins.cmake deleted file mode 100644 index 3cd460216..000000000 --- a/ai_recipe_generation/windows/flutter/generated_plugins.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST - cloud_firestore - file_selector_windows - firebase_core -) - -list(APPEND FLUTTER_FFI_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) - target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) - list(APPEND PLUGIN_BUNDLED_LIBRARIES $) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) -endforeach(plugin) - -foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) - add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) - list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) -endforeach(ffi_plugin) diff --git a/ai_recipe_generation/windows/runner/CMakeLists.txt b/ai_recipe_generation/windows/runner/CMakeLists.txt deleted file mode 100644 index 394917c05..000000000 --- a/ai_recipe_generation/windows/runner/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -# Define the application target. To change its name, change BINARY_NAME in the -# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer -# work. -# -# Any new source files that you add to the application should be added here. -add_executable(${BINARY_NAME} WIN32 - "flutter_window.cpp" - "main.cpp" - "utils.cpp" - "win32_window.cpp" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" - "Runner.rc" - "runner.exe.manifest" -) - -# Apply the standard set of build settings. This can be removed for applications -# that need different build settings. -apply_standard_settings(${BINARY_NAME}) - -# Add preprocessor definitions for the build version. -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") -target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") - -# Disable Windows macros that collide with C++ standard library functions. -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") - -# Add dependency libraries and include directories. Add any application-specific -# dependencies here. -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") - -# Run the Flutter tool portions of the build. This must not be removed. -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/ai_recipe_generation/windows/runner/Runner.rc b/ai_recipe_generation/windows/runner/Runner.rc deleted file mode 100644 index 5458ca734..000000000 --- a/ai_recipe_generation/windows/runner/Runner.rc +++ /dev/null @@ -1,121 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_APP_ICON ICON "resources\\app_icon.ico" - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) -#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD -#else -#define VERSION_AS_NUMBER 1,0,0,0 -#endif - -#if defined(FLUTTER_VERSION) -#define VERSION_AS_STRING FLUTTER_VERSION -#else -#define VERSION_AS_STRING "1.0.0" -#endif - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VERSION_AS_NUMBER - PRODUCTVERSION VERSION_AS_NUMBER - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "CompanyName", "com.example" "\0" - VALUE "FileDescription", "gemini_io_talk" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "gemini_io_talk" "\0" - VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "gemini_io_talk.exe" "\0" - VALUE "ProductName", "gemini_io_talk" "\0" - VALUE "ProductVersion", VERSION_AS_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/ai_recipe_generation/windows/runner/flutter_window.cpp b/ai_recipe_generation/windows/runner/flutter_window.cpp deleted file mode 100644 index 955ee3038..000000000 --- a/ai_recipe_generation/windows/runner/flutter_window.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "flutter_window.h" - -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject& project) - : project_(project) {} - -FlutterWindow::~FlutterWindow() {} - -bool FlutterWindow::OnCreate() { - if (!Win32Window::OnCreate()) { - return false; - } - - RECT frame = GetClientArea(); - - // The size here must match the window dimensions to avoid unnecessary surface - // creation / destruction in the startup path. - flutter_controller_ = std::make_unique( - frame.right - frame.left, frame.bottom - frame.top, project_); - // Ensure that basic setup of the controller was successful. - if (!flutter_controller_->engine() || !flutter_controller_->view()) { - return false; - } - RegisterPlugins(flutter_controller_->engine()); - SetChildContent(flutter_controller_->view()->GetNativeWindow()); - - flutter_controller_->engine()->SetNextFrameCallback([&]() { - this->Show(); - }); - - // Flutter can complete the first frame before the "show window" callback is - // registered. The following call ensures a frame is pending to ensure the - // window is shown. It is a no-op if the first frame hasn't completed yet. - flutter_controller_->ForceRedraw(); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_controller_) { - flutter_controller_ = nullptr; - } - - Win32Window::OnDestroy(); -} - -LRESULT -FlutterWindow::MessageHandler(HWND hwnd, UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opportunity to handle window messages. - if (flutter_controller_) { - std::optional result = - flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, - lparam); - if (result) { - return *result; - } - } - - switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; - } - - return Win32Window::MessageHandler(hwnd, message, wparam, lparam); -} diff --git a/ai_recipe_generation/windows/runner/flutter_window.h b/ai_recipe_generation/windows/runner/flutter_window.h deleted file mode 100644 index 6da0652f0..000000000 --- a/ai_recipe_generation/windows/runner/flutter_window.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef RUNNER_FLUTTER_WINDOW_H_ -#define RUNNER_FLUTTER_WINDOW_H_ - -#include -#include - -#include - -#include "win32_window.h" - -// A window that does nothing but host a Flutter view. -class FlutterWindow : public Win32Window { - public: - // Creates a new FlutterWindow hosting a Flutter view running |project|. - explicit FlutterWindow(const flutter::DartProject& project); - virtual ~FlutterWindow(); - - protected: - // Win32Window: - bool OnCreate() override; - void OnDestroy() override; - LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, - LPARAM const lparam) noexcept override; - - private: - // The project to run. - flutter::DartProject project_; - - // The Flutter instance hosted by this window. - std::unique_ptr flutter_controller_; -}; - -#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/ai_recipe_generation/windows/runner/main.cpp b/ai_recipe_generation/windows/runner/main.cpp deleted file mode 100644 index 2d644bc14..000000000 --- a/ai_recipe_generation/windows/runner/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "flutter_window.h" -#include "utils.h" - -int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, - _In_ wchar_t *command_line, _In_ int show_command) { - // Attach to console when present (e.g., 'flutter run') or create a - // new console when running with a debugger. - if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { - CreateAndAttachConsole(); - } - - // Initialize COM, so that it is available for use in the library and/or - // plugins. - ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - - flutter::DartProject project(L"data"); - - std::vector command_line_arguments = - GetCommandLineArguments(); - - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - FlutterWindow window(project); - Win32Window::Point origin(10, 10); - Win32Window::Size size(1280, 720); - if (!window.Create(L"gemini_io_talk", origin, size)) { - return EXIT_FAILURE; - } - window.SetQuitOnClose(true); - - ::MSG msg; - while (::GetMessage(&msg, nullptr, 0, 0)) { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - } - - ::CoUninitialize(); - return EXIT_SUCCESS; -} diff --git a/ai_recipe_generation/windows/runner/resource.h b/ai_recipe_generation/windows/runner/resource.h deleted file mode 100644 index 66a65d1e4..000000000 --- a/ai_recipe_generation/windows/runner/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Runner.rc -// -#define IDI_APP_ICON 101 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 102 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/ai_recipe_generation/windows/runner/resources/app_icon.ico b/ai_recipe_generation/windows/runner/resources/app_icon.ico deleted file mode 100644 index c04e20caf..000000000 Binary files a/ai_recipe_generation/windows/runner/resources/app_icon.ico and /dev/null differ diff --git a/ai_recipe_generation/windows/runner/runner.exe.manifest b/ai_recipe_generation/windows/runner/runner.exe.manifest deleted file mode 100644 index a42ea7687..000000000 --- a/ai_recipe_generation/windows/runner/runner.exe.manifest +++ /dev/null @@ -1,20 +0,0 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - diff --git a/ai_recipe_generation/windows/runner/utils.cpp b/ai_recipe_generation/windows/runner/utils.cpp deleted file mode 100644 index b2b08734d..000000000 --- a/ai_recipe_generation/windows/runner/utils.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "utils.h" - -#include -#include -#include -#include - -#include - -void CreateAndAttachConsole() { - if (::AllocConsole()) { - FILE *unused; - if (freopen_s(&unused, "CONOUT$", "w", stdout)) { - _dup2(_fileno(stdout), 1); - } - if (freopen_s(&unused, "CONOUT$", "w", stderr)) { - _dup2(_fileno(stdout), 2); - } - std::ios::sync_with_stdio(); - FlutterDesktopResyncOutputStreams(); - } -} - -std::vector GetCommandLineArguments() { - // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. - int argc; - wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); - if (argv == nullptr) { - return std::vector(); - } - - std::vector command_line_arguments; - - // Skip the first argument as it's the binary name. - for (int i = 1; i < argc; i++) { - command_line_arguments.push_back(Utf8FromUtf16(argv[i])); - } - - ::LocalFree(argv); - - return command_line_arguments; -} - -std::string Utf8FromUtf16(const wchar_t* utf16_string) { - if (utf16_string == nullptr) { - return std::string(); - } - int target_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr) - -1; // remove the trailing null character - int input_length = (int)wcslen(utf16_string); - std::string utf8_string; - if (target_length <= 0 || target_length > utf8_string.max_size()) { - return utf8_string; - } - utf8_string.resize(target_length); - int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - input_length, utf8_string.data(), target_length, nullptr, nullptr); - if (converted_length == 0) { - return std::string(); - } - return utf8_string; -} diff --git a/ai_recipe_generation/windows/runner/utils.h b/ai_recipe_generation/windows/runner/utils.h deleted file mode 100644 index 3879d5475..000000000 --- a/ai_recipe_generation/windows/runner/utils.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RUNNER_UTILS_H_ -#define RUNNER_UTILS_H_ - -#include -#include - -// Creates a console for the process, and redirects stdout and stderr to -// it for both the runner and the Flutter library. -void CreateAndAttachConsole(); - -// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string -// encoded in UTF-8. Returns an empty std::string on failure. -std::string Utf8FromUtf16(const wchar_t* utf16_string); - -// Gets the command line arguments passed in as a std::vector, -// encoded in UTF-8. Returns an empty std::vector on failure. -std::vector GetCommandLineArguments(); - -#endif // RUNNER_UTILS_H_ diff --git a/ai_recipe_generation/windows/runner/win32_window.cpp b/ai_recipe_generation/windows/runner/win32_window.cpp deleted file mode 100644 index 60608d0fe..000000000 --- a/ai_recipe_generation/windows/runner/win32_window.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "win32_window.h" - -#include -#include - -#include "resource.h" - -namespace { - -/// Window attribute that enables dark mode window decorations. -/// -/// Redefined in case the developer's machine has a Windows SDK older than -/// version 10.0.22000.0. -/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif - -constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; - -/// Registry key for app theme preference. -/// -/// A value of 0 indicates apps should use dark mode. A non-zero or missing -/// value indicates apps should use light mode. -constexpr const wchar_t kGetPreferredBrightnessRegKey[] = - L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; -constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; - -// The number of Win32Window objects that currently exist. -static int g_active_window_count = 0; - -using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); - -// Scale helper to convert logical scaler values to physical using passed in -// scale factor -int Scale(int source, double scale_factor) { - return static_cast(source * scale_factor); -} - -// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. -// This API is only needed for PerMonitor V1 awareness mode. -void EnableFullDpiSupportIfAvailable(HWND hwnd) { - HMODULE user32_module = LoadLibraryA("User32.dll"); - if (!user32_module) { - return; - } - auto enable_non_client_dpi_scaling = - reinterpret_cast( - GetProcAddress(user32_module, "EnableNonClientDpiScaling")); - if (enable_non_client_dpi_scaling != nullptr) { - enable_non_client_dpi_scaling(hwnd); - } - FreeLibrary(user32_module); -} - -} // namespace - -// Manages the Win32Window's window class registration. -class WindowClassRegistrar { - public: - ~WindowClassRegistrar() = default; - - // Returns the singleton registrar instance. - static WindowClassRegistrar* GetInstance() { - if (!instance_) { - instance_ = new WindowClassRegistrar(); - } - return instance_; - } - - // Returns the name of the window class, registering the class if it hasn't - // previously been registered. - const wchar_t* GetWindowClass(); - - // Unregisters the window class. Should only be called if there are no - // instances of the window. - void UnregisterWindowClass(); - - private: - WindowClassRegistrar() = default; - - static WindowClassRegistrar* instance_; - - bool class_registered_ = false; -}; - -WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; - -const wchar_t* WindowClassRegistrar::GetWindowClass() { - if (!class_registered_) { - WNDCLASS window_class{}; - window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); - window_class.lpszClassName = kWindowClassName; - window_class.style = CS_HREDRAW | CS_VREDRAW; - window_class.cbClsExtra = 0; - window_class.cbWndExtra = 0; - window_class.hInstance = GetModuleHandle(nullptr); - window_class.hIcon = - LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); - window_class.hbrBackground = 0; - window_class.lpszMenuName = nullptr; - window_class.lpfnWndProc = Win32Window::WndProc; - RegisterClass(&window_class); - class_registered_ = true; - } - return kWindowClassName; -} - -void WindowClassRegistrar::UnregisterWindowClass() { - UnregisterClass(kWindowClassName, nullptr); - class_registered_ = false; -} - -Win32Window::Win32Window() { - ++g_active_window_count; -} - -Win32Window::~Win32Window() { - --g_active_window_count; - Destroy(); -} - -bool Win32Window::Create(const std::wstring& title, - const Point& origin, - const Size& size) { - Destroy(); - - const wchar_t* window_class = - WindowClassRegistrar::GetInstance()->GetWindowClass(); - - const POINT target_point = {static_cast(origin.x), - static_cast(origin.y)}; - HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); - UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); - double scale_factor = dpi / 96.0; - - HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW, - Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), - Scale(size.width, scale_factor), Scale(size.height, scale_factor), - nullptr, nullptr, GetModuleHandle(nullptr), this); - - if (!window) { - return false; - } - - UpdateTheme(window); - - return OnCreate(); -} - -bool Win32Window::Show() { - return ShowWindow(window_handle_, SW_SHOWNORMAL); -} - -// static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - if (message == WM_NCCREATE) { - auto window_struct = reinterpret_cast(lparam); - SetWindowLongPtr(window, GWLP_USERDATA, - reinterpret_cast(window_struct->lpCreateParams)); - - auto that = static_cast(window_struct->lpCreateParams); - EnableFullDpiSupportIfAvailable(window); - that->window_handle_ = window; - } else if (Win32Window* that = GetThisFromHandle(window)) { - return that->MessageHandler(window, message, wparam, lparam); - } - - return DefWindowProc(window, message, wparam, lparam); -} - -LRESULT -Win32Window::MessageHandler(HWND hwnd, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept { - switch (message) { - case WM_DESTROY: - window_handle_ = nullptr; - Destroy(); - if (quit_on_close_) { - PostQuitMessage(0); - } - return 0; - - case WM_DPICHANGED: { - auto newRectSize = reinterpret_cast(lparam); - LONG newWidth = newRectSize->right - newRectSize->left; - LONG newHeight = newRectSize->bottom - newRectSize->top; - - SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, - newHeight, SWP_NOZORDER | SWP_NOACTIVATE); - - return 0; - } - case WM_SIZE: { - RECT rect = GetClientArea(); - if (child_content_ != nullptr) { - // Size and position the child window. - MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, TRUE); - } - return 0; - } - - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; - - case WM_DWMCOLORIZATIONCOLORCHANGED: - UpdateTheme(hwnd); - return 0; - } - - return DefWindowProc(window_handle_, message, wparam, lparam); -} - -void Win32Window::Destroy() { - OnDestroy(); - - if (window_handle_) { - DestroyWindow(window_handle_); - window_handle_ = nullptr; - } - if (g_active_window_count == 0) { - WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); - } -} - -Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( - GetWindowLongPtr(window, GWLP_USERDATA)); -} - -void Win32Window::SetChildContent(HWND content) { - child_content_ = content; - SetParent(content, window_handle_); - RECT frame = GetClientArea(); - - MoveWindow(content, frame.left, frame.top, frame.right - frame.left, - frame.bottom - frame.top, true); - - SetFocus(child_content_); -} - -RECT Win32Window::GetClientArea() { - RECT frame; - GetClientRect(window_handle_, &frame); - return frame; -} - -HWND Win32Window::GetHandle() { - return window_handle_; -} - -void Win32Window::SetQuitOnClose(bool quit_on_close) { - quit_on_close_ = quit_on_close; -} - -bool Win32Window::OnCreate() { - // No-op; provided for subclasses. - return true; -} - -void Win32Window::OnDestroy() { - // No-op; provided for subclasses. -} - -void Win32Window::UpdateTheme(HWND const window) { - DWORD light_mode; - DWORD light_mode_size = sizeof(light_mode); - LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, - kGetPreferredBrightnessRegValue, - RRF_RT_REG_DWORD, nullptr, &light_mode, - &light_mode_size); - - if (result == ERROR_SUCCESS) { - BOOL enable_dark_mode = light_mode == 0; - DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, - &enable_dark_mode, sizeof(enable_dark_mode)); - } -} diff --git a/ai_recipe_generation/windows/runner/win32_window.h b/ai_recipe_generation/windows/runner/win32_window.h deleted file mode 100644 index e901dde68..000000000 --- a/ai_recipe_generation/windows/runner/win32_window.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef RUNNER_WIN32_WINDOW_H_ -#define RUNNER_WIN32_WINDOW_H_ - -#include - -#include -#include -#include - -// A class abstraction for a high DPI-aware Win32 Window. Intended to be -// inherited from by classes that wish to specialize with custom -// rendering and input handling -class Win32Window { - public: - struct Point { - unsigned int x; - unsigned int y; - Point(unsigned int x, unsigned int y) : x(x), y(y) {} - }; - - struct Size { - unsigned int width; - unsigned int height; - Size(unsigned int width, unsigned int height) - : width(width), height(height) {} - }; - - Win32Window(); - virtual ~Win32Window(); - - // Creates a win32 window with |title| that is positioned and sized using - // |origin| and |size|. New windows are created on the default monitor. Window - // sizes are specified to the OS in physical pixels, hence to ensure a - // consistent size this function will scale the inputted width and height as - // as appropriate for the default monitor. The window is invisible until - // |Show| is called. Returns true if the window was created successfully. - bool Create(const std::wstring& title, const Point& origin, const Size& size); - - // Show the current window. Returns true if the window was successfully shown. - bool Show(); - - // Release OS resources associated with window. - void Destroy(); - - // Inserts |content| into the window tree. - void SetChildContent(HWND content); - - // Returns the backing Window handle to enable clients to set icon and other - // window properties. Returns nullptr if the window has been destroyed. - HWND GetHandle(); - - // If true, closing this window will quit the application. - void SetQuitOnClose(bool quit_on_close); - - // Return a RECT representing the bounds of the current client area. - RECT GetClientArea(); - - protected: - // Processes and route salient window messages for mouse handling, - // size change and DPI. Delegates handling of these to member overloads that - // inheriting classes can handle. - virtual LRESULT MessageHandler(HWND window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Called when CreateAndShow is called, allowing subclass window-related - // setup. Subclasses should return false if setup fails. - virtual bool OnCreate(); - - // Called when Destroy is called. - virtual void OnDestroy(); - - private: - friend class WindowClassRegistrar; - - // OS callback called by message pump. Handles the WM_NCCREATE message which - // is passed when the non-client area is being created and enables automatic - // non-client DPI scaling so that the non-client area automatically - // responds to changes in DPI. All other messages are handled by - // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, - UINT const message, - WPARAM const wparam, - LPARAM const lparam) noexcept; - - // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; - - // Update the window frame's theme to match the system theme. - static void UpdateTheme(HWND const window); - - bool quit_on_close_ = false; - - // window handle for top level window. - HWND window_handle_ = nullptr; - - // window handle for hosted content. - HWND child_content_ = nullptr; -}; - -#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/background_isolate_channels/pubspec.yaml b/background_isolate_channels/pubspec.yaml index 24e78dd9f..9b0d4c2e5 100644 --- a/background_isolate_channels/pubspec.yaml +++ b/background_isolate_channels/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: cupertino_icons: ^1.0.2 flutter: sdk: flutter - intl: ^0.19.0 + intl: ^0.20.0 path: ^1.8.2 path_provider: ^2.0.11 shared_preferences: ^2.0.15 diff --git a/compass_app/app/lib/config/assets.dart b/compass_app/app/lib/config/assets.dart index b60059e0a..cbbbc4ed1 100644 --- a/compass_app/app/lib/config/assets.dart +++ b/compass_app/app/lib/config/assets.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class Assets { +abstract final class Assets { static const activities = 'assets/activities.json'; static const destinations = 'assets/destinations.json'; } diff --git a/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart b/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart index 6d2d0bcc5..be7ce02c6 100644 --- a/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/activity/activity_repository_remote.dart @@ -24,8 +24,8 @@ class ActivityRepositoryRemote implements ActivityRepository { if (!_cachedData.containsKey(ref)) { // No cached data, request activities final result = await _apiClient.getActivityByDestination(ref); - if (result is Ok) { - _cachedData[ref] = result.asOk.value; + if (result is Ok>) { + _cachedData[ref] = result.value; } return result; } else { diff --git a/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart b/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart index 5c56b9621..aba56512f 100644 --- a/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart +++ b/compass_app/app/lib/data/repositories/auth/auth_repository_dev.dart @@ -16,12 +16,12 @@ class AuthRepositoryDev extends AuthRepository { required String email, required String password, }) async { - return Result.ok(null); + return const Result.ok(null); } /// Logout is always successful in dev scenarios @override Future> logout() async { - return Result.ok(null); + return const Result.ok(null); } } diff --git a/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart b/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart index 4a340d7c2..a41660257 100644 --- a/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart +++ b/compass_app/app/lib/data/repositories/booking/booking_repository_local.dart @@ -31,7 +31,7 @@ class BookingRepositoryLocal implements BookingRepository { // Bookings created come without id, we need to assign one final bookingWithId = booking.copyWith(id: _sequentialId++); _bookings.add(bookingWithId); - return Result.ok(null); + return const Result.ok(null); } @override @@ -92,6 +92,6 @@ class BookingRepositoryLocal implements BookingRepository { @override Future> delete(int id) async { _bookings.removeWhere((booking) => booking.id == id); - return Result.ok(null); + return const Result.ok(null); } } diff --git a/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart b/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart index 1ac1cd7cd..cdb66b86d 100644 --- a/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/booking/booking_repository_remote.dart @@ -42,18 +42,22 @@ class BookingRepositoryRemote implements BookingRepository { try { // Get booking by ID from server final resultBooking = await _apiClient.getBooking(id); - if (resultBooking is Error) { - return Result.error(resultBooking.error); + switch (resultBooking) { + case Error(): + return Result.error(resultBooking.error); + case Ok(): } - final booking = resultBooking.asOk.value; + final booking = resultBooking.value; // Load destinations if not loaded yet if (_cachedDestinations == null) { final resultDestination = await _apiClient.getDestinations(); - if (resultDestination is Error>) { - return Result.error(resultDestination.error); + switch (resultDestination) { + case Error>(): + return Result.error(resultDestination.error); + case Ok>(): } - _cachedDestinations = resultDestination.asOk.value; + _cachedDestinations = resultDestination.value; } // Get destination for booking @@ -62,11 +66,12 @@ class BookingRepositoryRemote implements BookingRepository { final resultActivities = await _apiClient.getActivityByDestination(destination.ref); - - if (resultActivities is Error>) { - return Result.error(resultActivities.error); + switch (resultActivities) { + case Error>(): + return Result.error(resultActivities.error); + case Ok>(): } - final activities = resultActivities.asOk.value + final activities = resultActivities.value .where((activity) => booking.activitiesRef.contains(activity.ref)) .toList(); @@ -88,20 +93,22 @@ class BookingRepositoryRemote implements BookingRepository { Future>> getBookingsList() async { try { final result = await _apiClient.getBookings(); - if (result is Error>) { - return Result.error(result.error); + switch (result) { + case Ok>(): + final bookingsApi = result.value; + return Result.ok(bookingsApi + .map( + (bookingApi) => BookingSummary( + id: bookingApi.id!, + name: bookingApi.name, + startDate: bookingApi.startDate, + endDate: bookingApi.endDate, + ), + ) + .toList()); + case Error>(): + return Result.error(result.error); } - final bookingsApi = result.asOk.value; - return Result.ok(bookingsApi - .map( - (bookingApi) => BookingSummary( - id: bookingApi.id!, - name: bookingApi.name, - startDate: bookingApi.startDate, - endDate: bookingApi.endDate, - ), - ) - .toList()); } on Exception catch (e) { return Result.error(e); } diff --git a/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart b/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart index 58a6e439e..a9b32f686 100644 --- a/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/continent/continent_repository_remote.dart @@ -24,9 +24,9 @@ class ContinentRepositoryRemote implements ContinentRepository { if (_cachedData == null) { // No cached data, request continents final result = await _apiClient.getContinents(); - if (result is Ok) { + if (result is Ok>) { // Store value if result Ok - _cachedData = result.asOk.value; + _cachedData = result.value; } return result; } else { diff --git a/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart b/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart index 191b2a6ed..a2357ba90 100644 --- a/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart +++ b/compass_app/app/lib/data/repositories/destination/destination_repository_remote.dart @@ -24,9 +24,9 @@ class DestinationRepositoryRemote implements DestinationRepository { if (_cachedData == null) { // No cached data, request destinations final result = await _apiClient.getDestinations(); - if (result is Ok) { + if (result is Ok>) { // Store value if result Ok - _cachedData = result.asOk.value; + _cachedData = result.value; } return result; } else { diff --git a/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart b/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart index 5bd9cc0d5..c819c7fef 100644 --- a/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart +++ b/compass_app/app/lib/data/repositories/itinerary_config/itinerary_config_repository_memory.dart @@ -22,6 +22,6 @@ class ItineraryConfigRepositoryMemory implements ItineraryConfigRepository { ItineraryConfig itineraryConfig, ) async { _itineraryConfig = itineraryConfig; - return Result.ok(true); + return const Result.ok(true); } } diff --git a/compass_app/app/lib/data/services/api/api_client.dart b/compass_app/app/lib/data/services/api/api_client.dart index 58f2d7a0a..5068c443b 100644 --- a/compass_app/app/lib/data/services/api/api_client.dart +++ b/compass_app/app/lib/data/services/api/api_client.dart @@ -53,7 +53,7 @@ class ApiClient { return Result.ok( json.map((element) => Continent.fromJson(element)).toList()); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -74,7 +74,7 @@ class ApiClient { return Result.ok( json.map((element) => Destination.fromJson(element)).toList()); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -97,7 +97,7 @@ class ApiClient { json.map((element) => Activity.fromJson(element)).toList(); return Result.ok(activities); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -119,7 +119,7 @@ class ApiClient { json.map((element) => BookingApiModel.fromJson(element)).toList(); return Result.ok(bookings); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -139,7 +139,7 @@ class ApiClient { final booking = BookingApiModel.fromJson(jsonDecode(stringData)); return Result.ok(booking); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -160,7 +160,7 @@ class ApiClient { final booking = BookingApiModel.fromJson(jsonDecode(stringData)); return Result.ok(booking); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -180,7 +180,7 @@ class ApiClient { final user = UserApiModel.fromJson(jsonDecode(stringData)); return Result.ok(user); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); @@ -197,9 +197,9 @@ class ApiClient { final response = await request.close(); // Response 204 "No Content", delete was successful if (response.statusCode == 204) { - return Result.ok(null); + return const Result.ok(null); } else { - return Result.error(const HttpException("Invalid response")); + return const Result.error(HttpException("Invalid response")); } } on Exception catch (error) { return Result.error(error); diff --git a/compass_app/app/lib/data/services/api/auth_api_client.dart b/compass_app/app/lib/data/services/api/auth_api_client.dart index 7c2191b46..89e309674 100644 --- a/compass_app/app/lib/data/services/api/auth_api_client.dart +++ b/compass_app/app/lib/data/services/api/auth_api_client.dart @@ -32,7 +32,7 @@ class AuthApiClient { final stringData = await response.transform(utf8.decoder).join(); return Result.ok(LoginResponse.fromJson(jsonDecode(stringData))); } else { - return Result.error(const HttpException("Login error")); + return const Result.error(HttpException("Login error")); } } on Exception catch (error) { return Result.error(error); diff --git a/compass_app/app/lib/data/services/shared_preferences_service.dart b/compass_app/app/lib/data/services/shared_preferences_service.dart index 05a684601..24a67a9b5 100644 --- a/compass_app/app/lib/data/services/shared_preferences_service.dart +++ b/compass_app/app/lib/data/services/shared_preferences_service.dart @@ -32,7 +32,7 @@ class SharedPreferencesService { _log.finer('Replaced token'); await sharedPreferences.setString(_tokenKey, token); } - return Result.ok(null); + return const Result.ok(null); } on Exception catch (e) { _log.warning('Failed to set token', e); return Result.error(e); diff --git a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart index eff951159..001ed7fc1 100644 --- a/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart +++ b/compass_app/app/lib/domain/use_cases/booking/booking_create_use_case.dart @@ -40,11 +40,13 @@ class BookingCreateUseCase { } final destinationResult = await _fetchDestination(itineraryConfig.destination!); - if (destinationResult is Error) { - _log.warning('Error fetching destination: ${destinationResult.error}'); - return Result.error(destinationResult.error); + switch (destinationResult) { + case Ok(): + _log.fine('Destination loaded: ${destinationResult.value.ref}'); + case Error(): + _log.warning('Error fetching destination: ${destinationResult.error}'); + return Result.error(destinationResult.error); } - _log.fine('Destination loaded: ${destinationResult.asOk.value.ref}'); // Get Activity objects from repository if (itineraryConfig.activities.isEmpty) { @@ -54,11 +56,13 @@ class BookingCreateUseCase { final activitiesResult = await _activityRepository.getByDestination( itineraryConfig.destination!, ); - if (activitiesResult is Error>) { - _log.warning('Error fetching activities: ${activitiesResult.error}'); - return Result.error(activitiesResult.error); + switch (activitiesResult) { + case Error>(): + _log.warning('Error fetching activities: ${activitiesResult.error}'); + return Result.error(activitiesResult.error); + case Ok>(): } - final activities = activitiesResult.asOk.value + final activities = activitiesResult.value .where( (activity) => itineraryConfig.activities.contains(activity.ref), ) @@ -74,7 +78,7 @@ class BookingCreateUseCase { final booking = Booking( startDate: itineraryConfig.startDate!, endDate: itineraryConfig.endDate!, - destination: destinationResult.asOk.value, + destination: destinationResult.value, activity: activities, ); @@ -98,7 +102,7 @@ class BookingCreateUseCase { case Ok>(): final destination = result.value .firstWhere((destination) => destination.ref == destinationRef); - return Ok(destination); + return Result.ok(destination); case Error>(): return Result.error(result.error); } diff --git a/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart b/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart index cff2f852b..b7d66f0c7 100644 --- a/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart +++ b/compass_app/app/lib/domain/use_cases/booking/booking_share_use_case.dart @@ -37,7 +37,7 @@ class BookingShareUseCase { try { await _share(text); _log.fine('Shared booking'); - return Result.ok(null); + return const Result.ok(null); } on Exception catch (error) { _log.severe('Failed to share booking', error); return Result.error(error); diff --git a/compass_app/app/lib/routing/routes.dart b/compass_app/app/lib/routing/routes.dart index bba607532..86ea0b789 100644 --- a/compass_app/app/lib/routing/routes.dart +++ b/compass_app/app/lib/routing/routes.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class Routes { +abstract final class Routes { static const home = '/'; static const login = '/login'; static const search = '/$searchRelative'; diff --git a/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart b/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart index dc86b6f48..5c6fa4af9 100644 --- a/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart +++ b/compass_app/app/lib/ui/activities/view_models/activities_viewmodel.dart @@ -8,6 +8,7 @@ import 'package:logging/logging.dart'; import '../../../data/repositories/activity/activity_repository.dart'; import '../../../data/repositories/itinerary_config/itinerary_config_repository.dart'; import '../../../domain/models/activity/activity.dart'; +import '../../../domain/models/itinerary_config/itinerary_config.dart'; import '../../../utils/command.dart'; import '../../../utils/result.dart'; @@ -45,21 +46,23 @@ class ActivitiesViewModel extends ChangeNotifier { Future> _loadActivities() async { final result = await _itineraryConfigRepository.getItineraryConfig(); - if (result is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - result.asError.error, - ); - return result; + switch (result) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + result.error, + ); + return result; + case Ok(): } - final destinationRef = result.asOk.value.destination; + final destinationRef = result.value.destination; if (destinationRef == null) { _log.severe('Destination missing in ItineraryConfig'); return Result.error(Exception('Destination not found')); } - _selectedActivities.addAll(result.asOk.value.activities); + _selectedActivities.addAll(result.value.activities); final resultActivities = await _activityRepository.getByDestination(destinationRef); @@ -120,21 +123,23 @@ class ActivitiesViewModel extends ChangeNotifier { Future> _saveActivities() async { final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - final itineraryConfig = resultConfig.asOk.value; + final itineraryConfig = resultConfig.value; final result = await _itineraryConfigRepository.setItineraryConfig( itineraryConfig.copyWith(activities: _selectedActivities.toList())); if (result is Error) { _log.warning( 'Failed to store ItineraryConfig', - result.asError.error, + result.error, ); } return result; diff --git a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart index c2e44ead6..f32d1a4bb 100644 --- a/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart +++ b/compass_app/app/lib/ui/booking/view_models/booking_viewmodel.dart @@ -61,11 +61,11 @@ class BookingViewModel extends ChangeNotifier { _log.fine('Created Booking'); _booking = result.value; notifyListeners(); - return Result.ok(null); + return const Result.ok(null); case Error(): _log.warning('Booking error: ${result.error}'); notifyListeners(); - return Result.error(result.asError.error); + return Result.error(result.error); } case Error(): _log.warning('ItineraryConfig error: ${itineraryConfig.error}'); diff --git a/compass_app/app/lib/ui/core/themes/colors.dart b/compass_app/app/lib/ui/core/themes/colors.dart index 9e42e36ec..8c98c8c70 100644 --- a/compass_app/app/lib/ui/core/themes/colors.dart +++ b/compass_app/app/lib/ui/core/themes/colors.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -class AppColors { +abstract final class AppColors { static const black1 = Color(0xFF101010); static const white1 = Color(0xFFFFF7FA); static const grey1 = Color(0xFFF2F2F2); diff --git a/compass_app/app/lib/ui/core/themes/dimens.dart b/compass_app/app/lib/ui/core/themes/dimens.dart index c2c895ae8..d665bcc4c 100644 --- a/compass_app/app/lib/ui/core/themes/dimens.dart +++ b/compass_app/app/lib/ui/core/themes/dimens.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; -sealed class Dimens { +abstract final class Dimens { const Dimens(); /// General horizontal padding used to separate UI items @@ -14,10 +14,12 @@ sealed class Dimens { static const paddingVertical = 24.0; /// Horizontal padding for screen edges - abstract final double paddingScreenHorizontal; + double get paddingScreenHorizontal; /// Vertical padding for screen edges - abstract final double paddingScreenVertical; + double get paddingScreenVertical; + + double get profilePictureSize; /// Horizontal symmetric padding for screen edges EdgeInsets get edgeInsetsScreenHorizontal => @@ -27,39 +29,37 @@ sealed class Dimens { EdgeInsets get edgeInsetsScreenSymmetric => EdgeInsets.symmetric( horizontal: paddingScreenHorizontal, vertical: paddingScreenVertical); - static final dimensDesktop = DimensDesktop(); - static final dimensMobile = DimensMobile(); + static final Dimens desktop = _DimensDesktop(); + static final Dimens mobile = _DimensMobile(); /// Get dimensions definition based on screen size factory Dimens.of(BuildContext context) => switch (MediaQuery.sizeOf(context).width) { - > 600 => dimensDesktop, - _ => dimensMobile, + > 600 => desktop, + _ => mobile, }; - - abstract final double profilePictureSize; } /// Mobile dimensions -class DimensMobile extends Dimens { +final class _DimensMobile extends Dimens { @override - double paddingScreenHorizontal = Dimens.paddingHorizontal; + final double paddingScreenHorizontal = Dimens.paddingHorizontal; @override - double paddingScreenVertical = Dimens.paddingVertical; + final double paddingScreenVertical = Dimens.paddingVertical; @override - double get profilePictureSize => 64.0; + final double profilePictureSize = 64.0; } /// Desktop/Web dimensions -class DimensDesktop extends Dimens { +final class _DimensDesktop extends Dimens { @override - double paddingScreenHorizontal = 100.0; + final double paddingScreenHorizontal = 100.0; @override - double paddingScreenVertical = 64.0; + final double paddingScreenVertical = 64.0; @override - double get profilePictureSize => 128.0; + final double profilePictureSize = 128.0; } diff --git a/compass_app/app/lib/ui/core/themes/theme.dart b/compass_app/app/lib/ui/core/themes/theme.dart index 34ae0c989..98483bcfc 100644 --- a/compass_app/app/lib/ui/core/themes/theme.dart +++ b/compass_app/app/lib/ui/core/themes/theme.dart @@ -6,7 +6,7 @@ import 'colors.dart'; import '../ui/tag_chip.dart'; import 'package:flutter/material.dart'; -class AppTheme { +abstract final class AppTheme { static const _textTheme = TextTheme( headlineLarge: TextStyle( fontSize: 32, diff --git a/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart b/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart index 5a2690ab9..94d1f5d2d 100644 --- a/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart +++ b/compass_app/app/lib/ui/results/view_models/results_viewmodel.dart @@ -50,14 +50,16 @@ class ResultsViewModel extends ChangeNotifier { Future> _search() async { // Load current itinerary config final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - _itineraryConfig = resultConfig.asOk.value; + _itineraryConfig = resultConfig.value; notifyListeners(); final result = await _destinationRepository.getDestinations(); @@ -86,15 +88,17 @@ class ResultsViewModel extends ChangeNotifier { assert(destinationRef.isNotEmpty, "destinationRef should not be empty"); final resultConfig = await _itineraryConfigRepository.getItineraryConfig(); - if (resultConfig is Error) { - _log.warning( - 'Failed to load stored ItineraryConfig', - resultConfig.asError.error, - ); - return resultConfig; + switch (resultConfig) { + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + resultConfig.error, + ); + return resultConfig; + case Ok(): } - final itineraryConfig = resultConfig.asOk.value; + final itineraryConfig = resultConfig.value; final result = await _itineraryConfigRepository .setItineraryConfig(itineraryConfig.copyWith( destination: destinationRef, @@ -103,7 +107,7 @@ class ResultsViewModel extends ChangeNotifier { if (result is Error) { _log.warning( 'Failed to store ItineraryConfig', - result.asError.error, + result.error, ); } return result; diff --git a/compass_app/app/lib/ui/results/widgets/results_screen.dart b/compass_app/app/lib/ui/results/widgets/results_screen.dart index cbe9778a5..2a93bcd40 100644 --- a/compass_app/app/lib/ui/results/widgets/results_screen.dart +++ b/compass_app/app/lib/ui/results/widgets/results_screen.dart @@ -132,7 +132,7 @@ class _AppSearchBar extends StatelessWidget { child: Padding( padding: EdgeInsets.only( top: Dimens.of(context).paddingScreenVertical, - bottom: Dimens.dimensMobile.paddingScreenVertical, + bottom: Dimens.mobile.paddingScreenVertical, ), child: AppSearchBar( config: widget.viewModel.config, diff --git a/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart b/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart index 565e5fc0f..c1eed2f92 100644 --- a/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart +++ b/compass_app/app/lib/ui/search_form/view_models/search_form_viewmodel.dart @@ -99,14 +99,10 @@ class SearchFormViewModel extends ChangeNotifier { final result = await _continentRepository.getContinents(); switch (result) { case Ok(): - { - _continents = result.value; - _log.fine('Continents (${_continents.length}) loaded'); - } + _continents = result.value; + _log.fine('Continents (${_continents.length}) loaded'); case Error(): - { - _log.warning('Failed to load continents', result.asError.error); - } + _log.warning('Failed to load continents', result.error); } notifyListeners(); return result; @@ -116,27 +112,23 @@ class SearchFormViewModel extends ChangeNotifier { final result = await _itineraryConfigRepository.getItineraryConfig(); switch (result) { case Ok(): - { - final itineraryConfig = result.value; - _selectedContinent = itineraryConfig.continent; - if (itineraryConfig.startDate != null && - itineraryConfig.endDate != null) { - _dateRange = DateTimeRange( - start: itineraryConfig.startDate!, - end: itineraryConfig.endDate!, - ); - } - _guests = itineraryConfig.guests ?? 0; - _log.fine('ItineraryConfig loaded'); - notifyListeners(); - } - case Error(): - { - _log.warning( - 'Failed to load stored ItineraryConfig', - result.asError.error, + final itineraryConfig = result.value; + _selectedContinent = itineraryConfig.continent; + if (itineraryConfig.startDate != null && + itineraryConfig.endDate != null) { + _dateRange = DateTimeRange( + start: itineraryConfig.startDate!, + end: itineraryConfig.endDate!, ); } + _guests = itineraryConfig.guests ?? 0; + _log.fine('ItineraryConfig loaded'); + notifyListeners(); + case Error(): + _log.warning( + 'Failed to load stored ItineraryConfig', + result.error, + ); } return result; } diff --git a/compass_app/app/lib/utils/result.dart b/compass_app/app/lib/utils/result.dart index 5370700b0..407b11ca1 100644 --- a/compass_app/app/lib/utils/result.dart +++ b/compass_app/app/lib/utils/result.dart @@ -18,22 +18,16 @@ sealed class Result { const Result(); - /// Creates an instance of Result containing a value - factory Result.ok(T value) => Ok(value); + /// Creates a successful [Result], completed with the specified [value]. + const factory Result.ok(T value) = Ok._; - /// Create an instance of Result containing an error - factory Result.error(Exception error) => Error(error); - - /// Convenience method to cast to Ok - Ok get asOk => this as Ok; - - /// Convenience method to cast to Error - Error get asError => this as Error; + /// Creates an error [Result], completed with the specified [error]. + const factory Result.error(Exception error) = Error._; } /// Subclass of Result for values final class Ok extends Result { - const Ok(this.value); + const Ok._(this.value); /// Returned value in result final T value; @@ -44,7 +38,7 @@ final class Ok extends Result { /// Subclass of Result for errors final class Error extends Result { - const Error(this.error); + const Error._(this.error); /// Returned error in result final Exception error; diff --git a/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart b/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart index 739f35084..a49702f9c 100644 --- a/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart +++ b/compass_app/app/test/data/repositories/activity/activity_repository_local_test.dart @@ -7,6 +7,8 @@ import 'package:compass_app/data/services/local/local_data_service.dart'; import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../../../testing/utils/result.dart'; + void main() { group('ActivityRepositoryLocal tests', () { // To load assets diff --git a/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart b/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart index a75734e54..18cb5a5e7 100644 --- a/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/activity/activity_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ActivityRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart b/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart index 54b907c1d..822405060 100644 --- a/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/booking/booking_repository_remote_test.dart @@ -9,6 +9,7 @@ import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; import '../../../../testing/models/booking.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('BookingRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart b/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart index 4a41120b7..37ae24bac 100644 --- a/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/continent/continent_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ContinentRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart b/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart index 62fa01357..f53cf77b4 100644 --- a/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart +++ b/compass_app/app/test/data/repositories/destination/destination_repository_local_test.dart @@ -7,6 +7,8 @@ import 'package:compass_app/utils/result.dart'; import 'package:compass_app/data/repositories/destination/destination_repository_local.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../../../testing/utils/result.dart'; + void main() { group('DestinationRepositoryLocal tests', () { // To load assets diff --git a/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart b/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart index 2559f030e..d918f8789 100644 --- a/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart +++ b/compass_app/app/test/data/repositories/destination/destination_repository_remote_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/fakes/services/fake_api_client.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('DestinationRepositoryRemote tests', () { diff --git a/compass_app/app/test/data/services/api/api_client_test.dart b/compass_app/app/test/data/services/api/api_client_test.dart index e3965e4e3..2bcf8de3f 100644 --- a/compass_app/app/test/data/services/api/api_client_test.dart +++ b/compass_app/app/test/data/services/api/api_client_test.dart @@ -12,6 +12,7 @@ import '../../../../testing/models/activity.dart'; import '../../../../testing/models/booking.dart'; import '../../../../testing/models/destination.dart'; import '../../../../testing/models/user.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('ApiClient', () { diff --git a/compass_app/app/test/data/services/api/auth_api_client_test.dart b/compass_app/app/test/data/services/api/auth_api_client_test.dart index 50d20e561..18222ba62 100644 --- a/compass_app/app/test/data/services/api/auth_api_client_test.dart +++ b/compass_app/app/test/data/services/api/auth_api_client_test.dart @@ -8,6 +8,7 @@ import 'package:compass_app/data/services/api/model/login_response/login_respons import 'package:flutter_test/flutter_test.dart'; import '../../../../testing/mocks.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('AuthApiClient', () { diff --git a/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart b/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart index e148eb582..6e22287d1 100644 --- a/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart +++ b/compass_app/app/test/domain/use_cases/booking/booking_create_use_case_test.dart @@ -12,6 +12,7 @@ import '../../../../testing/fakes/repositories/fake_destination_repository.dart' import '../../../../testing/models/activity.dart'; import '../../../../testing/models/booking.dart'; import '../../../../testing/models/destination.dart'; +import '../../../../testing/utils/result.dart'; void main() { group('BookingCreateUseCase tests', () { diff --git a/compass_app/app/test/utils/command_test.dart b/compass_app/app/test/utils/command_test.dart index a2b1c8870..964baf403 100644 --- a/compass_app/app/test/utils/command_test.dart +++ b/compass_app/app/test/utils/command_test.dart @@ -6,6 +6,8 @@ import 'package:compass_app/utils/command.dart'; import 'package:compass_app/utils/result.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../../testing/utils/result.dart'; + void main() { group('Command0 tests', () { test('should complete void command', () async { @@ -89,7 +91,7 @@ void main() { test('should complete bool command, bool argument', () async { // Action that returns bool argument final command = - Command1((a) => Future.value(Result.ok(true))); + Command1((a) => Future.value(const Result.ok(true))); // Run action with result and argument await command.execute(true); diff --git a/compass_app/app/testing/fakes/services/fake_auth_api_client.dart b/compass_app/app/testing/fakes/services/fake_auth_api_client.dart index 714e2e7c3..af4ea340c 100644 --- a/compass_app/app/testing/fakes/services/fake_auth_api_client.dart +++ b/compass_app/app/testing/fakes/services/fake_auth_api_client.dart @@ -11,7 +11,7 @@ class FakeAuthApiClient implements AuthApiClient { @override Future> login(LoginRequest loginRequest) async { if (loginRequest.email == 'EMAIL' && loginRequest.password == 'PASSWORD') { - return Result.ok(const LoginResponse(token: 'TOKEN', userId: '123')); + return const Result.ok(LoginResponse(token: 'TOKEN', userId: '123')); } return Result.error(Exception('ERROR!')); } diff --git a/compass_app/app/testing/utils/result.dart b/compass_app/app/testing/utils/result.dart new file mode 100644 index 000000000..457003cb5 --- /dev/null +++ b/compass_app/app/testing/utils/result.dart @@ -0,0 +1,9 @@ +import 'package:compass_app/utils/result.dart'; + +extension ResultCast on Result { + /// Convenience method to cast to Ok + Ok get asOk => this as Ok; + + /// Convenience method to cast to Error + Error get asError => this as Error; +} diff --git a/compass_app/server/lib/config/assets.dart b/compass_app/server/lib/config/assets.dart index 6ee55cf86..e2bec536d 100644 --- a/compass_app/server/lib/config/assets.dart +++ b/compass_app/server/lib/config/assets.dart @@ -8,7 +8,7 @@ import 'dart:io'; import '../model/activity/activity.dart'; import '../model/destination/destination.dart'; -class Assets { +abstract final class Assets { static const _activities = '../app/assets/activities.json'; static const _destinations = '../app/assets/destinations.json'; diff --git a/compass_app/server/lib/config/constants.dart b/compass_app/server/lib/config/constants.dart index 60f35b40d..a3cc6d67d 100644 --- a/compass_app/server/lib/config/constants.dart +++ b/compass_app/server/lib/config/constants.dart @@ -4,7 +4,7 @@ import '../model/user/user.dart'; -class Constants { +abstract final class Constants { /// Email for the hardcoded login. static const email = 'email@example.com'; diff --git a/compass_app/server/lib/routes/booking.dart b/compass_app/server/lib/routes/booking.dart index 90519c41d..83941bfc2 100644 --- a/compass_app/server/lib/routes/booking.dart +++ b/compass_app/server/lib/routes/booking.dart @@ -22,7 +22,7 @@ import '../model/booking/booking.dart'; class BookingApi { BookingApi() { // Create a default booking - var destination = Assets.destinations.first; + final destination = Assets.destinations.first; final activitiesRef = Assets.activities .where((activity) => activity.destinationRef == destination.ref) .map((activity) => activity.ref) diff --git a/compass_app/server/lib/routes/login.dart b/compass_app/server/lib/routes/login.dart index f5939fe77..35b3473b6 100644 --- a/compass_app/server/lib/routes/login.dart +++ b/compass_app/server/lib/routes/login.dart @@ -4,10 +4,10 @@ import 'dart:convert'; -import 'package:compass_server/config/constants.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; +import '../config/constants.dart'; import '../model/login_request/login_request.dart'; import '../model/login_response/login_response.dart'; diff --git a/compass_app/server/lib/routes/user.dart b/compass_app/server/lib/routes/user.dart index 534d8f8ff..045442e1f 100644 --- a/compass_app/server/lib/routes/user.dart +++ b/compass_app/server/lib/routes/user.dart @@ -4,10 +4,11 @@ import 'dart:convert'; -import 'package:compass_server/config/constants.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_router/shelf_router.dart'; +import '../config/constants.dart'; + /// Implements a simple user API. /// /// This API only returns a hardcoded user for demonstration purposes. diff --git a/compass_app/server/pubspec.yaml b/compass_app/server/pubspec.yaml index ba47e5e9d..2cb38cff4 100644 --- a/compass_app/server/pubspec.yaml +++ b/compass_app/server/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: dev_dependencies: http: ^1.1.0 - lints: ^3.0.0 + lints: ^5.0.0 test: ^1.24.0 build_runner: ^2.4.11 freezed: ^2.5.7 diff --git a/compass_app/server/test/server_test.dart b/compass_app/server/test/server_test.dart index 20140d9f1..2020a9519 100644 --- a/compass_app/server/test/server_test.dart +++ b/compass_app/server/test/server_test.dart @@ -21,7 +21,7 @@ void main() { final host = 'http://127.0.0.1:$port'; late Process p; - var headers = { + final headers = { 'Authorization': 'Bearer ${Constants.token}', }; @@ -116,7 +116,7 @@ void main() { headers: headers, body: jsonEncode( Booking( - name: "DESTINATION, CONTINENT", + name: 'DESTINATION, CONTINENT', startDate: DateTime(2024, 1, 1), endDate: DateTime(2024, 2, 2), destinationRef: 'REF', @@ -139,7 +139,7 @@ void main() { headers: headers, body: jsonEncode( Booking( - name: "DESTINATION, CONTINENT", + name: 'DESTINATION, CONTINENT', startDate: DateTime(2024, 1, 1), endDate: DateTime(2024, 2, 2), destinationRef: 'REF', diff --git a/experimental/pedometer/example/pubspec.yaml b/experimental/pedometer/example/pubspec.yaml index fc2874ab9..a13852bd9 100644 --- a/experimental/pedometer/example/pubspec.yaml +++ b/experimental/pedometer/example/pubspec.yaml @@ -40,7 +40,7 @@ dependencies: path: ../ ffi: ^2.1.2 - intl: ^0.19.0 + intl: ^0.20.0 jni: ^0.12.0 fl_chart: ^0.69.0 diff --git a/experimental/pedometer/pubspec.yaml b/experimental/pedometer/pubspec.yaml index bc1455ecd..ef17df0a9 100644 --- a/experimental/pedometer/pubspec.yaml +++ b/experimental/pedometer/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: ffi: ^2.1.2 dev_dependencies: - ffigen: ^15.0.0 + ffigen: ^16.0.0 jnigen: ^0.12.1 flutter_test: sdk: flutter diff --git a/form_app/pubspec.yaml b/form_app/pubspec.yaml index ce5df21e9..29fd73b0e 100644 --- a/form_app/pubspec.yaml +++ b/form_app/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 - intl: ^0.19.0 + intl: ^0.20.0 http: ^1.0.0 json_annotation: any english_words: ^4.0.0 diff --git a/tool/flutter_ci_script_beta.sh b/tool/flutter_ci_script_beta.sh index 373901071..a9fb8d5c3 100755 --- a/tool/flutter_ci_script_beta.sh +++ b/tool/flutter_ci_script_beta.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" diff --git a/tool/flutter_ci_script_master.sh b/tool/flutter_ci_script_master.sh index f366eb696..01f1f8d17 100755 --- a/tool/flutter_ci_script_master.sh +++ b/tool/flutter_ci_script_master.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" diff --git a/tool/flutter_ci_script_stable.sh b/tool/flutter_ci_script_stable.sh index b1171a4d4..ee14b2b49 100755 --- a/tool/flutter_ci_script_stable.sh +++ b/tool/flutter_ci_script_stable.sh @@ -14,7 +14,6 @@ declare -ar PROJECT_NAMES=( "add_to_app/multiple_flutters/multiple_flutters_module" "add_to_app/plugin/flutter_module_using_plugin" "add_to_app/prebuilt_module/flutter_module" - "ai_recipe_generation" "analysis_defaults" "android_splash_screen" "animations" diff --git a/veggieseasons/pubspec.yaml b/veggieseasons/pubspec.yaml index 06589a2d3..05e546d29 100644 --- a/veggieseasons/pubspec.yaml +++ b/veggieseasons/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: cupertino_icons: ^1.0.2 font_awesome_flutter: ^10.1.0 - intl: ^0.19.0 + intl: ^0.20.0 provider: ^6.0.1 shared_preferences: ^2.0.14 window_size: diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index eaf1aff5b..9edd8767e 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -11,32 +11,32 @@ }, "private": true, "dependencies": { - "@angular/animations": "^18.0.1", - "@angular/cdk": "^18.0.1", - "@angular/common": "^18.0.1", - "@angular/compiler": "^18.0.1", - "@angular/core": "^18.0.1", - "@angular/forms": "^18.0.1", - "@angular/material": "^18.0.1", - "@angular/platform-browser": "^18.0.1", - "@angular/platform-browser-dynamic": "^18.0.1", - "@angular/router": "^18.0.1", + "@angular/animations": "^19.0.0", + "@angular/cdk": "^19.0.0", + "@angular/common": "^19.0.0", + "@angular/compiler": "^19.0.0", + "@angular/core": "^19.0.3", + "@angular/forms": "^19.0.1", + "@angular/material": "^19.0.2", + "@angular/platform-browser": "^19.0.3", + "@angular/platform-browser-dynamic": "^19.0.0", + "@angular/router": "^19.0.1", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^18.0.2", - "@angular/cli": "~18.2.0", - "@angular/compiler-cli": "^18.0.1", + "@angular-devkit/build-angular": "^19.0.2", + "@angular/cli": "~19.0.2", + "@angular/compiler-cli": "^19.0.1", "@types/jasmine": "~5.1.0", - "jasmine-core": "~5.4.0", + "jasmine-core": "~5.5.0", "karma": "~6.4.2", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.6.2" + "typescript": "~5.7.2" }, "sideEffects": false }