Showing preview only (513K chars total). Download the full file or copy to clipboard to get everything.
Repository: ibrahimcetin/reins
Branch: main
Commit: c4d0d1f620d3
Files: 172
Total size: 466.2 KB
Directory structure:
gitextract_0cw_5yz_/
├── .gitignore
├── .metadata
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── LICENSE
├── PRIVACY
├── README.md
├── analysis_options.yaml
├── android/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── debug/
│ │ │ └── AndroidManifest.xml
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── dev/
│ │ │ │ └── ibrahimcetin/
│ │ │ │ └── reins/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-night/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-night-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── values/
│ │ │ │ └── styles.xml
│ │ │ ├── values-night/
│ │ │ │ └── styles.xml
│ │ │ ├── values-night-v31/
│ │ │ │ └── styles.xml
│ │ │ └── values-v31/
│ │ │ └── styles.xml
│ │ └── profile/
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ └── settings.gradle
├── devtools_options.yaml
├── ios/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── LaunchBackground.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── LaunchImage.imageset/
│ │ │ ├── Contents.json
│ │ │ └── README.md
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── RunnerTests/
│ └── RunnerTests.swift
├── lib/
│ ├── Constants/
│ │ ├── app_constants.dart
│ │ ├── chat_presets.dart
│ │ ├── constants.dart
│ │ ├── generate_title_constants.dart
│ │ └── path_manager.dart
│ ├── Extensions/
│ │ └── markdown_stylesheet_extension.dart
│ ├── Models/
│ │ ├── api/
│ │ │ ├── create_request.dart
│ │ │ ├── show_response.dart
│ │ │ └── tags_response.dart
│ │ ├── chat_configure_arguments.dart
│ │ ├── chat_preset.dart
│ │ ├── model_capabilities.dart
│ │ ├── ollama_chat.dart
│ │ ├── ollama_exception.dart
│ │ ├── ollama_message.dart
│ │ ├── ollama_model.dart
│ │ ├── ollama_request_state.dart
│ │ └── settings_route_arguments.dart
│ ├── Pages/
│ │ ├── chat_page/
│ │ │ ├── chat_page.dart
│ │ │ ├── chat_page_view_model.dart
│ │ │ └── subwidgets/
│ │ │ ├── chat_attachment/
│ │ │ │ ├── chat_attachment_image.dart
│ │ │ │ ├── chat_attachment_preset.dart
│ │ │ │ └── chat_attachment_row.dart
│ │ │ ├── chat_bubble/
│ │ │ │ ├── chat_bubble.dart
│ │ │ │ ├── chat_bubble_actions.dart
│ │ │ │ ├── chat_bubble_bottom_sheet.dart
│ │ │ │ ├── chat_bubble_image.dart
│ │ │ │ ├── chat_bubble_menu.dart
│ │ │ │ └── chat_bubble_think_block.dart
│ │ │ ├── chat_empty.dart
│ │ │ ├── chat_error.dart
│ │ │ ├── chat_list_view.dart
│ │ │ ├── chat_select_model_button.dart
│ │ │ ├── chat_text_field.dart
│ │ │ ├── chat_welcome.dart
│ │ │ └── subwidgets.dart
│ │ ├── main_page.dart
│ │ └── settings_page/
│ │ ├── settings_page.dart
│ │ └── subwidgets/
│ │ ├── reins_settings.dart
│ │ ├── server_settings.dart
│ │ ├── subwidgets.dart
│ │ └── themes_settings.dart
│ ├── Providers/
│ │ └── chat_provider.dart
│ ├── Services/
│ │ ├── database_service.dart
│ │ ├── image_service.dart
│ │ ├── ollama_service.dart
│ │ ├── permission_service.dart
│ │ └── services.dart
│ ├── Utils/
│ │ ├── border_painter.dart
│ │ ├── http_error_formatter.dart
│ │ ├── material_color_adapter.dart
│ │ ├── observe_size.dart
│ │ ├── request_review_helper.dart
│ │ └── retained_position_scroll_physics.dart
│ ├── Widgets/
│ │ ├── chat_app_bar.dart
│ │ ├── chat_configure_bottom_sheet.dart
│ │ ├── chat_drawer.dart
│ │ ├── chat_image.dart
│ │ ├── flexible_text.dart
│ │ ├── model_selection_bottom_sheet.dart
│ │ ├── ollama_bottom_sheet_header.dart
│ │ └── title_divider.dart
│ └── main.dart
├── linux/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flatpak/
│ │ ├── dev.ibrahimcetin.reins.desktop
│ │ └── dev.ibrahimcetin.reins.metainfo.xml
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── main.cc
│ ├── my_application.cc
│ └── my_application.h
├── macos/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Podfile
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ └── MainMenu.xib
│ │ ├── Configs/
│ │ │ ├── AppInfo.xcconfig
│ │ │ ├── Debug.xcconfig
│ │ │ ├── Release.xcconfig
│ │ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── RunnerTests/
│ └── RunnerTests.swift
├── pubspec.yaml
├── test/
│ ├── api_create_request_test.dart
│ ├── assets/
│ │ └── settings.hive
│ ├── chat_page_view_model_test.dart
│ ├── database_service_test.dart
│ └── ollama_service_test.dart
├── web/
│ ├── index.html
│ └── manifest.json
└── windows/
├── .gitignore
├── CMakeLists.txt
├── flutter/
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
└── runner/
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# 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
================================================
FILE: .metadata
================================================
# 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: "8495dee1fd4aacbe9de707e7581203232f591b2f"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: android
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: ios
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: linux
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: macos
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: web
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
- platform: windows
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
# 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'
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "reins",
"request": "launch",
"type": "dart"
},
{
"name": "reins (profile mode)",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "reins (release mode)",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"cmake.ignoreCMakeListsMissing": true,
"cSpell.words": [
"Ollama"
]
}
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
================================================
FILE: PRIVACY
================================================
Reins app does not track any activity or actions of their users. No private information is being collected by the app.
================================================
FILE: README.md
================================================
# Reins
Reins is a multi-platform, open-source, privacy-first app designed for Ollama users. **It simplifies chat configurations** with a user-friendly interface to configure system prompts, change the chat model, and adjust options for each conversation **individually**. Reins ensures a smooth, customizable experience for anyone working with self-hosted LLMs.
If you like the project, don't forget to give a ⭐️!
<a href="https://apps.apple.com/tr/app/reins-chat-for-ollama/id6739738501">
<img src=https://github.com/user-attachments/assets/fd7d615d-46c1-4266-b558-fb8e42555b04 alt="Download on the App Store" height=80 />
</a>
<a href='https://flathub.org/apps/dev.ibrahimcetin.reins'>
<img src='https://github.com/user-attachments/assets/2c902ab8-bef6-44a7-ae50-40da9ead3a13' alt='Get it on Flathub' height=80 />
</a>
You can download it for iOS and macOS on the App Store and for Linux on Flathub.
You can find Android and Windows releases from [here](https://github.com/ibrahimcetin/reins/releases).
## Key Features
- **Customizable Chat Configurations**: Configure system prompt, model, and options (e.g., temperature, seed, context size, max tokens) for each conversation.
- **Model Selection & Switching**: Change the model of the current chat without interruption.
- **Message Editing & Regeneration**: Edit and regenerate messages
- **Save Custom Models**: Save system and chat prompts as new models.
- **Image Integration**: Send and receive images within chats.
- **Multiple Chat Management**: Easily manage and switch between multiple conversations.
- **Real-Time Message Streaming**: Get messages instantly as they arrive.
## Mobile Screenshots
<img src=https://github.com/user-attachments/assets/29c06936-a1ff-430b-b892-3195db01497a alt="Main" height=500>
<img src=https://github.com/user-attachments/assets/a18f5d7b-d547-4da7-adbe-332349597f69 alt="Configuration" height=500>
<img src=https://github.com/user-attachments/assets/fd445119-9f7c-4dc1-bff6-df534f0a7a85 alt="Advanced Configurations" height=500>
<img src=https://github.com/user-attachments/assets/2db44515-fd63-4263-a16a-beecc9373c96 alt="Edit & Regenerate" height=500>
<img src=https://github.com/user-attachments/assets/ad8ce6bd-53a9-4ab4-b3b1-921a9ecd2a1e alt="Change Current Chat Model" height=500>
<img src=https://github.com/user-attachments/assets/fedb9a5f-f840-49b8-a9eb-90f9d222f6f3 alt="Select Model" height=500>
<img src=https://github.com/user-attachments/assets/f873ebdc-4a41-44ca-b5a2-75a1c6784ddd alt="Dark Theme" height=500>
## Large Screen Screenshots
<img src=https://github.com/user-attachments/assets/ab34966e-8975-4ee9-a498-03b3ed2d086a alt="Main" height=375>
<img src=https://github.com/user-attachments/assets/5f561d77-3b66-444e-aa6f-cf7d3ac60557 alt="Configuration" height=375>
## Contributing
Contributions are welcome! Feel free to fork the repository, make changes, and submit a pull request.
## License
Reins is licensed under the GPL-3.0.
================================================
FILE: analysis_options.yaml
================================================
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
formatter:
page_width: 120
================================================
FILE: android/.gitignore
================================================
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
**/.cxx
================================================
FILE: android/app/build.gradle
================================================
plugins {
id "com.android.application"
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
namespace = "dev.ibrahimcetin.reins"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "dev.ibrahimcetin.reins"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
signingConfigs {
release {
keyAlias = keystoreProperties['keyAlias']
keyPassword = keystoreProperties['keyPassword']
storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword = keystoreProperties['storePassword']
}
}
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.release
}
}
}
flutter {
source = "../.."
}
================================================
FILE: android/app/src/debug/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: android/app/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="Reins"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
================================================
FILE: android/app/src/main/kotlin/dev/ibrahimcetin/reins/MainActivity.kt
================================================
package dev.ibrahimcetin.reins
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity()
================================================
FILE: android/app/src/main/res/drawable/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
================================================
FILE: android/app/src/main/res/drawable-night/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
================================================
FILE: android/app/src/main/res/drawable-night-v21/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
================================================
FILE: android/app/src/main/res/drawable-v21/launch_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>
================================================
FILE: android/app/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: android/app/src/main/res/values-night/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: android/app/src/main/res/values-night-v31/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#000000</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: android/app/src/main/res/values-v31/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#ffffff</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
================================================
FILE: android/app/src/profile/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
================================================
FILE: android/build.gradle
================================================
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
}
================================================
FILE: android/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
================================================
FILE: android/gradle.properties
================================================
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true
================================================
FILE: android/settings.gradle
================================================
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
}()
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.0" apply false
id "org.jetbrains.kotlin.android" version "2.3.10" apply false
}
include ":app"
================================================
FILE: devtools_options.yaml
================================================
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
================================================
FILE: ios/.gitignore
================================================
**/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
================================================
FILE: ios/Flutter/AppFrameworkInfo.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>
================================================
FILE: ios/Flutter/Debug.xcconfig
================================================
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: ios/Flutter/Release.xcconfig
================================================
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
================================================
FILE: ios/Podfile
================================================
# Uncomment this line to define a global platform for your project
# platform :ios, '13.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)
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
]
end
end
end
================================================
FILE: ios/Runner/AppDelegate.swift
================================================
import Flutter
import UIKit
@main
@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)
}
}
================================================
FILE: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"filename" : "reins.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "reins-dark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "reins-dark 1.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "background.png",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "darkbackground.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "LaunchImage.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "LaunchImageDark.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "LaunchImage@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "LaunchImageDark@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "LaunchImage@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "LaunchImageDark@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# 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.
================================================
FILE: ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" image="LaunchBackground" translatesAutoresizingMaskIntoConstraints="NO" id="tWc-Dq-wcI"/>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"></imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="RPx-PI-7Xg"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="SdS-ul-q2q"/>
<constraint firstAttribute="trailing" secondItem="tWc-Dq-wcI" secondAttribute="trailing" id="Swv-Gf-Rwn"/>
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="kV7-tw-vXt"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="192" height="384"/>
<image name="LaunchBackground" width="1" height="1"/>
</resources>
</document>
================================================
FILE: ios/Runner/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
================================================
FILE: ios/Runner/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Reins</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>reins</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSPhotoLibraryUsageDescription</key>
<string>Reins needs access to your photo library to let you select images to send in chats.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
================================================
FILE: ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"
================================================
FILE: ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*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 */; };
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 */; };
D519756EA826A2976D5FA068 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8BD3A7DD18536256343BFFDC /* Pods_RunnerTests.framework */; };
F1FA0DD01D618F4B1250B9A3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56D5B87EEA532CCA2F863866 /* Pods_Runner.framework */; };
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; };
/* 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 */
0A807142E3816A90C2C1F3D4 /* 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 = "<group>"; };
0C36C37B8FE2F882B7F66CF5 /* 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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
27B7B2D0B1593B1F4FB15290 /* 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 = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
56D5B87EEA532CCA2F863866 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7E0760B186B5CD533FADA873 /* 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 = "<group>"; };
8BD3A7DD18536256343BFFDC /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
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 = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B457AD5CBA9FD11ED3A21575 /* 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 = "<group>"; };
FA4D4BD68716F904BFDE79C0 /* 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 = "<group>"; };
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
172BA7F1156A620486622267 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D519756EA826A2976D5FA068 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */,
F1FA0DD01D618F4B1250B9A3 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
864C3237747B13B08BB74FFF /* Pods */ = {
isa = PBXGroup;
children = (
27B7B2D0B1593B1F4FB15290 /* Pods-Runner.debug.xcconfig */,
FA4D4BD68716F904BFDE79C0 /* Pods-Runner.release.xcconfig */,
0C36C37B8FE2F882B7F66CF5 /* Pods-Runner.profile.xcconfig */,
B457AD5CBA9FD11ED3A21575 /* Pods-RunnerTests.debug.xcconfig */,
7E0760B186B5CD533FADA873 /* Pods-RunnerTests.release.xcconfig */,
0A807142E3816A90C2C1F3D4 /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
864C3237747B13B08BB74FFF /* Pods */,
A531F8A5C015E45D758173D1 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
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 = "<group>";
};
A531F8A5C015E45D758173D1 /* Frameworks */ = {
isa = PBXGroup;
children = (
56D5B87EEA532CCA2F863866 /* Pods_Runner.framework */,
8BD3A7DD18536256343BFFDC /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
2AA46EDF392C6009BDC73374 /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
172BA7F1156A620486622267 /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
packageProductDependencies = (
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
580E76C33CE6BEC0CAC15957 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8120DB1D8C623988F45DD411 /* [CP] Embed Pods Frameworks */,
1959A3E64A568FEB8F91481F /* [CP] Copy Pods Resources */,
);
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 */ = {
packageReferences = (
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */,
);
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 */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
1959A3E64A568FEB8F91481F /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2AA46EDF392C6009BDC73374 /* [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;
};
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";
};
580E76C33CE6BEC0CAC15957 /* [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;
};
8120DB1D8C623988F45DD411 /* [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;
};
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";
};
/* 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 = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
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;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
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 = 13.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 = 2;
DEVELOPMENT_TEAM = 9HQV48CK77;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Reins;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.ibrahimcetin.reins;
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 = B457AD5CBA9FD11ED3A21575 /* 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 = dev.ibrahimcetin.reins.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 = 7E0760B186B5CD533FADA873 /* 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 = dev.ibrahimcetin.reins.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 = 0A807142E3816A90C2C1F3D4 /* 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 = dev.ibrahimcetin.reins.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;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
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;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
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 = 13.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;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
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;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
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 = 13.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 = 2;
DEVELOPMENT_TEAM = 9HQV48CK77;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Reins;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.ibrahimcetin.reins.debug;
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 = 2;
DEVELOPMENT_TEAM = 9HQV48CK77;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Reins;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.ibrahimcetin.reins;
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 */
/* Begin XCLocalSwiftPackageReference section */
781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = {
isa = XCSwiftPackageProductDependency;
productName = FlutterGeneratedPluginSwiftPackage;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PreActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Run Prepare Flutter Framework Script"
scriptText = "/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" prepare ">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PreActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
================================================
FILE: ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
================================================
FILE: ios/RunnerTests/RunnerTests.swift
================================================
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.
}
}
================================================
FILE: lib/Constants/app_constants.dart
================================================
class AppConstants {
static const String appName = 'Reins';
static const String appIconPng = 'assets/images/reins.png';
static const String appIconSvg = 'assets/images/reins.svg';
static const String ollamaIconPng = 'assets/images/ollama.png';
}
class NotificationNames {
static const String generationBegin = "generation_begin_notification";
}
================================================
FILE: lib/Constants/chat_presets.dart
================================================
import 'package:reins/Models/chat_preset.dart';
class ChatPresets {
static final List<ChatPreset> chatPresets = List.unmodifiable([
ChatPreset(
title: "Brainstorm ideas",
subtitle: "to spark creativity and solve challenges",
prompt:
"Can you help brainstorm 10 innovative ideas for a startup focusing on renewable energy and technology?"),
ChatPreset(
title: "Plan a trip",
subtitle: "with a detailed itinerary and suggestions",
prompt:
"I want to plan a 5-day trip to Paris, France, including must-visit attractions, restaurants, and transportation tips."),
ChatPreset(
title: "Learn a new skill",
subtitle: "with a structured step-by-step plan",
prompt:
"Help me create a 3-month learning plan to master digital painting as a beginner."),
ChatPreset(
title: "Write a story",
subtitle: "that captivates readers with vivid details",
prompt:
"Create a short science fiction story about a world where AI governs all aspects of daily life."),
ChatPreset(
title: "Design a workout plan",
subtitle: "to meet fitness goals effectively",
prompt:
"I want a 4-week workout plan for building muscle and improving endurance. Include exercises, reps, and rest days."),
ChatPreset(
title: "Cook a special dish",
subtitle: "with a simple recipe and clear steps",
prompt:
"Give me a detailed recipe for making homemade lasagna, including all the ingredients and cooking instructions."),
ChatPreset(
title: "Explain a concept",
subtitle: "in a way that's easy to understand",
prompt:
"Explain the concept of blockchain technology as if you were teaching a 10-year-old."),
ChatPreset(
title: "Solve a problem",
subtitle: "with practical and actionable advice",
prompt:
"I am struggling with procrastination. Can you provide strategies to overcome it and improve productivity?"),
ChatPreset(
title: "Prepare for an interview",
subtitle: "with common questions and tips",
prompt:
"Help me prepare for a software engineering interview, including potential coding challenges and behavioral questions."),
ChatPreset(
title: "Improve writing",
subtitle: "with tips to refine and enhance text",
prompt:
"I have a draft of an email to my professor. Can you help me improve its tone and clarity?"),
ChatPreset(
title: "Learn about a topic",
subtitle: "with clear and concise information",
prompt:
"Teach me about the basics of artificial intelligence and its applications in daily life."),
ChatPreset(
title: "Generate a table",
subtitle: "to organize information neatly",
prompt:
"Create a comparison table for three smartphones: iPhone 15, Samsung Galaxy S23, and Google Pixel 8. Include columns for features, price, and battery life."),
ChatPreset(
title: "Create a meal plan",
subtitle: "tailored to specific dietary needs",
prompt:
"I need a 5-day vegan meal plan that includes breakfast, lunch, and dinner. Please make it nutritious and easy to prepare."),
ChatPreset(
title: "Find inspiration",
subtitle: "to tackle creative blocks",
prompt:
"Give me 5 unique ideas for a blog post about sustainable living and eco-friendly habits."),
ChatPreset(
title: "Analyze data",
subtitle: "to extract insights and trends",
prompt:
"Given the following data about monthly sales, help identify trends and provide suggestions for improvement."),
ChatPreset(
title: "Write a poem",
subtitle: "that captures emotion and depth",
prompt:
"Write a romantic poem about finding love in an unexpected place."),
ChatPreset(
title: "Generate a list",
subtitle: "of items related to a topic",
prompt:
"Give me a list of 10 books to read for improving public speaking skills."),
ChatPreset(
title: "Craft a speech",
subtitle: "for a special occasion",
prompt:
"Help me write a heartfelt speech for my best friend's wedding. Include memories and well wishes."),
ChatPreset(
title: "Design a budget",
subtitle: "to manage expenses effectively",
prompt:
"I earn \$3,000 per month. Help me create a monthly budget for savings, rent, groceries, and leisure."),
ChatPreset(
title: "Learn a language",
subtitle: "with basic phrases and tips",
prompt:
"Teach me 10 essential phrases in Spanish for traveling to Spain."),
ChatPreset(
title: "Plan an event",
subtitle: "with all the necessary details",
prompt:
"I want to organize a surprise birthday party for my partner. Can you help with a plan, including themes, locations, and activities?"),
ChatPreset(
title: "Write a cover letter",
subtitle: "that highlights your strengths",
prompt:
"Help me write a cover letter for a software engineering job application. Highlight my coding skills and project experience."),
ChatPreset(
title: "Create a list",
subtitle: "of fun activities to try",
prompt:
"Suggest 10 fun weekend activities for a group of friends in the city."),
ChatPreset(
title: "Summarize a book",
subtitle: "into key points and takeaways",
prompt:
"Provide a summary of the book 'Atomic Habits' by James Clear, focusing on its key principles."),
ChatPreset(
title: "Plan a garden",
subtitle: "with layout and plant ideas",
prompt:
"I have a small backyard. Can you suggest a garden layout with plants suitable for a beginner?"),
ChatPreset(
title: "Write a review",
subtitle: "to provide clear and honest feedback",
prompt:
"Help me write a review for the latest Marvel movie. Include both strengths and areas for improvement."),
ChatPreset(
title: "Solve a puzzle",
subtitle: "to test your problem-solving skills",
prompt:
"Can you help me solve this Sudoku puzzle? Here's the current grid: [provide grid]."),
ChatPreset(
title: "Get travel tips",
subtitle: "for a destination",
prompt:
"I am visiting Rome, Italy, next month. Can you suggest travel tips, including local customs and transportation?"),
ChatPreset(
title: "Discover hidden gems",
subtitle: "to explore unique destinations",
prompt:
"Suggest 5 hidden gem locations in Tokyo that tourists often miss, including why they are worth visiting."),
ChatPreset(
title: "Plan a study schedule",
subtitle: "to prepare effectively for exams",
prompt:
"Help me create a 2-week study plan for my upcoming biology exam, covering key topics and including breaks."),
ChatPreset(
title: "Understand a process",
subtitle: "with step-by-step guidance",
prompt:
"Explain the process of photosynthesis in plants step by step in a simple and concise way."),
ChatPreset(
title: "Improve productivity",
subtitle: "with actionable strategies",
prompt:
"What are some effective time management techniques for balancing work, study, and personal life?"),
ChatPreset(
title: "Get relationship advice",
subtitle: "to navigate challenges effectively",
prompt:
"I had a misunderstanding with my friend. How can I approach them to resolve the issue and rebuild trust?"),
ChatPreset(
title: "Explore career options",
subtitle: "aligned with skills and interests",
prompt:
"I am skilled in graphic design and love storytelling. What are some potential career paths for me?"),
ChatPreset(
title: "Generate a packing list",
subtitle: "tailored to your trip destination",
prompt:
"I'm going on a 10-day trip to Iceland in winter. What should I pack to stay comfortable and prepared?"),
ChatPreset(
title: "Get gift ideas",
subtitle: "for any occasion",
prompt:
"I'm looking for a birthday gift for my 10-year-old nephew who loves science and puzzles. Can you suggest some ideas?"),
ChatPreset(
title: "Create a meditation guide",
subtitle: "for relaxation and mindfulness",
prompt:
"Provide a 10-minute guided meditation script to help reduce stress and increase focus."),
ChatPreset(
title: "Learn a fun fact",
subtitle: "to surprise and engage others",
prompt: "Tell me a fun and surprising fact about space exploration."),
ChatPreset(
title: "Host a trivia night",
subtitle: "with engaging questions",
prompt:
"Create a set of 10 trivia questions about world history for a game night."),
ChatPreset(
title: "Plan a budget-friendly trip",
subtitle: "without compromising on experiences",
prompt:
"How can I plan a 3-day trip to New York City on a budget of \$500? Include activities and food options."),
ChatPreset(
title: "Write a thank-you note",
subtitle: "to express gratitude sincerely",
prompt:
"Help me draft a thank-you email to my mentor for their guidance during my internship."),
ChatPreset(
title: "Debunk a myth",
subtitle: "with accurate information",
prompt:
"Is it true that cracking your knuckles causes arthritis? Provide evidence-based information."),
ChatPreset(
title: "Plan a creative project",
subtitle: "from concept to execution",
prompt:
"I want to start a photography series capturing daily life in my city. Can you help me plan this project?"),
ChatPreset(
title: "Learn about famous landmarks",
subtitle: "and their historical significance",
prompt:
"Tell me the story behind the construction of the Eiffel Tower and why it is iconic."),
ChatPreset(
title: "Get workout motivation",
subtitle: "to achieve your fitness goals",
prompt:
"I've been struggling to stay consistent with workouts. Can you provide motivational tips and a simple routine to get back on track?"),
ChatPreset(
title: "Write a job description",
subtitle: "for your team's new role",
prompt:
"Draft a job description for a junior web developer position, focusing on required skills and job responsibilities."),
ChatPreset(
title: "Generate a bucket list",
subtitle: "for unforgettable experiences",
prompt:
"Help me create a bucket list of 20 unique activities to try before turning 40."),
ChatPreset(
title: "Design a menu",
subtitle: "for an upcoming dinner party",
prompt:
"Can you suggest a three-course menu for a dinner party, including an appetizer, main course, and dessert?"),
ChatPreset(
title: "Write a persuasive letter",
subtitle: "to convey your message effectively",
prompt:
"Help me write a letter to my local council advocating for better public transport services in our area."),
ChatPreset(
title: "Explore myths and legends",
subtitle: "from around the world",
prompt:
"Share a famous myth or legend from Japanese folklore and its cultural significance."),
ChatPreset(
title: "Host a themed party",
subtitle: "with creative ideas and details",
prompt:
"I want to organize a 'Roaring Twenties' themed party. Can you suggest decor, costumes, and activities?"),
ChatPreset(
title: "Write a business pitch",
subtitle: "to attract investors",
prompt:
"Create a pitch for a new app that helps people track and reduce their carbon footprint."),
ChatPreset(
title: "Plan a charity event",
subtitle: "to raise funds for a cause",
prompt:
"I want to organize a local fun run to raise funds for animal shelters. Can you provide a detailed plan?"),
ChatPreset(
title: "Teach a life skill",
subtitle: "in an easy-to-follow way",
prompt:
"Explain how to tie a tie step by step, as if teaching a beginner."),
ChatPreset(
title: "Craft a bedtime story",
subtitle: "to delight and calm children",
prompt:
"Write a short bedtime story about a magical tree that grants wishes to animals in the forest."),
ChatPreset(
title: "Plan a surprise date",
subtitle: "with romantic ideas",
prompt:
"Suggest a creative and budget-friendly date idea for my partner this weekend."),
// More presets can be added here following the same pattern
]);
static List<ChatPreset> get randomPresets {
final presetsCopy = List.of(chatPresets);
presetsCopy.shuffle();
return presetsCopy.take(5).toList();
}
}
================================================
FILE: lib/Constants/constants.dart
================================================
export 'app_constants.dart';
export 'path_manager.dart';
export 'chat_presets.dart';
export 'generate_title_constants.dart';
================================================
FILE: lib/Constants/generate_title_constants.dart
================================================
class GenerateTitleConstants {
static const String systemPrompt =
"You are a title generator for a chat application. Your task is to create a concise and descriptive title based on the user's first message in a chat. The title should capture the main topic or intent of the message while being engaging and informative. Avoid generic titles like 'Chat' or 'Conversation.' Keep the title under 5 words. For example: If the first message is 'What's the weather like today in Paris?' the title should be 'Weather in Paris.' If the first message is 'Can you help me with my homework?' the title could be 'Homework Help.' If the first message is 'Tell me a story about a dragon,' the title could be 'Dragon Story Request.' Always focus on the essence of the message and aim for clarity and relevance.";
static const String prompt =
"You are a title generator for a chat application. Your task is to create a concise and descriptive title based on the user's first message in a chat. Respond with the title only—do not include any additional words, explanations, or phrases. The title should be no more than 5 words and capture the main topic of the user's message. For example: Input: 'What's the weather in Paris?' → Output: 'Weather in Paris' Input: 'Tell me a story about a dragon.' → Output: 'Dragon Story' Input: 'Plan a trip to Italy.' → Output: 'Italy Trip Plan'. Now generate a title for this message: ";
}
================================================
FILE: lib/Constants/path_manager.dart
================================================
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class PathManager {
static final PathManager _instance = PathManager._internal();
late final Directory documentsDirectory;
PathManager._internal();
static Future<void> initialize() async {
if (Platform.isLinux) {
final directory = await getApplicationSupportDirectory();
_instance.documentsDirectory = directory;
} else {
final directory = await getApplicationDocumentsDirectory();
_instance.documentsDirectory = directory;
}
}
static PathManager get instance => _instance;
}
================================================
FILE: lib/Extensions/markdown_stylesheet_extension.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
/// Extension on [BuildContext] to provide consistent markdown styling across the app.
extension MarkdownStyleSheetExtension on BuildContext {
/// Returns a [MarkdownStyleSheet] that matches the app's theme with bodyLarge text size.
///
/// This ensures markdown content uses the same base size as other readable text
/// in the app, while respecting user accessibility settings up to 2x scale.
MarkdownStyleSheet get markdownStyleSheet {
return MarkdownStyleSheet.fromTheme(
Theme.of(this).copyWith(
textTheme: Theme.of(this).textTheme.copyWith(
bodyMedium: Theme.of(this).textTheme.bodyLarge,
),
),
).copyWith(
textScaler: MediaQuery.textScalerOf(this).clamp(
minScaleFactor: 0.8,
maxScaleFactor: 2.0,
),
);
}
}
================================================
FILE: lib/Models/api/create_request.dart
================================================
import 'package:reins/Models/ollama_chat.dart';
import 'package:reins/Models/ollama_message.dart';
/// Request body for POST /api/create
///
/// Creates a model from another model with optional system prompt,
/// parameters, and message history.
class ApiCreateRequest {
/// Name of the model to create.
final String model;
/// Name of an existing model to create the new model from.
final String from;
/// A system prompt for the model.
final String? system;
/// A dictionary of parameters for the model.
final Map<String, dynamic>? parameters;
/// A list of message objects used to seed the conversation.
final List<OllamaMessage>? messages;
/// If `false` the response will be returned as a single response object,
/// rather than a stream of objects.
final bool stream;
ApiCreateRequest({
required this.model,
required this.from,
this.system,
this.parameters,
this.messages,
this.stream = false,
});
/// Constructs an [ApiCreateRequest] from an [OllamaChat] and optional messages.
///
/// Only non-default parameters are included in the request to avoid
/// overriding the base model's defaults unnecessarily.
factory ApiCreateRequest.fromChat(
String model, {
required OllamaChat chat,
List<OllamaMessage>? messages,
}) {
final defaultOptions = OllamaChatOptions().toMap();
final chatOptions = chat.options.toMap();
// Only include parameters that differ from the defaults.
final nonDefaultParameters = <String, dynamic>{};
chatOptions.forEach((key, value) {
if (defaultOptions[key] != value) {
nonDefaultParameters[key] = value;
}
});
return ApiCreateRequest(
model: model,
from: chat.model,
system: chat.systemPrompt,
parameters: nonDefaultParameters.isNotEmpty ? nonDefaultParameters : null,
messages: messages != null && messages.isNotEmpty ? messages : null,
);
}
Future<Map<String, dynamic>> toJson() async {
return {
'model': model,
'from': from,
if (system != null && system!.isNotEmpty) 'system': system,
if (parameters != null) 'parameters': parameters,
if (messages != null) 'messages': await Future.wait(messages!.map((m) => m.toChatJson())),
'stream': stream,
};
}
}
================================================
FILE: lib/Models/api/show_response.dart
================================================
/// Response from POST /api/show
class ApiShowResponse {
final String modelfile;
final String parameters;
final String template;
final ApiShowModelDetails details;
final Map<String, dynamic> modelInfo;
final List<String> capabilities;
ApiShowResponse({
required this.modelfile,
required this.parameters,
required this.template,
required this.details,
required this.modelInfo,
required this.capabilities,
});
factory ApiShowResponse.fromJson(Map<String, dynamic> json) {
return ApiShowResponse(
modelfile: json['modelfile'] ?? '',
parameters: json['parameters'] ?? '',
template: json['template'] ?? '',
details: ApiShowModelDetails.fromJson(json['details'] ?? {}),
modelInfo: json['model_info'] ?? {},
capabilities: json['capabilities'] != null ? List<String>.from(json['capabilities']) : [],
);
}
}
/// Model details from /api/show response
class ApiShowModelDetails {
final String parentModel;
final String format;
final String family;
final List<String>? families;
final String parameterSize;
final String quantizationLevel;
ApiShowModelDetails({
required this.parentModel,
required this.format,
required this.family,
this.families,
required this.parameterSize,
required this.quantizationLevel,
});
factory ApiShowModelDetails.fromJson(Map<String, dynamic> json) {
return ApiShowModelDetails(
parentModel: json['parent_model'] ?? '',
format: json['format'] ?? '',
family: json['family'] ?? '',
families: json['families'] != null ? List<String>.from(json['families']) : null,
parameterSize: json['parameter_size'] ?? '',
quantizationLevel: json['quantization_level'] ?? '',
);
}
}
================================================
FILE: lib/Models/api/tags_response.dart
================================================
/// Response from GET /api/tags
class ApiTagsResponse {
final List<ApiTagsModel> models;
ApiTagsResponse({required this.models});
factory ApiTagsResponse.fromJson(Map<String, dynamic> json) {
return ApiTagsResponse(
models: (json['models'] as List).map((m) => ApiTagsModel.fromJson(m)).toList(),
);
}
}
/// Individual model from /api/tags response
class ApiTagsModel {
final String name;
final String model;
final DateTime modifiedAt;
final int size;
final String digest;
final ApiTagsModelDetails details;
ApiTagsModel({
required this.name,
required this.model,
required this.modifiedAt,
required this.size,
required this.digest,
required this.details,
});
factory ApiTagsModel.fromJson(Map<String, dynamic> json) {
return ApiTagsModel(
name: json['name'],
model: json['model'],
modifiedAt: DateTime.parse(json['modified_at']),
size: json['size'],
digest: json['digest'],
details: ApiTagsModelDetails.fromJson(json['details']),
);
}
}
/// Model details from /api/tags response
class ApiTagsModelDetails {
final String parentModel;
final String format;
final String family;
final List<String>? families;
final String parameterSize;
final String quantizationLevel;
ApiTagsModelDetails({
required this.parentModel,
required this.format,
required this.family,
this.families,
required this.parameterSize,
required this.quantizationLevel,
});
factory ApiTagsModelDetails.fromJson(Map<String, dynamic> json) {
return ApiTagsModelDetails(
parentModel: json['parent_model'] ?? '',
format: json['format'] ?? '',
family: json['family'] ?? '',
families: json['families'] != null ? List<String>.from(json['families']) : null,
parameterSize: json['parameter_size'] ?? '',
quantizationLevel: json['quantization_level'] ?? '',
);
}
}
================================================
FILE: lib/Models/chat_configure_arguments.dart
================================================
import 'package:reins/Models/ollama_chat.dart';
class ChatConfigureArguments {
String? systemPrompt;
OllamaChatOptions chatOptions;
ChatConfigureArguments({
required this.systemPrompt,
required this.chatOptions,
});
static get defaultArguments => ChatConfigureArguments(
systemPrompt: null,
chatOptions: OllamaChatOptions(),
);
}
================================================
FILE: lib/Models/chat_preset.dart
================================================
class ChatPreset {
final String title;
final String subtitle;
final String prompt;
ChatPreset({
required this.title,
required this.subtitle,
required this.prompt,
});
}
================================================
FILE: lib/Models/model_capabilities.dart
================================================
/// Model capabilities extracted from /api/show response
class ModelCapabilities {
final bool completion;
final bool vision;
final bool tools;
final bool embedding;
final bool thinking;
const ModelCapabilities({
this.completion = false,
this.vision = false,
this.tools = false,
this.embedding = false,
this.thinking = false,
});
/// Creates capabilities from the raw capabilities list from /api/show
factory ModelCapabilities.fromList(List<String> capabilities) {
return ModelCapabilities(
completion: capabilities.contains('completion'),
vision: capabilities.contains('vision'),
tools: capabilities.contains('tools'),
embedding: capabilities.contains('embedding'),
thinking: capabilities.contains('thinking'),
);
}
@override
String toString() {
final caps = <String>[];
if (completion) caps.add('completion');
if (vision) caps.add('vision');
if (tools) caps.add('tools');
if (embedding) caps.add('embedding');
if (thinking) caps.add('thinking');
return 'ModelCapabilities(${caps.join(', ')})';
}
}
================================================
FILE: lib/Models/ollama_chat.dart
================================================
import 'dart:convert';
import 'package:uuid/uuid.dart';
class OllamaChat {
final String id;
final String model;
final String title;
final String? systemPrompt;
final OllamaChatOptions options;
OllamaChat({
String? id,
required this.model,
String? title,
this.systemPrompt,
OllamaChatOptions? options,
}) : id = id ?? Uuid().v4(),
title = title ?? 'New Chat',
options = options ?? OllamaChatOptions();
factory OllamaChat.fromMap(Map<String, dynamic> map) {
return OllamaChat(
id: map['chat_id'],
model: map['model'],
title: map['chat_title'],
systemPrompt: map['system_prompt'],
options: map['options'] != null ? OllamaChatOptions.fromJson(map['options']) : null,
);
}
}
/// Represents configuration options for controlling the behavior of the Ollama chat model.
class OllamaChatOptions {
/// Enables Mirostat sampling for controlling perplexity.
/// 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0.
int mirostat;
/// Influences how quickly the algorithm responds to feedback from the generated text.
/// A lower value results in slower adjustments; a higher value makes the algorithm more responsive.
double mirostatEta;
/// Controls the balance between coherence and diversity of the output.
/// A lower value results in more focused and coherent text.
double mirostatTau;
/// Sets the size of the context window used to generate the next token.
int contextSize;
/// Sets how far back the model looks to prevent repetition.
/// 0 = disabled, -1 = full context size.
int repeatLastN;
/// Sets the strength of penalizing repetitions.
/// A higher value (e.g., 1.5) penalizes repetitions more strongly.
double repeatPenalty;
/// Controls the temperature of the model.
/// Higher values result in more creative outputs, lower values in more deterministic outputs.
double temperature;
/// Sets the random seed for text generation.
/// A specific value ensures the same text is generated for the same input.
int seed;
/// Controls tail-free sampling to reduce the impact of less probable tokens.
/// 1.0 disables this setting; higher values reduce the impact more.
double tailFreeSampling;
/// Sets the maximum number of tokens to predict during text generation.
/// -1 = infinite generation.
int maxTokens;
/// Limits the probability of generating nonsense.
/// A higher value (e.g., 100) allows more diverse answers, while a lower value (e.g., 10) is more conservative.
int topK;
/// Works with topK to control text diversity.
/// Higher values lead to more diverse text, lower values to more focused text.
double topP;
/// Ensures a balance of quality and variety by setting a minimum token probability relative to the most likely token.
/// Tokens with lower probability are filtered out.
double minP;
/// Creates an instance of [OllamaChatOptions] with default values.
OllamaChatOptions({
int? mirostat,
double? mirostatEta,
double? mirostatTau,
int? contextSize,
int? repeatLastN,
double? repeatPenalty,
double? temperature,
int? seed,
double? tailFreeSampling,
int? maxTokens,
int? topK,
double? topP,
double? minP,
}) : mirostat = mirostat ?? 0,
mirostatEta = mirostatEta ?? 0.1,
mirostatTau = mirostatTau ?? 5.0,
contextSize = contextSize ?? 2048,
repeatLastN = repeatLastN ?? 64,
repeatPenalty = repeatPenalty ?? 1.1,
temperature = temperature ?? 0.8,
seed = seed ?? 0,
tailFreeSampling = tailFreeSampling ?? 1.0,
maxTokens = maxTokens ?? -1,
topK = topK ?? 40,
topP = topP ?? 0.9,
minP = minP ?? 0.0;
/// Factory method for creating an instance of [OllamaChatOptions] from a map.
factory OllamaChatOptions.fromMap(Map<String, dynamic> map) {
return OllamaChatOptions(
mirostat: map['mirostat'],
mirostatEta: map['mirostat_eta']?.toDouble(),
mirostatTau: map['mirostat_tau']?.toDouble(),
contextSize: map['num_ctx'],
repeatLastN: map['repeat_last_n'],
repeatPenalty: map['repeat_penalty']?.toDouble(),
temperature: map['temperature']?.toDouble(),
seed: map['seed'],
tailFreeSampling: map['tfs_z']?.toDouble(),
maxTokens: map['num_predict'],
topK: map['top_k'],
topP: map['top_p']?.toDouble(),
minP: map['min_p']?.toDouble(),
);
}
/// Factory method for creating an instance of [OllamaChatOptions] from a JSON string.
factory OllamaChatOptions.fromJson(String json) {
return OllamaChatOptions.fromMap(jsonDecode(json));
}
/// Converts the instance of [OllamaChatOptions] to a map.
Map<String, dynamic> toMap() {
return {
'mirostat': mirostat,
'mirostat_eta': mirostatEta,
'mirostat_tau': mirostatTau,
'num_ctx': contextSize,
'repeat_last_n': repeatLastN,
'repeat_penalty': repeatPenalty,
'temperature': temperature,
'seed': seed,
'tfs_z': tailFreeSampling,
if (maxTokens > 0) 'num_predict': maxTokens,
'top_k': topK,
'top_p': topP,
'min_p': minP,
};
}
/// Converts the instance of [OllamaChatOptions] to a JSON string.
String toJson() {
return jsonEncode(toMap());
}
}
================================================
FILE: lib/Models/ollama_exception.dart
================================================
class OllamaException implements Exception {
final String message;
OllamaException(this.message);
@override
String toString() {
return message;
}
}
================================================
FILE: lib/Models/ollama_message.dart
================================================
import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'package:reins/Constants/constants.dart';
import 'package:uuid/uuid.dart';
class OllamaMessage {
/// The unique identifier of the message.
String id;
/// The text content of the message.
String content;
/// The image content of the message.
List<File>? images;
/// The date and time the message was created.
DateTime createdAt;
/// The role of the message.
OllamaMessageRole role;
/// The model used to generate the message.
String? model;
// Metadata fields
bool? done;
String? doneReason;
List<int>? context;
int? totalDuration;
int? loadDuration;
int? promptEvalCount;
int? promptEvalDuration;
int? evalCount;
int? evalDuration;
OllamaMessage(
this.content, {
String? id,
required this.role,
this.images,
DateTime? createdAt,
this.model,
this.done,
this.doneReason,
this.context,
this.totalDuration,
this.loadDuration,
this.promptEvalCount,
this.promptEvalDuration,
this.evalCount,
this.evalDuration,
}) : id = id ?? Uuid().v4(),
createdAt = createdAt ?? DateTime.now();
factory OllamaMessage.fromJson(Map<String, dynamic> json) => OllamaMessage(
json["message"] != null
? json["message"]["content"] // For chat messages
: json["response"], // For generated messages
role: json["message"] != null
? OllamaMessageRole.fromString(json["message"]["role"])
: OllamaMessageRole.assistant, // For generated messages (default)
images: null, // TODO: Implement image support
createdAt: DateTime.parse(json["created_at"]),
model: json["model"],
// Metadata fields
done: json["done"],
doneReason: json["done_reason"],
context: json["context"] != null
? List<int>.from(json["context"].map((x) => x))
: null,
totalDuration: json["total_duration"],
loadDuration: json["load_duration"],
promptEvalCount: json["prompt_eval_count"],
promptEvalDuration: json["prompt_eval_duration"],
evalCount: json["eval_count"],
evalDuration: json["eval_duration"],
);
factory OllamaMessage.fromDatabase(Map<String, dynamic> map) {
return OllamaMessage(
map['content'],
id: map['message_id'],
role: OllamaMessageRole.fromString(map['role']),
images: _constructImages(map['images']),
createdAt: DateTime.fromMillisecondsSinceEpoch(map['timestamp']),
model: map['model'],
);
}
Future<Map<String, dynamic>> toJson() async => {
"model": model,
"created_at": createdAt.toIso8601String(),
"message": {
"role": role.name,
"content": content,
"images": await _base64EncodeImages(),
},
"done": done,
"done_reason": doneReason,
"context":
context == null ? null : List<dynamic>.from(context!.map((x) => x)),
"total_duration": totalDuration,
"load_duration": loadDuration,
"prompt_eval_count": promptEvalCount,
"prompt_eval_duration": promptEvalDuration,
"eval_count": evalCount,
"eval_duration": evalDuration,
};
Future<Map<String, dynamic>> toChatJson() async => {
"role": role.name,
"content": content,
"images": await _base64EncodeImages(),
};
Map<String, dynamic> toDatabaseMap() => {
'message_id': id,
'content': content,
'images': _breakImages(images),
'role': role.name,
'timestamp': createdAt.millisecondsSinceEpoch,
};
void updateMetadataFrom(OllamaMessage message) {
done = message.done;
doneReason = message.doneReason;
context = message.context;
totalDuration = message.totalDuration;
loadDuration = message.loadDuration;
promptEvalCount = message.promptEvalCount;
promptEvalDuration = message.promptEvalDuration;
evalCount = message.evalCount;
evalDuration = message.evalDuration;
}
Future<List<String>?> _base64EncodeImages() async {
if (images != null) {
return await Future.wait(images!.map(
(file) async => base64Encode(await file.readAsBytes()),
));
}
return null;
}
static List<File>? _constructImages(String? raw) {
if (raw != null) {
final List<dynamic> decoded = jsonDecode(raw);
return decoded.map((imageRelativePath) {
return File(path.join(
PathManager.instance.documentsDirectory.path,
imageRelativePath,
));
}).toList();
}
return null;
}
String? _breakImages(List<File>? images) {
if (images != null) {
final relativePathImages = images.map((file) {
return path.relative(
file.path,
from: PathManager.instance.documentsDirectory.path,
);
}).toList();
return jsonEncode(relativePathImages);
}
return null;
}
}
enum OllamaMessageRole {
user,
assistant,
system;
factory OllamaMessageRole.fromString(String role) {
switch (role) {
case 'user':
return OllamaMessageRole.user;
case 'assistant':
return OllamaMessageRole.assistant;
case 'system':
return OllamaMessageRole.system;
default:
throw ArgumentError('Unknown role: $role');
}
}
}
================================================
FILE: lib/Models/ollama_model.dart
================================================
import 'package:reins/Models/api/tags_response.dart';
import 'package:reins/Models/api/show_response.dart';
import 'package:reins/Models/model_capabilities.dart';
/// Domain model representing an Ollama model.
/// Combines data from /api/tags and optionally /api/show.
class OllamaModel {
final String name;
final String model;
final DateTime modifiedAt;
final int size;
final String digest;
final String parameterSize;
final ModelCapabilities? capabilities;
OllamaModel({
required this.name,
required this.model,
required this.modifiedAt,
required this.size,
required this.digest,
required this.parameterSize,
this.capabilities,
});
/// Creates an OllamaModel from /api/tags and optional /api/show response
factory OllamaModel.from(ApiTagsModel tagsModel, ApiShowResponse? showResponse) {
return OllamaModel(
name: tagsModel.name,
model: tagsModel.model,
modifiedAt: tagsModel.modifiedAt,
size: tagsModel.size,
digest: tagsModel.digest,
parameterSize: tagsModel.details.parameterSize,
capabilities: showResponse != null ? ModelCapabilities.fromList(showResponse.capabilities) : null,
);
}
/// For backward compatibility with existing JSON serialization
factory OllamaModel.fromJson(Map<String, dynamic> json) => OllamaModel(
name: json["name"],
model: json["model"],
modifiedAt: DateTime.parse(json["modified_at"]),
size: json["size"],
digest: json["digest"],
parameterSize: json["details"]["parameter_size"] ?? '',
capabilities: null,
);
Map<String, dynamic> toJson() => {
"name": name,
"model": model,
"modified_at": modifiedAt.toIso8601String(),
"size": size,
"digest": digest,
"parameter_size": parameterSize,
};
@override
String toString() {
return name;
}
@override
int get hashCode => digest.hashCode;
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is OllamaModel && other.digest == digest;
}
}
================================================
FILE: lib/Models/ollama_request_state.dart
================================================
enum OllamaRequestState {
error,
loading,
success,
uninitialized,
}
================================================
FILE: lib/Models/settings_route_arguments.dart
================================================
class SettingsRouteArguments {
final bool autoFocusServerAddress;
SettingsRouteArguments({required this.autoFocusServerAddress});
}
================================================
FILE: lib/Pages/chat_page/chat_page.dart
================================================
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:responsive_framework/responsive_framework.dart';
import 'package:reins/Widgets/chat_app_bar.dart';
import 'package:reins/Widgets/model_selection_bottom_sheet.dart';
import 'chat_page_view_model.dart';
import 'subwidgets/subwidgets.dart';
class ChatPage extends StatefulWidget {
const ChatPage({super.key});
@override
State<ChatPage> createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
// ViewModel reference
late final ChatPageViewModel _viewModel;
// Welcome screen animation state
var _crossFadeState = CrossFadeState.showFirst;
double _scale = 1.0;
@override
void initState() {
super.initState();
_viewModel = context.read<ChatPageViewModel>();
}
@override
Widget build(BuildContext context) {
// Subscribe to ViewModel changes
context.watch<ChatPageViewModel>();
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (!ResponsiveBreakpoints.of(context).isMobile) ChatAppBar(), // If the screen is large, show the app bar
Expanded(
child: Stack(
alignment: Alignment.bottomLeft,
children: [
_buildChatBody(),
_buildChatFooter(),
],
),
),
// TODO: Wrap with ConstrainedBox to limit the height
Padding(
padding: const EdgeInsets.all(8.0),
child: ChatTextField(
key: ValueKey(_viewModel.currentChat?.id),
controller: _viewModel.textFieldController,
onEditingComplete: _sendMessage,
prefixIcon: IconButton(
icon: Icon(Icons.add),
onPressed: _handleAttachmentButton,
),
suffixIcon: _buildTextFieldSuffixIcon(),
),
),
],
);
}
Widget _buildChatBody() {
if (_viewModel.messages.isEmpty) {
if (_viewModel.currentChat == null) {
if (!_viewModel.isServerConfigured) {
return ChatEmpty(
child: ChatWelcome(
showingState: _crossFadeState,
onFirstChildFinished: () => setState(() => _crossFadeState = CrossFadeState.showSecond),
secondChildScale: _scale,
onSecondChildScaleEnd: () => setState(() => _scale = 1.0),
),
);
} else {
return ChatEmpty(
child: ChatSelectModelButton(
currentModelName: _viewModel.selectedModel?.name,
onPressed: _showModelSelectionBottomSheet,
),
);
}
} else {
return ChatEmpty(
child: Text('No messages yet!'),
);
}
} else {
return ChatListView(
key: PageStorageKey<String>(_viewModel.currentChat?.id ?? 'empty'),
messages: _viewModel.messages,
isAwaitingReply: _viewModel.isThinking,
error: _viewModel.currentError != null
? ChatError(
message: _viewModel.currentError!.message,
onRetry: () => _viewModel.retryLastPrompt(),
)
: null,
bottomPadding: _viewModel.hasImageAttachments
? MediaQuery.of(context).size.height * 0.15
: null, // TODO: Calculate the height of attachments row
);
}
}
Widget _buildChatFooter() {
if (_viewModel.hasImageAttachments) {
return ChatAttachmentRow(
itemCount: _viewModel.imageFiles.length,
itemBuilder: (context, index) {
return ChatAttachmentImage(
imageFile: _viewModel.imageFiles[index],
onRemove: (imageFile) => _viewModel.removeImage(imageFile),
);
},
);
} else if (_viewModel.messages.isEmpty) {
return ChatAttachmentRow(
itemCount: _viewModel.presets.length,
itemBuilder: (context, index) {
final preset = _viewModel.presets[index];
return ChatAttachmentPreset(
preset: preset,
onPressed: () async {
_viewModel.setTextFieldValue(preset.prompt);
await _sendMessage();
},
);
},
);
} else {
return const SizedBox();
}
}
Widget? _buildTextFieldSuffixIcon() {
if (_viewModel.isStreaming) {
return IconButton(
icon: const Icon(Icons.stop_rounded),
color: Theme.of(context).colorScheme.onSurface,
onPressed: _viewModel.cancelStreaming,
);
} else if (_viewModel.hasText) {
return IconButton(
icon: const Icon(Icons.arrow_upward_rounded),
color: Theme.of(context).colorScheme.onSurface,
onPressed: _sendMessage,
);
} else {
return null;
}
}
Future<void> _sendMessage() async {
await _viewModel.sendMessage(
onModelSelectionRequired: _showModelSelectionBottomSheet,
onServerNotConfigured: _onServerNotConfigured,
);
}
Future<void> _showModelSelectionBottomSheet() async {
final selectedModel = await showModelSelectionBottomSheet(
context: context,
title: "Select a Model",
currentModelName: _viewModel.selectedModel?.name,
);
if (selectedModel != null) {
_viewModel.setSelectedModel(selectedModel);
}
}
Future<void> _handleAttachmentButton() async {
await _viewModel.pickImages(
onPermissionDenied: _showPhotosDeniedAlert,
);
}
void _onServerNotConfigured() {
setState(() {
_crossFadeState = CrossFadeState.showSecond;
_scale = _scale == 1.0 ? 1.05 : 1.0;
});
}
Future<void> _showPhotosDeniedAlert() async {
await showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: const Text('Photos Permission Denied'),
content: const Text('Please allow access to photos in the settings.'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('OK'),
),
],
);
},
);
}
}
================================================
FILE: lib/Pages/chat_page/chat_page_view_model.dart
================================================
import 'dart:async';
import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:image_picker/image_picker.dart';
import 'package:reins/Constants/constants.dart';
import 'package:reins/Models/chat_preset.dart';
import 'package:reins/Models/ollama_chat.dart';
import 'package:reins/Models/ollama_exception.dart';
import 'package:reins/Models/ollama_message.dart';
import 'package:reins/Models/ollama_model.dart';
import 'package:reins/Providers/chat_provider.dart';
import 'package:reins/Services/services.dart';
class ChatPageViewModel extends ChangeNotifier {
final ChatProvider _chatProvider;
final PermissionService _permissionService;
final ImageService _imageService;
ChatPageViewModel({
required ChatProvider chatProvider,
required PermissionService permissionService,
required ImageService imageService,
}) : _chatProvider = chatProvider,
_permissionService = permissionService,
_imageService = imageService {
_initialize();
}
// ============================================================
// Page State
// ============================================================
/// The selected model for new chats
OllamaModel? _selectedModel;
OllamaModel? get selectedModel => _selectedModel;
/// The list of chat presets
List<ChatPreset> _presets = ChatPresets.randomPresets;
List<ChatPreset> get presets => _presets;
/// The text field controller
final TextEditingController textFieldController = TextEditingController();
/// Whether the text field has text
bool get hasText => textFieldController.text.trim().isNotEmpty;
/// The app lifecycle listener for cleanup
late final AppLifecycleListener _appLifecycleListener;
/// The Hive settings subscription
late final StreamSubscription _settingsSubscription;
bool get isServerConfigured {
return Hive.box('settings').get('serverAddress') != null;
}
// ============================================================
// Initialization
// ============================================================
void _initialize() {
// Listen to ChatProvider changes and forward notifications
_chatProvider.addListener(_onChatProviderChanged);
// Listen to text field changes to update UI (e.g., send button visibility)
textFieldController.addListener(_onTextFieldChanged);
// If the server address changes, reset the selected model
_settingsSubscription = Hive.box('settings').watch(key: 'serverAddress').listen((event) {
_selectedModel = null;
notifyListeners();
});
// Listen for app exit to delete unused attached images
_appLifecycleListener = AppLifecycleListener(onExitRequested: () async {
await _imageService.deleteImages(imageFiles);
return AppExitResponse.exit;
});
}
void _onChatProviderChanged() {
notifyListeners();
}
void _onTextFieldChanged() {
notifyListeners();
}
@override
void dispose() {
_chatProvider.removeListener(_onChatProviderChanged);
textFieldController.removeListener(_onTextFieldChanged);
textFieldController.dispose();
_appLifecycleListener.dispose();
_settingsSubscription.cancel();
super.dispose();
}
// ============================================================
// ChatProvider State (Proxied)
// ============================================================
/// The list of messages in the current chat
List<OllamaMessage> get messages => _chatProvider.messages;
/// The current chat
OllamaChat? get currentChat => _chatProvider.currentChat;
/// Whether the current chat is streaming a response
bool get isStreaming => _chatProvider.isCurrentChatStreaming;
/// Whether the current chat is thinking (waiting for response)
bool get isThinking => _chatProvider.isCurrentChatThinking;
/// The current chat error, if any
OllamaException? get currentError => _chatProvider.currentChatError;
// ============================================================
// ChatProvider Actions (Delegated)
// ============================================================
/// Cancels the current streaming response
void cancelStreaming() {
_chatProvider.cancelCurrentStreaming();
}
/// Retries the last prompt
Future<void> retryLastPrompt() async {
await _chatProvider.retryLastPrompt();
}
/// Fetches available models from the server
Future<List<OllamaModel>> fetchAvailableModels() async {
return await _chatProvider.fetchAvailableModels();
}
// ============================================================
// Model Selection
// ============================================================
/// Sets the selected model
void setSelectedModel(OllamaModel? model) {
_selectedModel = model;
notifyListeners();
}
// ============================================================
// Text Field
// ============================================================
/// Sets the text field value (e.g., for presets)
void setTextFieldValue(String value) {
textFieldController.text = value;
}
/// Gets and clears the text field value (for sending)
String _takeTextFieldValue() {
final value = textFieldController.text;
textFieldController.clear();
return value;
}
// ============================================================
// Image Attachments
// ============================================================
final List<File> _imageFiles = [];
/// The list of attached image files
List<File> get imageFiles => List.unmodifiable(_imageFiles);
/// Whether there are any image attachments
bool get hasImageAttachments => _imageFiles.isNotEmpty;
/// Handles image picking and compression
Future<void> pickImages({
VoidCallback? onPermissionDenied,
int quality = 10,
}) async {
// Check permissions
final hasPermission = await _permissionService.requestPhotoPermission(
onDenied: onPermissionDenied,
);
if (!hasPermission) return;
// Pick images
final picker = ImagePicker();
final pickedImage = await picker.pickImage(
source: ImageSource.gallery,
);
// await _picker.pickMultiImage(limit: maxImages);
if (pickedImage == null) return;
// Compress and save
final compressedFile = await _imageService.compressAndSave(
pickedImage.path,
quality: quality,
);
// Add an empty path if the image could not be compressed to show error
if (compressedFile != null) {
_imageFiles.add(compressedFile);
} else {
_imageFiles.add(File(''));
}
notifyListeners();
}
/// Deletes a single image and removes it from the list
Future<void> removeImage(File imageFile) async {
await _imageService.deleteImage(imageFile);
_imageFiles.remove(imageFile);
notifyListeners();
}
/// Gets and clears the current images (for sending)
List<File> _takeImages() {
final images = _imageFiles.toList();
_imageFiles.clear();
return images;
}
// ============================================================
// Operations
// ============================================================
/// Handles sending a message
/// Returns true if the message was sent successfully
Future<bool> sendMessage({
required Future<void> Function() onModelSelectionRequired,
required void Function() onServerNotConfigured,
}) async {
// Early return if nothing to send or currently streaming
if (!hasText || isStreaming) {
return false;
}
// Check if server is configured
if (!isServerConfigured) {
onServerNotConfigured();
return false;
}
// If no current chat, need to create one
if (_chatProvider.currentChat == null) {
// If no model selected, request selection
if (_selectedModel == null) {
await onModelSelectionRequired();
}
// If still no model after selection, abort
if (_selectedModel == null) {
return false;
}
// Create a new chat with the selected model
await _chatProvider.createNewChat(_selectedModel!);
// Take the prompt and images and refresh the presets
final prompt = _takeTextFieldValue();
final images = _takeImages();
_presets = ChatPresets.randomPresets;
// Notify listeners
notifyListeners();
// Send the prompt
await _chatProvider.sendPrompt(prompt, images: images);
// Generate title for the new chat
await _chatProvider.generateTitleForCurrentChat();
} else {
// Get and clear the prompt and images
final prompt = _takeTextFieldValue();
final images = _takeImages();
// Notify listeners (text field is cleared)
notifyListeners();
// Send the prompt
await _chatProvider.sendPrompt(prompt, images: images);
}
return true;
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_image.dart
================================================
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:reins/Widgets/chat_image.dart';
class ChatAttachmentImage extends StatelessWidget {
final File imageFile;
final Function(File) onRemove;
const ChatAttachmentImage({
super.key,
required this.imageFile,
required this.onRemove,
});
@override
Widget build(BuildContext context) {
return Stack(
children: [
ChatImage(
image: FileImage(imageFile),
height: MediaQuery.of(context).size.height * 0.15,
),
Positioned(
top: 2,
right: 2,
child: InkWell(
onTap: () => onRemove(imageFile),
child: Icon(
Icons.close,
color: Colors.white,
shadows: [BoxShadow(blurRadius: 10)],
),
),
),
],
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_preset.dart
================================================
import 'package:flutter/material.dart';
import 'package:reins/Models/chat_preset.dart';
class ChatAttachmentPreset extends StatelessWidget {
final ChatPreset preset;
final Function() onPressed;
const ChatAttachmentPreset({
super.key,
required this.preset,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onPressed,
borderRadius: BorderRadius.circular(16),
child: Ink(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainer,
borderRadius: BorderRadius.circular(16),
),
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(preset.title, style: Theme.of(context).textTheme.titleSmall),
Text(
preset.subtitle,
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_row.dart
================================================
import 'package:flutter/material.dart';
class ChatAttachmentRow extends StatelessWidget {
final int itemCount;
final IndexedWidgetBuilder itemBuilder;
const ChatAttachmentRow({
super.key,
required this.itemCount,
required this.itemBuilder,
});
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 8.0),
physics: const ClampingScrollPhysics(),
child: Row(
spacing: 8.0,
children: List.generate(
itemCount,
(index) => itemBuilder(context, index),
),
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:reins/Extensions/markdown_stylesheet_extension.dart';
import 'package:reins/Models/ollama_message.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'chat_bubble_actions.dart';
import 'chat_bubble_image.dart';
import 'chat_bubble_menu.dart';
import 'chat_bubble_think_block.dart';
class ChatBubble extends StatelessWidget {
final OllamaMessage message;
const ChatBubble({
super.key,
required this.message,
});
@override
Widget build(BuildContext context) {
final actions = ChatBubbleActions(message);
return ChatBubbleMenu(
menuChildren: [
MenuItemButton(
onPressed: actions.handleCopy,
leadingIcon: Icon(Icons.copy_outlined),
child: const Text('Copy'),
),
MenuItemButton(
onPressed: () => actions.handleSelectText(context),
leadingIcon: Icon(Icons.select_all_outlined),
child: const Text('Select Text'),
),
MenuItemButton(
onPressed: () => actions.handleRegenerate(context),
leadingIcon: Icon(Icons.refresh_outlined),
child: const Text('Regenerate'),
),
Divider(),
MenuItemButton(
onPressed: () => actions.handleEdit(context),
closeOnActivate: false,
leadingIcon: Icon(Icons.edit_outlined),
child: const Text('Edit'),
),
MenuItemButton(
onPressed: () => actions.handleDelete(context),
leadingIcon: Icon(Icons.delete_outline),
child: const Text('Delete'),
),
],
child: _ChatBubbleBody(message: message),
);
}
}
class _ChatBubbleBody extends StatelessWidget {
final OllamaMessage message;
const _ChatBubbleBody({super.key, required this.message});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0),
child: Column(
spacing: 8,
crossAxisAlignment: bubbleAlignment,
children: [
// If the message has an image attachment, display it
if (message.images != null && message.images!.isNotEmpty)
Wrap(
spacing: 8,
runSpacing: 8,
children: message.images!
.map((imageFile) => ChatBubbleImage(imageFile: imageFile))
.toList(),
),
Container(
padding: isSentFromUser ? const EdgeInsets.all(10.0) : null,
constraints: BoxConstraints(
maxWidth: isSentFromUser
? MediaQuery.of(context).size.width * 0.8
: double.infinity,
),
decoration: BoxDecoration(
color: isSentFromUser
? Theme.of(context).colorScheme.primaryContainer
: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(10.0),
),
child: MarkdownBody(
data: message.content,
selectable: true,
softLineBreak: true,
styleSheet: context.markdownStyleSheet.copyWith(
code: GoogleFonts.sourceCodePro(),
),
builders: {'think': ThinkBlockBuilder()},
extensionSet: md.ExtensionSet(
<md.BlockSyntax>[
ThinkBlockSyntax(),
...md.ExtensionSet.gitHubFlavored.blockSyntaxes
],
<md.InlineSyntax>[
md.EmojiSyntax(),
...md.ExtensionSet.gitHubFlavored.inlineSyntaxes
],
),
onTapLink: (text, href, title) => launchUrlString(href!),
),
),
Text(
TimeOfDay.fromDateTime(message.createdAt.toLocal()).format(context),
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
),
);
}
/// Returns true if the message is sent from the user.
bool get isSentFromUser => message.role == OllamaMessageRole.user;
/// Returns the alignment of the bubble.
///
/// If the message is sent from the user, the alignment is [Alignment.centerRight].
/// Otherwise, the alignment is [Alignment.centerLeft].
CrossAxisAlignment get bubbleAlignment =>
isSentFromUser ? CrossAxisAlignment.end : CrossAxisAlignment.start;
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_actions.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:reins/Models/ollama_message.dart';
import 'package:reins/Providers/chat_provider.dart';
import 'chat_bubble_bottom_sheet.dart';
class ChatBubbleActions {
final OllamaMessage message;
ChatBubbleActions(this.message);
void handleCopy() {
Clipboard.setData(ClipboardData(text: message.content));
}
void handleSelectText(BuildContext context) {
showModalBottomSheet(
context: context,
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.9,
),
isScrollControlled: true,
builder: (context) {
return ChatBubbleBottomSheet(
title: 'Select Text',
child: SelectableText(
message.content,
style: Theme.of(context).textTheme.bodyLarge,
),
);
},
);
}
void handleRegenerate(BuildContext context) {
final chatProvider = Provider.of<ChatProvider>(context, listen: false);
chatProvider.regenerateMessage(message);
}
void handleEdit(BuildContext context) {
final chatProvider = Provider.of<ChatProvider>(context, listen: false);
showModalBottomSheet(
context: context,
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.9,
),
isScrollControlled: true,
isDismissible: false,
enableDrag: false,
builder: (context) {
String textFieldText = message.content;
return ChatBubbleBottomSheet(
title: 'Edit Message',
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () async {
if (textFieldText.isNotEmpty) {
await chatProvider.updateMessage(
message,
newContent: textFieldText,
);
if (context.mounted) Navigator.pop(context, textFieldText);
}
},
child: const Text('Save'),
),
],
child: TextFormField(
initialValue: textFieldText,
onChanged: (value) => textFieldText = value,
autofocus: true,
maxLines: null,
expands: true,
textAlignVertical: TextAlignVertical.top,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(border: OutlineInputBorder()),
),
);
},
);
}
void handleDelete(BuildContext context) {
final chatProvider = Provider.of<ChatProvider>(context, listen: false);
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Delete Message?'),
content: const Text('This action cannot be undone.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () async {
await chatProvider.deleteMessage(message);
if (context.mounted) Navigator.pop(context);
},
child: const Text(
'Delete',
style: TextStyle(color: Colors.red),
),
),
],
);
},
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_bottom_sheet.dart
================================================
import 'package:flutter/material.dart';
class ChatBubbleBottomSheet extends StatelessWidget {
final String title;
final Widget child;
final List<Widget> actions;
const ChatBubbleBottomSheet({
super.key,
required this.title,
required this.child,
this.actions = const [],
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
titleTextStyle: Theme.of(context)
.textTheme
.titleMedium
?.copyWith(fontWeight: FontWeight.bold),
forceMaterialTransparency: true,
automaticallyImplyLeading: false,
actions: [
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.close),
),
],
),
body: SafeArea(
child: Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: child,
),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: actions,
),
],
),
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_image.dart
================================================
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:reins/Widgets/chat_image.dart';
class ChatBubbleImage extends StatelessWidget {
final File imageFile;
const ChatBubbleImage({super.key, required this.imageFile});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
Navigator.of(context).push(
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) {
return _ChatBubbleImageFullScreen(imageFile: imageFile);
},
transitionsBuilder: (context, animation, _, child) {
return FadeTransition(opacity: animation, child: child);
},
),
);
},
child: Hero(
tag: imageFile.path,
child: ChatImage(
image: FileImage(imageFile),
aspectRatio: 1.5,
width: max(
MediaQuery.of(context).size.width * 0.35,
MediaQuery.of(context).size.height * 0.25,
),
),
),
);
}
}
class _ChatBubbleImageFullScreen extends StatelessWidget {
const _ChatBubbleImageFullScreen({required this.imageFile});
final File imageFile;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Center(
child: PhotoView(
imageProvider: FileImage(imageFile),
errorBuilder: (context, error, stackTrace) {
return Center(
child: Icon(Icons.error, color: Colors.red),
);
},
backgroundDecoration: BoxDecoration(
color: Colors.transparent,
),
heroAttributes: PhotoViewHeroAttributes(
tag: imageFile.path,
),
),
),
Positioned(
top: 5,
right: 0,
child: IconButton(
icon: Icon(
Icons.close,
color: Colors.white,
shadows: [BoxShadow(blurRadius: 10)],
),
onPressed: () => Navigator.pop(context),
),
),
],
),
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_menu.dart
================================================
import 'package:flutter/material.dart';
import 'package:reins/Utils/border_painter.dart';
class ChatBubbleMenu extends StatefulWidget {
final Widget child;
final List<Widget> menuChildren;
const ChatBubbleMenu({
super.key,
required this.child,
required this.menuChildren,
});
@override
State<ChatBubbleMenu> createState() => _ChatBubbleMenuState();
}
class _ChatBubbleMenuState extends State<ChatBubbleMenu> {
@override
Widget build(BuildContext context) {
return MenuAnchor(
menuChildren: widget.menuChildren,
builder: (context, controller, child) {
return GestureDetector(
onTap: () => controller.close(),
onLongPressStart: (details) {
controller.open(position: details.localPosition);
},
onDoubleTapDown: (details) {
if (controller.isOpen) {
controller.close();
} else {
controller.open(position: details.localPosition);
}
},
onSecondaryTapDown: (details) {
controller.open(position: details.localPosition);
},
child: CustomPaint(
foregroundPainter: BorderPainter(
color: controller.isOpen
? Theme.of(context).colorScheme.primaryContainer
: Theme.of(context).colorScheme.surface,
borderRadius: Radius.circular(10.0),
strokeWidth: 2,
padding: EdgeInsets.symmetric(horizontal: 10.0),
),
child: child,
),
);
},
child: widget.child,
onOpen: () => setState(() {}),
onClose: () => setState(() {}),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_think_block.dart
================================================
import 'package:flutter/material.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:flutter_markdown/flutter_markdown.dart';
class ThinkBlockSyntax extends md.BlockSyntax {
@override
RegExp get pattern => RegExp(r'^<think>$');
@override
bool canEndBlock(md.BlockParser parser) => false;
const ThinkBlockSyntax();
@override
List<md.Line> parseChildLines(md.BlockParser parser) {
final childLines = <md.Line>[];
parser.advance(); // Advance past the opening <think> tag
while (!parser.isDone) {
if (parser.current.content == '</think>') {
parser.advance(); // Advance past the closing </think> tag
break;
}
childLines.add(parser.current);
parser.advance();
}
return childLines;
}
@override
md.Node parse(md.BlockParser parser) {
final childLines = parseChildLines(parser);
var content = childLines.map((e) => e.content).join('\n');
return md.Element('pre', [md.Element.text('think', content)]);
}
}
class ThinkBlockBuilder extends MarkdownElementBuilder {
@override
Widget visitElementAfter(md.Element element, TextStyle? preferredStyle) {
return ThinkBlockWidget(content: element.textContent);
}
}
class ThinkBlockWidget extends StatefulWidget {
final String content;
const ThinkBlockWidget({super.key, required this.content});
@override
State<ThinkBlockWidget> createState() => _ThinkBlockWidgetState();
}
class _ThinkBlockWidgetState extends State<ThinkBlockWidget> {
bool _showingThought = true;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: () {
setState(() => _showingThought = !_showingThought);
},
child: Row(
children: [
Text('Thought', style: TextStyle(color: _thoughtColor)),
Icon(_thoughtButtonIcon, color: _thoughtColor),
],
),
),
if (_showingThought)
SelectableText(widget.content,
style: TextStyle(color: _thoughtColor)),
],
);
}
IconData get _thoughtButtonIcon =>
_showingThought ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_up;
Color get _thoughtColor => Theme.of(context).colorScheme.secondary;
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_empty.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:reins/Constants/constants.dart';
class ChatEmpty extends StatelessWidget {
final Widget child;
const ChatEmpty({super.key, required this.child});
@override
Widget build(BuildContext context) {
return Center(
child: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
AppConstants.appIconSvg,
height: 48,
colorFilter: ColorFilter.mode(
Theme.of(context).colorScheme.onSurface,
BlendMode.srcIn,
),
),
child,
],
),
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_error.dart
================================================
import 'package:flutter/material.dart';
class ChatError extends StatelessWidget {
final String message;
final void Function() onRetry;
const ChatError({
super.key,
required this.message,
required this.onRetry,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.error,
),
borderRadius: BorderRadius.circular(10.0),
),
padding: EdgeInsets.all(10.0),
margin: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
message,
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
const SizedBox(height: 10.0),
FilledButton(
onPressed: onRetry,
style: FilledButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.error,
),
child: Text('Retry'),
),
],
),
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_list_view.dart
================================================
import 'package:flutter/material.dart';
import 'package:reins/Models/ollama_message.dart';
import 'package:shimmer/shimmer.dart';
import 'package:notification_centre/notification_centre.dart';
import 'chat_bubble/chat_bubble.dart';
import 'package:reins/Constants/constants.dart';
import 'package:reins/Utils/observe_size.dart';
import 'package:reins/Utils/retained_position_scroll_physics.dart';
class ChatListView extends StatefulWidget {
final List<OllamaMessage> messages;
final bool isAwaitingReply;
final Widget? error;
final double? bottomPadding;
const ChatListView({
super.key,
required this.messages,
required this.isAwaitingReply,
this.error,
this.bottomPadding,
});
@override
State<ChatListView> createState() => _ChatListViewState();
}
class _ChatListViewState extends State<ChatListView> {
final ScrollController _scrollController = ScrollController();
bool _isScrollToBottomButtonVisible = false;
final _messageSizeProxy = WidgetSizeProxy();
@override
void initState() {
super.initState();
_scrollController.addListener(() {
_updateScrollToBottomButtonVisibility();
});
NotificationCenter().addObserver(
NotificationNames.generationBegin,
this,
(n) => _scrollToBottom(),
);
}
@override
void didUpdateWidget(covariant ChatListView oldWidget) {
super.didUpdateWidget(oldWidget);
// Add to the post frame callback to ensure that the scroll offset is
// read after the widget has been updated.
WidgetsBinding.instance.addPostFrameCallback((_) {
// Update the button visibility when the user switches chats,
// regenerates a message or delete a message.
_updateScrollToBottomButtonVisibility();
});
}
@override
void dispose() {
_scrollController.dispose();
// Remove the observer for the generation begin notification
NotificationCenter().removeObserver(NotificationNames.generationBegin, this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.bottomCenter,
children: [
CustomScrollView(
controller: _scrollController,
reverse: true,
physics: RetainedPositionScrollPhysics(
widgetSizeProxy: _messageSizeProxy,
),
slivers: [
if (widget.bottomPadding != null)
SliverPadding(
padding: EdgeInsets.only(bottom: widget.bottomPadding!),
),
if (widget.error != null)
SliverToBoxAdapter(
child: widget.error,
),
if (widget.isAwaitingReply)
SliverToBoxAdapter(
child: Shimmer.fromColors(
// TODO: Play with the colors to make it look better
baseColor: Theme.of(context).colorScheme.onPrimary,
highlightColor: Theme.of(context).colorScheme.onSurface,
period: const Duration(milliseconds: 2500),
child: const ListTile(
title: Padding(
padding: EdgeInsets.all(10.0),
child: Text("Thinking"),
),
),
),
),
SliverList.builder(
key: widget.key,
itemCount: widget.messages.length,
itemBuilder: (context, index) {
final message = widget.messages[widget.messages.length - index - 1];
if (index == 0) {
return ObserveSize(
key: Key(message.id),
onSizeChanged: _onMessageSizeChanged,
child: ChatBubble(message: message),
);
}
return ChatBubble(message: message);
},
),
],
),
if (_isScrollToBottomButtonVisible)
IconButton(
onPressed: _scrollToBottom,
icon: const Icon(Icons.arrow_downward_rounded),
style: IconButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.onInverseSurface,
),
),
],
);
}
void _onMessageSizeChanged(Size? previousSize, Size currentSize) {
final currentHeight = currentSize.height;
final previousHeight = (previousSize ?? currentSize).height;
_messageSizeProxy.deltaHeight = currentHeight - previousHeight;
}
void _updateScrollToBottomButtonVisibility() {
if (_scrollController.position.pixels > 100 && !_isScrollToBottomButtonVisible) {
setState(() {
_isScrollToBottomButtonVisible = true;
});
}
if (_scrollController.position.pixels < 100 && _isScrollToBottomButtonVisible) {
setState(() {
_isScrollToBottomButtonVisible = false;
});
}
}
void _scrollToBottom() {
_scrollController.animateTo(
0.0,
duration: const Duration(milliseconds: 150),
curve: Curves.easeOut,
);
}
}
================================================
FILE: lib/Pages/chat_page/subwidgets/chat_select_model_button.dart
================================================
import 'package:flutter/material.dart';
class ChatSelectModelButton extends StatelessWidget {
final String? currentModelName;
final void Function() onPressed;
const ChatSelectModelButton({
super.key,
this.currentModelName,
required this.onPressed,
});
@override
Widget build(BuildContext context) {
return TextButton.icon(
icon: const Icon(Icons.auto_awesome_outlined),
label: Text(currentModelName ?? 'Select a model to s
gitextract_0cw_5yz_/
├── .gitignore
├── .metadata
├── .vscode/
│ ├── launch.json
│ └── settings.json
├── LICENSE
├── PRIVACY
├── README.md
├── analysis_options.yaml
├── android/
│ ├── .gitignore
│ ├── app/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── debug/
│ │ │ └── AndroidManifest.xml
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── kotlin/
│ │ │ │ └── dev/
│ │ │ │ └── ibrahimcetin/
│ │ │ │ └── reins/
│ │ │ │ └── MainActivity.kt
│ │ │ └── res/
│ │ │ ├── drawable/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-night/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-night-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── drawable-v21/
│ │ │ │ └── launch_background.xml
│ │ │ ├── values/
│ │ │ │ └── styles.xml
│ │ │ ├── values-night/
│ │ │ │ └── styles.xml
│ │ │ ├── values-night-v31/
│ │ │ │ └── styles.xml
│ │ │ └── values-v31/
│ │ │ └── styles.xml
│ │ └── profile/
│ │ └── AndroidManifest.xml
│ ├── build.gradle
│ ├── gradle/
│ │ └── wrapper/
│ │ └── gradle-wrapper.properties
│ ├── gradle.properties
│ └── settings.gradle
├── devtools_options.yaml
├── ios/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── LaunchBackground.imageset/
│ │ │ │ └── Contents.json
│ │ │ └── LaunchImage.imageset/
│ │ │ ├── Contents.json
│ │ │ └── README.md
│ │ ├── Base.lproj/
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── Runner-Bridging-Header.h
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata/
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── RunnerTests/
│ └── RunnerTests.swift
├── lib/
│ ├── Constants/
│ │ ├── app_constants.dart
│ │ ├── chat_presets.dart
│ │ ├── constants.dart
│ │ ├── generate_title_constants.dart
│ │ └── path_manager.dart
│ ├── Extensions/
│ │ └── markdown_stylesheet_extension.dart
│ ├── Models/
│ │ ├── api/
│ │ │ ├── create_request.dart
│ │ │ ├── show_response.dart
│ │ │ └── tags_response.dart
│ │ ├── chat_configure_arguments.dart
│ │ ├── chat_preset.dart
│ │ ├── model_capabilities.dart
│ │ ├── ollama_chat.dart
│ │ ├── ollama_exception.dart
│ │ ├── ollama_message.dart
│ │ ├── ollama_model.dart
│ │ ├── ollama_request_state.dart
│ │ └── settings_route_arguments.dart
│ ├── Pages/
│ │ ├── chat_page/
│ │ │ ├── chat_page.dart
│ │ │ ├── chat_page_view_model.dart
│ │ │ └── subwidgets/
│ │ │ ├── chat_attachment/
│ │ │ │ ├── chat_attachment_image.dart
│ │ │ │ ├── chat_attachment_preset.dart
│ │ │ │ └── chat_attachment_row.dart
│ │ │ ├── chat_bubble/
│ │ │ │ ├── chat_bubble.dart
│ │ │ │ ├── chat_bubble_actions.dart
│ │ │ │ ├── chat_bubble_bottom_sheet.dart
│ │ │ │ ├── chat_bubble_image.dart
│ │ │ │ ├── chat_bubble_menu.dart
│ │ │ │ └── chat_bubble_think_block.dart
│ │ │ ├── chat_empty.dart
│ │ │ ├── chat_error.dart
│ │ │ ├── chat_list_view.dart
│ │ │ ├── chat_select_model_button.dart
│ │ │ ├── chat_text_field.dart
│ │ │ ├── chat_welcome.dart
│ │ │ └── subwidgets.dart
│ │ ├── main_page.dart
│ │ └── settings_page/
│ │ ├── settings_page.dart
│ │ └── subwidgets/
│ │ ├── reins_settings.dart
│ │ ├── server_settings.dart
│ │ ├── subwidgets.dart
│ │ └── themes_settings.dart
│ ├── Providers/
│ │ └── chat_provider.dart
│ ├── Services/
│ │ ├── database_service.dart
│ │ ├── image_service.dart
│ │ ├── ollama_service.dart
│ │ ├── permission_service.dart
│ │ └── services.dart
│ ├── Utils/
│ │ ├── border_painter.dart
│ │ ├── http_error_formatter.dart
│ │ ├── material_color_adapter.dart
│ │ ├── observe_size.dart
│ │ ├── request_review_helper.dart
│ │ └── retained_position_scroll_physics.dart
│ ├── Widgets/
│ │ ├── chat_app_bar.dart
│ │ ├── chat_configure_bottom_sheet.dart
│ │ ├── chat_drawer.dart
│ │ ├── chat_image.dart
│ │ ├── flexible_text.dart
│ │ ├── model_selection_bottom_sheet.dart
│ │ ├── ollama_bottom_sheet_header.dart
│ │ └── title_divider.dart
│ └── main.dart
├── linux/
│ ├── .gitignore
│ ├── CMakeLists.txt
│ ├── flatpak/
│ │ ├── dev.ibrahimcetin.reins.desktop
│ │ └── dev.ibrahimcetin.reins.metainfo.xml
│ ├── flutter/
│ │ ├── CMakeLists.txt
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugin_registrant.h
│ │ └── generated_plugins.cmake
│ └── runner/
│ ├── CMakeLists.txt
│ ├── main.cc
│ ├── my_application.cc
│ └── my_application.h
├── macos/
│ ├── .gitignore
│ ├── Flutter/
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Podfile
│ ├── Runner/
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets/
│ │ │ └── AppIcon.appiconset/
│ │ │ └── Contents.json
│ │ ├── Base.lproj/
│ │ │ └── MainMenu.xib
│ │ ├── Configs/
│ │ │ ├── AppInfo.xcconfig
│ │ │ ├── Debug.xcconfig
│ │ │ ├── Release.xcconfig
│ │ │ └── Warnings.xcconfig
│ │ ├── DebugProfile.entitlements
│ │ ├── Info.plist
│ │ ├── MainFlutterWindow.swift
│ │ └── Release.entitlements
│ ├── Runner.xcodeproj/
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace/
│ │ │ └── xcshareddata/
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata/
│ │ └── xcschemes/
│ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── RunnerTests/
│ └── RunnerTests.swift
├── pubspec.yaml
├── test/
│ ├── api_create_request_test.dart
│ ├── assets/
│ │ └── settings.hive
│ ├── chat_page_view_model_test.dart
│ ├── database_service_test.dart
│ └── ollama_service_test.dart
├── web/
│ ├── index.html
│ └── manifest.json
└── windows/
├── .gitignore
├── CMakeLists.txt
├── flutter/
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
└── runner/
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
SYMBOL INDEX (377 symbols across 72 files)
FILE: lib/Constants/app_constants.dart
class AppConstants (line 1) | class AppConstants {
class NotificationNames (line 9) | class NotificationNames {
FILE: lib/Constants/chat_presets.dart
class ChatPresets (line 3) | class ChatPresets {
FILE: lib/Constants/generate_title_constants.dart
class GenerateTitleConstants (line 1) | class GenerateTitleConstants {
FILE: lib/Constants/path_manager.dart
class PathManager (line 5) | class PathManager {
method initialize (line 11) | Future<void> initialize()
FILE: lib/Models/api/create_request.dart
class ApiCreateRequest (line 8) | class ApiCreateRequest {
method toJson (line 66) | Future<Map<String, dynamic>> toJson()
FILE: lib/Models/api/show_response.dart
class ApiShowResponse (line 2) | class ApiShowResponse {
class ApiShowModelDetails (line 32) | class ApiShowModelDetails {
FILE: lib/Models/api/tags_response.dart
class ApiTagsResponse (line 2) | class ApiTagsResponse {
class ApiTagsModel (line 15) | class ApiTagsModel {
class ApiTagsModelDetails (line 45) | class ApiTagsModelDetails {
FILE: lib/Models/chat_configure_arguments.dart
class ChatConfigureArguments (line 3) | class ChatConfigureArguments {
FILE: lib/Models/chat_preset.dart
class ChatPreset (line 1) | class ChatPreset {
FILE: lib/Models/model_capabilities.dart
class ModelCapabilities (line 2) | class ModelCapabilities {
method toString (line 29) | String toString()
FILE: lib/Models/ollama_chat.dart
class OllamaChat (line 4) | class OllamaChat {
class OllamaChatOptions (line 33) | class OllamaChatOptions {
method toMap (line 139) | Map<String, dynamic> toMap()
method toJson (line 158) | String toJson()
FILE: lib/Models/ollama_exception.dart
class OllamaException (line 1) | class OllamaException implements Exception {
method toString (line 7) | String toString()
FILE: lib/Models/ollama_message.dart
class OllamaMessage (line 8) | class OllamaMessage {
method toJson (line 92) | Future<Map<String, dynamic>> toJson()
method toChatJson (line 112) | Future<Map<String, dynamic>> toChatJson()
method toDatabaseMap (line 118) | Map<String, dynamic> toDatabaseMap()
method updateMetadataFrom (line 126) | void updateMetadataFrom(OllamaMessage message)
method _base64EncodeImages (line 138) | Future<List<String>?> _base64EncodeImages()
method _constructImages (line 148) | List<File>? _constructImages(String? raw)
method _breakImages (line 162) | String? _breakImages(List<File>? images)
type OllamaMessageRole (line 178) | enum OllamaMessageRole {
FILE: lib/Models/ollama_model.dart
class OllamaModel (line 7) | class OllamaModel {
method toJson (line 50) | Map<String, dynamic> toJson()
method toString (line 60) | String toString()
FILE: lib/Models/ollama_request_state.dart
type OllamaRequestState (line 1) | enum OllamaRequestState {
FILE: lib/Models/settings_route_arguments.dart
class SettingsRouteArguments (line 1) | class SettingsRouteArguments {
FILE: lib/Pages/chat_page/chat_page.dart
class ChatPage (line 11) | class ChatPage extends StatefulWidget {
method createState (line 15) | State<ChatPage> createState()
class _ChatPageState (line 18) | class _ChatPageState extends State<ChatPage> {
method initState (line 27) | void initState()
method build (line 33) | Widget build(BuildContext context)
method _buildChatBody (line 68) | Widget _buildChatBody()
method _buildChatFooter (line 111) | Widget _buildChatFooter()
method _buildTextFieldSuffixIcon (line 141) | Widget? _buildTextFieldSuffixIcon()
method _sendMessage (line 159) | Future<void> _sendMessage()
method _showModelSelectionBottomSheet (line 166) | Future<void> _showModelSelectionBottomSheet()
method _handleAttachmentButton (line 178) | Future<void> _handleAttachmentButton()
method _onServerNotConfigured (line 184) | void _onServerNotConfigured()
method _showPhotosDeniedAlert (line 191) | Future<void> _showPhotosDeniedAlert()
FILE: lib/Pages/chat_page/chat_page_view_model.dart
class ChatPageViewModel (line 18) | class ChatPageViewModel extends ChangeNotifier {
method _initialize (line 65) | void _initialize()
method _onChatProviderChanged (line 85) | void _onChatProviderChanged()
method _onTextFieldChanged (line 89) | void _onTextFieldChanged()
method dispose (line 94) | void dispose()
method cancelStreaming (line 127) | void cancelStreaming()
method retryLastPrompt (line 132) | Future<void> retryLastPrompt()
method fetchAvailableModels (line 137) | Future<List<OllamaModel>> fetchAvailableModels()
method setSelectedModel (line 146) | void setSelectedModel(OllamaModel? model)
method setTextFieldValue (line 156) | void setTextFieldValue(String value)
method _takeTextFieldValue (line 161) | String _takeTextFieldValue()
method pickImages (line 180) | Future<void> pickImages({
method removeImage (line 216) | Future<void> removeImage(File imageFile)
method _takeImages (line 223) | List<File> _takeImages()
method sendMessage (line 235) | Future<bool> sendMessage({
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_image.dart
class ChatAttachmentImage (line 6) | class ChatAttachmentImage extends StatelessWidget {
method build (line 17) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_preset.dart
class ChatAttachmentPreset (line 4) | class ChatAttachmentPreset extends StatelessWidget {
method build (line 15) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_row.dart
class ChatAttachmentRow (line 3) | class ChatAttachmentRow extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble.dart
class ChatBubble (line 14) | class ChatBubble extends StatelessWidget {
method build (line 23) | Widget build(BuildContext context)
class _ChatBubbleBody (line 61) | class _ChatBubbleBody extends StatelessWidget {
method build (line 67) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_actions.dart
class ChatBubbleActions (line 9) | class ChatBubbleActions {
method handleCopy (line 14) | void handleCopy()
method handleSelectText (line 18) | void handleSelectText(BuildContext context)
method handleRegenerate (line 37) | void handleRegenerate(BuildContext context)
method handleEdit (line 43) | void handleEdit(BuildContext context)
method handleDelete (line 92) | void handleDelete(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_bottom_sheet.dart
class ChatBubbleBottomSheet (line 3) | class ChatBubbleBottomSheet extends StatelessWidget {
method build (line 16) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_image.dart
class ChatBubbleImage (line 8) | class ChatBubbleImage extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
class _ChatBubbleImageFullScreen (line 43) | class _ChatBubbleImageFullScreen extends StatelessWidget {
method build (line 49) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_menu.dart
class ChatBubbleMenu (line 4) | class ChatBubbleMenu extends StatefulWidget {
method createState (line 15) | State<ChatBubbleMenu> createState()
class _ChatBubbleMenuState (line 18) | class _ChatBubbleMenuState extends State<ChatBubbleMenu> {
method build (line 20) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_think_block.dart
class ThinkBlockSyntax (line 5) | class ThinkBlockSyntax extends md.BlockSyntax {
method canEndBlock (line 10) | bool canEndBlock(md.BlockParser parser)
method parseChildLines (line 15) | List<md.Line> parseChildLines(md.BlockParser parser)
method parse (line 34) | md.Node parse(md.BlockParser parser)
class ThinkBlockBuilder (line 43) | class ThinkBlockBuilder extends MarkdownElementBuilder {
method visitElementAfter (line 45) | Widget visitElementAfter(md.Element element, TextStyle? preferredStyle)
class ThinkBlockWidget (line 50) | class ThinkBlockWidget extends StatefulWidget {
method createState (line 56) | State<ThinkBlockWidget> createState()
class _ThinkBlockWidgetState (line 59) | class _ThinkBlockWidgetState extends State<ThinkBlockWidget> {
method build (line 63) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_empty.dart
class ChatEmpty (line 5) | class ChatEmpty extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_error.dart
class ChatError (line 3) | class ChatError extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_list_view.dart
class ChatListView (line 11) | class ChatListView extends StatefulWidget {
method createState (line 26) | State<ChatListView> createState()
class _ChatListViewState (line 29) | class _ChatListViewState extends State<ChatListView> {
method initState (line 36) | void initState()
method didUpdateWidget (line 51) | void didUpdateWidget(covariant ChatListView oldWidget)
method dispose (line 64) | void dispose()
method build (line 74) | Widget build(BuildContext context)
method _onMessageSizeChanged (line 139) | void _onMessageSizeChanged(Size? previousSize, Size currentSize)
method _updateScrollToBottomButtonVisibility (line 145) | void _updateScrollToBottomButtonVisibility()
method _scrollToBottom (line 159) | void _scrollToBottom()
FILE: lib/Pages/chat_page/subwidgets/chat_select_model_button.dart
class ChatSelectModelButton (line 3) | class ChatSelectModelButton extends StatelessWidget {
method build (line 14) | Widget build(BuildContext context)
FILE: lib/Pages/chat_page/subwidgets/chat_text_field.dart
class ChatTextField (line 6) | class ChatTextField extends StatefulWidget {
method createState (line 25) | State<ChatTextField> createState()
class _ChatTextFieldState (line 28) | class _ChatTextFieldState extends State<ChatTextField> {
method initState (line 32) | void initState()
method deactivate (line 42) | void deactivate()
method build (line 50) | Widget build(BuildContext context)
method _readTextFieldState (line 86) | String _readTextFieldState()
method _writeTextFieldState (line 90) | void _writeTextFieldState(String text)
FILE: lib/Pages/chat_page/subwidgets/chat_welcome.dart
class ChatWelcome (line 5) | class ChatWelcome extends StatelessWidget {
method build (line 22) | Widget build(BuildContext context)
class _ChatWelcomeText (line 60) | class _ChatWelcomeText extends StatelessWidget {
method build (line 66) | Widget build(BuildContext context)
class _ChatConfigureServerAddressButton (line 87) | class _ChatConfigureServerAddressButton extends StatelessWidget {
method build (line 89) | Widget build(BuildContext context)
FILE: lib/Pages/main_page.dart
class ReinsMainPage (line 7) | class ReinsMainPage extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
class _ReinsMobileMainPage (line 20) | class _ReinsMobileMainPage extends StatelessWidget {
method build (line 24) | Widget build(BuildContext context)
class _ReinsLargeMainPage (line 33) | class _ReinsLargeMainPage extends StatelessWidget {
method build (line 37) | Widget build(BuildContext context)
FILE: lib/Pages/settings_page/settings_page.dart
class SettingsPage (line 7) | class SettingsPage extends StatelessWidget {
method build (line 13) | Widget build(BuildContext context)
class _SettingsPageContent (line 25) | class _SettingsPageContent extends StatelessWidget {
method build (line 31) | Widget build(BuildContext context)
FILE: lib/Pages/settings_page/subwidgets/reins_settings.dart
class ReinsSettings (line 9) | class ReinsSettings extends StatelessWidget {
method build (line 13) | Widget build(BuildContext context)
method _openShareSheet (line 94) | void _openShareSheet(BuildContext context)
FILE: lib/Pages/settings_page/subwidgets/server_settings.dart
class ServerSettings (line 14) | class ServerSettings extends StatefulWidget {
method createState (line 20) | State<ServerSettings> createState()
class _ServerSettingsState (line 23) | class _ServerSettingsState extends State<ServerSettings> {
method initState (line 34) | void initState()
method dispose (line 50) | void dispose()
method build (line 57) | Widget build(BuildContext context)
method _saveServerAddressWith (line 159) | void _saveServerAddressWith((OllamaRequestState, Uri) result)
method _establishServerConnection (line 172) | Future<(OllamaRequestState, Uri)> _establishServerConnection(
method _validateServerAddress (line 189) | String _validateServerAddress(String address)
method _showOllamaInfoBottomSheet (line 227) | void _showOllamaInfoBottomSheet(BuildContext context)
method _handleSearchLocalNetwork (line 236) | void _handleSearchLocalNetwork()
method _searchLocalNetwork (line 264) | Future<(OllamaRequestState, Uri)> _searchLocalNetwork()
class _ConnectionStatusIndicator (line 300) | class _ConnectionStatusIndicator extends StatelessWidget {
method build (line 309) | Widget build(BuildContext context)
class _OllamaInfoBottomSheet (line 328) | class _OllamaInfoBottomSheet extends StatelessWidget {
method build (line 334) | Widget build(BuildContext context)
FILE: lib/Pages/settings_page/subwidgets/themes_settings.dart
class ThemesSettings (line 5) | class ThemesSettings extends StatefulWidget {
method createState (line 9) | State<ThemesSettings> createState()
class _ThemesSettingsState (line 12) | class _ThemesSettingsState extends State<ThemesSettings> {
method build (line 16) | Widget build(BuildContext context)
method _toggleBrightness (line 90) | void _toggleBrightness()
class _ThemeButton (line 107) | class _ThemeButton extends StatelessWidget {
method build (line 114) | Widget build(BuildContext context)
FILE: lib/Providers/chat_provider.dart
class ChatProvider (line 16) | class ChatProvider extends ChangeNotifier {
method _initialize (line 74) | Future<void> _initialize()
method destinationChatSelected (line 82) | void destinationChatSelected(int destination)
method _resetChat (line 94) | void _resetChat()
method _loadCurrentChat (line 102) | Future<void> _loadCurrentChat()
method createNewChat (line 117) | Future<void> createNewChat(OllamaModel model)
method updateCurrentChat (line 135) | Future<void> updateCurrentChat({
method updateChat (line 153) | Future<void> updateChat(
method deleteCurrentChat (line 186) | Future<void> deleteCurrentChat()
method sendPrompt (line 198) | Future<void> sendPrompt(String text, {List<File>? images})
method _initializeChatStream (line 219) | Future<void> _initializeChatStream(OllamaChat associatedChat)
method _streamOllamaMessage (line 266) | Future<OllamaMessage?> _streamOllamaMessage(OllamaChat associatedChat)
method regenerateMessage (line 318) | Future<void> regenerateMessage(OllamaMessage message)
method retryLastPrompt (line 338) | Future<void> retryLastPrompt()
method updateMessage (line 354) | Future<void> updateMessage(
method deleteMessage (line 364) | Future<void> deleteMessage(OllamaMessage message)
method cancelCurrentStreaming (line 373) | void cancelCurrentStreaming()
method _moveCurrentChatToTop (line 378) | void _moveCurrentChatToTop()
method fetchAvailableModels (line 386) | Future<List<OllamaModel>> fetchAvailableModels()
method _updateOllamaServiceAddress (line 390) | void _updateOllamaServiceAddress()
method saveAsNewModel (line 402) | Future<void> saveAsNewModel(String modelName)
method generateTitleForCurrentChat (line 416) | Future<void> generateTitleForCurrentChat()
FILE: lib/Services/database_service.dart
class DatabaseService (line 11) | class DatabaseService {
method getDatabasesPathForPlatform (line 14) | Future<String> getDatabasesPathForPlatform()
method open (line 22) | Future<void> open(String databaseFile)
method close (line 62) | Future<void> close()
method createChat (line 66) | Future<OllamaChat> createChat(String model)
method getChat (line 80) | Future<OllamaChat?> getChat(String chatId)
method updateChat (line 94) | Future<void> updateChat(
method deleteChat (line 114) | Future<void> deleteChat(String chatId)
method getAllChats (line 131) | Future<List<OllamaChat>> getAllChats()
method addMessage (line 146) | Future<void> addMessage(
method getMessage (line 156) | Future<OllamaMessage?> getMessage(String messageId)
method updateMessage (line 170) | Future<void> updateMessage(
method deleteMessage (line 184) | Future<void> deleteMessage(String messageId)
method getMessages (line 194) | Future<List<OllamaMessage>> getMessages(String chatId)
method deleteMessages (line 207) | Future<void> deleteMessages(List<OllamaMessage> messages)
method _cleanupDeletedImages (line 223) | Future<void> _cleanupDeletedImages()
method _constructImages (line 251) | List<File>? _constructImages(String? raw)
FILE: lib/Services/image_service.dart
class ImageService (line 8) | class ImageService {
method getImagesDirectory (line 9) | Future<Directory> getImagesDirectory()
method compressAndSave (line 15) | Future<File?> compressAndSave(String sourcePath, {int quality = 10})
method _compressAndSaveImageForPlatform (line 33) | Future<File?> _compressAndSaveImageForPlatform(
method _compressAndSaveImage (line 53) | Future<File?> _compressAndSaveImage(
method _compressAndSaveImageLinux (line 67) | Future<File?> _compressAndSaveImageLinux(
method deleteImage (line 90) | Future<void> deleteImage(File imageFile)
method deleteImages (line 96) | Future<void> deleteImages(List<File> imageFiles)
FILE: lib/Services/ollama_service.dart
class OllamaService (line 13) | class OllamaService {
method constructUrl (line 32) | Uri constructUrl(String path)
method generate (line 55) | Future<OllamaMessage> generate(
method generateStream (line 85) | Stream<OllamaMessage> generateStream(
method chat (line 127) | Future<OllamaMessage> chat(
method chatStream (line 156) | Stream<OllamaMessage> chatStream(
method _processStream (line 187) | Stream<OllamaMessage> _processStream(Stream stream)
method _prepareMessagesWithSystemPrompt (line 215) | Future<List<Map<String, dynamic>>> _prepareMessagesWithSystemPrompt(
method listModels (line 233) | Future<List<OllamaModel>> listModels()
method _fetchTags (line 248) | Future<ApiTagsResponse> _fetchTags()
method _showModel (line 267) | Future<ApiShowResponse?> _showModel(String name)
method createModel (line 288) | Future<void> createModel(
method deleteModel (line 316) | Future<void> deleteModel(String model)
FILE: lib/Services/permission_service.dart
class PermissionService (line 5) | class PermissionService {
method requestPhotoPermission (line 6) | Future<bool> requestPhotoPermission({
FILE: lib/Utils/border_painter.dart
class BorderPainter (line 3) | class BorderPainter extends CustomPainter {
method paint (line 19) | void paint(Canvas canvas, Size size)
method shouldRepaint (line 46) | bool shouldRepaint(BorderPainter oldDelegate)
FILE: lib/Utils/http_error_formatter.dart
class HttpErrorFormatter (line 8) | class HttpErrorFormatter {
method formatException (line 12) | String formatException(Object error)
method formatHttpError (line 43) | String formatHttpError(int statusCode, {String? body})
FILE: lib/Utils/material_color_adapter.dart
class MaterialColorAdapter (line 4) | class MaterialColorAdapter extends TypeAdapter<MaterialColor> {
method read (line 9) | MaterialColor read(BinaryReader reader)
method write (line 18) | void write(BinaryWriter writer, MaterialColor obj)
FILE: lib/Utils/observe_size.dart
class ObserveSize (line 4) | class ObserveSize extends SingleChildRenderObjectWidget {
method createRenderObject (line 14) | RenderObject createRenderObject(BuildContext context)
class _RenderObserveSize (line 19) | class _RenderObserveSize extends RenderProxyBox {
method performLayout (line 27) | void performLayout()
FILE: lib/Utils/request_review_helper.dart
class RequestReviewHelper (line 3) | final class RequestReviewHelper {
method initialize (line 27) | Future<RequestReviewHelper> initialize()
method incrementCount (line 38) | Future<void> incrementCount({bool isLaunch = false})
method shouldRequestReview (line 46) | bool shouldRequestReview()
method save (line 57) | Future<void> save()
FILE: lib/Utils/retained_position_scroll_physics.dart
class WidgetSizeProxy (line 3) | class WidgetSizeProxy {
class RetainedPositionScrollPhysics (line 7) | class RetainedPositionScrollPhysics extends ScrollPhysics {
method applyTo (line 16) | ScrollPhysics applyTo(ScrollPhysics? ancestor)
method adjustPositionForNewDimensions (line 24) | double adjustPositionForNewDimensions({
FILE: lib/Widgets/chat_app_bar.dart
class ChatAppBar (line 10) | class ChatAppBar extends StatelessWidget implements PreferredSizeWidget {
method build (line 14) | Widget build(BuildContext context)
method _handleModelSelectionButton (line 51) | Future<void> _handleModelSelectionButton(BuildContext context)
method _handleConfigureButton (line 65) | Future<void> _handleConfigureButton(BuildContext context)
FILE: lib/Widgets/chat_configure_bottom_sheet.dart
class ChatConfigureBottomSheet (line 11) | class ChatConfigureBottomSheet extends StatelessWidget {
method build (line 17) | Widget build(BuildContext context)
class _ChatConfigureBottomSheetContent (line 40) | class _ChatConfigureBottomSheetContent extends StatefulWidget {
method createState (line 49) | State<_ChatConfigureBottomSheetContent> createState()
class __ChatConfigureBottomSheetContentState (line 52) | class __ChatConfigureBottomSheetContentState extends State<_ChatConfigur...
method initState (line 59) | void initState()
method dispose (line 66) | void dispose()
method build (line 73) | Widget build(BuildContext context)
class _RenameButton (line 268) | class _RenameButton extends StatelessWidget {
method build (line 272) | Widget build(BuildContext context)
method _showRenameDialog (line 292) | Future<String?> _showRenameDialog(
class _SaveAsNewModelButton (line 334) | class _SaveAsNewModelButton extends StatelessWidget {
method build (line 338) | Widget build(BuildContext context)
method _showSaveAsNewModelDialog (line 381) | Future<String?> _showSaveAsNewModelDialog(BuildContext context)
class _SaveAsNewModelDialog (line 390) | class _SaveAsNewModelDialog extends StatefulWidget {
method createState (line 394) | State<_SaveAsNewModelDialog> createState()
class _SaveAsNewModelDialogState (line 397) | class _SaveAsNewModelDialogState extends State<_SaveAsNewModelDialog> {
method build (line 402) | Widget build(BuildContext context)
method _validateModelName (line 449) | String? _validateModelName(String value)
class _DeleteButton (line 466) | class _DeleteButton extends StatelessWidget {
method build (line 470) | Widget build(BuildContext context)
method _showDeleteDialog (line 482) | void _showDeleteDialog(BuildContext context)
class _BottomSheetButton (line 516) | class _BottomSheetButton extends StatelessWidget {
method build (line 532) | Widget build(BuildContext context)
class _BottomSheetTextField (line 561) | class _BottomSheetTextField<T> extends StatefulWidget {
method createState (line 580) | State<_BottomSheetTextField<T>> createState()
class _BottomSheetTextFieldState (line 583) | class _BottomSheetTextFieldState<T> extends State<_BottomSheetTextField<...
method build (line 587) | Widget build(BuildContext context)
type _BottomSheetTextFieldType (line 717) | enum _BottomSheetTextFieldType {
type ChatConfigureBottomSheetAction (line 724) | enum ChatConfigureBottomSheetAction {
FILE: lib/Widgets/chat_drawer.dart
class ChatDrawer (line 9) | class ChatDrawer extends StatelessWidget {
method build (line 13) | Widget build(BuildContext context)
class ChatNavigationDrawer (line 40) | class ChatNavigationDrawer extends StatelessWidget {
method build (line 44) | Widget build(BuildContext context)
FILE: lib/Widgets/chat_image.dart
class ChatImage (line 3) | class ChatImage extends StatelessWidget {
method build (line 18) | Widget build(BuildContext context)
FILE: lib/Widgets/flexible_text.dart
class FlexibleText (line 7) | class FlexibleText extends StatelessWidget {
method build (line 26) | Widget build(BuildContext context)
FILE: lib/Widgets/model_selection_bottom_sheet.dart
class ModelSelectionBottomSheet (line 12) | class ModelSelectionBottomSheet extends StatefulWidget {
method createState (line 23) | State<ModelSelectionBottomSheet> createState()
class _ModelSelectionBottomSheetState (line 26) | class _ModelSelectionBottomSheetState extends State<ModelSelectionBottom...
method initState (line 41) | void initState()
method dispose (line 54) | void dispose()
method _findModelByName (line 59) | OllamaModel? _findModelByName(String? name)
method _fetchModels (line 68) | Future<void> _fetchModels()
method build (line 95) | Widget build(BuildContext context)
method _buildBody (line 130) | Widget _buildBody(BuildContext context)
class _ModelListTile (line 168) | class _ModelListTile extends StatelessWidget {
method build (line 174) | Widget build(BuildContext context)
method _buildCapabilityChips (line 197) | List<Widget> _buildCapabilityChips(ModelCapabilities capabilities)
class _CapabilityChip (line 223) | class _CapabilityChip extends StatelessWidget {
method build (line 233) | Widget build(BuildContext context)
function showModelSelectionBottomSheet (line 244) | Future<OllamaModel?> showModelSelectionBottomSheet({
FILE: lib/Widgets/ollama_bottom_sheet_header.dart
class OllamaBottomSheetHeader (line 5) | class OllamaBottomSheetHeader extends StatelessWidget {
method build (line 11) | Widget build(BuildContext context)
FILE: lib/Widgets/title_divider.dart
class TitleDivider (line 3) | class TitleDivider extends StatelessWidget {
method build (line 9) | Widget build(BuildContext context)
FILE: lib/main.dart
function main (line 18) | void main()
class ReinsApp (line 76) | class ReinsApp extends StatelessWidget {
method build (line 80) | Widget build(BuildContext context)
FILE: linux/flutter/generated_plugin_registrant.cc
function fl_register_plugins (line 12) | void fl_register_plugins(FlPluginRegistry* registry) {
FILE: linux/runner/main.cc
function main (line 3) | int main(int argc, char** argv) {
FILE: linux/runner/my_application.cc
type _MyApplication (line 10) | struct _MyApplication {
function my_application_activate (line 18) | static void my_application_activate(GApplication* application) {
function gboolean (line 66) | static gboolean my_application_local_command_line(GApplication* applicat...
function my_application_startup (line 85) | static void my_application_startup(GApplication* application) {
function my_application_shutdown (line 94) | static void my_application_shutdown(GApplication* application) {
function my_application_dispose (line 103) | static void my_application_dispose(GObject* object) {
function my_application_class_init (line 109) | static void my_application_class_init(MyApplicationClass* klass) {
function my_application_init (line 117) | static void my_application_init(MyApplication* self) {}
function MyApplication (line 119) | MyApplication* my_application_new() {
FILE: test/api_create_request_test.dart
function main (line 6) | void main()
FILE: test/chat_page_view_model_test.dart
function main (line 18) | void main()
function createTestModel (line 330) | OllamaModel createTestModel(String name)
function createTestChat (line 341) | OllamaChat createTestChat(String id)
class FakeChatProvider (line 355) | class FakeChatProvider extends ChangeNotifier implements ChatProvider {
method setMessages (line 371) | void setMessages(List<OllamaMessage> messages)
method setCurrentChat (line 375) | void setCurrentChat(OllamaChat? chat)
method setIsStreaming (line 379) | void setIsStreaming(bool value)
method setIsThinking (line 383) | void setIsThinking(bool value)
method setCurrentError (line 387) | void setCurrentError(OllamaException? error)
method setAvailableModels (line 391) | void setAvailableModels(List<OllamaModel> models)
method triggerNotifyListeners (line 395) | void triggerNotifyListeners()
method cancelCurrentStreaming (line 415) | void cancelCurrentStreaming()
method retryLastPrompt (line 420) | Future<void> retryLastPrompt()
method fetchAvailableModels (line 425) | Future<List<OllamaModel>> fetchAvailableModels()
method createNewChat (line 430) | Future<void> createNewChat(OllamaModel model)
method sendPrompt (line 436) | Future<void> sendPrompt(String prompt, {List<File>? images})
method generateTitleForCurrentChat (line 443) | Future<void> generateTitleForCurrentChat()
method noSuchMethod (line 449) | dynamic noSuchMethod(Invocation invocation)
class FakePermissionService (line 452) | class FakePermissionService implements PermissionService {
method requestPhotoPermission (line 457) | Future<bool> requestPhotoPermission({VoidCallback? onDenied})
class FakeImageService (line 466) | class FakeImageService implements ImageService {
method compressAndSave (line 471) | Future<File?> compressAndSave(String sourcePath, {int quality = 10})
method deleteImage (line 476) | Future<void> deleteImage(File imageFile)
method deleteImages (line 481) | Future<void> deleteImages(List<File> imageFiles)
method getImagesDirectory (line 486) | Future<Directory> getImagesDirectory()
class FakePathProviderPlatform (line 491) | class FakePathProviderPlatform extends Fake with MockPlatformInterfaceMi...
method getApplicationDocumentsPath (line 493) | Future<String?> getApplicationDocumentsPath()
FILE: test/database_service_test.dart
function main (line 14) | void main()
class FakePathProviderPlatform (line 359) | class FakePathProviderPlatform extends Fake
method getApplicationDocumentsPath (line 363) | Future<String?> getApplicationDocumentsPath()
FILE: test/ollama_service_test.dart
function main (line 9) | void main()
FILE: windows/flutter/generated_plugin_registrant.cc
function RegisterPlugins (line 14) | void RegisterPlugins(flutter::PluginRegistry* registry) {
FILE: windows/runner/flutter_window.cpp
function LRESULT (line 50) | LRESULT
FILE: windows/runner/flutter_window.h
function class (line 12) | class FlutterWindow : public Win32Window {
FILE: windows/runner/main.cpp
function wWinMain (line 8) | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FILE: windows/runner/utils.cpp
function CreateAndAttachConsole (line 10) | void CreateAndAttachConsole() {
function GetCommandLineArguments (line 24) | std::vector<std::string> GetCommandLineArguments() {
function Utf8FromUtf16 (line 44) | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
FILE: windows/runner/win32_window.cpp
function Scale (line 36) | int Scale(int source, double scale_factor) {
function EnableFullDpiSupportIfAvailable (line 42) | void EnableFullDpiSupportIfAvailable(HWND hwnd) {
class WindowClassRegistrar (line 59) | class WindowClassRegistrar {
method WindowClassRegistrar (line 64) | static WindowClassRegistrar* GetInstance() {
method WindowClassRegistrar (line 80) | WindowClassRegistrar() = default;
function wchar_t (line 89) | const wchar_t* WindowClassRegistrar::GetWindowClass() {
function LRESULT (line 157) | LRESULT CALLBACK Win32Window::WndProc(HWND const window,
function LRESULT (line 176) | LRESULT
function Win32Window (line 236) | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
function RECT (line 252) | RECT Win32Window::GetClientArea() {
function HWND (line 258) | HWND Win32Window::GetHandle() {
FILE: windows/runner/win32_window.h
type Size (line 21) | struct Size {
Condensed preview — 172 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (512K chars).
[
{
"path": ".gitignore",
"chars": 709,
"preview": "# Miscellaneous\n*.class\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.build/\n.buildlog/\n.history\n.svn/\n.swiftpm/\nmigrate_working_d"
},
{
"path": ".metadata",
"chars": 1706,
"preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
},
{
"path": ".vscode/launch.json",
"chars": 693,
"preview": "{\n // Use IntelliSense to learn about possible attributes.\n // Hover to view descriptions of existing attributes.\n"
},
{
"path": ".vscode/settings.json",
"chars": 91,
"preview": "{\n \"cmake.ignoreCMakeListsMissing\": true,\n \"cSpell.words\": [\n \"Ollama\"\n ]\n}"
},
{
"path": "LICENSE",
"chars": 35149,
"preview": " GNU GENERAL PUBLIC LICENSE\n Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
},
{
"path": "PRIVACY",
"chars": 118,
"preview": "Reins app does not track any activity or actions of their users. No private information is being collected by the app."
},
{
"path": "README.md",
"chars": 2962,
"preview": "# Reins\n\nReins is a multi-platform, open-source, privacy-first app designed for Ollama users. **It simplifies chat confi"
},
{
"path": "analysis_options.yaml",
"chars": 1449,
"preview": "# This file configures the analyzer, which statically analyzes Dart code to\n# check for errors, warnings, and lints.\n#\n#"
},
{
"path": "android/.gitignore",
"chars": 255,
"preview": "gradle-wrapper.jar\n/.gradle\n/captures/\n/gradlew\n/gradlew.bat\n/local.properties\nGeneratedPluginRegistrant.java\n\n# Remembe"
},
{
"path": "android/app/build.gradle",
"chars": 1925,
"preview": "plugins {\n id \"com.android.application\"\n id \"kotlin-android\"\n // The Flutter Gradle Plugin must be applied afte"
},
{
"path": "android/app/src/debug/AndroidManifest.xml",
"chars": 378,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <!-- The INTERNET permission is required for d"
},
{
"path": "android/app/src/main/AndroidManifest.xml",
"chars": 2315,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <application\n android:label=\"Reins\"\n "
},
{
"path": "android/app/src/main/kotlin/dev/ibrahimcetin/reins/MainActivity.kt",
"chars": 123,
"preview": "package dev.ibrahimcetin.reins\n\nimport io.flutter.embedding.android.FlutterActivity\n\nclass MainActivity: FlutterActivity"
},
{
"path": "android/app/src/main/res/drawable/launch_background.xml",
"chars": 321,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item"
},
{
"path": "android/app/src/main/res/drawable-night/launch_background.xml",
"chars": 321,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item"
},
{
"path": "android/app/src/main/res/drawable-night-v21/launch_background.xml",
"chars": 321,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item"
},
{
"path": "android/app/src/main/res/drawable-v21/launch_background.xml",
"chars": 321,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <item"
},
{
"path": "android/app/src/main/res/values/styles.xml",
"chars": 1267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "android/app/src/main/res/values-night/styles.xml",
"chars": 1266,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "android/app/src/main/res/values-night-v31/styles.xml",
"chars": 1224,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "android/app/src/main/res/values-v31/styles.xml",
"chars": 1225,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <!-- Theme applied to the Android Window while the process is sta"
},
{
"path": "android/app/src/profile/AndroidManifest.xml",
"chars": 378,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <!-- The INTERNET permission is required for d"
},
{
"path": "android/build.gradle",
"chars": 322,
"preview": "allprojects {\n repositories {\n google()\n mavenCentral()\n }\n}\n\nrootProject.buildDir = \"../build\"\nsubp"
},
{
"path": "android/gradle/wrapper/gradle-wrapper.properties",
"chars": 200,
"preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dist"
},
{
"path": "android/gradle.properties",
"chars": 135,
"preview": "org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError\nandroid.useAndroidX=true\nandroid.enabl"
},
{
"path": "android/settings.gradle",
"chars": 727,
"preview": "pluginManagement {\n def flutterSdkPath = {\n def properties = new Properties()\n file(\"local.properties\")"
},
{
"path": "devtools_options.yaml",
"chars": 184,
"preview": "description: This file stores settings for Dart & Flutter DevTools.\ndocumentation: https://docs.flutter.dev/tools/devtoo"
},
{
"path": "ios/.gitignore",
"chars": 569,
"preview": "**/dgph\n*.mode1v3\n*.mode2v3\n*.moved-aside\n*.pbxuser\n*.perspectivev3\n**/*sync/\n.sconsign.dblite\n.tags*\n**/.vagrant/\n**/De"
},
{
"path": "ios/Flutter/AppFrameworkInfo.plist",
"chars": 774,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Flutter/Debug.xcconfig",
"chars": 107,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"Generated.xcconfig\"\n"
},
{
"path": "ios/Flutter/Release.xcconfig",
"chars": 109,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"Generated.xcconfig\"\n"
},
{
"path": "ios/Podfile",
"chars": 1649,
"preview": "# Uncomment this line to define a global platform for your project\n# platform :ios, '13.0'\n\n# CocoaPods analytics sends "
},
{
"path": "ios/Runner/AppDelegate.swift",
"chars": 391,
"preview": "import Flutter\nimport UIKit\n\n@main\n@objc class AppDelegate: FlutterAppDelegate {\n override func application(\n _ appl"
},
{
"path": "ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 715,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"reins.png\",\n \"idiom\" : \"universal\",\n \"platform\" : \"ios\",\n \"siz"
},
{
"path": "ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json",
"chars": 361,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"background.png\",\n \"idiom\" : \"universal\"\n },\n {\n \"appearances\""
},
{
"path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
"chars": 1069,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"LaunchImage.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n },\n "
},
{
"path": "ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
"chars": 336,
"preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
},
{
"path": "ios/Runner/Base.lproj/LaunchScreen.storyboard",
"chars": 3487,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "ios/Runner/Base.lproj/Main.storyboard",
"chars": 1605,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "ios/Runner/Info.plist",
"chars": 1874,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner/Runner-Bridging-Header.h",
"chars": 38,
"preview": "#import \"GeneratedPluginRegistrant.h\"\n"
},
{
"path": "ios/Runner.xcodeproj/project.pbxproj",
"chars": 33362,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 4717,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1510\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "ios/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 224,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
"chars": 226,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "ios/RunnerTests/RunnerTests.swift",
"chars": 285,
"preview": "import Flutter\nimport UIKit\nimport XCTest\n\nclass RunnerTests: XCTestCase {\n\n func testExample() {\n // If you add cod"
},
{
"path": "lib/Constants/app_constants.dart",
"chars": 357,
"preview": "class AppConstants {\n static const String appName = 'Reins';\n static const String appIconPng = 'assets/images/reins.pn"
},
{
"path": "lib/Constants/chat_presets.dart",
"chars": 13487,
"preview": "import 'package:reins/Models/chat_preset.dart';\n\nclass ChatPresets {\n static final List<ChatPreset> chatPresets = List."
},
{
"path": "lib/Constants/constants.dart",
"chars": 125,
"preview": "export 'app_constants.dart';\nexport 'path_manager.dart';\nexport 'chat_presets.dart';\nexport 'generate_title_constants.da"
},
{
"path": "lib/Constants/generate_title_constants.dart",
"chars": 1428,
"preview": "class GenerateTitleConstants {\n static const String systemPrompt =\n \"You are a title generator for a chat applicat"
},
{
"path": "lib/Constants/path_manager.dart",
"chars": 598,
"preview": "import 'dart:io';\n\nimport 'package:path_provider/path_provider.dart';\n\nclass PathManager {\n static final PathManager _i"
},
{
"path": "lib/Extensions/markdown_stylesheet_extension.dart",
"chars": 910,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_markdown/flutter_markdown.dart';\n\n/// Extension on [Buil"
},
{
"path": "lib/Models/api/create_request.dart",
"chars": 2306,
"preview": "import 'package:reins/Models/ollama_chat.dart';\nimport 'package:reins/Models/ollama_message.dart';\n\n/// Request body for"
},
{
"path": "lib/Models/api/show_response.dart",
"chars": 1763,
"preview": "/// Response from POST /api/show\nclass ApiShowResponse {\n final String modelfile;\n final String parameters;\n final St"
},
{
"path": "lib/Models/api/tags_response.dart",
"chars": 1925,
"preview": "/// Response from GET /api/tags\nclass ApiTagsResponse {\n final List<ApiTagsModel> models;\n\n ApiTagsResponse({required "
},
{
"path": "lib/Models/chat_configure_arguments.dart",
"chars": 373,
"preview": "import 'package:reins/Models/ollama_chat.dart';\n\nclass ChatConfigureArguments {\n String? systemPrompt;\n OllamaChatOpti"
},
{
"path": "lib/Models/chat_preset.dart",
"chars": 192,
"preview": "class ChatPreset {\n final String title;\n final String subtitle;\n final String prompt;\n\n ChatPreset({\n required th"
},
{
"path": "lib/Models/model_capabilities.dart",
"chars": 1114,
"preview": "/// Model capabilities extracted from /api/show response\nclass ModelCapabilities {\n final bool completion;\n final bool"
},
{
"path": "lib/Models/ollama_chat.dart",
"chars": 5319,
"preview": "import 'dart:convert';\nimport 'package:uuid/uuid.dart';\n\nclass OllamaChat {\n final String id;\n final String model;\n f"
},
{
"path": "lib/Models/ollama_exception.dart",
"chars": 164,
"preview": "class OllamaException implements Exception {\n final String message;\n\n OllamaException(this.message);\n\n @override\n St"
},
{
"path": "lib/Models/ollama_message.dart",
"chars": 5423,
"preview": "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:path/path.dart' as path;\nimport 'package:reins/Constants/const"
},
{
"path": "lib/Models/ollama_model.dart",
"chars": 2114,
"preview": "import 'package:reins/Models/api/tags_response.dart';\nimport 'package:reins/Models/api/show_response.dart';\nimport 'pack"
},
{
"path": "lib/Models/ollama_request_state.dart",
"chars": 76,
"preview": "enum OllamaRequestState {\n error,\n loading,\n success,\n uninitialized,\n}\n"
},
{
"path": "lib/Models/settings_route_arguments.dart",
"chars": 137,
"preview": "class SettingsRouteArguments {\n final bool autoFocusServerAddress;\n\n SettingsRouteArguments({required this.autoFocusSe"
},
{
"path": "lib/Pages/chat_page/chat_page.dart",
"chars": 6148,
"preview": "import 'package:flutter/material.dart';\nimport 'package:provider/provider.dart';\nimport 'package:responsive_framework/re"
},
{
"path": "lib/Pages/chat_page/chat_page_view_model.dart",
"chars": 8916,
"preview": "import 'dart:async';\nimport 'dart:io';\nimport 'dart:ui';\n\nimport 'package:flutter/material.dart';\nimport 'package:hive_f"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_image.dart",
"chars": 874,
"preview": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:reins/Widgets/chat_image.dart';\n\nclass ChatAt"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_preset.dart",
"chars": 1060,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Models/chat_preset.dart';\n\nclass ChatAttachmentPreset exte"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_attachment/chat_attachment_row.dart",
"chars": 675,
"preview": "import 'package:flutter/material.dart';\n\nclass ChatAttachmentRow extends StatelessWidget {\n final int itemCount;\n fina"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble.dart",
"chars": 4660,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_markdown/flutter_markdown.dart';\nimport 'package:google_"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_actions.dart",
"chars": 3543,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\nimport 'package:provider/provider.dart';"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_bottom_sheet.dart",
"chars": 1266,
"preview": "import 'package:flutter/material.dart';\n\nclass ChatBubbleBottomSheet extends StatelessWidget {\n final String title;\n f"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_image.dart",
"chars": 2393,
"preview": "import 'dart:io';\nimport 'dart:math';\n\nimport 'package:flutter/material.dart';\nimport 'package:photo_view/photo_view.dar"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_menu.dart",
"chars": 1702,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Utils/border_painter.dart';\n\nclass ChatBubbleMenu extends "
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_bubble/chat_bubble_think_block.dart",
"chars": 2355,
"preview": "import 'package:flutter/material.dart';\nimport 'package:markdown/markdown.dart' as md;\nimport 'package:flutter_markdown/"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_empty.dart",
"chars": 830,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter_svg/svg.dart';\nimport 'package:reins/Constants/constants"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_error.dart",
"chars": 1092,
"preview": "import 'package:flutter/material.dart';\n\nclass ChatError extends StatelessWidget {\n final String message;\n final void "
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_list_view.dart",
"chars": 5060,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Models/ollama_message.dart';\nimport 'package:shimmer/shimm"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_select_model_button.dart",
"chars": 554,
"preview": "import 'package:flutter/material.dart';\n\nclass ChatSelectModelButton extends StatelessWidget {\n final String? currentMo"
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_text_field.dart",
"chars": 2596,
"preview": "import 'dart:io' show Platform;\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nclass "
},
{
"path": "lib/Pages/chat_page/subwidgets/chat_welcome.dart",
"chars": 2900,
"preview": "import 'package:animated_text_kit/animated_text_kit.dart';\nimport 'package:flutter/material.dart';\nimport 'package:reins"
},
{
"path": "lib/Pages/chat_page/subwidgets/subwidgets.dart",
"chars": 340,
"preview": "export 'chat_list_view.dart';\nexport 'chat_empty.dart';\nexport 'chat_select_model_button.dart';\nexport 'chat_welcome.dar"
},
{
"path": "lib/Pages/main_page.dart",
"chars": 1183,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Pages/chat_page/chat_page.dart';\nimport 'package:reins/Wid"
},
{
"path": "lib/Pages/settings_page/settings_page.dart",
"chars": 1179,
"preview": "import 'package:flutter/material.dart';\nimport 'package:google_fonts/google_fonts.dart';\nimport 'package:reins/Models/se"
},
{
"path": "lib/Pages/settings_page/subwidgets/reins_settings.dart",
"chars": 3384,
"preview": "import 'package:flutter/material.dart';\nimport 'package:share_plus/share_plus.dart';\nimport 'package:url_launcher/url_la"
},
{
"path": "lib/Pages/settings_page/subwidgets/server_settings.dart",
"chars": 10919,
"preview": "import 'dart:io';\nimport 'dart:isolate';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_markdown/flutt"
},
{
"path": "lib/Pages/settings_page/subwidgets/subwidgets.dart",
"chars": 92,
"preview": "export 'server_settings.dart';\nexport 'themes_settings.dart';\nexport 'reins_settings.dart';\n"
},
{
"path": "lib/Pages/settings_page/subwidgets/themes_settings.dart",
"chars": 5072,
"preview": "import 'package:flutter/material.dart';\nimport 'package:hive_flutter/hive_flutter.dart';\nimport 'package:reins/Constants"
},
{
"path": "lib/Providers/chat_provider.dart",
"chars": 14002,
"preview": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:hive_flutter/hive_flutter.dart';\nimport 'pack"
},
{
"path": "lib/Services/database_service.dart",
"chars": 6639,
"preview": "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:reins/Constants/constants.dart';\nimport 'package:reins/Models/"
},
{
"path": "lib/Services/image_service.dart",
"chars": 2681,
"preview": "import 'dart:io';\nimport 'package:flutter_image_compress/flutter_image_compress.dart';\nimport 'package:image_compression"
},
{
"path": "lib/Services/ollama_service.dart",
"chars": 11229,
"preview": "import 'dart:convert';\n\nimport 'package:http/http.dart' as http;\nimport 'package:reins/Utils/http_error_formatter.dart';"
},
{
"path": "lib/Services/permission_service.dart",
"chars": 504,
"preview": "import 'dart:io';\nimport 'package:flutter/material.dart' show VoidCallback;\nimport 'package:permission_handler/permissio"
},
{
"path": "lib/Services/services.dart",
"chars": 125,
"preview": "export 'database_service.dart';\nexport 'ollama_service.dart';\nexport 'permission_service.dart';\nexport 'image_service.da"
},
{
"path": "lib/Utils/border_painter.dart",
"chars": 1352,
"preview": "import 'package:flutter/material.dart';\n\nclass BorderPainter extends CustomPainter {\n final Color? color;\n final Gradi"
},
{
"path": "lib/Utils/http_error_formatter.dart",
"chars": 3094,
"preview": "import 'dart:async';\nimport 'dart:io';\n\n/// A utility class for formatting HTTP errors and exceptions into human-readabl"
},
{
"path": "lib/Utils/material_color_adapter.dart",
"chars": 492,
"preview": "import 'package:hive/hive.dart';\nimport 'package:flutter/material.dart';\n\nclass MaterialColorAdapter extends TypeAdapter"
},
{
"path": "lib/Utils/observe_size.dart",
"chars": 762,
"preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/rendering.dart';\n\nclass ObserveSize extends SingleChildR"
},
{
"path": "lib/Utils/request_review_helper.dart",
"chars": 1588,
"preview": "import 'package:hive/hive.dart';\n\nfinal class RequestReviewHelper {\n /// The number of times the app has been launched\n"
},
{
"path": "lib/Utils/retained_position_scroll_physics.dart",
"chars": 1297,
"preview": "import 'package:flutter/material.dart';\n\nclass WidgetSizeProxy {\n double deltaHeight = 0.0;\n}\n\nclass RetainedPositionSc"
},
{
"path": "lib/Widgets/chat_app_bar.dart",
"chars": 3017,
"preview": "import 'package:flutter/material.dart';\nimport 'package:google_fonts/google_fonts.dart';\nimport 'package:reins/Constants"
},
{
"path": "lib/Widgets/chat_configure_bottom_sheet.dart",
"chars": 24163,
"preview": "import 'package:flutter/material.dart';\nimport 'package:provider/provider.dart';\nimport 'package:reins/Models/chat_confi"
},
{
"path": "lib/Widgets/chat_drawer.dart",
"chars": 2811,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Constants/constants.dart';\nimport 'package:reins/Providers"
},
{
"path": "lib/Widgets/chat_image.dart",
"chars": 874,
"preview": "import 'package:flutter/material.dart';\n\nclass ChatImage extends StatelessWidget {\n final ImageProvider image;\n final "
},
{
"path": "lib/Widgets/flexible_text.dart",
"chars": 867,
"preview": "import 'package:flutter/material.dart';\n\n/// A [Text] widget wrapped in [Flexible] for use inside [Row] or [Column].\n///"
},
{
"path": "lib/Widgets/model_selection_bottom_sheet.dart",
"chars": 7203,
"preview": "import 'package:flutter/material.dart';\nimport 'package:async/async.dart';\nimport 'package:hive_flutter/hive_flutter.dar"
},
{
"path": "lib/Widgets/ollama_bottom_sheet_header.dart",
"chars": 741,
"preview": "import 'package:flutter/material.dart';\nimport 'package:reins/Constants/constants.dart';\nimport 'package:reins/Widgets/f"
},
{
"path": "lib/Widgets/title_divider.dart",
"chars": 458,
"preview": "import 'package:flutter/material.dart';\n\nclass TitleDivider extends StatelessWidget {\n final String title;\n\n const Tit"
},
{
"path": "lib/main.dart",
"chars": 4407,
"preview": "import 'package:flutter/material.dart';\nimport 'package:in_app_review/in_app_review.dart';\nimport 'package:reins/Constan"
},
{
"path": "linux/.gitignore",
"chars": 18,
"preview": "flutter/ephemeral\n"
},
{
"path": "linux/CMakeLists.txt",
"chars": 4754,
"preview": "# Project-level configuration.\ncmake_minimum_required(VERSION 3.13)\nproject(runner LANGUAGES CXX)\n\n# The name of the exe"
},
{
"path": "linux/flatpak/dev.ibrahimcetin.reins.desktop",
"chars": 215,
"preview": "[Desktop Entry]\nType=Application\n\nName=Reins\nComment=Private AI Chat\nCategories=Utility;Development;Chat;\nKeywords=ai;ch"
},
{
"path": "linux/flatpak/dev.ibrahimcetin.reins.metainfo.xml",
"chars": 4066,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<component type=\"desktop-application\">\n <id>dev.ibrahimcetin.reins</id>\n\n <name"
},
{
"path": "linux/flutter/CMakeLists.txt",
"chars": 2815,
"preview": "# This file controls Flutter-level build steps. It should not be edited.\ncmake_minimum_required(VERSION 3.10)\n\nset(EPHEM"
},
{
"path": "linux/flutter/generated_plugin_registrant.cc",
"chars": 713,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n#include <file_se"
},
{
"path": "linux/flutter/generated_plugin_registrant.h",
"chars": 303,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "linux/flutter/generated_plugins.cmake",
"chars": 782,
"preview": "#\n# Generated file, do not edit.\n#\n\nlist(APPEND FLUTTER_PLUGIN_LIST\n file_selector_linux\n url_launcher_linux\n)\n\nlist(A"
},
{
"path": "linux/runner/CMakeLists.txt",
"chars": 974,
"preview": "cmake_minimum_required(VERSION 3.13)\nproject(runner LANGUAGES CXX)\n\n# Define the application target. To change its name,"
},
{
"path": "linux/runner/main.cc",
"chars": 180,
"preview": "#include \"my_application.h\"\n\nint main(int argc, char** argv) {\n g_autoptr(MyApplication) app = my_application_new();\n "
},
{
"path": "linux/runner/my_application.cc",
"chars": 4744,
"preview": "#include \"my_application.h\"\n\n#include <flutter_linux/flutter_linux.h>\n#ifdef GDK_WINDOWING_X11\n#include <gdk/gdkx.h>\n#en"
},
{
"path": "linux/runner/my_application.h",
"chars": 388,
"preview": "#ifndef FLUTTER_MY_APPLICATION_H_\n#define FLUTTER_MY_APPLICATION_H_\n\n#include <gtk/gtk.h>\n\nG_DECLARE_FINAL_TYPE(MyApplic"
},
{
"path": "macos/.gitignore",
"chars": 89,
"preview": "# Flutter-related\n**/Flutter/ephemeral/\n**/Pods/\n\n# Xcode-related\n**/dgph\n**/xcuserdata/\n"
},
{
"path": "macos/Flutter/Flutter-Debug.xcconfig",
"chars": 125,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xccon"
},
{
"path": "macos/Flutter/Flutter-Release.xcconfig",
"chars": 127,
"preview": "#include? \"Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig\"\n#include \"ephemeral/Flutter-Generated.xcc"
},
{
"path": "macos/Flutter/GeneratedPluginRegistrant.swift",
"chars": 968,
"preview": "//\n// Generated file. Do not edit.\n//\n\nimport FlutterMacOS\nimport Foundation\n\nimport file_selector_macos\nimport flutter"
},
{
"path": "macos/Podfile",
"chars": 1389,
"preview": "platform :osx, '10.15'\n\n# CocoaPods analytics sends network stats synchronously affecting flutter build latency.\nENV['CO"
},
{
"path": "macos/Runner/AppDelegate.swift",
"chars": 311,
"preview": "import Cocoa\nimport FlutterMacOS\n\n@main\nclass AppDelegate: FlutterAppDelegate {\n override func applicationShouldTermina"
},
{
"path": "macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 1582,
"preview": "{\n \"info\": {\n \"version\": 1,\n \"author\": \"xcode\"\n },\n \"images\": [\n {\n \"size\": \"16"
},
{
"path": "macos/Runner/Base.lproj/MainMenu.xib",
"chars": 23775,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion"
},
{
"path": "macos/Runner/Configs/AppInfo.xcconfig",
"chars": 606,
"preview": "// Application-level settings for the Runner target.\n//\n// This may be replaced with something auto-generated from metad"
},
{
"path": "macos/Runner/Configs/Debug.xcconfig",
"chars": 77,
"preview": "#include \"../../Flutter/Flutter-Debug.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
},
{
"path": "macos/Runner/Configs/Release.xcconfig",
"chars": 79,
"preview": "#include \"../../Flutter/Flutter-Release.xcconfig\"\n#include \"Warnings.xcconfig\"\n"
},
{
"path": "macos/Runner/Configs/Warnings.xcconfig",
"chars": 580,
"preview": "WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverl"
},
{
"path": "macos/Runner/DebugProfile.entitlements",
"chars": 473,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "macos/Runner/Info.plist",
"chars": 1204,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "macos/Runner/MainFlutterWindow.swift",
"chars": 388,
"preview": "import Cocoa\nimport FlutterMacOS\n\nclass MainFlutterWindow: NSWindow {\n override func awakeFromNib() {\n let flutterVi"
},
{
"path": "macos/Runner/Release.entitlements",
"chars": 365,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "macos/Runner.xcodeproj/project.pbxproj",
"chars": 35371,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXAggregateTarget sec"
},
{
"path": "macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
"chars": 4555,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n LastUpgradeVersion = \"1510\"\n version = \"1.3\">\n <BuildAction\n "
},
{
"path": "macos/Runner.xcworkspace/contents.xcworkspacedata",
"chars": 224,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"group:Runner.xcodepr"
},
{
"path": "macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "macos/RunnerTests/RunnerTests.swift",
"chars": 290,
"preview": "import Cocoa\nimport FlutterMacOS\nimport XCTest\n\nclass RunnerTests: XCTestCase {\n\n func testExample() {\n // If you ad"
},
{
"path": "pubspec.yaml",
"chars": 5125,
"preview": "name: reins\ndescription: \"Best-in-class chat experience for Ollama.\"\n# The following line prevents the package from bein"
},
{
"path": "test/api_create_request_test.dart",
"chars": 4970,
"preview": "import 'package:reins/Models/api/create_request.dart';\nimport 'package:reins/Models/ollama_chat.dart';\nimport 'package:r"
},
{
"path": "test/chat_page_view_model_test.dart",
"chars": 13768,
"preview": "import 'dart:io';\n\nimport 'package:flutter/material.dart';\nimport 'package:flutter_test/flutter_test.dart';\nimport 'pack"
},
{
"path": "test/database_service_test.dart",
"chars": 11721,
"preview": "import 'dart:io';\n\nimport 'package:flutter_test/flutter_test.dart';\nimport 'package:reins/Constants/constants.dart';\nimp"
},
{
"path": "test/ollama_service_test.dart",
"chars": 8037,
"preview": "import 'dart:io';\n\nimport 'package:path/path.dart' as path;\nimport 'package:reins/Models/ollama_chat.dart';\nimport 'pack"
},
{
"path": "web/index.html",
"chars": 1208,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <!--\n If you are serving your web app in a path other than the root, change the\n h"
},
{
"path": "web/manifest.json",
"chars": 906,
"preview": "{\n \"name\": \"reins\",\n \"short_name\": \"reins\",\n \"start_url\": \".\",\n \"display\": \"standalone\",\n \"background_col"
},
{
"path": "windows/.gitignore",
"chars": 291,
"preview": "flutter/ephemeral/\n\n# Visual Studio user-specific files.\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# Visual Studio bu"
},
{
"path": "windows/CMakeLists.txt",
"chars": 4146,
"preview": "# Project-level configuration.\ncmake_minimum_required(VERSION 3.14)\nproject(reins LANGUAGES CXX)\n\n# The name of the exec"
},
{
"path": "windows/flutter/CMakeLists.txt",
"chars": 3742,
"preview": "# This file controls Flutter-level build steps. It should not be edited.\ncmake_minimum_required(VERSION 3.14)\n\nset(EPHEM"
},
{
"path": "windows/flutter/generated_plugin_registrant.cc",
"chars": 868,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#include \"generated_plugin_registrant.h\"\n\n#include <file_se"
},
{
"path": "windows/flutter/generated_plugin_registrant.h",
"chars": 302,
"preview": "//\n// Generated file. Do not edit.\n//\n\n// clang-format off\n\n#ifndef GENERATED_PLUGIN_REGISTRANT_\n#define GENERATED_PLUG"
},
{
"path": "windows/flutter/generated_plugins.cmake",
"chars": 832,
"preview": "#\n# Generated file, do not edit.\n#\n\nlist(APPEND FLUTTER_PLUGIN_LIST\n file_selector_windows\n permission_handler_windows"
},
{
"path": "windows/runner/CMakeLists.txt",
"chars": 1796,
"preview": "cmake_minimum_required(VERSION 3.14)\nproject(runner LANGUAGES CXX)\n\n# Define the application target. To change its name,"
},
{
"path": "windows/runner/Runner.rc",
"chars": 3027,
"preview": "// Microsoft Visual C++ generated resource script.\n//\n#pragma code_page(65001)\n#include \"resource.h\"\n\n#define APSTUDIO_R"
},
{
"path": "windows/runner/flutter_window.cpp",
"chars": 2122,
"preview": "#include \"flutter_window.h\"\n\n#include <optional>\n\n#include \"flutter/generated_plugin_registrant.h\"\n\nFlutterWindow::Flutt"
},
{
"path": "windows/runner/flutter_window.h",
"chars": 928,
"preview": "#ifndef RUNNER_FLUTTER_WINDOW_H_\n#define RUNNER_FLUTTER_WINDOW_H_\n\n#include <flutter/dart_project.h>\n#include <flutter/f"
},
{
"path": "windows/runner/main.cpp",
"chars": 1258,
"preview": "#include <flutter/dart_project.h>\n#include <flutter/flutter_view_controller.h>\n#include <windows.h>\n\n#include \"flutter_w"
},
{
"path": "windows/runner/resource.h",
"chars": 432,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by Runner.rc\n//\n#define IDI_APP_ICON "
},
{
"path": "windows/runner/runner.exe.manifest",
"chars": 602,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersi"
},
{
"path": "windows/runner/utils.cpp",
"chars": 1797,
"preview": "#include \"utils.h\"\n\n#include <flutter_windows.h>\n#include <io.h>\n#include <stdio.h>\n#include <windows.h>\n\n#include <iost"
},
{
"path": "windows/runner/utils.h",
"chars": 672,
"preview": "#ifndef RUNNER_UTILS_H_\n#define RUNNER_UTILS_H_\n\n#include <string>\n#include <vector>\n\n// Creates a console for the proce"
},
{
"path": "windows/runner/win32_window.cpp",
"chars": 8534,
"preview": "#include \"win32_window.h\"\n\n#include <dwmapi.h>\n#include <flutter_windows.h>\n\n#include \"resource.h\"\n\nnamespace {\n\n/// Win"
},
{
"path": "windows/runner/win32_window.h",
"chars": 3522,
"preview": "#ifndef RUNNER_WIN32_WINDOW_H_\n#define RUNNER_WIN32_WINDOW_H_\n\n#include <windows.h>\n\n#include <functional>\n#include <mem"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the ibrahimcetin/reins GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 172 files (466.2 KB), approximately 119.6k tokens, and a symbol index with 377 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.